Skip to content

Commit

Permalink
CHANGED to single allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
willemt committed Oct 26, 2014
1 parent c32ce9b commit fd2051f
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 77 deletions.
90 changes: 43 additions & 47 deletions bipbuffer.c
Original file line number Diff line number Diff line change
@@ -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 <stdlib.h>

/* for memcpy */
#include <string.h>

#include <assert.h>

#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);
}

Expand All @@ -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)
Expand All @@ -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;
}

Expand All @@ -94,21 +103,19 @@ 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;

/* make sure we can actually poll this data */
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.. */
Expand All @@ -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);
}
63 changes: 40 additions & 23 deletions bipbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
15 changes: 8 additions & 7 deletions tests/test_bipbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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));
}

Expand All @@ -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)
Expand Down Expand Up @@ -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;

Expand All @@ -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
Expand Down

0 comments on commit fd2051f

Please sign in to comment.