/* cStringBuffer: a file-like string buffer. Copyright (C) 2004 Mooneer Salem This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Include necessary includes. */ #include #include #include #include #include #include #include "config.h" #ifdef HAVE_PTHREAD_H #include #endif #include "csb_private.h" #include "csb.h" /* csb_addchunk(): Increase the size of the buffer by BUFFER_INCREMENT. Parameters: buf: The buffer to operate on. Returns: nothing. */ void csb_addchunk(csb_buf *buf) /*@modifies buf->length, buf->string, buf->fileptr@*/ { /* Declare variables. */ size_t position; char *newstring; /* Check to see we have a valid buffer. */ assert(buf != NULL && buf->string != NULL); /* Save a copy of the current file position; it may change. */ position = csb_tellpos(buf); /* Call realloc() to increase the size of the string. It must increase by the next multiple of BUFFER_INCREMENT; however, there is a compile flag that will use powers of 2 instead to reduce the number of realloc() calls needed (not recommended unless you want to waste lots of RAM). */ #ifdef CSB_OPTIMIZE_AND_EAT_RAM buf->length = BUFFER_INCREMENT * (1 << ++buf->multipletwo); #else buf->length = BUFFER_INCREMENT * (buf->length / BUFFER_INCREMENT + 1); #endif newstring = malloc(buf->length); if (newstring == NULL) { /* eek! return! */ return; } /* Copy string to new string. */ memcpy(newstring, buf->string, buf->stringsize); free(buf->string); buf->string = newstring; #ifdef CSB_DEBUG memset(buf->string + (buf->length - 1024), '\b', 1024); #endif /* Reset file pointer to its previous position. */ CSB_SEEK_NORESET(buf, position); } /* csb_align(): align a number on a boundary. Parameters: n: The number to align. grain: The boundary to align on. Returns: the aligned number. */ static size_t csb_align (size_t n, size_t grain) /*@*/ { const size_t remainder = n % grain; return (remainder > 0 ? n + (grain - remainder) : n); } /* csb_prealloc(): Preallocate a set amount of space for the string. Parameters: buf: The buffer to operate on. length: The amount to allocate. Returns: true on success, false otherwise. */ int csb_prealloc(csb_buf *buf, size_t length) /*@modifies buf->string, buf->length, buf->fileptr@*/ { /* Declare variables. */ size_t position = csb_tellpos(buf); char *newstring; /* Perform sanity checks to make sure we have a valid buffer. */ assert(buf != NULL && buf->string != NULL); /* Round the length up to the next multiple of BUFFER_INCREMENT, and then allocate the memory. */ buf->length = csb_align (length, BUFFER_INCREMENT); newstring = malloc(buf->length); if (newstring == NULL) { /* Return false, the reallocation wasn't successful. */ return (FALSE); } /* Copy the string from the old variable to the new one. */ memcpy(newstring, buf->string, buf->stringsize); free(buf->string); buf->string = newstring; /* Reset the position of the file pointer. */ CSB_SEEK_NORESET(buf, position); /* Return true; it was a success. */ return(TRUE); }