should be reliable now with producent and consumer threads. Removed length variable. Also removed useless "bonus" funcs.
This commit is contained in:
@@ -1,39 +1,54 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#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_empty(CircularBuffer *inst)
|
||||
bool cbuf_full(circbuf_t *inst)
|
||||
{
|
||||
return inst->data_len == 0;
|
||||
if (inst->read_pos == 0) {
|
||||
return inst->write_pos == inst->capacity - 1;
|
||||
} else {
|
||||
return inst->write_pos == inst->read_pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool cbuf_write(CircularBuffer *inst, uint8_t b)
|
||||
bool cbuf_empty(circbuf_t *inst)
|
||||
{
|
||||
if (inst->write_pos == 0) {
|
||||
return inst->read_pos == inst->capacity - 1;
|
||||
} else {
|
||||
return inst->read_pos == inst->write_pos - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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,25 +59,27 @@ 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;
|
||||
}
|
||||
|
||||
*b = inst->buffer[inst->read_pos];
|
||||
|
||||
// zero out the read byte (for debug)
|
||||
//inst->buffer[inst->read_pos] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool cbuf_peek(CircularBuffer *inst, uint8_t *b)
|
||||
bool cbuf_peek(circbuf_t *inst, uint8_t *b)
|
||||
{
|
||||
if (cbuf_empty(inst)) return false;
|
||||
|
||||
@@ -71,123 +88,8 @@ bool cbuf_peek(CircularBuffer *inst, uint8_t *b)
|
||||
}
|
||||
|
||||
|
||||
uint16_t cbuf_data_size(CircularBuffer *inst)
|
||||
void cbuf_clear(circbuf_t *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->read_pos = inst->capacity - 1;
|
||||
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));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint16_t cbuf_write_partial(CircularBuffer *inst, const uint8_t *b, uint16_t max)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,99 +2,49 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user