|
|
|
@ -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_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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|