From 8d7d7a57b31433fad9bcfb2bb21cfa5cd1090679 Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Sun, 8 Dec 2002 09:59:57 +0000 Subject: [PATCH] Some changes to safe_buffer structure. --- gedcom/buffer.c | 34 +++++++++++++++++++++++----------- gedcom/buffer.h | 19 ++++++++++++++++++- gedcom/message.c | 2 +- gedcom/write.c | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/gedcom/buffer.c b/gedcom/buffer.c index c09eaa5..6f807b1 100644 --- a/gedcom/buffer.c +++ b/gedcom/buffer.c @@ -33,8 +33,11 @@ void reset_buffer(struct safe_buffer* b) { - if (b && b->buffer != NULL) - b->buffer[0] = '\0'; + if (b && b->buffer != NULL) { + memset(b->buffer, 0, b->bufsize); + b->buf_end = b->buffer; + b->buflen = 0; + } } void cleanup_buffer(struct safe_buffer *b) @@ -50,6 +53,8 @@ void init_buffer(struct safe_buffer *b) if (b->buffer) { b->buffer[0] = '\0'; b->bufsize = INITIAL_BUF_SIZE; + b->buf_end = b->buffer; + b->buflen = 0; if (b->cleanup_func && atexit(b->cleanup_func) != 0) { fprintf(stderr, _("Could not register buffer cleanup function")); fprintf(stderr, "\n"); @@ -63,31 +68,38 @@ void init_buffer(struct safe_buffer *b) } } +void grow_buffer(struct safe_buffer *b) +{ + b->bufsize *= 2; + b->buffer = realloc(b->buffer, b->bufsize); + b->buf_end = b->buffer + b->buflen; +} + int safe_buf_vappend(struct safe_buffer *b, const char *s, va_list ap) { int res = 0; - int len; init_buffer(b); if (b && b->buffer) { - len = strlen(b->buffer); while (1) { - char *buf_ptr = b->buffer + len; - int rest_size = b->bufsize - len; + int rest_size = b->bufsize - b->buflen; #if HAVE_VSNPRINTF - res = vsnprintf(buf_ptr, rest_size, s, ap); + res = vsnprintf(b->buf_end, rest_size, s, ap); if (res > -1 && res < rest_size) { + b->buf_end = b->buf_end + res; + b->buflen = b->buflen + res; break; } - else { - b->bufsize *= 2; - b->buffer = realloc(b->buffer, b->bufsize); + else { + grow_buffer(b); } #else /* not HAVE_VSNPRINTF */ # if HAVE_VSPRINTF # warning "Using VSPRINTF. Buffer overflow could happen!" - vsprintf(buf_ptr, s, ap); + res = vsprintf(b->buf_end, s, ap); + b->buf_end = b->buf_end + res; + b->buflen = b->buflen + res; break; # else /* not HAVE_VPRINTF */ # error "Your standard library has neither vsnprintf nor vsprintf defined. One of them is required!" diff --git a/gedcom/buffer.h b/gedcom/buffer.h index f51acff..8475e8c 100644 --- a/gedcom/buffer.h +++ b/gedcom/buffer.h @@ -29,16 +29,33 @@ struct safe_buffer { char* buffer; - size_t bufsize; + size_t bufsize; /* total size */ + char* buf_end; + size_t buflen; /* used size */ void (*cleanup_func)(void); }; void init_buffer(struct safe_buffer* b); void reset_buffer(struct safe_buffer* b); void cleanup_buffer(struct safe_buffer* b); +void grow_buffer(struct safe_buffer* b); int safe_buf_vappend(struct safe_buffer* b, const char* s, va_list ap); int safe_buf_append(struct safe_buffer* b, const char* s, ...); char* get_buf_string(struct safe_buffer* b); +#define SAFE_BUF_ADDCHAR(b, ch) \ + { \ + struct safe_buffer *buf = b; \ + char c = ch; \ + if (buf && buf->buffer == NULL) \ + init_buffer(buf); \ + if (buf && buf->buffer) { \ + if (buf->buflen == buf->bufsize) \ + grow_buffer(buf); \ + *buf->buf_end++ = c; \ + buf->buflen++; \ + } \ + } + #endif /* __BUFFER_H */ diff --git a/gedcom/message.c b/gedcom/message.c index 6943f60..3fe288b 100644 --- a/gedcom/message.c +++ b/gedcom/message.c @@ -27,7 +27,7 @@ void cleanup_mess_buffer(); -struct safe_buffer mess_buffer = { NULL, 0, cleanup_mess_buffer }; +struct safe_buffer mess_buffer = { NULL, 0, NULL, 0, cleanup_mess_buffer }; Gedcom_msg_handler msg_handler = NULL; void gedcom_set_message_handler(Gedcom_msg_handler func) diff --git a/gedcom/write.c b/gedcom/write.c index e74a571..e82fd62 100644 --- a/gedcom/write.c +++ b/gedcom/write.c @@ -61,7 +61,7 @@ const char* terminator[] = { void cleanup_write_buffer(); -struct safe_buffer write_buffer = { NULL, 0, cleanup_write_buffer }; +struct safe_buffer write_buffer = { NULL, 0, NULL, 0, cleanup_write_buffer }; void cleanup_write_buffer() { -- 2.30.2