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 <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "circbuf.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;
|
inst->capacity = length;
|
||||||
|
|
||||||
cbuf_clear(inst);
|
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;
|
if (cbuf_full(inst)) return false;
|
||||||
|
|
||||||
inst->buffer[inst->write_pos] = b;
|
inst->buffer[inst->write_pos] = b;
|
||||||
|
|
||||||
inst->write_pos++;
|
inst->write_pos++;
|
||||||
inst->data_len++;
|
|
||||||
|
|
||||||
// wrap
|
// wrap
|
||||||
if (inst->write_pos >= inst->capacity) {
|
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;
|
if (cbuf_empty(inst)) return false;
|
||||||
|
|
||||||
*b = inst->buffer[inst->read_pos];
|
|
||||||
|
|
||||||
inst->read_pos++;
|
inst->read_pos++;
|
||||||
inst->data_len--;
|
|
||||||
|
|
||||||
// wrap
|
// wrap
|
||||||
if (inst->read_pos >= inst->capacity) {
|
if (inst->read_pos >= inst->capacity) {
|
||||||
inst->read_pos = 0;
|
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;
|
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;
|
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;
|
inst->read_pos = inst->capacity - 1;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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->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 <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct {
|
// Circular Character Buffer implementation
|
||||||
|
|
||||||
|
typedef struct CircularBuffer_struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint16_t capacity;
|
uint16_t capacity;
|
||||||
uint16_t read_pos;
|
uint16_t read_pos;
|
||||||
uint16_t write_pos;
|
uint16_t write_pos;
|
||||||
uint16_t data_len;
|
} circbuf_t;
|
||||||
} CircularBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
/** Init a buffer */
|
/** 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 */
|
/** Test for full buffer */
|
||||||
bool cbuf_full(CircularBuffer *inst);
|
bool cbuf_full(circbuf_t *inst);
|
||||||
|
|
||||||
|
|
||||||
/** Test for empty buffer */
|
/** Test for empty buffer */
|
||||||
bool cbuf_empty(CircularBuffer *inst);
|
bool cbuf_empty(circbuf_t *inst);
|
||||||
|
|
||||||
|
|
||||||
/** Write a byte to buffer, returns success */
|
/** 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.
|
* Get byte at the read cursor, without incrementing it.
|
||||||
* False on empty.
|
* False on empty.
|
||||||
*/
|
*/
|
||||||
bool cbuf_peek(CircularBuffer *inst, uint8_t *b);
|
bool cbuf_peek(circbuf_t *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);
|
|
||||||
|
|
||||||
|
|
||||||
/** Remove all data from buffer */
|
/** Remove all data from buffer */
|
||||||
void cbuf_clear(CircularBuffer *inst);
|
void cbuf_clear(circbuf_t *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);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user