diff options
Diffstat (limited to 'src/helper/membuf.c')
-rw-r--r-- | src/helper/membuf.c | 476 |
1 files changed, 238 insertions, 238 deletions
diff --git a/src/helper/membuf.c b/src/helper/membuf.c index af396ca..30b653c 100644 --- a/src/helper/membuf.c +++ b/src/helper/membuf.c @@ -1,238 +1,238 @@ -/***************************************************************************
- * Copyright (C) 2009 By Duane Ellis *
- * openocd@duaneellis.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * 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. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <malloc.h>
-#include <string.h>
-
-#include "membuf.h"
-
-struct membuf {
- // buflen is alway "+1" bigger then
- // what is shown here, the +1 is for
- // the NULL string terminator
-#define DEFAULT_BUFSIZE 100
- size_t maxlen; // allocated size
- size_t curlen; // where we are inserting at
- char *_strtoklast;
- void *buf;
-};
-
-
-#define space_avail( pBuf ) (pBuf->maxlen - pBuf->curlen)
-#define dataend( pBuf ) ( ((char *)(pBuf->buf)) + pBuf->curlen )
-
-size_t
-membuf_len( struct membuf *pBuf )
-{
- return pBuf->curlen;
-}
-
-const void *
-membuf_datapointer( struct membuf *pBuf )
-{
- return ((void *)(pBuf->buf));
-}
-
-const char *
-membuf_strtok( struct membuf *pBuf, const char *sep, void **pLast )
-{
- if( pBuf ){
- pBuf->_strtoklast = NULL;
- *pLast = pBuf;
- return strtok_r( ((char *)(pBuf->buf)), sep, &(pBuf->_strtoklast) );
- } else {
- // recover our pBuf
- pBuf = *((struct membuf **)(pLast));
- return strtok_r( NULL, sep, &(pBuf->_strtoklast) );
- }
-}
-
-
-
-struct membuf *
-membuf_new(void)
-{
- // by default - parameters are zero.
- struct membuf *pBuf;
-
- pBuf = calloc( 1, sizeof(*pBuf) );
- if( pBuf ){
- // we *ALWAYS* allocate +1 for null terminator.
- pBuf->buf = calloc( DEFAULT_BUFSIZE+1, sizeof(char));
- if( pBuf->buf == NULL ){
- free(pBuf);
- pBuf = NULL;
- } else {
- pBuf->maxlen = DEFAULT_BUFSIZE;
- }
- }
- return pBuf;
-}
-
-
-struct membuf *
-membuf_grow( struct membuf *pBuf, int n )
-{
- void *vp;
- signed int newsize;
-
- // this is a *SIGNED* value
- newsize = ((int)(pBuf->maxlen)) + n;
-
- // do not go negative, or too small
- if( newsize < DEFAULT_BUFSIZE ){
- newsize = DEFAULT_BUFSIZE;
- }
-
- // always alloc +1 for the null terminator
- vp = realloc( pBuf->buf, newsize+1 );
- if( vp ){
- pBuf->buf = vp;
- pBuf->maxlen = newsize;
- return pBuf;
- } else {
- return NULL;
- }
-}
-
-
-void membuf_reset( struct membuf *pBuf )
-{
- pBuf->curlen = 0;
-}
-
-
-void membuf_delete( struct membuf *pBuf )
-{
- if( pBuf ){
- if( pBuf->buf){
- // wack data so it cannot be reused
- memset(pBuf->buf,0,pBuf->maxlen);
- free(pBuf->buf);
- }
- // wack dat so it cannot be reused
- memset(pBuf,0,sizeof(pBuf));
- free(pBuf);
- }
-}
-
-int
-membuf_sprintf( struct membuf *pBuf , const char *fmt, ... )
-{
- int r;
- va_list ap;
- va_start( ap, fmt );
- r = membuf_vsprintf( pBuf, fmt, ap );
- va_end(ap);
- return r;
-}
-
-int
-membuf_vsprintf( struct membuf *pBuf, const char *fmt, va_list ap )
-{
- int r;
- size_t sa;
- int grew;
-
-
- grew = 0;
- for(;;) {
- sa = space_avail(pBuf);
-
- // do work
- r = vsnprintf( dataend( pBuf ),
- sa,
- fmt,
- ap );
- if( (r > 0) && (((size_t)(r)) < sa) ){
- // Success!
- pBuf->curlen += ((size_t)(r));
- // remember: We always alloc'ed +1
- // so this does not overflow
- ((char *)(pBuf->buf))[ pBuf->curlen ] = 0;
- r = 0;
- break;
- }
-
- // failure
- if( r < 0 ){
- // Option(A) format error
- // Option(B) glibc2.0 bug
- // assume (B).
- r = (4 * DEFAULT_BUFSIZE);
- }
-
- // don't do this again
- if( grew ){
- r = -1;
- break;
- }
- grew = 1;
- pBuf = membuf_grow( pBuf, r );
- if(pBuf == NULL){
- // grow failed
- r = -1;
- break;
- }
- }
- return r;
-}
-
-struct membuf *
-membuf_strcat( struct membuf *pBuf, const char *pStr )
-{
- return membuf_append( pBuf, pStr, strlen( pStr ) );
-}
-
-struct membuf *
-membuf_append( struct membuf *pBuf, const void *pData, size_t len )
-{
- size_t sa;
- int r;
-
- // how much room is there?
- sa = space_avail( pBuf );
-
- // will it fit?
- if( sa < len ){
- // if not, how much do we need?
- r = ((int)(sa - len));
- // do the grow.
- pBuf = membuf_grow( pBuf, r );
- // failed?
- if(pBuf==NULL){
- return pBuf;
- }
- }
- // append
- memcpy( dataend(pBuf),
- pData,
- len );
- pBuf->curlen += len;
- return pBuf;
-}
-
-
-
-
-
-
+/*************************************************************************** + * Copyright (C) 2009 By Duane Ellis * + * openocd@duaneellis.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <stdio.h> +#include <stdarg.h> +#include <malloc.h> +#include <string.h> + +#include "membuf.h" + +struct membuf { + // buflen is alway "+1" bigger then + // what is shown here, the +1 is for + // the NULL string terminator +#define DEFAULT_BUFSIZE 100 + size_t maxlen; // allocated size + size_t curlen; // where we are inserting at + char *_strtoklast; + void *buf; +}; + + +#define space_avail( pBuf ) (pBuf->maxlen - pBuf->curlen) +#define dataend( pBuf ) ( ((char *)(pBuf->buf)) + pBuf->curlen ) + +size_t +membuf_len( struct membuf *pBuf ) +{ + return pBuf->curlen; +} + +const void * +membuf_datapointer( struct membuf *pBuf ) +{ + return ((void *)(pBuf->buf)); +} + +const char * +membuf_strtok( struct membuf *pBuf, const char *sep, void **pLast ) +{ + if( pBuf ){ + pBuf->_strtoklast = NULL; + *pLast = pBuf; + return strtok_r( ((char *)(pBuf->buf)), sep, &(pBuf->_strtoklast) ); + } else { + // recover our pBuf + pBuf = *((struct membuf **)(pLast)); + return strtok_r( NULL, sep, &(pBuf->_strtoklast) ); + } +} + + + +struct membuf * +membuf_new(void) +{ + // by default - parameters are zero. + struct membuf *pBuf; + + pBuf = calloc( 1, sizeof(*pBuf) ); + if( pBuf ){ + // we *ALWAYS* allocate +1 for null terminator. + pBuf->buf = calloc( DEFAULT_BUFSIZE+1, sizeof(char)); + if( pBuf->buf == NULL ){ + free(pBuf); + pBuf = NULL; + } else { + pBuf->maxlen = DEFAULT_BUFSIZE; + } + } + return pBuf; +} + + +struct membuf * +membuf_grow( struct membuf *pBuf, int n ) +{ + void *vp; + signed int newsize; + + // this is a *SIGNED* value + newsize = ((int)(pBuf->maxlen)) + n; + + // do not go negative, or too small + if( newsize < DEFAULT_BUFSIZE ){ + newsize = DEFAULT_BUFSIZE; + } + + // always alloc +1 for the null terminator + vp = realloc( pBuf->buf, newsize+1 ); + if( vp ){ + pBuf->buf = vp; + pBuf->maxlen = newsize; + return pBuf; + } else { + return NULL; + } +} + + +void membuf_reset( struct membuf *pBuf ) +{ + pBuf->curlen = 0; +} + + +void membuf_delete( struct membuf *pBuf ) +{ + if( pBuf ){ + if( pBuf->buf){ + // wack data so it cannot be reused + memset(pBuf->buf,0,pBuf->maxlen); + free(pBuf->buf); + } + // wack dat so it cannot be reused + memset(pBuf,0,sizeof(pBuf)); + free(pBuf); + } +} + +int +membuf_sprintf( struct membuf *pBuf , const char *fmt, ... ) +{ + int r; + va_list ap; + va_start( ap, fmt ); + r = membuf_vsprintf( pBuf, fmt, ap ); + va_end(ap); + return r; +} + +int +membuf_vsprintf( struct membuf *pBuf, const char *fmt, va_list ap ) +{ + int r; + size_t sa; + int grew; + + + grew = 0; + for(;;) { + sa = space_avail(pBuf); + + // do work + r = vsnprintf( dataend( pBuf ), + sa, + fmt, + ap ); + if( (r > 0) && (((size_t)(r)) < sa) ){ + // Success! + pBuf->curlen += ((size_t)(r)); + // remember: We always alloc'ed +1 + // so this does not overflow + ((char *)(pBuf->buf))[ pBuf->curlen ] = 0; + r = 0; + break; + } + + // failure + if( r < 0 ){ + // Option(A) format error + // Option(B) glibc2.0 bug + // assume (B). + r = (4 * DEFAULT_BUFSIZE); + } + + // don't do this again + if( grew ){ + r = -1; + break; + } + grew = 1; + pBuf = membuf_grow( pBuf, r ); + if(pBuf == NULL){ + // grow failed + r = -1; + break; + } + } + return r; +} + +struct membuf * +membuf_strcat( struct membuf *pBuf, const char *pStr ) +{ + return membuf_append( pBuf, pStr, strlen( pStr ) ); +} + +struct membuf * +membuf_append( struct membuf *pBuf, const void *pData, size_t len ) +{ + size_t sa; + int r; + + // how much room is there? + sa = space_avail( pBuf ); + + // will it fit? + if( sa < len ){ + // if not, how much do we need? + r = ((int)(sa - len)); + // do the grow. + pBuf = membuf_grow( pBuf, r ); + // failed? + if(pBuf==NULL){ + return pBuf; + } + } + // append + memcpy( dataend(pBuf), + pData, + len ); + pBuf->curlen += len; + return pBuf; +} + + + + + + |