source added
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
Circular byte buffer
|
||||||
|
====================
|
||||||
|
|
||||||
|
This is a circular buffer implementation, useful for embedded systems (buffer for UART RX queue etc).
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint8_t buffer[32]; // array backing the buffer
|
||||||
|
|
||||||
|
CircularByteBuffer cb; // buffer instance
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
cbuf_init(&cb, buffer, 32); // init the buffer
|
||||||
|
|
||||||
|
// now it's ready for use!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Many function return success flag, so make sure to check the return values.
|
||||||
|
|
||||||
|
False is returned on buffer overflow / underflow, attempted read past available data size etc. See the header file for details.
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Do whatever you want with the code.
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "circbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
void cbuf_init(CircularBuffer *inst, uint8_t *buffer, uint16_t length)
|
||||||
|
{
|
||||||
|
inst->buffer = buffer;
|
||||||
|
inst->capacity = length;
|
||||||
|
|
||||||
|
cbuf_clear(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cbuf_full(CircularBuffer *inst)
|
||||||
|
{
|
||||||
|
return inst->data_len == inst->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cbuf_empty(CircularBuffer *inst)
|
||||||
|
{
|
||||||
|
return inst->data_len == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cbuf_write(CircularBuffer *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) {
|
||||||
|
inst->write_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cbuf_read(CircularBuffer *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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cbuf_write_string(CircularBuffer *inst, const char *str)
|
||||||
|
{
|
||||||
|
return cbuf_write_n(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_upto(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_upto(CircularBuffer *inst, char *str, uint16_t max)
|
||||||
|
{
|
||||||
|
uint16_t cnt = cbuf_read_upto(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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *buffer;
|
||||||
|
uint16_t capacity;
|
||||||
|
uint16_t read_pos;
|
||||||
|
uint16_t write_pos;
|
||||||
|
uint16_t data_len;
|
||||||
|
} CircularByteBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
/** Init a buffer */
|
||||||
|
void cbuf_init(CircularByteBuffer *inst, uint8_t *buffer, uint16_t length);
|
||||||
|
|
||||||
|
|
||||||
|
/** Test for full buffer */
|
||||||
|
bool cbuf_full(CircularByteBuffer *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** Test for empty buffer */
|
||||||
|
bool cbuf_empty(CircularByteBuffer *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** Write a byte to buffer, returns success */
|
||||||
|
bool cbuf_write(CircularByteBuffer *inst, uint8_t b);
|
||||||
|
|
||||||
|
|
||||||
|
/** Read a byte from the buffer, return susccess */
|
||||||
|
bool cbuf_read(CircularByteBuffer *inst, uint8_t *b);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get byte at the read cursor, without incrementing it. False on empty. */
|
||||||
|
bool cbuf_peek(CircularByteBuffer *inst, uint8_t *b);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get data count */
|
||||||
|
uint16_t cbuf_data_size(CircularByteBuffer *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get free space in the buffer */
|
||||||
|
uint16_t cbuf_free_space(CircularByteBuffer *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** Remove all data from buffer */
|
||||||
|
void cbuf_clear(CircularByteBuffer *inst);
|
||||||
|
|
||||||
|
|
||||||
|
/** Write N bytes. Returns success */
|
||||||
|
bool cbuf_write_n(CircularByteBuffer *inst, const uint8_t *b, uint16_t count);
|
||||||
|
|
||||||
|
|
||||||
|
/** Write a string (without \0) */
|
||||||
|
bool cbuf_write_string(CircularByteBuffer *inst, const char *str);
|
||||||
|
|
||||||
|
|
||||||
|
/** Read N bytes, if available. Returns success. */
|
||||||
|
bool cbuf_read_n(CircularByteBuffer *inst, uint8_t *buf, uint16_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/** Read string of given length, append \0. `str` must be len+1 long */
|
||||||
|
bool cbuf_read_string(CircularByteBuffer *inst, char *str, uint16_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/** Read up to N bytes. Returns byte count */
|
||||||
|
uint16_t cbuf_read_upto(CircularByteBuffer *inst, uint8_t *buf, uint16_t max);
|
||||||
|
|
||||||
|
|
||||||
|
/** Read string up to N chars long, append \0. `str` must be max+1 long */
|
||||||
|
uint16_t cbuf_read_string_upto(CircularByteBuffer *inst, char *str, uint16_t max);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search buffer and return position of the first occurence
|
||||||
|
* of the given byte (position relative to read_pos).
|
||||||
|
* Returns -1 if not found.
|
||||||
|
*/
|
||||||
|
int32_t cbuf_find(CircularByteBuffer *inst, uint8_t b);
|
||||||
Reference in New Issue
Block a user