176 lines
4.0 KiB
C
176 lines
4.0 KiB
C
/*
|
|
* Copyright (c) 2012, ETH Zurich.
|
|
* All rights reserved.
|
|
*
|
|
* This file is distributed under the terms in the attached LICENSE file.
|
|
* If you do not find this file, copies can be found by writing to:
|
|
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
|
|
*/
|
|
|
|
#include <collections/flipbuffer.h>
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/**
|
|
* \brief Append data to front buffer.
|
|
*
|
|
* \param fbuf Flip buffer to append data to.
|
|
* \param data Data to append. Don't have to be \0-terminated.
|
|
* \param length Length of data to append.
|
|
*/
|
|
void collections_fbuf_append(struct collections_fbuf *fbuf, const void *data,
|
|
size_t length)
|
|
{
|
|
if (data == NULL || length == 0) {
|
|
return;
|
|
}
|
|
|
|
if (fbuf->front == NULL) {
|
|
// allocate a new front buffer
|
|
fbuf->front = malloc(length);
|
|
assert(fbuf->front != NULL);
|
|
memcpy(fbuf->front, data, length);
|
|
fbuf->frontlen = length;
|
|
} else {
|
|
// append to existing buffer
|
|
fbuf->front = realloc(fbuf->front, fbuf->frontlen + length);
|
|
assert(fbuf->front != NULL);
|
|
memcpy(fbuf->front + fbuf->frontlen, data, length);
|
|
fbuf->frontlen += length;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Create a new flip buffer.
|
|
*
|
|
* \param fbuf Pointer to a pointer to a flip buffer. Filled-in by function.
|
|
*/
|
|
void collections_fbuf_create(struct collections_fbuf **fbuf)
|
|
{
|
|
*fbuf = malloc(sizeof(struct collections_fbuf));
|
|
assert(*fbuf != NULL);
|
|
|
|
(*fbuf)->front = NULL;
|
|
(*fbuf)->frontlen = 0;
|
|
(*fbuf)->back = NULL;
|
|
(*fbuf)->backlen = 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Flip the buffer, i.e. change the role of the front and back buffer.
|
|
*
|
|
* \param fbuf Flip buffer to flip.
|
|
*/
|
|
void collections_fbuf_flip(struct collections_fbuf *fbuf)
|
|
{
|
|
char *tmpbuf;
|
|
size_t tmplen;
|
|
|
|
tmpbuf = fbuf->front;
|
|
tmplen = fbuf->frontlen;
|
|
|
|
fbuf->front = fbuf->back;
|
|
fbuf->frontlen = fbuf->backlen;
|
|
|
|
fbuf->back = tmpbuf;
|
|
fbuf->backlen = tmplen;
|
|
}
|
|
|
|
/**
|
|
* \brief Empty the front buffer
|
|
*
|
|
* \param fbuf Flip buffer to operate on.
|
|
*/
|
|
void collections_fbuf_free(struct collections_fbuf *fbuf)
|
|
{
|
|
if (fbuf->front != NULL) {
|
|
free(fbuf->front);
|
|
fbuf->front = NULL;
|
|
}
|
|
fbuf->frontlen = 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Retrieve the data from the front buffer.
|
|
*
|
|
* \param fbuf Flip buffer to get data from.
|
|
* \return Content of the front buffer. Not \0 terminated.
|
|
*/
|
|
void *collections_fbuf_get_data(struct collections_fbuf *fbuf)
|
|
{
|
|
return fbuf->front;
|
|
}
|
|
|
|
/**
|
|
* \brief Retrieve the length of the data of the front buffer.
|
|
*
|
|
* \param fbuf Flip buffer to get length of data from.
|
|
* \return Length of the data in the front buffer.
|
|
*/
|
|
size_t collections_fbuf_get_length(struct collections_fbuf *fbuf)
|
|
{
|
|
return fbuf->frontlen;
|
|
}
|
|
|
|
/**
|
|
* \brief Is the front buffer empty?
|
|
*
|
|
* \param fbuf Flip buffer to check.
|
|
* \return Whether or not the front buffer contains any data?
|
|
*/
|
|
bool collections_fbuf_is_empty(struct collections_fbuf *fbuf)
|
|
{
|
|
if (fbuf->front == NULL || fbuf->frontlen == 0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Is the back buffer empty?
|
|
*
|
|
* \param fbuf Flip buffer to check.
|
|
* \return Whether or not the back buffer contains any data?
|
|
*/
|
|
bool collections_fbuf_other_is_empty(struct collections_fbuf *fbuf)
|
|
{
|
|
if (fbuf->back == NULL || fbuf->backlen == 0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Empty the back buffer
|
|
*
|
|
* \param fbuf Flip buffer to operate on.
|
|
*/
|
|
void collections_fbuf_other_free(struct collections_fbuf *fbuf)
|
|
{
|
|
if (fbuf->back != NULL) {
|
|
free(fbuf->back);
|
|
fbuf->back = NULL;
|
|
}
|
|
fbuf->backlen = 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Free all memory associated with the flip buffer.
|
|
*/
|
|
void collections_fbuf_release(struct collections_fbuf *fbuf)
|
|
{
|
|
if (fbuf == NULL) {
|
|
return;
|
|
}
|
|
|
|
collections_fbuf_free(fbuf);
|
|
collections_fbuf_other_free(fbuf);
|
|
|
|
free(fbuf);
|
|
}
|