using size_t, peek with offset, better field names

master
Ondřej Hruška 9 years ago
parent a3485b9ced
commit 2f352b653f
  1. 72
      circbuf.c
  2. 19
      circbuf.h

@ -6,10 +6,10 @@
#include "circbuf.h" #include "circbuf.h"
void cbuf_init(circbuf_t *inst, uint16_t length) void cbuf_init(circbuf_t *inst, size_t capacity)
{ {
inst->buffer = malloc(length); inst->buf = malloc(capacity);
inst->capacity = length; inst->cap = capacity;
cbuf_clear(inst); cbuf_clear(inst);
} }
@ -17,29 +17,32 @@ void cbuf_init(circbuf_t *inst, uint16_t length)
void cbuf_deinit(circbuf_t *inst) void cbuf_deinit(circbuf_t *inst)
{ {
if (inst->buffer != NULL) { if (inst->buf != NULL) {
free(inst->buffer); free(inst->buf);
} }
} }
bool cbuf_full(circbuf_t *inst) bool cbuf_full(circbuf_t *inst)
{ {
if (inst->read_pos == 0) { return (inst->lr == inst->nw);
return inst->write_pos == inst->capacity - 1; }
static bool can_read_at(circbuf_t *inst, size_t i)
{
if (inst->lr < inst->nw) {
return i > inst->lr && i < inst->nw;
} else { } else {
return inst->write_pos == inst->read_pos; // NW < LR
return (i < inst->cap && i > inst->lr) || i < inst->nw;
} }
} }
bool cbuf_empty(circbuf_t *inst) bool cbuf_empty(circbuf_t *inst)
{ {
if (inst->write_pos == 0) { return ((inst->lr + 1) % inst->cap) == inst->nw;
return inst->read_pos == inst->capacity - 1;
} else {
return inst->read_pos == inst->write_pos - 1;
}
} }
@ -47,13 +50,11 @@ 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->buf[inst->nw] = b;
inst->write_pos++;
// wrap // increment
if (inst->write_pos >= inst->capacity) { inst->nw++;
inst->write_pos = 0; if (inst->nw == inst->cap) inst->nw = 0;
}
return true; return true;
} }
@ -63,33 +64,38 @@ bool cbuf_read(circbuf_t *inst, uint8_t *b)
{ {
if (cbuf_empty(inst)) return false; if (cbuf_empty(inst)) return false;
inst->read_pos++; // increment
inst->lr++;
// wrap if (inst->lr == inst->cap) inst->lr = 0;
if (inst->read_pos >= inst->capacity) {
inst->read_pos = 0;
}
*b = inst->buffer[inst->read_pos]; *b = inst->buf[inst->lr];
// zero out the read byte (for debug) //zero out the read byte (for debug)
//inst->buffer[inst->read_pos] = 0; inst->buf[inst->lr] = 0;
return true; return true;
} }
bool cbuf_peek(circbuf_t *inst, uint8_t *b) bool cbuf_peek(circbuf_t *inst, size_t nth, uint8_t *b)
{ {
if (cbuf_empty(inst)) return false; // check if can read there (can't use module, could "wrap")
size_t n = inst->lr;
for (size_t i = 0; i <= nth; i++) {
// increment N
n++;
if (n == inst->cap) n = 0;
if (!can_read_at(inst, n)) return false;
}
*b = inst->buffer[inst->read_pos]; *b = inst->buf[n];
return true; return true;
} }
void cbuf_clear(circbuf_t *inst) void cbuf_clear(circbuf_t *inst)
{ {
inst->read_pos = inst->capacity - 1; inst->lr = inst->cap - 1;
inst->write_pos = 0; inst->nw = 0;
} }

@ -1,19 +1,20 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
// Circular Character Buffer implementation // Circular Character Buffer implementation
typedef struct { typedef struct CircularBuffer_struct {
uint8_t *buffer; uint8_t *buf;
uint16_t capacity; size_t cap;
uint16_t read_pos; size_t lr; // last read pos
uint16_t write_pos; size_t nw; // next write pos
} circbuf_t; } circbuf_t;
/** Init a buffer */ /** Init a buffer */
void cbuf_init(circbuf_t *inst, uint16_t length); void cbuf_init(circbuf_t *inst, size_t capacity);
/** Deinit a buffer (free the memory) */ /** Deinit a buffer (free the memory) */
@ -40,10 +41,10 @@ bool cbuf_read(circbuf_t *inst, uint8_t *b);
/** /**
* Get byte at the read cursor, without incrementing it. * Get n-th byte from the buffer, without removing it.
* False on empty. * Returns false if offset is invalid (ie. empty buffer).
*/ */
bool cbuf_peek(circbuf_t *inst, uint8_t *b); bool cbuf_peek(circbuf_t *inst, size_t nth, uint8_t *b);
/** Remove all data from buffer */ /** Remove all data from buffer */

Loading…
Cancel
Save