diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2017-12-27 00:47:19 +0100 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2017-12-27 00:50:56 +0100 |
commit | a5080622b2de7c09393daa208a56606c068db1f3 (patch) | |
tree | b4b4a8077fbfc45fbb1964686028f028eb097eca /lib/ringbuf.c | |
parent | lib: add ring buffer (diff) | |
download | frr-a5080622b2de7c09393daa208a56606c068db1f3.tar.xz frr-a5080622b2de7c09393daa208a56606c068db1f3.zip |
lib: add ringbuf_peek()
Peek functionality for ring buffers and associated tests.
Also:
* Slight optimization to avoid 0-byte memcpy() by changing > to >=
* Add rv checks for some ringbuf_[put|get] calls that were missing them
in the test
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib/ringbuf.c')
-rw-r--r-- | lib/ringbuf.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/ringbuf.c b/lib/ringbuf.c index fee5b5d69..f8e9a9bd8 100644 --- a/lib/ringbuf.c +++ b/lib/ringbuf.c @@ -77,7 +77,7 @@ size_t ringbuf_get(struct ringbuf *buf, void *data, size_t size) 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; @@ -90,6 +90,26 @@ size_t ringbuf_get(struct ringbuf *buf, void *data, size_t size) 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; |