1/* 2 * Copyright (c) 2012, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <collections/flipbuffer.h> 11 12#include <assert.h> 13#include <stdlib.h> 14#include <string.h> 15 16/** 17 * \brief Append data to front buffer. 18 * 19 * \param fbuf Flip buffer to append data to. 20 * \param data Data to append. Don't have to be \0-terminated. 21 * \param length Length of data to append. 22 */ 23void collections_fbuf_append(struct collections_fbuf *fbuf, const void *data, 24 size_t length) 25{ 26 if (data == NULL || length == 0) { 27 return; 28 } 29 30 if (fbuf->front == NULL) { 31 // allocate a new front buffer 32 fbuf->front = malloc(length); 33 assert(fbuf->front != NULL); 34 memcpy(fbuf->front, data, length); 35 fbuf->frontlen = length; 36 } else { 37 // append to existing buffer 38 fbuf->front = realloc(fbuf->front, fbuf->frontlen + length); 39 assert(fbuf->front != NULL); 40 memcpy(fbuf->front + fbuf->frontlen, data, length); 41 fbuf->frontlen += length; 42 } 43} 44 45/** 46 * \brief Create a new flip buffer. 47 * 48 * \param fbuf Pointer to a pointer to a flip buffer. Filled-in by function. 49 */ 50void collections_fbuf_create(struct collections_fbuf **fbuf) 51{ 52 *fbuf = malloc(sizeof(struct collections_fbuf)); 53 assert(*fbuf != NULL); 54 55 (*fbuf)->front = NULL; 56 (*fbuf)->frontlen = 0; 57 (*fbuf)->back = NULL; 58 (*fbuf)->backlen = 0; 59} 60 61/** 62 * \brief Flip the buffer, i.e. change the role of the front and back buffer. 63 * 64 * \param fbuf Flip buffer to flip. 65 */ 66void collections_fbuf_flip(struct collections_fbuf *fbuf) 67{ 68 char *tmpbuf; 69 size_t tmplen; 70 71 tmpbuf = fbuf->front; 72 tmplen = fbuf->frontlen; 73 74 fbuf->front = fbuf->back; 75 fbuf->frontlen = fbuf->backlen; 76 77 fbuf->back = tmpbuf; 78 fbuf->backlen = tmplen; 79} 80 81/** 82 * \brief Empty the front buffer 83 * 84 * \param fbuf Flip buffer to operate on. 85 */ 86void collections_fbuf_free(struct collections_fbuf *fbuf) 87{ 88 if (fbuf->front != NULL) { 89 free(fbuf->front); 90 fbuf->front = NULL; 91 } 92 fbuf->frontlen = 0; 93} 94 95/** 96 * \brief Retrieve the data from the front buffer. 97 * 98 * \param fbuf Flip buffer to get data from. 99 * \return Content of the front buffer. Not \0 terminated. 100 */ 101void *collections_fbuf_get_data(struct collections_fbuf *fbuf) 102{ 103 return fbuf->front; 104} 105 106/** 107 * \brief Retrieve the length of the data of the front buffer. 108 * 109 * \param fbuf Flip buffer to get length of data from. 110 * \return Length of the data in the front buffer. 111 */ 112size_t collections_fbuf_get_length(struct collections_fbuf *fbuf) 113{ 114 return fbuf->frontlen; 115} 116 117/** 118 * \brief Is the front buffer empty? 119 * 120 * \param fbuf Flip buffer to check. 121 * \return Whether or not the front buffer contains any data? 122 */ 123bool collections_fbuf_is_empty(struct collections_fbuf *fbuf) 124{ 125 if (fbuf->front == NULL || fbuf->frontlen == 0) { 126 return true; 127 } else { 128 return false; 129 } 130} 131 132/** 133 * \brief Is the back buffer empty? 134 * 135 * \param fbuf Flip buffer to check. 136 * \return Whether or not the back buffer contains any data? 137 */ 138bool collections_fbuf_other_is_empty(struct collections_fbuf *fbuf) 139{ 140 if (fbuf->back == NULL || fbuf->backlen == 0) { 141 return true; 142 } else { 143 return false; 144 } 145} 146 147 148/** 149 * \brief Empty the back buffer 150 * 151 * \param fbuf Flip buffer to operate on. 152 */ 153void collections_fbuf_other_free(struct collections_fbuf *fbuf) 154{ 155 if (fbuf->back != NULL) { 156 free(fbuf->back); 157 fbuf->back = NULL; 158 } 159 fbuf->backlen = 0; 160} 161 162/** 163 * \brief Free all memory associated with the flip buffer. 164 */ 165void collections_fbuf_release(struct collections_fbuf *fbuf) 166{ 167 if (fbuf == NULL) { 168 return; 169 } 170 171 collections_fbuf_free(fbuf); 172 collections_fbuf_other_free(fbuf); 173 174 free(fbuf); 175} 176