changeset 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 86c845f86868
files buffer.c buffer.h
diffstat 2 files changed, 42 insertions(+), 12 deletions(-) [+]
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);
 
--- a/buffer.h	Mon Sep 05 23:01:29 2011 +0200
+++ b/buffer.h	Tue Sep 06 17:43:59 2011 +0200
@@ -26,12 +26,14 @@
 struct buffer {
 	char	*data;		/* string buffer */
 	size_t	length;		/* string's length */
-	size_t	size;		/* current size */
-	size_t	bsize;		/* block size */
 
 #define BUFFER_AUTO	0x00000001
 #define BUFFER_FIXED	0x00000010
 	int	flags;		/* buffer's flags (default AUTO) */
+
+	/* Private should not be modified by user */
+	size_t	size;		/* current size */
+	size_t	bsize;		/* block size */
 };
 
 struct buffer	*buffer_new(const char *, size_t, int);
@@ -39,6 +41,7 @@
 #define buffer_new_fixed(max)	buffer_new(NULL, max, BUFFER_FIXED)
 
 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 *, ...);