Mercurial > code
changeset 107:2b2cb686e358
Buffer is outdated and need to be reviewed
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 07 Feb 2012 10:00:35 +0100 |
parents | 06c968b92090 |
children | d5ea329ba28e |
files | buffer.c buffer.h |
diffstat | 2 files changed, 0 insertions(+), 341 deletions(-) [+] |
line wrap: on
line diff
--- a/buffer.c Sat Jan 28 19:38:59 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,286 +0,0 @@ -/* - * buffer.c -- safe unlimited size string - * - * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> - -#include "buffer.h" - -static int buffer_grow(struct buffer *, size_t); - -/* - * Initialize a new buffer. - */ - -int -buffer_init(struct buffer *buf) -{ - /* Set defaults if needed */ - buf->bsize = (buf->length == 0) ? BUFFER_DEFAULT_BSIZE : buf->length; - buf->size = buf->bsize + 1; - buf->malloc = (buf->malloc == NULL) ? &malloc : buf->malloc; - buf->realloc = (buf->realloc == NULL) ? &realloc : buf->realloc; - - if ((buf->text = buf->malloc(buf->size)) == NULL) { - free(buf); - return -1; - } - - memset(buf->text, 0, buf->size); - - return 0; -} - -/* - * Valid options that can be set for a buffer : - * l -> optional buffer block size of type int - * m -> malloc function that must matches void * (*malloc)(size_t) - * r -> realloc function that must matches void * (*realloc)(void *, size_t) - * t -> type of array of type enum array_type - */ - -void -buffer_set(struct buffer *buf, const char *fmt, ...) -{ - va_list ap; - const char *p; - - va_start(ap, fmt); - for (p = fmt; *p != '\0'; ++p) - switch (*p) { - case 'l': - buf->bsize = va_arg(ap, int); - break; - case 'm': - buf->malloc = va_arg(ap, void *(*)(size_t)); - break; - case 'r': - buf->realloc = va_arg(ap, void *(*)(void *, size_t)); - break; - case 't': - buf->type = va_arg(ap, int); - break; - default: - break; - } -} - -/* - * Concatenate the string into the buffer. - */ - -int -buffer_strcat(struct buffer *buf, const char *str) -{ - size_t length; - - length = strlen(str); - if (buffer_grow(buf, length) < 0) - return -1; - - if (buf->type == BUFFER_AUTO) - length = buf->size - buf->length - 1; - - strncpy(buf->text + buf->length, str, length); - buf->length = strlen(buf->text); - - return 0; -} - -/* - * Append the character `c' to the end of buffer. - */ - -int -buffer_putc(struct buffer *buf, char c) -{ - if (buffer_grow(buf, 1) < 0) - return -1; - - if (buf->type != BUFFER_AUTO && buf->size - buf->length - 1 <= 2) - return -1; - - buf->text[buf->length++] = c; - buf->text[buf->length] = '\0'; - - return 0; -} - -/* - * Concatenate the byte pointer into the buffer. - */ - -int -buffer_bcat(struct buffer *buf, const void *data, size_t size) -{ - if (buffer_grow(buf, size) < 0) - return -1; - - /* Do not truncate void pointer */ - if (buf->type == BUFFER_AUTO && size > (buf->size - buf->length - 1)) - return -1; - - memcpy(buf->text + buf->length, data, size); - buf->length += size; - - return 0; -} - -/* - * Print into the buffer using va_list from stdarg.h - */ - -int -buffer_vprintf(struct buffer *buf, const char *fmt, va_list ap) -{ - va_list ap_save; - int nb, result = 1; - - /* - * vsnprintf on windows returns -1 instead of the number of bytes that - * should be printed... - */ - if (buf->type == BUFFER_AUTO) { - do { - va_copy(ap_save, ap); - nb = vsnprintf(buf->text + buf->length, - buf->size - buf->length - 1, fmt, ap_save); - - if (nb == -1 || (size_t) nb >= buf->size - buf->length - 1) { - if (buffer_grow(buf, buf->size + buf->bsize)) - result = -1; - } else - result = 0; - } while (result == 1); - - va_end(ap_save); - } else { - result = 0; - vsnprintf(buf->text + buf->length, buf->size - buf->length - 1, - fmt, ap); - } - - buf->length = strlen(buf->text); - - return result; -} - -/* - * Use printf(3) functions like to write into the buffer. - */ - -int -buffer_printf(struct buffer *buf, const char *fmt, ...) -{ - va_list ap; - int status; - - va_start(ap, fmt); - status = buffer_vprintf(buf, fmt, ap); - va_end(ap); - - return status; -} - -/* - * Reduce the data buffer to the exact size. Returns -1 on failure. - */ - -int -buffer_shrink(struct buffer *buf) -{ - if ((buf->text = buf->realloc(buf->text, buf->length + 1)) == NULL) { - buf->size = 0; - return -1; - } - - buf->size = buf->length + 1; - - return 0; -} - -/* - * Returns the buffer data and then free the buffer object. - */ - -char * -buffer_end(struct buffer *buf) -{ - char *text; - - buffer_shrink(buf); - text = buf->text; - free(buf); - - return text; -} - -/* - * Reset the struct buffer. - */ - -void -buffer_clear(struct buffer *buf) -{ - memset(buf->text, 0, buf->size); - buf->length = 0; -} - -void -buffer_free(struct buffer *buf) -{ - buffer_clear(buf); - - if (buf->text) - free(buf->text); - - free(buf); -} - -/* - * Functions that tries to extend the buffer to the `needed' size if the buffer - * allows it. If the buffer is fixed size and there is not enough space the - * functions returns -1 otherwise 0 is returned. - */ - -static int -buffer_grow(struct buffer *buf, size_t needed) -{ - size_t newlen; - - if ((buf->size - buf->length) > needed) - return 0; - - if (buf->type == BUFFER_AUTO) { - newlen = buf->size; - while (newlen - buf->length - 1 <= needed) - newlen += buf->bsize; - - if ((buf->text = buf->realloc(buf->text, newlen)) == NULL) { - buf->size = 0; - return -1; - } - - buf->size = newlen; - memset(buf->text + buf->length, 0, buf->size - buf->length); - } - - return 0; -}
--- a/buffer.h Sat Jan 28 19:38:59 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * buffer.h -- safe unlimited size string - * - * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BUFFER_H_ -#define _BUFFER_H_ - -#include <stdarg.h> - -#define BUFFER_DEFAULT_BSIZE 512 - -enum buffer_type { - BUFFER_FIXED = 0, - BUFFER_AUTO = 1 -}; - -struct buffer { - enum buffer_type type; /* buffer type (default AUTO) */ - char *text; /* string buffer */ - size_t length; /* string's real length */ - size_t size; /* current allocated size */ - int bsize; /* initial length */ - - /* Own allocation functions */ - void * (*malloc)(size_t); - void * (*realloc)(void *, size_t); -}; - -int buffer_init(struct buffer *); -void buffer_set(struct buffer *, const char *, ...); -int buffer_strcat(struct buffer *, const char *); -int buffer_putc(struct buffer *buf, char); -int buffer_bcat(struct buffer *, const void *, size_t); -int buffer_vprintf(struct buffer *, const char *, va_list); -int buffer_printf(struct buffer *, const char *, ...); -int buffer_shrink(struct buffer *); -char *buffer_end(struct buffer *); -void buffer_clear(struct buffer *); -void buffer_free(struct buffer *); - -#endif /* _BUFFER_H_ */