size_t remain = ringbuf_remain(buf);
size_t copysize = MIN(remain, size);
size_t tocopy = copysize;
- if (tocopy > buf->size - buf->start) {
+ if (tocopy >= buf->size - buf->start) {
size_t ts = buf->size - buf->start;
memcpy(dp, buf->data + buf->start, ts);
buf->start = 0;
return copysize;
}
+size_t ringbuf_peek(struct ringbuf *buf, size_t offset, void *data, size_t size)
+{
+ uint8_t *dp = data;
+ size_t remain = ringbuf_remain(buf);
+ if (offset >= remain)
+ return 0;
+ size_t copysize = MAX(MIN(remain - offset, size), (size_t) 0);
+ size_t tocopy = copysize;
+ size_t cstart = (buf->start + offset) % buf->size;
+ if (tocopy >= buf->size - cstart) {
+ size_t ts = buf->size - cstart;
+ memcpy(dp, buf->data + cstart, ts);
+ buf->start = cstart = 0;
+ tocopy -= ts;
+ dp += ts;
+ }
+ memcpy(dp, buf->data + cstart, tocopy);
+ return copysize;
+}
+
void ringbuf_reset(struct ringbuf *buf)
{
buf->start = buf->end = 0;
*/
size_t ringbuf_get(struct ringbuf *buf, void *data, size_t size);
+/*
+ * Peek data from the ring buffer.
+ *
+ * @param offset where to get the data from, in bytes offset from the
+ * start of the data
+ * @param data where to put the data
+ * @param size how much data to get
+ * @return number of bytes read into data; will be less than size
+ * if there was not enough data to read; will be -1 if the
+ * offset exceeds the amount of data left in the ring
+ * buffer
+ */
+size_t ringbuf_peek(struct ringbuf *buf, size_t offset, void *data,
+ size_t size);
+
/*
* Reset buffer. Does not wipe.
*
/* put another 10 bytes and validate wraparound */
printf("Validating wraparound...\n");
- assert(ringbuf_put(soil, &compost[BUFSIZ / 2], 10) == 10);
+ assert(ringbuf_put(soil, &compost[BUFSIZ/2], 10) == 10);
validate_state(soil, BUFSIZ, BUFSIZ - 15 + 10);
assert(soil->start == 15);
/* validate simple data encode / decode */
const char *organ = "seed";
printf("Encoding: '%s'\n", organ);
- ringbuf_put(soil, organ, strlen(organ));
+ assert(ringbuf_put(soil, organ, strlen(organ)) == 4);
char water[strlen(organ) + 1];
- ringbuf_get(soil, &water, strlen(organ));
+ assert(ringbuf_get(soil, &water, strlen(organ)) == 4);
water[strlen(organ)] = '\0';
printf("Retrieved: '%s'\n", water);
soil->end = soil->start;
const char *phloem = "root";
printf("Encoding: '%s'\n", phloem);
- ringbuf_put(soil, phloem, strlen(phloem));
+ assert(ringbuf_put(soil, phloem, strlen(phloem)) == 4);
char xylem[strlen(phloem) + 1];
- ringbuf_get(soil, &xylem, 100);
+ assert(ringbuf_get(soil, &xylem, 100) == 4);
xylem[strlen(phloem)] = '\0';
printf("Retrieved: '%s'\n", xylem);
+ ringbuf_wipe(soil);
+
+ /* validate simple data peek across ring boundary */
+ soil->start = soil->size - 2;
+ soil->end = soil->start;
+ const char *cytoplasm = "tree";
+ printf("Encoding: '%s'\n", cytoplasm);
+ assert(ringbuf_put(soil, cytoplasm, strlen(cytoplasm)) == 4);
+ char chloroplast[strlen(cytoplasm) + 1];
+ assert(ringbuf_peek(soil, 2, &chloroplast[0], 100) == 2);
+ assert(ringbuf_peek(soil, 0, &chloroplast[2], 2) == 2);
+ chloroplast[strlen(cytoplasm)] = '\0';
+ assert(!strcmp(chloroplast, "eetr"));
+ printf("Retrieved: '%s'\n", chloroplast);
+
printf("Deleting...\n");
ringbuf_del(soil);