1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* Copyright (C) 2007-2008 The Android Open Source Project 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert** 3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** This software is licensed under the terms of the GNU General Public 4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** License version 2, as published by the Free Software Foundation, and 5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** may be copied, distributed, and modified under those terms. 6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** 7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** This program is distributed in the hope that it will be useful, 8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** but WITHOUT ANY WARRANTY; without even the implied warranty of 9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson** GNU General Public License for more details. 11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson*/ 12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "android/cbuffer.h" 13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include "android/utils/stralloc.h" 14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include <string.h> 15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include <stdlib.h> 16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include <assert.h> 17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#include <stdio.h> 18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#define DEBUG 0 20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert#if DEBUG 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert# define ASSERT(cond,fmt,...) ({ if (!(cond)) { fprintf(stderr, fmt, __VA_ARGS__); assert(cond); } }) 23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#else 24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson# define ASSERT(cond,fmt,...) ((void)0) 25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#endif 26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#if DEBUG 28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonvoid 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_assert( CBuffer* cb, const char* file, long lineno ) 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson const char* reason = NULL; 32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (cb->rpos < 0 || cb->rpos >= cb->size) { 34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson reason = "rpos is out of bounds"; 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson else if (cb->count < 0 || cb->count > cb->size) { 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson reason = "count is incorrect"; 38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (!reason) 40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return; 41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson fprintf(stderr, "assert:%s:%ld: assertion failed: %s (pos=%d count=%d size=%d)\n", 43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson file, lineno, reason, cb->rpos, cb->count, cb->size); 44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson assert(0); 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson# define CBUFFER_ASSERT(cb) cbuffer_assert(cb,__FUNCTION__,__LINE__) 47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#else 48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson# define CBUFFER_ASSERT(cb) ((void)0) 49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson#endif 50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonint 52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_write_peek( CBuffer* cb, uint8_t* *pbase ) 53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int wpos = cb->rpos + cb->count; 55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int avail = cb->size - cb->count; 56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (wpos >= cb->size) 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson wpos -= cb->size; 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (wpos + avail > cb->size) 63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = cb->size - wpos; 64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *pbase = cb->buff + wpos; 66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return avail; 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertvoid 70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_write_step( CBuffer* cb, int len ) 71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->count += len; 75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (cb->count > cb->size) 76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->count = cb->size; 77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonint 81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_write( CBuffer* cb, const void* from, int len ) 82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int len2 = len; 84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson while (len2 > 0) { 88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int avail = cb->size - cb->count; 89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int wpos = cb->rpos + cb->count; 90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ASSERT(avail >= 0, "avail is negative: %d", avail); 92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (avail == 0) 94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson break; 95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (wpos >= cb->size) 97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson wpos -= cb->size; 98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ASSERT( wpos >= 0 && wpos < cb->size, "wpos is out-of-bounds: %d (rpos=%d)", wpos, cb->rpos); 100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (wpos + avail > cb->size) 102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = cb->size - wpos; 103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (avail > len2) 105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = len2; 106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson memcpy( cb->buff + wpos, (const char*)from, avail ); 108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson from = (char*)from + avail; 110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson len2 -= avail; 111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->count += avail; 112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return len - len2; 114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonint 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertcbuffer_read( CBuffer* cb, void* to, int len ) 118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int len2 = len; 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson while (len2 > 0) { 124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int avail = cb->count; 125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int rpos = cb->rpos; 126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ASSERT(avail >= 0, "avail is negative: %d", avail); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (avail == 0) 130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson break; 131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ASSERT((rpos >= 0 && rpos < cb->size), "rpos is out-of-bounds: %d", rpos); 133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (rpos+avail > cb->size) 135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = cb->size - rpos; 136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (avail > len2) 138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = len2; 139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson memcpy( (char*)to, (const char*)cb->buff + rpos, avail ); 141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson to = (char*)to + avail; 142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson len2 -= avail; 143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->count -= avail; 144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->rpos += avail; 145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (cb->rpos >= cb->size) 146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson cb->rpos -= cb->size; 147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return len - len2; 149090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertint 152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_read_peek( CBuffer* cb, uint8_t* *pbase ) 153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int rpos = cb->rpos; 155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int avail = cb->count; 156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 159090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (rpos + avail > cb->size) 160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson avail = cb->size - rpos; 161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 162090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *pbase = cb->buff + rpos; 163090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return avail; 164090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 165090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 166090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 167090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonvoid 168090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsoncbuffer_read_step( CBuffer* cb, int len ) 169090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson{ 170090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson CBUFFER_ASSERT(cb); 171090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 172090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (len > cb->count) 173090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson len = cb->count; 174 175 cb->rpos += len; 176 if (cb->rpos >= cb->size) 177 cb->rpos -= cb->size; 178 179 cb->count -= len; 180} 181 182const char* 183cbuffer_quote( CBuffer* cb ) 184{ 185 STRALLOC_DEFINE(s); 186 char* q; 187 188 stralloc_format( s, "cbuffer %p (pos=%d count=%d size=%d)", 189 cb, cb->rpos, cb->count, cb->size ); 190 191 q = stralloc_to_tempstr( s ); 192 stralloc_reset(s); 193 194 return q; 195} 196 197const char* 198cbuffer_quote_data( CBuffer* cb ) 199{ 200 STRALLOC_DEFINE(s); 201 int len = cb->count; 202 int rpos = cb->rpos; 203 char* result; 204 205 while (len > 0) { 206 int avail = len; 207 208 if (rpos >= cb->size) 209 rpos -= cb->size; 210 211 if (rpos + avail > cb->size) 212 avail = cb->size - rpos; 213 214 stralloc_add_quote_bytes( s, cb->buff + rpos, avail ); 215 rpos += avail; 216 len -= avail; 217 } 218 219 result = stralloc_to_tempstr(s); 220 stralloc_reset(s); 221 222 return result; 223} 224 225void 226cbuffer_print( CBuffer* cb ) 227{ 228 /* print the content of a cbuffer */ 229 printf( "%s: %s", cbuffer_quote(cb), cbuffer_quote_data(cb) ); 230} 231 232