[dovecot-cvs] dovecot/src/lib buffer.c,1.13,1.14 buffer.h,1.6,1.7

cras at dovecot.org cras at dovecot.org
Sat Jul 31 23:43:47 EEST 2004


Update of /home/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv24143

Modified Files:
	buffer.c buffer.h 
Log Message:
Removed start_pos and limit handling, they weren't used much and were only
making it more complex. Also made data and size variables directly
accessible to make it easier to use buffers.



Index: buffer.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/buffer.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- buffer.c	26 Oct 2003 07:27:51 -0000	1.13
+++ buffer.c	31 Jul 2004 20:43:45 -0000	1.14
@@ -5,26 +5,22 @@
 #include "lib.h"
 #include "buffer.h"
 
-struct buffer {
-	pool_t pool;
-
+struct real_buffer {
+	/* public: */
 	const unsigned char *r_buffer;
-	unsigned char *w_buffer;
+	size_t used;
 
-	/* buffer_set_start_pos() modifies start_pos, but internally we deal
-	   only with absolute positions. buffer_check_read|write modifies
-	   given position to absolute one.
+	/* private: */
+	unsigned char *w_buffer;
+	size_t alloc, max_alloc;
 
-	   start_pos <= used <= alloc <= max_alloc.
-	   start_pos <= limit <= max_alloc */
-	size_t start_pos, used, alloc, max_alloc, limit;
+	pool_t pool;
 
 	unsigned int alloced:1;
-	unsigned int readonly:1;
 	unsigned int hard:1;
 };
 
-static void buffer_alloc(buffer_t *buf, size_t size)
+static void buffer_alloc(struct real_buffer *buf, size_t size)
 {
 	i_assert(buf->w_buffer == NULL || buf->alloced);
 
@@ -40,50 +36,47 @@
 	buf->alloced = TRUE;
 }
 
-static int buffer_check_read(const buffer_t *buf,
+static int buffer_check_read(const struct real_buffer *buf,
 			     size_t *pos, size_t *data_size)
 {
-	size_t used_size, max_size;
+	size_t max_size;
 
-	used_size = I_MIN(buf->used, buf->limit);
-	if (*pos >= used_size - buf->start_pos)
+	if (*pos >= buf->used)
 		return FALSE;
 
-	*pos += buf->start_pos;
-	max_size = used_size - *pos;
+	max_size = buf->used - *pos;
 	if (*data_size > max_size)
 		*data_size = max_size;
 	return TRUE;
 }
 
 static inline int
-buffer_check_limits(buffer_t *buf, size_t pos, size_t *data_size,
+buffer_check_limits(struct real_buffer *buf, size_t pos, size_t *data_size,
 		    int accept_partial)
 {
 	size_t new_size, alloc_size;
 
-	if (buf->readonly)
-		return FALSE;
-
 	/* make sure we're within our limits */
-	if (buf->limit - pos < *data_size) {
+	if (pos >= buf->max_alloc ||
+	    buf->max_alloc - pos < *data_size) {
 		if (buf->hard) {
 			i_panic("Buffer full (%"PRIuSIZE_T" > "
-				"%"PRIuSIZE_T")", pos + *data_size, buf->limit);
+				"%"PRIuSIZE_T")", pos + *data_size,
+				buf->max_alloc);
 		}
 
-		if (!accept_partial)
+		if (!accept_partial || pos >= buf->max_alloc)
 			return FALSE;
 
-		*data_size = buf->limit - pos;
+		*data_size = buf->max_alloc - pos;
 	}
 	new_size = pos + *data_size;
 
 	/* see if we need to grow the buffer */
 	if (new_size > buf->alloc) {
 		alloc_size = nearest_power(new_size);
-		if (alloc_size > buf->limit)
-			alloc_size = buf->limit;
+		if (alloc_size > buf->max_alloc)
+			alloc_size = buf->max_alloc;
 
 		if (alloc_size != buf->alloc)
 			buffer_alloc(buf, alloc_size);
@@ -94,30 +87,15 @@
 	return TRUE;
 }
 
-static int buffer_check_write(buffer_t *buf, size_t *pos,
-			      size_t *data_size, int accept_partial)
-{
-	if (*pos >= buf->limit - buf->start_pos) {
-		if (buf->hard) {
-			i_panic("Buffer offset too large (%"PRIuSIZE_T")",
-				*pos);
-		}
-		return FALSE;
-	}
-	*pos += buf->start_pos;
-
-	return buffer_check_limits(buf, *pos, data_size, accept_partial);
-}
-
 buffer_t *buffer_create_static(pool_t pool, size_t size)
 {
-	buffer_t *buf;
+	struct real_buffer *buf;
 
-	buf = p_new(pool, buffer_t, 1);
+	buf = p_new(pool, struct real_buffer, 1);
 	buf->pool = pool;
-	buf->max_alloc = buf->limit = size;
+	buf->max_alloc = size;
 	buffer_alloc(buf, size);
-	return buf;
+	return (buffer_t *)buf;
 }
 
 buffer_t *buffer_create_static_hard(pool_t pool, size_t size)
@@ -125,53 +103,55 @@
 	buffer_t *buf;
 
 	buf = buffer_create_static(pool, size);
-	buf->hard = TRUE;
+	((struct real_buffer *)buf)->hard = TRUE;
 	return buf;
 }
 
 buffer_t *buffer_create_data(pool_t pool, void *data, size_t size)
 {
-	buffer_t *buf;
+	struct real_buffer *buf;
 
-	buf = p_new(pool, buffer_t, 1);
+	buf = p_new(pool, struct real_buffer, 1);
 	buf->pool = pool;
-	buf->alloc = buf->max_alloc = buf->limit = size;
+	buf->alloc = buf->max_alloc = size;
 	buf->r_buffer = buf->w_buffer = data;
-	return buf;
+	return (buffer_t *)buf;
 }
 
 buffer_t *buffer_create_const_data(pool_t pool, const void *data, size_t size)
 {
-	buffer_t *buf;
+	struct real_buffer *buf;
 
-	buf = p_new(pool, buffer_t, 1);
+	buf = p_new(pool, struct real_buffer, 1);
 	buf->pool = pool;
-	buf->used = buf->alloc = buf->max_alloc = buf->limit = size;
+	buf->used = buf->alloc = buf->max_alloc = size;
 	buf->r_buffer = data;
-	buf->readonly = TRUE;
-	return buf;
+	return (buffer_t *)buf;
 }
 
 buffer_t *buffer_create_dynamic(pool_t pool, size_t init_size, size_t max_size)
 {
-	buffer_t *buf;
+	struct real_buffer *buf;
 
-	buf = p_new(pool, buffer_t, 1);
+	buf = p_new(pool, struct real_buffer, 1);
 	buf->pool = pool;
-	buf->max_alloc = buf->limit = max_size;
+	buf->max_alloc = max_size;
 	buffer_alloc(buf, init_size);
-	return buf;
+	return (buffer_t *)buf;
 }
 
-void buffer_free(buffer_t *buf)
+void buffer_free(buffer_t *_buf)
 {
+	struct real_buffer *buf = (struct real_buffer *)_buf;
+
 	if (buf->alloced)
 		p_free(buf->pool, buf->w_buffer);
 	p_free(buf->pool, buf);
 }
 
-void *buffer_free_without_data(buffer_t *buf)
+void *buffer_free_without_data(buffer_t *_buf)
 {
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 	void *data;
 
 	data = buf->w_buffer;
@@ -179,30 +159,26 @@
 	return data;
 }
 
-size_t buffer_write(buffer_t *buf, size_t pos,
+size_t buffer_write(buffer_t *_buf, size_t pos,
 		    const void *data, size_t data_size)
 {
-	if (!buffer_check_write(buf, &pos, &data_size, TRUE))
+	struct real_buffer *buf = (struct real_buffer *)_buf;
+
+	if (!buffer_check_limits(buf, pos, &data_size, TRUE))
 		return 0;
 
 	memcpy(buf->w_buffer + pos, data, data_size);
 	return data_size;
 }
 
-size_t buffer_append(buffer_t *buf, const void *data, size_t data_size)
+size_t buffer_append(buffer_t *_buf, const void *data, size_t data_size)
 {
-	size_t pos = buf->used;
-
-	if (pos >= buf->limit) {
-		if (buf->hard)
-			i_panic("Buffer full (%"PRIuSIZE_T")", pos);
-		return 0;
-	}
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 
-	if (!buffer_check_limits(buf, pos, &data_size, TRUE))
+	if (!buffer_check_limits(buf, buf->used, &data_size, TRUE))
 		return 0;
 
-	memcpy(buf->w_buffer + pos, data, data_size);
+	memcpy(buf->w_buffer + buf->used, data, data_size);
 	return data_size;
 }
 
@@ -211,16 +187,17 @@
 	return buffer_append(buf, &chr, 1);
 }
 
-size_t buffer_insert(buffer_t *buf, size_t pos,
+size_t buffer_insert(buffer_t *_buf, size_t pos,
 		     const void *data, size_t data_size)
 {
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 	size_t move_size, size;
 
+	if (pos >= buf->used)
+		return buffer_write(_buf, pos, data, data_size);
+
 	/* move_size == number of bytes we have to move forward to make space */
-	move_size = I_MIN(buf->used, buf->limit) - buf->start_pos;
-	if (pos >= move_size)
-		return buffer_write(buf, pos, data, data_size);
-	move_size -= pos;
+	move_size = buf->used - pos;
 
 	/* size == number of bytes we want to modify after pos */
 	if (data_size < (size_t)-1 - move_size)
@@ -228,7 +205,7 @@
 	else
 		size = (size_t)-1;
 
-	if (!buffer_check_write(buf, &pos, &size, TRUE))
+	if (!buffer_check_limits(buf, pos, &size, TRUE))
 		return 0;
 
 	i_assert(size >= move_size);
@@ -240,40 +217,40 @@
 	return size;
 }
 
-size_t buffer_delete(buffer_t *buf, size_t pos, size_t size)
+size_t buffer_delete(buffer_t *_buf, size_t pos, size_t size)
 {
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 	size_t end_size;
 
-	if (buf->readonly)
-		return 0;
-
-	end_size = I_MIN(buf->used, buf->limit) - buf->start_pos;
-	if (pos >= end_size)
+	if (pos >= buf->used)
 		return 0;
-	end_size -= pos;
+	end_size = buf->used - pos;
 
 	if (size < end_size) {
 		/* delete from between */
 		end_size -= size;
-		memmove(buf->w_buffer + buf->start_pos + pos,
-			buf->w_buffer + buf->start_pos + pos + size, end_size);
+		memmove(buf->w_buffer + pos,
+			buf->w_buffer + pos + size, end_size);
 	} else {
 		/* delete the rest of the buffer */
 		size = end_size;
 		end_size = 0;
 	}
 
-	buffer_set_used_size(buf, pos + end_size);
+	buffer_set_used_size(_buf, pos + end_size);
 	return size;
 }
 
-size_t buffer_copy(buffer_t *dest, size_t dest_pos,
-		   const buffer_t *src, size_t src_pos, size_t copy_size)
+size_t buffer_copy(buffer_t *_dest, size_t dest_pos,
+		   const buffer_t *_src, size_t src_pos, size_t copy_size)
 {
+	struct real_buffer *dest = (struct real_buffer *)_dest;
+	struct real_buffer *src = (struct real_buffer *)_src;
+
 	if (!buffer_check_read(src, &src_pos, &copy_size))
 		return 0;
 
-	if (!buffer_check_write(dest, &dest_pos, &copy_size, TRUE))
+	if (!buffer_check_limits(dest, dest_pos, &copy_size, TRUE))
 		return 0;
 
 	if (src == dest) {
@@ -289,13 +266,14 @@
 size_t buffer_append_buf(buffer_t *dest, const buffer_t *src,
 			 size_t src_pos, size_t copy_size)
 {
-	return buffer_copy(dest, dest->used - dest->start_pos,
-			   src, src_pos, copy_size);
+	return buffer_copy(dest, dest->used, src, src_pos, copy_size);
 }
 
-void *buffer_get_space_unsafe(buffer_t *buf, size_t pos, size_t size)
+void *buffer_get_space_unsafe(buffer_t *_buf, size_t pos, size_t size)
 {
-	if (!buffer_check_write(buf, &pos, &size, FALSE))
+	struct real_buffer *buf = (struct real_buffer *)_buf;
+
+	if (!buffer_check_limits(buf, pos, &size, FALSE))
 		return NULL;
 
 	return buf->w_buffer + pos;
@@ -303,71 +281,32 @@
 
 void *buffer_append_space_unsafe(buffer_t *buf, size_t size)
 {
-	return buffer_get_space_unsafe(buf, buf->used - buf->start_pos, size);
+	return buffer_get_space_unsafe(buf, buf->used, size);
 }
 
-const void *buffer_get_data(const buffer_t *buf, size_t *used_size)
+void *buffer_get_modifyable_data(const buffer_t *_buf, size_t *used_size)
 {
-	if (used_size != NULL)
-		*used_size = I_MIN(buf->used, buf->limit) - buf->start_pos;
-	return buf->r_buffer + buf->start_pos;
-}
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 
-void *buffer_get_modifyable_data(const buffer_t *buf, size_t *used_size)
-{
 	if (used_size != NULL)
-		*used_size = I_MIN(buf->used, buf->limit) - buf->start_pos;
-	return buf->w_buffer + buf->start_pos;
-}
-
-void buffer_set_used_size(buffer_t *buf, size_t used_size)
-{
-	i_assert(used_size <= I_MIN(buf->alloc, buf->limit) - buf->start_pos);
-
-	buf->used = used_size + buf->start_pos;
-}
-
-size_t buffer_get_used_size(const buffer_t *buf)
-{
-	return I_MIN(buf->used, buf->limit) - buf->start_pos;
-}
-
-size_t buffer_set_start_pos(buffer_t *buf, size_t abs_pos)
-{
-	size_t old = buf->start_pos;
-
-	i_assert(abs_pos <= I_MIN(buf->used, buf->limit));
-
-	buf->start_pos = abs_pos;
-	return old;
-}
-
-size_t buffer_get_start_pos(const buffer_t *buf)
-{
-	return buf->start_pos;
+		*used_size = buf->used;
+	return buf->w_buffer;
 }
 
-size_t buffer_set_limit(buffer_t *buf, size_t limit)
+void buffer_set_used_size(buffer_t *_buf, size_t used_size)
 {
-	size_t old = buf->limit;
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 
-	if (limit > (size_t)-1 - buf->start_pos)
-		limit = (size_t)-1;
-	else
-		limit += buf->start_pos;
+	i_assert(used_size <= buf->alloc);
 
-	buf->limit = I_MIN(limit, buf->max_alloc);
-	return old - buf->start_pos;
+	buf->used = used_size;
 }
 
-size_t buffer_get_limit(const buffer_t *buf)
+size_t buffer_get_size(const buffer_t *_buf)
 {
-	return buf->limit - buf->start_pos;
-}
+	struct real_buffer *buf = (struct real_buffer *)_buf;
 
-size_t buffer_get_size(const buffer_t *buf)
-{
-	return buf->alloc - buf->start_pos;
+	return buf->alloc;
 }
 
 #ifdef BUFFER_TEST
@@ -402,21 +341,6 @@
 	i_assert(buffer_append(buf, "123456", 6) == 5);
 	i_assert(buf->used == 10);
 
-	buf = buffer_create_data(system_pool, data, sizeof(data));
-	buffer_set_used_size(buf, 1);
-	buffer_set_start_pos(buf, 1);
-	buffer_set_limit(buf, sizeof(data)-2);
-	i_assert(buffer_append(buf, "12345", 5) == 5);
-	i_assert(buffer_insert(buf, 2, "123456", 6) == 5);
-	i_assert(buf->used == 11);
-	i_assert(memcmp(buf->r_buffer, "!1212345345", 11) == 0);
-	i_assert(buffer_delete(buf, 2, 5) == 5);
-	i_assert(buf->used == 6);
-	i_assert(memcmp(buf->r_buffer, "!12345", 6) == 0);
-	i_assert(buffer_delete(buf, 3, 5) == 2);
-	i_assert(buf->used == 4);
-	i_assert(memcmp(buf->r_buffer, "!123", 4) == 0);
-
 	i_assert(data[0] == '!');
 	i_assert(data[sizeof(data)-1] == '!');
 	return 0;

Index: buffer.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib/buffer.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- buffer.h	26 Oct 2003 07:27:51 -0000	1.6
+++ buffer.h	31 Jul 2004 20:43:45 -0000	1.7
@@ -1,6 +1,11 @@
 #ifndef __BUFFER_H
 #define __BUFFER_H
 
+struct buffer {
+	const unsigned char *data;
+	const size_t used;
+};
+
 /* WARNING: Be careful with functions that return pointers to data.
    With dynamic buffers they are valid only as long as buffer is not
    realloc()ed. You shouldn't rely on it being valid if you have modified
@@ -22,7 +27,7 @@
    directly from the memory pool. */
 void buffer_free(buffer_t *buf);
 /* Free the memory used by buffer structure, but return the buffer data
-   unfree'd. NOTE: Current start_pos doesn't affect the returned value. */
+   unfree'd. */
 void *buffer_free_without_data(buffer_t *buf);
 
 /* Write data to buffer at specified position, returns number of bytes
@@ -59,9 +64,6 @@
    of it, or NULL if there's not enough space in buffer. */
 void *buffer_append_space_unsafe(buffer_t *buf, size_t size);
 
-/* Returns pointer to beginning of buffer data. Current used size of buffer is
-   stored in used_size if it's non-NULL. */
-const void *buffer_get_data(const buffer_t *buf, size_t *used_size);
 /* Like buffer_get_data(), but don't return it as const. Returns NULL if the
    buffer is non-modifyable. WARNING: The returned address may become invalid
    if you add more data to buffer. */
@@ -70,23 +72,24 @@
 /* Set the "used size" of buffer, ie. 0 would set the buffer empty.
    Must not be used to grow buffer. */
 void buffer_set_used_size(buffer_t *buf, size_t used_size);
-/* Returns the current used buffer size. */
-size_t buffer_get_used_size(const buffer_t *buf);
-
-/* Change the buffer start position. The buffer acts as if data was removed or
-   inserted to beginning. Returns the old start position. */
-size_t buffer_set_start_pos(buffer_t *buf, size_t abs_pos);
-/* Returns the current start position. */
-size_t buffer_get_start_pos(const buffer_t *buf);
-
-/* Limit buffer size temporarily. All handling is treated as if this is the
-   current allocated memory size, except dynamic buffer won't be grown.
-   Setting the limit to (size_t)-1 removes it. Returns the old limit. */
-size_t buffer_set_limit(buffer_t *buf, size_t limit);
-/* Returns the current buffer limit, or (size_t)-1 if there's none. */
-size_t buffer_get_limit(const buffer_t *buf);
 
 /* Returns the current buffer size. */
 size_t buffer_get_size(const buffer_t *buf);
 
+/* Returns pointer to beginning of buffer data. Current used size of buffer is
+   stored in used_size if it's non-NULL. */
+static inline const void *
+buffer_get_data(const buffer_t *buf, size_t *used_size)
+{
+	if (used_size != NULL)
+		*used_size = buf->used;
+	return buf->data;
+}
+
+/* Returns the current used buffer size. */
+static inline size_t buffer_get_used_size(const buffer_t *buf)
+{
+	return buf->used;
+}
+
 #endif



More information about the dovecot-cvs mailing list