diff buffer.c @ 1:22d7bb03e569

for buffer: o added a new function buffer_putc(struct buffer *, char) that append the character to the end of the buffer o fix buffer_printf on BUFFER_AUTO
author David Demelier <markand@malikania.fr>
date Tue, 06 Sep 2011 17:43:59 +0200
parents a20beb164de8
children e19a50d6a5be
line wrap: on
line diff
--- a/buffer.c	Mon Sep 05 23:01:29 2011 +0200
+++ b/buffer.c	Tue Sep 06 17:43:59 2011 +0200
@@ -82,6 +82,22 @@
 }
 
 /*
+ * 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;
+
+	buf->data[buf->length++]	= c;
+	buf->data[buf->length]		= '\0';
+
+	return 0;
+}
+
+/*
  * Concatenate the byte pointer into the buffer.
  */
 
@@ -109,7 +125,7 @@
 buffer_vprintf(struct buffer *buf, const char *fmt, va_list ap)
 {
 	va_list ap_save;
-	int nb, stop = 0;
+	int nb, result = 1;
 
 	/*
 	 * vsnprintf on windows returns -1 instead of the number of bytes that
@@ -121,19 +137,23 @@
 			nb = vsnprintf(buf->data + buf->length,
 			    buf->size - buf->length - 1, fmt, ap_save);
 
-			if (nb == -1 || nb > strlen(buf->data)) {
+			if (nb == -1 || nb >= buf->size - buf->length - 1) {
 				if (buffer_grow(buf, buf->size + buf->bsize))
-					return -1;
+					result = -1;
 			} else
-				stop = 1;
-		} while (stop == 0);
-	} else
+				result = 0;
+		} while (result == 1);
+
+		va_end(ap_save);
+	} else {
+		result = 0;
 		vsnprintf(buf->data + buf->length, buf->size - buf->length - 1,
 		    fmt, ap);
+	}
 
-	va_end(ap_save);
+	buf->length = strlen(buf->data);
 
-	return 0;
+	return result;
 }
 
 /*
@@ -204,6 +224,12 @@
 	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)
 {
@@ -211,12 +237,13 @@
 		return 0;
 
 	if (buf->flags & BUFFER_AUTO) {
-		while (buf->size - buf->length < needed)
+		while (buf->size - buf->length - 1 < needed)
 			buf->size += buf->bsize;
 
 		if (!(buf->data = realloc(buf->data, buf->size)))
 			return -1;
-	}
+	} else if ((buf->flags & BUFFER_FIXED))
+		return (buf->bsize == buf->length) ? -1 : 0;
 
 	memset(buf->data + buf->length, 0, buf->size - buf->length);