/* buffer.c */
/* Manage auto-extending buffers */
#include "common.h"
#include "buffer.h"
#include <stdlib.h>
#include <string.h>
int buffer_init( buffer * b, size_t initsize, size_t growby ) {
if ( initsize > 0 ) {
if ( b->buf = malloc( initsize ), !b->buf ) {
return ERR_Not_Enough_Memory;
}
}
else {
b->buf = NULL;
}
b->size = initsize;
b->used = 0;
b->growby = growby;
b->flags = 0;
return ERR_None;
}
int buffer_delete( buffer * b ) {
free( b->buf );
b->buf = NULL;
b->size = 0;
b->used = 0;
b->growby = 0;
b->flags = 0;
return ERR_None;
}
int buffer_ensure( buffer * b, size_t minsize ) {
if ( b->size < minsize ) {
size_t nsize = NMAX( b->size + b->growby, minsize );
/* Could realloc here but malloc() / free() works better
with our debug memory manager. */
void *nbuf = malloc( nsize );
if ( !nbuf ) {
return ERR_Not_Enough_Memory;
}
if ( b->buf ) {
memcpy( nbuf, b->buf, b->used );
free( b->buf );
}
b->buf = nbuf;
b->size = nsize;
}
return ERR_None;
}
int buffer_ensure_free( buffer * b, size_t minfree ) {
return buffer_ensure( b, b->used + minfree );
}
int buffer_append( buffer * b, const void *m, size_t len ) {
int err;
if ( err = buffer_ensure_free( b, len ), ERR_None != err ) {
return err;
}
memcpy( ( char * )b->buf + b->used, m, len );
b->used += len;
return ERR_None;
}
int buffer_set_used( buffer * b, size_t used ) {
int err;
if ( used > b->used ) {
if ( err =
buffer_ensure_free( b, used - b->used ), ERR_None != err ) {
return err;
}
}
b->used = used;
return ERR_None;
}