Copied from old documentation. Removed all Gedcom_val details.
[gedcom-parse.git] / gedcom / buffer.c
index c09eaa548db7b7b179493a79f8e981e5a159a591..0c3e17ca8cc094ad4925f47924266faafe23bbca 100644 (file)
 
 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)
@@ -48,8 +51,10 @@ void init_buffer(struct safe_buffer *b)
   if (b && b->buffer == NULL) {
     b->buffer = (char *)malloc(INITIAL_BUF_SIZE);
     if (b->buffer) {
-      b->buffer[0] = '\0';
       b->bufsize = INITIAL_BUF_SIZE;
+      memset(b->buffer, 0, b->bufsize);
+      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,46 @@ void init_buffer(struct safe_buffer *b)
   }
 }
 
+void grow_buffer(struct safe_buffer *b)
+{
+  char* new_buffer;
+  size_t old_size = b->bufsize;
+  b->bufsize *= 2;
+  new_buffer = realloc(b->buffer, b->bufsize);
+  if (new_buffer) {
+    b->buffer = new_buffer;
+    memset(b->buffer + old_size, 0, b->bufsize - old_size);
+    b->buf_end = b->buffer + b->buflen;
+  }
+  else
+    b->buffer = NULL;
+}
+
 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!"