--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/util/talon/buffer.c Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Expanding text buffer
+*
+*/
+
+
+
+
+#include <malloc.h>
+#include "buffer.h"
+#include <string.h>
+
+/* efficient allocation unit: */
+#define ALLOCSIZE 4096
+#define INITIALBLOCKCOUNT 128
+
+byteblock *buffer_newblock(buffer *b, unsigned int size)
+{
+ byteblock *bb;
+ if (!b)
+ return NULL;
+
+ b->lastblock++;
+
+ if (b->lastblock == b->maxblocks)
+ {
+ byteblock **nbb = (byteblock **)realloc(b->blocks, sizeof(byteblock *) * (b->maxblocks + INITIALBLOCKCOUNT));
+ if (!nbb)
+ return NULL;
+
+ b->blocks = nbb;
+ b->maxblocks += INITIALBLOCKCOUNT;
+ }
+
+ bb = malloc(sizeof(byteblock) + size-1);
+
+ if (!bb)
+ {
+
+ return NULL;
+ }
+
+ b->blocks[b->lastblock] = bb;
+
+ bb->fill = 0;
+ bb->size = size;
+
+ return bb;
+}
+
+buffer *buffer_new(void)
+{
+ buffer *b = malloc(sizeof(buffer));
+
+ if (b)
+ {
+ b->lastblock = -1; /* no blocks as yet */
+ b->maxblocks = INITIALBLOCKCOUNT;
+ b->blocks = (byteblock **)malloc(sizeof(byteblock *) * b->maxblocks);
+ if (!b->blocks)
+ {
+ free(b);
+ return NULL;
+ }
+
+ buffer_newblock(b, ALLOCSIZE);
+ }
+
+ return b;
+}
+
+
+char *buffer_append(buffer *b, char *bytes, unsigned int size)
+{
+ if (!b || !bytes)
+ return NULL;
+
+ char *space = buffer_makespace(b, size);
+ if (!space)
+ return NULL;
+ memcpy(space, bytes, size);
+ buffer_usespace(b, size);
+
+ return space;
+}
+
+char *buffer_prepend(buffer *b, char *bytes, unsigned int size)
+{
+ byteblock *bb;
+
+ if (!b || !bytes)
+ return NULL;
+
+ bb = buffer_newblock(b, size);
+ /* cheat by moving the new block from the end to the start. */
+
+ bb = b->blocks[b->lastblock];
+ if (b->lastblock != 0)
+ {
+ memmove(b->blocks+1, b->blocks, sizeof(byteblock *) * b->lastblock );
+ b->blocks[0] = bb;
+ }
+
+ memcpy(&(b->blocks[0]->byte0), bytes, size);
+
+ b->blocks[0]->fill = size;
+
+ return &(b->blocks[0]->byte0);
+}
+
+/* Allocate memory at the end of the buffer (if there isn't
+ * enough already) so that the user can append at least that
+ * many bytes without overrunning the buffer. This is useful
+ * where one may not know in advance how many bytes are to be
+ * added (e.g. reading from a socket) but one does know the
+ * upper limit.
+ */
+char *buffer_makespace(buffer *b, unsigned int size)
+{
+ byteblock *bb;
+ byteblock *last;
+ if (!b)
+ return NULL;
+
+ last = b->blocks[b->lastblock];
+
+ if (last->size - last->fill > size)
+ return (&last->byte0 + last->fill);
+
+ if (size > ALLOCSIZE)
+ {
+ bb = buffer_newblock(b, size);
+ } else {
+ bb = buffer_newblock(b, ALLOCSIZE);
+ }
+
+ if (!bb)
+ return NULL;
+
+ return &bb->byte0;
+}
+
+void buffer_usespace(buffer *b, unsigned int nbytes)
+{
+ byteblock *last;
+
+ if (!b)
+ return;
+
+ last = b->blocks[b->lastblock];
+
+ if (last->fill + nbytes < last->size)
+ last->fill += nbytes;
+ else
+ last->fill = last->size; /* really an error - no exceptions though. */
+}
+
+byteblock *buffer_getbytes(buffer *b, int *iterator)
+{
+ if (!b)
+ return NULL;
+
+ if (*iterator > b->lastblock)
+ return NULL;
+
+ return b->blocks[(*iterator)++];
+}
+
+void buffer_free(buffer **b)
+{
+ int i;
+ buffer *bf;
+
+ if (!b || !*b)
+ return;
+
+ bf=*b;
+
+ if (bf->blocks)
+ {
+ for (i=0; i <= bf->lastblock; i++)
+ {
+ if (bf->blocks[i])
+ free(bf->blocks[i]);
+ }
+ free(bf->blocks);
+ }
+ free(bf);
+
+ *b = NULL;
+}
+