[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: