added modded bipbuffer
This commit is contained in:
parent
f311e96400
commit
e88d4d66d6
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.o
|
||||||
2
Makefile
2
Makefile
@ -8,4 +8,4 @@ dataflow: bipbuffer/bipbuffer.o
|
|||||||
|
|
||||||
.PHONE: clean
|
.PHONE: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o dataflow
|
rm -rf *.o dataflow bipbuffer/*.o
|
||||||
|
|||||||
176
bipbuffer/bipbuffer.c
Normal file
176
bipbuffer/bipbuffer.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @author Willem Thiart himself@willemthiart.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* for memcpy */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bipbuffer.h"
|
||||||
|
|
||||||
|
size_t bipbuf_sizeof(const unsigned int size)
|
||||||
|
{
|
||||||
|
return sizeof(bipbuf_t) + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bipbuf_unused(const bipbuf_t* me)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
if (1 == me->b_inuse)
|
||||||
|
/* distance between region B and region A */
|
||||||
|
return me->a_start - me->b_end;
|
||||||
|
else
|
||||||
|
return me->size - me->a_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bipbuf_size(const bipbuf_t* me)
|
||||||
|
{
|
||||||
|
return me->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bipbuf_used(const bipbuf_t* me)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
return (me->a_end - me->a_start) + me->b_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bipbuf_init(bipbuf_t* me, const unsigned int size)
|
||||||
|
{
|
||||||
|
me->a_start = me->a_end = me->b_end = 0;
|
||||||
|
me->size = 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bipbuf_is_empty(const bipbuf_t* me)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
/* not enough space */
|
||||||
|
if (bipbuf_unused(me) < size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (1 == me->b_inuse)
|
||||||
|
{
|
||||||
|
memcpy(me->data + me->b_end, data, size);
|
||||||
|
me->b_end += size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(me->data + me->a_end, data, size);
|
||||||
|
me->a_end += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
__check_for_switch_to_b(me);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *bipbuf_reserve( bipbuf_t* me, const unsigned int size ) {
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
printf("%s %d %d\n", __func__, bipbuf_unused(me), size);
|
||||||
|
if (bipbuf_unused(me) < size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void * data = NULL;
|
||||||
|
if( 1 == me->b_inuse ) {
|
||||||
|
data = me->data + me->b_end;
|
||||||
|
me->reserved_size = size;
|
||||||
|
} else {
|
||||||
|
data = me->data + me->a_end;
|
||||||
|
me->reserved_size = size;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bipbuf_commit( bipbuf_t* me, const unsigned int size ) {
|
||||||
|
assert( me->reserved_size > 0 );
|
||||||
|
assert( me->reserved_size >= size );
|
||||||
|
unsigned long int reserved_size = (size < me->reserved_size)?size:me->reserved_size;
|
||||||
|
if( 1 == me->b_inuse ) {
|
||||||
|
me->b_end += reserved_size;
|
||||||
|
} else {
|
||||||
|
me->a_end += reserved_size;
|
||||||
|
}
|
||||||
|
me->reserved_size = 0;
|
||||||
|
__check_for_switch_to_b(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *bipbuf_peek(const bipbuf_t* me, const unsigned int size)
|
||||||
|
{
|
||||||
|
/* make sure we can actually peek at this data */
|
||||||
|
if (me->size < me->a_start + size)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (bipbuf_is_empty(me))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (unsigned char*)me->data + me->a_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size)
|
||||||
|
{
|
||||||
|
assert( me->reserved_size == 0 );
|
||||||
|
if (bipbuf_is_empty(me))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* make sure we can actually poll this data */
|
||||||
|
if (me->size < me->a_start + size)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
void *end = me->data + me->a_start;
|
||||||
|
me->a_start += size;
|
||||||
|
|
||||||
|
/* we seem to be empty.. */
|
||||||
|
if (me->a_start == me->a_end)
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
80
bipbuffer/bipbuffer.h
Normal file
80
bipbuffer/bipbuffer.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef BIPBUFFER_H
|
||||||
|
#define BIPBUFFER_H
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long int size;
|
||||||
|
unsigned long int reserved_size;
|
||||||
|
|
||||||
|
/* region A */
|
||||||
|
unsigned int a_start, a_end;
|
||||||
|
|
||||||
|
/* region B */
|
||||||
|
unsigned int b_end;
|
||||||
|
|
||||||
|
/* is B inuse? */
|
||||||
|
int b_inuse;
|
||||||
|
|
||||||
|
unsigned char data[];
|
||||||
|
} bipbuf_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new bip buffer.
|
||||||
|
*
|
||||||
|
* malloc()s space
|
||||||
|
*
|
||||||
|
* @param[in] size The size of the buffer */
|
||||||
|
bipbuf_t *bipbuf_new(const unsigned 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the bip buffer */
|
||||||
|
void bipbuf_free(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);
|
||||||
|
|
||||||
|
void *bipbuf_reserve( bipbuf_t* me, const unsigned int size );
|
||||||
|
void bipbuf_commit( bipbuf_t* me, const unsigned int size );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 how much space we have assigned */
|
||||||
|
int bipbuf_used(const bipbuf_t* cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bytes of unused space */
|
||||||
|
int bipbuf_unused(const bipbuf_t* me);
|
||||||
|
|
||||||
|
#endif /* BIPBUFFER_H */
|
||||||
Loading…
Reference in New Issue
Block a user