/* cStringBuffer: a file-like string buffer.
Copyright (C) 2004 Mooneer Salem <mooneer@translator.cx>
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <unistd.h>
#include "config.h"
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include "csb_private.h"
#include "csb.h"
/* csb_puts(): Print string to file buffer.
Parameters:
buf: The buffer to print to.
string: The string to print.
Returns: true on success, false otherwise.
*/
int csb_puts(csb_buf *buf, /*@unique@*/ const char *str) /*@modifies buf->fileptr, buf->string, buf->stringsize, buf->length, buf->ungetc_buffer@*/ {
const size_t str_size = strlen(str);
/* Do some sanity checks to make sure we're getting a valid buffer. */
assert(buf != NULL && buf->string != NULL);
/* Dynamically make the buffer bigger until we're sure the string fits. */
CSB_RESIZE_TO_FIT(buf, str);
/* "Print" the string to the buffer at its current position. When done,
reset the size of the string and seek to the end of the combined
string. */
strncpy (buf->fileptr, str, str_size);
buf->fileptr += str_size;
if (buf->fileptr >= buf->string + buf->stringsize) {
buf->stringsize = (size_t)((unsigned long)(buf->fileptr) - (unsigned long)(buf->string));
*buf->fileptr = '\0';
}
/* Return TRUE; it was successful. */
return (TRUE);
}
/* csb_putc(): Print a character to file buffer.
Parameters:
buf: The buffer to print to.
ch: The character to print.
Returns: true on success, false otherwise.
*/
int csb_putc(csb_buf *buf, char ch) /*@modifies buf->fileptr, buf->string, buf->stringsize, buf->length, buf->ungetc_buffer, buf->ungetc_length@*/ {
/* Declare variables. */
char str[2];
/* Initialize the string to be the character passed in followed by '\0'. */
str[0] = ch;
str[1] = '\0';
/* Send the string to csb_puts() since there's common code in there. */
return (csb_puts(buf, str));
}
/* csb_write(): write binary data to buffer.
Parameters:
buf: Buffer to operate on.
data: Data to write.
length: The size of the data to write.
Returns: true on success, false otherwise.
*/
int csb_write(csb_buf *buf, /*@unique@*/ const void *data, size_t length) /*@modifies buf->fileptr, buf->string, buf->stringsize, buf->length, buf->ungetc_buffer@*/ {
/* Perform sanity checks to make sure we have a valid buffer. */
assert(buf != NULL && buf->string != NULL);
/* Grow the buffer to the needed size. */
/*while (buf->stringsize + length > buf->length) {
csb_addchunk(buf);
}*/
if (buf->stringsize + length > buf->length) {
(void)csb_prealloc(buf, buf->stringsize + length);
}
/* Copy the data to the position of the file pointer. */
memcpy(buf->fileptr, data, length);
buf->fileptr += length;
/* Adjust the size of the string and move the file pointer
to the end of the string. */
if (buf->stringsize < (size_t)((unsigned long)(buf->fileptr) - (unsigned long)(buf->string))) {
buf->stringsize = (size_t)((unsigned long)(buf->fileptr) - (unsigned long)(buf->string));
*buf->fileptr = '\0';
}
/* Return true, it was a success. */
return(TRUE);
}
/* csb_printf(): write formatted output to the buffer.
Parameters:
buf: Buffer to print to.
fmt: The format of the output (see the man page for printf)
...: each parameter specified in fmt.
Returns: true on success, false otherwise.
*/
int csb_printf(csb_buf *buf, const char *fmt, ...) /*@modifies buf->fileptr, buf->string, buf->stringsize, buf->length, buf->ungetc_buffer@*/ {
/* Declare variables. */
va_list ap;
int retval;
/* Perform sanity checks to make sure we have a valid buffer. */
assert(buf != NULL && buf->string != NULL);
/* Pass the parameters to the system prinf. */
va_start(ap, fmt);
retval = vsnprintf (buf->fileptr, buf->length - buf->stringsize - 1, fmt, ap);
if (retval >= 0) {
if (retval > (int)(buf->length - buf->stringsize - 1)) {
/* Grow the buffer to the needed size. */
/*while (buf->stringsize + retval + 1 > buf->length)
csb_addchunk (buf);*/
if (buf->stringsize + retval + 1 > buf->length) {
(void)csb_prealloc(buf, buf->stringsize + retval + 1);
}
retval = vsnprintf (buf->fileptr, buf->length - buf->stringsize - 1, fmt, ap);
}
buf->fileptr += retval;
/* Adjust the size of the string and move the file pointer
to the end of the string. */
buf->stringsize = (size_t)((unsigned long)(buf->fileptr) - (unsigned long)(buf->string));
}
va_end(ap);
/* Return the return value of csb_puts(). */
return (retval);
}
syntax highlighted by Code2HTML, v. 0.9.1