Something went wrong on our end
-
David Wehr authoredDavid Wehr authored
circ_buffer.c 1.87 KiB
//
// Created by dawehr on 10/24/2016.
//
#include "circ_buffer.h"
#define circ_buf_min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
unsigned char buffer[CIRC_BUFFER_SIZE];
size_t buf_start = 0;
size_t buf_end = 0;
size_t size = 0;
struct data_chunk getChunk() {
size_t chunk_end = buf_end;
if (buf_end < buf_start) {
chunk_end = CIRC_BUFFER_SIZE;
}
size_t ret_size = chunk_end - buf_start;
struct data_chunk c = {
ret_size,
&buffer[buf_start]
};
return c;
}
void markConsumed( size_t n_consumed) {
size_t chunk_end = buf_start + n_consumed;
buf_start = chunk_end;
size -= n_consumed;
if (buf_start == CIRC_BUFFER_SIZE) {
buf_start = 0;
}
}
size_t putChunk(struct data_chunk c) {
// The amount that will be placed into the buffer
size_t will_place = circ_buf_min(CIRC_BUFFER_SIZE - size, c.length);
// Actual amount placed so far
size_t placed = 0;
while (placed < will_place) {
// Available room without wrapping
size_t to_copy;
if (buf_end >= buf_start) {
// If buffer is not wrapped, we can copy until the end of the buffer
to_copy = circ_buf_min(will_place, CIRC_BUFFER_SIZE - buf_end);
} else {
// Otherwise, remaining space in buffer is contiguous
to_copy = will_place - placed;
}
memcpy(buffer + buf_end, c.data + placed, to_copy);
// Update buffer endpoint
buf_end += to_copy;
if (buf_end > CIRC_BUFFER_SIZE) {
printf("Error: buf_end: %d\n", buf_end);
}
// If we copied to the end
if (buf_end == CIRC_BUFFER_SIZE) {
buf_end = 0;
}
placed += to_copy;
}
size += placed;
return placed;
}
size_t get_buffer_size() {
return size;
}