[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[RFC/PATCH 4/4] libdpkg: Reorganize buffer module around new buffer_type struct



Create a new buffer_type struct to combine information about each
buffer type.  This puts most code concerning a given buffer type in
one place and of not needing to maintain a unique numerical buffer
type ids.  The intent is to make it easier to add new buffer types.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Unfortunately, this doesn’t make the caller-visible API much saner.
The caller still puts an argument in data->arg when initializing a
buffer, and the backend consumes the argument, possibly to replace it
with something else.

It might nice to have a family of constructor functions:

 . memory_area_buffer()
 . varbuf_buffer()
 . fd_buffer()
 and so on,

That is orthogonal to this patch, though.

 lib/dpkg/buffer.c |  136 +++++++++++++++++++++++++++++++++++++----------------
 lib/dpkg/buffer.h |   65 ++++++++++++++++----------
 2 files changed, 135 insertions(+), 66 deletions(-)

diff --git a/lib/dpkg/buffer.c b/lib/dpkg/buffer.c
index a760250..5acff13 100644
--- a/lib/dpkg/buffer.c
+++ b/lib/dpkg/buffer.c
@@ -37,6 +37,20 @@
 #include <dpkg/md5.h>
 #include <dpkg/buffer.h>
 
+static off_t
+write_unsupported(struct buffer_data *data, const void *buf, off_t length)
+{
+	internerr("unsupported buffer type '%s' in buffer_write",
+	          data->type->name);
+}
+
+static off_t
+read_unsupported(struct buffer_data *data, void *buf, off_t length)
+{
+	internerr("unsupported buffer type '%s' in buffer_read",
+	          data->type->name);
+}
+
 /*
  * Fixed-length memory area.
  */
@@ -49,6 +63,14 @@ write_buf(struct buffer_data *data, const void *buf, off_t length)
 	return length;
 }
 
+const struct buffer_type buffer_write_buf = {
+	.name = "buf",
+	.init = NULL,
+	.done = NULL,
+	.write = write_buf,
+	.read = read_unsupported,
+};
+
 /*
  * Variable-length memory area.
  */
@@ -60,6 +82,14 @@ write_vbuf(struct buffer_data *data, const void *buf, off_t length)
 	return length;
 }
 
+const struct buffer_type buffer_write_vbuf = {
+	.name = "vbuf",
+	.init = NULL,
+	.done = NULL,
+	.write = write_vbuf,
+	.read = read_unsupported,
+};
+
 /*
  * Unix file output.
  */
@@ -70,6 +100,14 @@ write_fd(struct buffer_data *data, const void *buf, off_t length)
 	return write(data->arg.i, buf, length);
 }
 
+const struct buffer_type buffer_write_fd = {
+	.name = "write_fd",
+	.init = NULL,
+	.done = NULL,
+	.write = write_fd,
+	.read = read_unsupported,
+};
+
 /*
  * Data sink.
  */
@@ -80,6 +118,14 @@ write_null(struct buffer_data *data, const void *buf, off_t length)
 	return length;
 }
 
+const struct buffer_type buffer_write_null = {
+	.name = "null",
+	.init = NULL,
+	.done = NULL,
+	.write = write_null,
+	.read = read_unsupported,
+};
+
 /*
  * Standard C output.
  */
@@ -96,6 +142,14 @@ write_stream(struct buffer_data *data, const void *buf, off_t length)
 	return ret;
 }
 
+const struct buffer_type buffer_write_stream = {
+	.name = "write_stream",
+	.init = NULL,
+	.done = NULL,
+	.write = write_vbuf,
+	.read = read_unsupported,
+};
+
 /*
  * MD5 hash accumulator.
  */
@@ -114,7 +168,7 @@ write_md5(struct buffer_data *data, const void *buf, off_t length)
 }
 
 static void
-buffer_md5_init(struct buffer_data *data)
+init_md5(struct buffer_data *data)
 {
 	struct buffer_write_md5ctx *ctx;
 
@@ -125,7 +179,7 @@ buffer_md5_init(struct buffer_data *data)
 }
 
 static void
-buffer_md5_done(struct buffer_data *data)
+done_md5(struct buffer_data *data)
 {
 	struct buffer_write_md5ctx *ctx;
 	unsigned char digest[16], *p = digest;
@@ -143,6 +197,14 @@ buffer_md5_done(struct buffer_data *data)
 	free(ctx);
 }
 
+const struct buffer_type buffer_write_md5 = {
+	.name = "md5",
+	.init = init_md5,
+	.done = done_md5,
+	.write = write_md5,
+	.read = read_unsupported,
+};
+
 /*
  * Unix file input.
  */
@@ -153,6 +215,14 @@ read_fd(struct buffer_data *data, void *buf, off_t length)
 	return read(data->arg.i, buf, length);
 }
 
+const struct buffer_type buffer_read_fd = {
+	.name = "read_fd",
+	.init = NULL,
+	.done = NULL,
+	.write = write_unsupported,
+	.read = read_fd,
+};
+
 /*
  * Standard C input.
  */
@@ -166,8 +236,17 @@ read_stream(struct buffer_data *data, void *buf, off_t length)
 		return ret;
 	if (ferror((FILE *)data->arg.ptr))
 		return -1;
+	return ret;
 }
 
+const struct buffer_type buffer_read_stream = {
+	.name = "read_stream",
+	.init = NULL,
+	.done = NULL,
+	.write = write_unsupported,
+	.read = read_stream,
+};
+
 /*
  * Generic input and output.
  */
@@ -175,63 +254,37 @@ read_stream(struct buffer_data *data, void *buf, off_t length)
 void
 buffer_init(struct buffer_data *read_data, struct buffer_data *write_data)
 {
-	switch (write_data->type) {
-	case BUFFER_WRITE_MD5:
-		buffer_md5_init(write_data);
-		break;
-	}
+	if (read_data != NULL && read_data->type->init != NULL)
+		read_data->type->init(read_data);
+	if (write_data != NULL && write_data->type->init != NULL)
+		write_data->type->init(write_data);
 }
 
 void
 buffer_done(struct buffer_data *read_data, struct buffer_data *write_data)
 {
-	switch (write_data->type) {
-	case BUFFER_WRITE_MD5:
-		buffer_md5_done(write_data);
-		break;
-	}
+	if (read_data != NULL && read_data->type->done != NULL)
+		read_data->type->done(read_data);
+	if (write_data != NULL && write_data->type->done != NULL)
+		write_data->type->done(write_data);
 }
 
 off_t
 buffer_write(struct buffer_data *data, const void *buf, off_t length)
 {
-	switch (data->type) {
-	case BUFFER_WRITE_BUF:
-		return write_buf(data, buf, length);
-	case BUFFER_WRITE_VBUF:
-		return write_vbuf(data, buf, length);
-	case BUFFER_WRITE_FD:
-		return write_fd(data, buf, length);
-	case BUFFER_WRITE_NULL:
-		return write_null(data, buf, length);
-	case BUFFER_WRITE_STREAM:
-		return write_stream(data, buf, length);
-	case BUFFER_WRITE_MD5:
-		return write_md5(data, buf, length);
-	default:
-		internerr("unknown data type '%i' in buffer_write",
-		          data->type);
-	}
+	return data->type->write(data, buf, length);
 }
 
 off_t
 buffer_read(struct buffer_data *data, void *buf, off_t length)
 {
-	switch (data->type) {
-	case BUFFER_READ_FD:
-		return read_fd(data, buf, length);
-	case BUFFER_READ_STREAM:
-		return read_stream(data, buf, length);
-	default:
-		internerr("unknown data type '%i' in buffer_read\n",
-		          data->type);
-	}
+	return data->type->read(data, buf, length);
 }
 
 #define buffer_copy_TYPE(name, type1, name1, type2, name2) \
 off_t \
-buffer_copy_##name(type1 n1, int typeIn, \
-                   type2 n2, int typeOut, \
+buffer_copy_##name(type1 n1, const struct buffer_type *typeIn, \
+                   type2 n2, const struct buffer_type *typeOut, \
                    off_t limit, const char *desc, ...) \
 { \
 	va_list al; \
@@ -263,7 +316,8 @@ buffer_copy_TYPE(PtrInt, void *, ptr, int, i);
 buffer_copy_TYPE(PtrPtr, void *, ptr, void *, ptr);
 
 off_t
-buffer_hash(const void *input, void *output, int type, off_t limit)
+buffer_hash(const void *input, void *output,
+            const struct buffer_type *type, off_t limit)
 {
 	struct buffer_data data = { .arg.ptr = output, .type = type };
 	off_t ret;
diff --git a/lib/dpkg/buffer.h b/lib/dpkg/buffer.h
index b09215d..e94042c 100644
--- a/lib/dpkg/buffer.h
+++ b/lib/dpkg/buffer.h
@@ -30,75 +30,90 @@
 
 DPKG_BEGIN_DECLS
 
-#define BUFFER_WRITE_BUF		0
-#define BUFFER_WRITE_VBUF		1
-#define BUFFER_WRITE_FD			2
-#define BUFFER_WRITE_NULL		3
-#define BUFFER_WRITE_STREAM		4
-#define BUFFER_WRITE_MD5		5
+struct buffer_data;
 
-#define BUFFER_READ_FD			0
-#define BUFFER_READ_STREAM		1
+struct buffer_type {
+	const char *name;
+	void (*init)(struct buffer_data *data);
+	void (*done)(struct buffer_data *data);
+	off_t (*write)(struct buffer_data *data, const void *buf, off_t length);
+	off_t (*read)(struct buffer_data *data, void *buf, off_t length);
+};
 
 struct buffer_data {
 	union {
 		void *ptr;
 		int i;
 	} arg;
-	int type;
+	const struct buffer_type *type;
 };
 
+const struct buffer_type buffer_write_buf;
+const struct buffer_type buffer_write_vbuf;
+const struct buffer_type buffer_write_fd;
+const struct buffer_type buffer_write_null;
+const struct buffer_type buffer_write_stream;
+const struct buffer_type buffer_write_md5;
+
+const struct buffer_type buffer_read_fd;
+const struct buffer_type buffer_read_stream;
+
 # define buffer_md5(buf, hash, limit) \
-	buffer_hash(buf, hash, BUFFER_WRITE_MD5, limit)
+	buffer_hash(buf, hash, &buffer_write_md5, limit)
 
 # define fd_md5(fd, hash, limit, ...) \
-	buffer_copy_IntPtr(fd, BUFFER_READ_FD, hash, BUFFER_WRITE_MD5, \
+	buffer_copy_IntPtr(fd, &buffer_read_fd, hash, &buffer_write_md5, \
 	                   limit, __VA_ARGS__)
 # define stream_md5(file, hash, limit, ...) \
-	buffer_copy_PtrPtr(file, BUFFER_READ_STREAM, hash, BUFFER_WRITE_MD5, \
+	buffer_copy_PtrPtr(file, &buffer_read_stream, hash, &buffer_write_md5, \
 	                   limit, __VA_ARGS__)
 # define fd_fd_copy(fd1, fd2, limit, ...) \
-	buffer_copy_IntInt(fd1, BUFFER_READ_FD, fd2, BUFFER_WRITE_FD, \
+	buffer_copy_IntInt(fd1, &buffer_read_fd, fd2, &buffer_write_fd, \
 	                   limit, __VA_ARGS__)
 # define fd_buf_copy(fd, buf, limit, ...) \
-	buffer_copy_IntPtr(fd, BUFFER_READ_FD, buf, BUFFER_WRITE_BUF, \
+	buffer_copy_IntPtr(fd, &buffer_read_fd, buf, &buffer_write_buf, \
 	                   limit, __VA_ARGS__)
 # define fd_vbuf_copy(fd, buf, limit, ...) \
-	buffer_copy_IntPtr(fd, BUFFER_READ_FD, buf, BUFFER_WRITE_VBUF, \
+	buffer_copy_IntPtr(fd, &buffer_read_fd, buf, &buffer_write_vbuf, \
 	                   limit, __VA_ARGS__)
 # define fd_null_copy(fd, limit, ...) \
 	if (lseek(fd, limit, SEEK_CUR) == -1) { \
 		if (errno != ESPIPE) \
 			ohshite(__VA_ARGS__); \
-		buffer_copy_IntPtr(fd, BUFFER_READ_FD, \
-		                   NULL, BUFFER_WRITE_NULL, \
+		buffer_copy_IntPtr(fd, &buffer_read_fd, \
+		                   NULL, &buffer_write_null, \
 		                   limit, __VA_ARGS__); \
 	}
 # define stream_null_copy(file, limit, ...) \
 	if (fseek(file, limit, SEEK_CUR) == -1) { \
 		if (errno != EBADF) \
 			ohshite(__VA_ARGS__); \
-		buffer_copy_PtrPtr(file, BUFFER_READ_STREAM, \
-		                   NULL, BUFFER_WRITE_NULL, \
+		buffer_copy_PtrPtr(file, &buffer_read_stream, \
+		                   NULL, &buffer_write_null, \
 		                   limit, __VA_ARGS__); \
 	}
 # define stream_fd_copy(file, fd, limit, ...) \
-	buffer_copy_PtrInt(file, BUFFER_READ_STREAM, fd, BUFFER_WRITE_FD, \
+	buffer_copy_PtrInt(file, &buffer_read_stream, fd, &buffer_write_fd, \
 	                   limit, __VA_ARGS__)
 
-off_t buffer_copy_PtrInt(void *p, int typeIn, int i, int typeOut,
+off_t buffer_copy_PtrInt(void *p, const struct buffer_type *typeIn,
+                         int i, const struct buffer_type *typeOut,
                          off_t limit, const char *desc,
                          ...) DPKG_ATTR_PRINTF(6);
-off_t buffer_copy_PtrPtr(void *p1, int typeIn, void *p2, int typeOut,
+off_t buffer_copy_PtrPtr(void *p1, const struct buffer_type *typeIn,
+                         void *p2, const struct buffer_type *typeOut,
                          off_t limit, const char *desc,
                          ...) DPKG_ATTR_PRINTF(6);
-off_t buffer_copy_IntPtr(int i, int typeIn, void *p, int typeOut,
+off_t buffer_copy_IntPtr(int i, const struct buffer_type *typeIn,
+                         void *p, const struct buffer_type *typeOut,
                          off_t limit, const char *desc,
                          ...) DPKG_ATTR_PRINTF(6);
-off_t buffer_copy_IntInt(int i1, int typeIn, int i2, int typeOut,
+off_t buffer_copy_IntInt(int i1, const struct buffer_type *typeIn,
+                         int i2, const struct buffer_type *typeOut,
                          off_t limit, const char *desc,
                          ...) DPKG_ATTR_PRINTF(6);
-off_t buffer_hash(const void *buf, void *hash, int typeOut, off_t length);
+off_t buffer_hash(const void *buf, void *hash,
+                  const struct buffer_type *typeOut, off_t length);
 
 off_t buffer_write(struct buffer_data *data, const void *buf, off_t length);
 off_t buffer_read(struct buffer_data *data, void *buf, off_t length);
-- 
1.7.0.3


Reply to: