Something went wrong on our end
circ_buffer.c 1.98 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; })
static unsigned char buffer[CIRC_BUFFER_SIZE];
static size_t buf_start = 0;
static size_t buf_end = 0;
static size_t size = 0;
struct data_chunk getChunk(size_t amount) {
size_t chunk_end = buf_end;
if (buf_end < buf_start) {
chunk_end = CIRC_BUFFER_SIZE;
}
size_t ret_size = circ_buf_min(amount, 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;
int loops = 0; // Limit on number of iterations, just in case
while (placed < will_place && loops < 2) {
// 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 we copied to the end
if (buf_end >= CIRC_BUFFER_SIZE) {
buf_end = 0;
}
placed += to_copy;
loops += 1;
}
size += placed;
return placed;
}
size_t circ_buf_size(){
return size;
}
size_t circ_buf_available() {
return CIRC_BUFFER_SIZE - size;
}