From 55f4e4a5ec657a017e3bf75299ad71fd1c968dd3 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- cbuffer.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 cbuffer.c (limited to 'cbuffer.c') diff --git a/cbuffer.c b/cbuffer.c new file mode 100644 index 0000000..082b0dd --- /dev/null +++ b/cbuffer.c @@ -0,0 +1,231 @@ +/* Copyright (C) 2007-2008 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ +#include "cbuffer.h" +#include "android_utils.h" +#include +#include +#include +#include + +#define DEBUG 0 + +#if DEBUG +# define ASSERT(cond,fmt,...) ({ if (!(cond)) { fprintf(stderr, fmt, __VA_ARGS__); assert(cond); } }) +#else +# define ASSERT(cond,fmt,...) ((void)0) +#endif + +#if DEBUG +void +cbuffer_assert( CBuffer* cb, const char* file, long lineno ) +{ + const char* reason = NULL; + + if (cb->rpos < 0 || cb->rpos >= cb->size) { + reason = "rpos is out of bounds"; + } + else if (cb->count < 0 || cb->count > cb->size) { + reason = "count is incorrect"; + } + if (!reason) + return; + + fprintf(stderr, "assert:%s:%ld: assertion failed: %s (pos=%d count=%d size=%d)\n", + file, lineno, reason, cb->rpos, cb->count, cb->size); + assert(0); +} +# define CBUFFER_ASSERT(cb) cbuffer_assert(cb,__FUNCTION__,__LINE__) +#else +# define CBUFFER_ASSERT(cb) ((void)0) +#endif + +int +cbuffer_write_peek( CBuffer* cb, uint8_t* *pbase ) +{ + int wpos = cb->rpos + cb->count; + int avail = cb->size - cb->count; + + CBUFFER_ASSERT(cb); + + if (wpos >= cb->size) + wpos -= cb->size; + + if (wpos + avail > cb->size) + avail = cb->size - wpos; + + *pbase = cb->buff + wpos; + return avail; +} + +void +cbuffer_write_step( CBuffer* cb, int len ) +{ + CBUFFER_ASSERT(cb); + + cb->count += len; + if (cb->count > cb->size) + cb->count = cb->size; +} + + +int +cbuffer_write( CBuffer* cb, const void* from, int len ) +{ + int len2 = len; + + CBUFFER_ASSERT(cb); + + while (len2 > 0) { + int avail = cb->size - cb->count; + int wpos = cb->rpos + cb->count; + + ASSERT(avail >= 0, "avail is negative: %d", avail); + + if (avail == 0) + break; + + if (wpos >= cb->size) + wpos -= cb->size; + + ASSERT( wpos >= 0 && wpos < cb->size, "wpos is out-of-bounds: %d (rpos=%d)", wpos, cb->rpos); + + if (wpos + avail > cb->size) + avail = cb->size - wpos; + + if (avail > len2) + avail = len2; + + memcpy( cb->buff + wpos, (const char*)from, avail ); + + from = (char*)from + avail; + len2 -= avail; + cb->count += avail; + } + return len - len2; +} + +int +cbuffer_read( CBuffer* cb, void* to, int len ) +{ + int len2 = len; + + CBUFFER_ASSERT(cb); + + while (len2 > 0) { + int avail = cb->count; + int rpos = cb->rpos; + + ASSERT(avail >= 0, "avail is negative: %d", avail); + + if (avail == 0) + break; + + ASSERT((rpos >= 0 && rpos < cb->size), "rpos is out-of-bounds: %d", rpos); + + if (rpos+avail > cb->size) + avail = cb->size - rpos; + + if (avail > len2) + avail = len2; + + memcpy( (char*)to, (const char*)cb->buff + rpos, avail ); + to = (char*)to + avail; + len2 -= avail; + cb->count -= avail; + cb->rpos += avail; + if (cb->rpos >= cb->size) + cb->rpos -= cb->size; + } + return len - len2; +} + +int +cbuffer_read_peek( CBuffer* cb, uint8_t* *pbase ) +{ + int rpos = cb->rpos; + int avail = cb->count; + + CBUFFER_ASSERT(cb); + + if (rpos + avail > cb->size) + avail = cb->size - rpos; + + *pbase = cb->buff + rpos; + return avail; +} + + +void +cbuffer_read_step( CBuffer* cb, int len ) +{ + CBUFFER_ASSERT(cb); + + if (len > cb->count) + len = cb->count; + + cb->rpos += len; + if (cb->rpos >= cb->size) + cb->rpos -= cb->size; + + cb->count -= len; +} + +const char* +cbuffer_quote( CBuffer* cb ) +{ + STRALLOC_DEFINE(s); + char* q; + + stralloc_format( s, "cbuffer %p (pos=%d count=%d size=%d)", + cb, cb->rpos, cb->count, cb->size ); + + q = tempstr_from_stralloc( s ); + stralloc_reset(s); + + return q; +} + +const char* +cbuffer_quote_data( CBuffer* cb ) +{ + STRALLOC_DEFINE(s); + int len = cb->count; + int rpos = cb->rpos; + char* result; + + while (len > 0) { + int avail = len; + + if (rpos >= cb->size) + rpos -= cb->size; + + if (rpos + avail > cb->size) + avail = cb->size - rpos; + + stralloc_add_quote_bytes( s, cb->buff + rpos, avail ); + rpos += avail; + len -= avail; + } + + result = tempstr_from_stralloc(s); + stralloc_reset(s); + + return result; +} + +void +cbuffer_print( CBuffer* cb ) +{ + /* print the content of a cbuffer */ + printf( "%s: %s", cbuffer_quote(cb), cbuffer_quote_data(cb) ); +} + -- cgit v1.1