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 <[email protected]> --- 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 -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

