From fd2051f6066df3961ae2c4b28d736c1a01f8e450 Mon Sep 17 00:00:00 2001 From: Willem Thiart Date: Sun, 26 Oct 2014 22:01:46 +0900 Subject: [PATCH] CHANGED to single allocation --- bipbuffer.c | 90 ++++++++++++++++++++---------------------- bipbuffer.h | 63 ++++++++++++++++++----------- tests/test_bipbuffer.c | 15 +++---- 3 files changed, 91 insertions(+), 77 deletions(-) diff --git a/bipbuffer.c b/bipbuffer.c index b18acc0..1b0be43 100644 --- a/bipbuffer.c +++ b/bipbuffer.c @@ -1,62 +1,62 @@ - /** * Copyright (c) 2011, Willem-Hendrik Thiart * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. + * found in the LICENSE file. * * @file * @author Willem Thiart himself@willemthiart.com */ #include "stdio.h" - #include /* for memcpy */ #include -#include - #include "bipbuffer.h" -#define fail() assert(0) +size_t bipbuf_sizeof(const unsigned int size) +{ + return sizeof(bipbuf_t) + size; +} -int bipbuf_get_unused_size(bipbuf_t* me) +int bipbuf_spaceunused(const bipbuf_t* me) { if (1 == me->b_inuse) - { /* distance between region B and region A */ return me->a_start - me->b_end; - } else - { - /* find out if we should turn on region B? - * ie. is the distance between B and A more than A to buffer's end? */ - if (me->a_start - me->b_end > me->size - me->a_end) - { - me->b_inuse = 1; - return me->a_start - me->b_end; - } - else - { - return me->size - me->a_end; - } - } + return me->size - me->a_end; } -bipbuf_t *bipbuf_new(const unsigned int size) +int bipbuf_size(const bipbuf_t* me) +{ + return me->size; +} + +int bipbuf_spaceused(const bipbuf_t* me) +{ + return (me->a_end - me->a_start) + me->b_end; +} + +void bipbuf_init(bipbuf_t* me, const unsigned int size) { - bipbuf_t *me = malloc(sizeof(bipbuf_t)); me->a_start = me->a_end = me->b_end = 0; me->size = size; - me->data = malloc(me->size); me->b_inuse = 0; +} + +bipbuf_t *bipbuf_new(const unsigned int size) +{ + bipbuf_t *me = malloc(bipbuf_sizeof(size)); + if (!me) + return NULL; + bipbuf_init(me, size); return me; } void bipbuf_free(bipbuf_t* me) { - free(me->data); free(me); } @@ -65,10 +65,18 @@ int bipbuf_is_empty(const bipbuf_t* me) return me->a_start == me->a_end; } +/* find out if we should turn on region B + * ie. is the distance from A to buffer's end less than B to A? */ +static void __check_for_switch_to_b(bipbuf_t* me) +{ + if (me->size - me->a_end < me->a_start - me->b_end) + me->b_inuse = 1; +} + int bipbuf_offer(bipbuf_t* me, const unsigned char *data, const int size) { /* not enough space */ - if (size > bipbuf_get_unused_size(me)) + if (bipbuf_spaceunused(me) < size) return 0; if (1 == me->b_inuse) @@ -82,6 +90,7 @@ int bipbuf_offer(bipbuf_t* me, const unsigned char *data, const int size) me->a_end += size; } + __check_for_switch_to_b(me); return size; } @@ -94,13 +103,11 @@ unsigned char *bipbuf_peek(const bipbuf_t* me, const unsigned int size) if (bipbuf_is_empty(me)) return NULL; - return me->data + me->a_start; + return (void*)me->data + me->a_start; } unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size) { - void *end; - if (bipbuf_is_empty(me)) return NULL; @@ -108,7 +115,7 @@ unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size) if (me->size < me->a_start + size) return NULL; - end = me->data + me->a_start; + void *end = me->data + me->a_start; me->a_start += size; /* we seem to be empty.. */ @@ -117,26 +124,15 @@ unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size) /* replace a with region b */ if (1 == me->b_inuse) { - me->a_start = 0; - me->a_end = me->b_end; - me->b_end = me->b_inuse = 0; + me->a_start = 0; + me->a_end = me->b_end; + me->b_end = me->b_inuse = 0; } else - { - /* safely move the pointer back to the start because we are empty */ + /* safely move cursor back to the start because we are empty */ me->a_start = me->a_end = 0; - } } + __check_for_switch_to_b(me); return end; } - -int bipbuf_get_size(const bipbuf_t* me) -{ - return me->size; -} - -int bipbuf_get_spaceused(const bipbuf_t* me) -{ - return (me->a_end - me->a_start) + (me->b_end); -} diff --git a/bipbuffer.h b/bipbuffer.h index 8381a6a..e51a7f3 100644 --- a/bipbuffer.h +++ b/bipbuffer.h @@ -4,56 +4,73 @@ typedef struct { unsigned long int size; + /* region A */ unsigned int a_start, a_end; + /* region B */ unsigned int b_end; + /* is B inuse? */ int b_inuse; - void *data; + unsigned char data[]; } bipbuf_t; - /** - * creat new bip buffer. - * @param order to the power of two equals size*/ -bipbuf_t *bipbuf_new(const unsigned int order); + * Create a new bip buffer. + * + * malloc()s space + * + * @param[in] size The size of the buffer */ +bipbuf_t *bipbuf_new(const unsigned int size); /** - * De-allocate bip buffer */ -void bipbuf_poll_release(bipbuf_t *me, const int size); + * Initialise a bip buffer. Use memory provided by user. + * + * No malloc()s are performed. + * + * @param[in] size The size of the array */ +void bipbuf_init(bipbuf_t* me, const unsigned int size); /** - * @return number of bytes offered - **/ -int bipbuf_offer(bipbuf_t *me, const unsigned char *data, const int size); + * Free the bip buffer */ +void bipbuf_free(bipbuf_t *me); /** - * @return bytes of unused space the bipbuffer has */ -int bipbuf_get_unused_size(bipbuf_t* me); + * @param[in] data The data to be offered to the buffer + * @param[in] size The size of the data to be offered + * @return number of bytes offered */ +int bipbuf_offer(bipbuf_t *me, const unsigned char *data, const int size); /** - * Look at data. - * Don't move cursor - */ + * Look at data. Don't move cursor + * + * @param[in] len The length of the data to be peeked + * @return data on success, NULL if we can't peek at this much data */ unsigned char *bipbuf_peek(const bipbuf_t* me, const unsigned int len); -/** +/** * Get pointer to data to read. Move the cursor on. * - * @return pointer to data, null if we can't poll this much data - */ + * @param[in] len The length of the data to be polled + * @return pointer to data, NULL if we can't poll this much data */ unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size); -int bipbuf_get_size(const bipbuf_t* me); - -void bipbuf_free(bipbuf_t* me); +/** + * @return the size of the bipbuffer */ +int bipbuf_size(const bipbuf_t* me); +/** + * @return 1 if buffer is empty; 0 otherwise */ int bipbuf_is_empty(const bipbuf_t* me); /** - * @return tell us how much space we have assigned */ -int bipbuf_get_spaceused(const bipbuf_t* cb); + * @return how much space we have assigned */ +int bipbuf_spaceused(const bipbuf_t* cb); + +/** + * @return bytes of unused space */ +int bipbuf_spaceunused(const bipbuf_t* me); #endif /* BIPBUFFER_H */ diff --git a/tests/test_bipbuffer.c b/tests/test_bipbuffer.c index 1381c42..981795d 100644 --- a/tests/test_bipbuffer.c +++ b/tests/test_bipbuffer.c @@ -12,7 +12,7 @@ void Testbipbuffer_set_size_with_init(CuTest * tc) void *cb; cb = bipbuf_new(16); - CuAssertTrue(tc, 16 == bipbuf_get_size(cb)); + CuAssertTrue(tc, 16 == bipbuf_size(cb)); } void Testbipbuffer_is_empty_after_init(CuTest * tc) @@ -28,7 +28,7 @@ void Testbipbuffer_is_not_empty_after_offer(CuTest * tc) void *cb; cb = bipbuf_new(16); - bipbuf_offer(cb, (unsigned char*)"abcd", 4); + bipbuf_offer(cb, (unsigned char*)strdup("abcd"), 4); CuAssertTrue(tc, !bipbuf_is_empty(cb)); } @@ -48,9 +48,9 @@ void Testbipbuffer_spaceused_is_zero_after_poll_release(CuTest * tc) cb = bipbuf_new(16); bipbuf_offer(cb, (unsigned char*)"abcd", 4); - CuAssertTrue(tc, 4 == bipbuf_get_spaceused(cb)); + CuAssertTrue(tc, 4 == bipbuf_spaceused(cb)); bipbuf_poll(cb, 4); - CuAssertTrue(tc, 0 == bipbuf_get_spaceused(cb)); + CuAssertTrue(tc, 0 == bipbuf_spaceused(cb)); } void Txestbipbuffer_cant_offer_if_full(CuTest * tc) @@ -132,7 +132,8 @@ void Testbipbuffer_bipbuffers_independant_of_each_other(CuTest * tc) CuAssertTrue(tc, 0 == strncmp("efgh", (char*)bipbuf_poll(cb2, 4), 4)); } -void Testbipbuffer_bipbuffers_independant_of_each_other_with_no_polling(CuTest * tc) +void Testbipbuffer_bipbuffers_independant_of_each_other_with_no_polling( + CuTest * tc) { void *cb, *cb2; @@ -141,8 +142,8 @@ void Testbipbuffer_bipbuffers_independant_of_each_other_with_no_polling(CuTest * bipbuf_offer(cb, (unsigned char*)"abcd", 4); bipbuf_offer(cb2, (unsigned char*)"efgh", 4); - CuAssertTrue(tc, 0 == strncmp("abcd", (char*)bipbuf_peek(cb,4), 4)); - CuAssertTrue(tc, 0 == strncmp("efgh", (char*)bipbuf_peek(cb2,4), 4)); + CuAssertTrue(tc, 0 == strncmp("abcd", (char*)bipbuf_peek(cb, 4), 4)); + CuAssertTrue(tc, 0 == strncmp("efgh", (char*)bipbuf_peek(cb2, 4), 4)); } #if 0