diff --git a/circbuf.c b/circbuf.c index aca9411..bc965f6 100644 --- a/circbuf.c +++ b/circbuf.c @@ -1,39 +1,54 @@ #include #include #include +#include #include "circbuf.h" -void cbuf_init(CircularBuffer *inst, uint8_t *buffer, uint16_t length) +void cbuf_init(circbuf_t *inst, uint16_t length) { - inst->buffer = buffer; + inst->buffer = malloc(length); inst->capacity = length; cbuf_clear(inst); } -bool cbuf_full(CircularBuffer *inst) +void cbuf_deinit(circbuf_t *inst) { - return inst->data_len == inst->capacity; + if (inst->buffer != NULL) { + free(inst->buffer); + } +} + + +bool cbuf_full(circbuf_t *inst) +{ + if (inst->read_pos == 0) { + return inst->write_pos == inst->capacity - 1; + } else { + return inst->write_pos == inst->read_pos; + } } -bool cbuf_empty(CircularBuffer *inst) +bool cbuf_empty(circbuf_t *inst) { - return inst->data_len == 0; + if (inst->write_pos == 0) { + return inst->read_pos == inst->capacity - 1; + } else { + return inst->read_pos == inst->write_pos - 1; + } } -bool cbuf_write(CircularBuffer *inst, uint8_t b) +bool cbuf_write(circbuf_t *inst, uint8_t b) { if (cbuf_full(inst)) return false; inst->buffer[inst->write_pos] = b; - inst->write_pos++; - inst->data_len++; // wrap if (inst->write_pos >= inst->capacity) { @@ -44,150 +59,37 @@ bool cbuf_write(CircularBuffer *inst, uint8_t b) } -bool cbuf_read(CircularBuffer *inst, uint8_t *b) +bool cbuf_read(circbuf_t *inst, uint8_t *b) { if (cbuf_empty(inst)) return false; - *b = inst->buffer[inst->read_pos]; - inst->read_pos++; - inst->data_len--; // wrap if (inst->read_pos >= inst->capacity) { inst->read_pos = 0; } - return true; -} - - -bool cbuf_peek(CircularBuffer *inst, uint8_t *b) -{ - if (cbuf_empty(inst)) return false; - *b = inst->buffer[inst->read_pos]; - return true; -} - -uint16_t cbuf_data_size(CircularBuffer *inst) -{ - return inst->data_len; -} - - -uint16_t cbuf_free_space(CircularBuffer *inst) -{ - return inst->capacity - inst->data_len; -} - - -void cbuf_clear(CircularBuffer *inst) -{ - inst->read_pos = 0; - inst->write_pos = 0; - inst->data_len = 0; -} - - -bool cbuf_write_n(CircularBuffer *inst, const uint8_t *b, uint16_t count) -{ - if (cbuf_free_space(inst) < count) return false; - - for (uint16_t i = 0; i < count; i++) { - cbuf_write(inst, *(b + i)); - } + // zero out the read byte (for debug) + //inst->buffer[inst->read_pos] = 0; return true; } -uint16_t cbuf_write_partial(CircularBuffer *inst, const uint8_t *b, uint16_t max) +bool cbuf_peek(circbuf_t *inst, uint8_t *b) { - uint16_t i; - for (i = 0; i < max; i++) { - if (cbuf_full(inst)) break; - cbuf_write(inst, *(b + i)); - } - - return i; -} - - -bool cbuf_write_string(CircularBuffer *inst, const char *str) -{ - return cbuf_write_n(inst, (uint8_t *) str, strlen(str)); -} - - -uint16_t cbuf_write_string_partial(CircularBuffer *inst, const char *str) -{ - return cbuf_write_partial(inst, (uint8_t *) str, strlen(str)); -} - - -bool cbuf_read_n(CircularBuffer *inst, uint8_t *buf, uint16_t len) -{ - if (cbuf_data_size(inst) < len) return false; - - for (uint16_t i = 0; i < len; i++) { - cbuf_read(inst, buf + i); - } - - return true; -} - - -bool cbuf_read_string(CircularBuffer *inst, char *str, uint16_t len) -{ - bool b = cbuf_read_n(inst, (uint8_t *) str, len); - if (!b) return false; - - str[len] = 0; + if (cbuf_empty(inst)) return false; + *b = inst->buffer[inst->read_pos]; return true; } -uint16_t cbuf_read_partial(CircularBuffer *inst, uint8_t *buf, uint16_t max) -{ - uint16_t i; - for (i = 0; i < max; i++) { - if (cbuf_empty(inst)) break; - cbuf_read(inst, buf + i); - } - - return i; -} - - -uint16_t cbuf_read_string_partial(CircularBuffer *inst, char *str, uint16_t max) +void cbuf_clear(circbuf_t *inst) { - uint16_t cnt = cbuf_read_partial(inst, (uint8_t *) str, max); - str[cnt] = 0; - return cnt; -} - - -int32_t cbuf_find(CircularBuffer *inst, uint8_t b) -{ - uint16_t cursor = inst->read_pos; - uint16_t cnt = 0; - - while (cursor != inst->write_pos) { - - if (inst->buffer[cursor] == b) return cnt; - - cursor++; - cnt++; - - // wrap - if (cursor >= inst->capacity) { - cursor = 0; - } - } - - return -1; + inst->read_pos = inst->capacity - 1; + inst->write_pos = 0; } - diff --git a/circbuf.h b/circbuf.h index 63340f7..5110e0f 100644 --- a/circbuf.h +++ b/circbuf.h @@ -2,99 +2,49 @@ #include #include -typedef struct { +// Circular Character Buffer implementation + +typedef struct CircularBuffer_struct { uint8_t *buffer; uint16_t capacity; uint16_t read_pos; uint16_t write_pos; - uint16_t data_len; -} CircularBuffer; +} circbuf_t; /** Init a buffer */ -void cbuf_init(CircularBuffer *inst, uint8_t *buffer, uint16_t length); +void cbuf_init(circbuf_t *inst, uint16_t length); + + +/** Deinit a buffer (free the memory) */ +void cbuf_deinit(circbuf_t *inst); /** Test for full buffer */ -bool cbuf_full(CircularBuffer *inst); +bool cbuf_full(circbuf_t *inst); /** Test for empty buffer */ -bool cbuf_empty(CircularBuffer *inst); +bool cbuf_empty(circbuf_t *inst); /** Write a byte to buffer, returns success */ -bool cbuf_write(CircularBuffer *inst, uint8_t b); +bool cbuf_write(circbuf_t *inst, uint8_t b); -/** Read a byte from the buffer, return susccess */ -bool cbuf_read(CircularBuffer *inst, uint8_t *b); +/** + * Read a byte from the buffer, return susccess. + * If `b` is NULL, the read byte is discarded. + */ +bool cbuf_read(circbuf_t *inst, uint8_t *b); /** * Get byte at the read cursor, without incrementing it. * False on empty. */ -bool cbuf_peek(CircularBuffer *inst, uint8_t *b); - - -/** Get data count */ -uint16_t cbuf_data_size(CircularBuffer *inst); - - -/** Get free space in the buffer */ -uint16_t cbuf_free_space(CircularBuffer *inst); +bool cbuf_peek(circbuf_t *inst, uint8_t *b); /** Remove all data from buffer */ -void cbuf_clear(CircularBuffer *inst); - - -/** Write N bytes, or none. Returns success */ -bool cbuf_write_n(CircularBuffer *inst, const uint8_t *b, uint16_t count); - - -/** Try to write N bytes. Returns actual number of bytes written. */ -uint16_t cbuf_write_partial(CircularBuffer *inst, const uint8_t *b, uint16_t max); - - -/** Write a string (excluding \0) - or nothing. */ -bool cbuf_write_string(CircularBuffer *inst, const char *str); - - -/** - * Try to write string (excluding \0). - * Returns actual number of chars written. - */ -uint16_t cbuf_write_string_partial(CircularBuffer *inst, const char *str); - - -/** Read N bytes, or none. Returns success. */ -bool cbuf_read_n(CircularBuffer *inst, uint8_t *buf, uint16_t len); - - -/** Read up to N bytes. Returns byte count */ -uint16_t cbuf_read_partial(CircularBuffer *inst, uint8_t *buf, uint16_t max); - - -/** Read string of given length, append \0. `str` must be len+1 long */ -bool cbuf_read_string(CircularBuffer *inst, char *str, uint16_t len); - - -/** - * Read string up to N chars long, append \0. - * `str` must be max+1 long - */ -uint16_t cbuf_read_string_partial(CircularBuffer *inst, char *str, uint16_t max); - - -/** - * Search buffer and return position of the first occurence - * of the given byte (position relative to read_pos). - * - * The returned value is zero-based, add 1 to get string - * length including the delimiter. - * - * Returns -1 if not found. - */ -int32_t cbuf_find(CircularBuffer *inst, uint8_t b); +void cbuf_clear(circbuf_t *inst);