From b5a801be02b9ce42caed09a03491c4f92c5e2175 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Thu, 16 May 2013 11:30:46 +0200 Subject: [PATCH] Changed reader interface from a funtion to a [const] vtable struct. --- lib/c/Makefile | 3 +- lib/c/labcomm.c | 21 ++- lib/c/labcomm.h | 16 ++- lib/c/labcomm_fd_reader.c | 123 +++++++++--------- lib/c/labcomm_fd_reader.h | 5 +- lib/c/labcomm_private.h | 58 +-------- lib/c/test/test_labcomm_basic_type_encoding.c | 3 +- lib/c/test/test_labcomm_generated_encoding.c | 6 - test/Makefile | 2 + 9 files changed, 98 insertions(+), 139 deletions(-) diff --git a/lib/c/Makefile b/lib/c/Makefile index 83f350f..1cc9aa0 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -10,7 +10,8 @@ OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_w LABCOMM_JAR=../../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) -TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding test_labcomm +TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding +#test_labcomm #FIXME: test_labcomm_errors TEST_DIR=test TESTDATA_DIR=$(TEST_DIR)/testdata diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 5c443d2..4ebc4f5 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -573,7 +573,7 @@ static int do_decode_one(labcomm_decoder_t *d) int result; do { - result = d->reader.read(&d->reader, labcomm_reader_start); + result = d->reader.action.start(&d->reader); if (result > 0) { labcomm_decoder_context_t *context = d->context; @@ -642,7 +642,7 @@ static int do_decode_one(labcomm_decoder_t *d) } } } - d->reader.read(&d->reader, labcomm_reader_end); + d->reader.action.end(&d->reader); /* TODO: should we really loop, or is it OK to return after a typedef/sample */ } while (result > 0 && result < LABCOMM_USER); @@ -650,7 +650,7 @@ static int do_decode_one(labcomm_decoder_t *d) } labcomm_decoder_t *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), + const struct labcomm_reader_action action, void *reader_context) { labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t)); @@ -664,14 +664,13 @@ labcomm_decoder_t *labcomm_decoder_new( result->reader.data_size = 0; result->reader.count = 0; result->reader.pos = 0; - result->reader.read = reader; - result->reader.ioctl = NULL; + result->reader.action = action; result->reader.on_error = on_error_fprintf; result->do_register = do_decoder_register; result->do_decode_one = do_decode_one; result->on_error = on_error_fprintf; result->on_new_datatype = on_new_datatype; - result->reader.read(&result->reader, labcomm_reader_alloc, LABCOMM_VERSION); + result->reader.action.alloc(&result->reader, LABCOMM_VERSION); } return result; } @@ -714,7 +713,7 @@ void labcomm_decoder_run(labcomm_decoder_t *d) void labcomm_decoder_free(labcomm_decoder_t* d) { - d->reader.read(&d->reader, labcomm_reader_free); + d->reader.action.free(&d->reader); labcomm_decoder_context_t *context = (labcomm_decoder_context_t *) d->context; labcomm_sample_entry_t *entry = context->sample; labcomm_sample_entry_t *entry_next; @@ -735,11 +734,11 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, { int result = -ENOTSUP; - if (decoder->reader.ioctl != NULL) { + if (decoder->reader.action.ioctl != NULL) { va_list va; va_start(va, action); - result = decoder->reader.ioctl(&decoder->reader, action, NULL, va); + result = decoder->reader.action.ioctl(&decoder->reader, action, NULL, va); va_end(va); } return result; @@ -752,8 +751,8 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, { int result = -ENOTSUP; - if (decoder->reader.ioctl != NULL) { - result = decoder->reader.ioctl(&decoder->reader, action, NULL, va); + if (decoder->reader.action.ioctl != NULL) { + result = decoder->reader.action.ioctl(&decoder->reader, action, NULL, va); } return result; } diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index 8bc80cf..7d38828 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -91,19 +91,29 @@ typedef enum { labcomm_reader_ioctl } labcomm_reader_action_t; +struct labcomm_reader; + +struct labcomm_reader_action { + int (*alloc)(struct labcomm_reader *, char *labcomm_version); + int (*free)(struct labcomm_reader *); + int (*start)(struct labcomm_reader *); + int (*fill)(struct labcomm_reader *); + int (*end)(struct labcomm_reader *); + int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list); +}; + typedef struct labcomm_reader { void *context; unsigned char *data; int data_size; int count; int pos; - int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...); - int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list); + struct labcomm_reader_action action; labcomm_error_handler_callback on_error; } labcomm_reader_t; struct labcomm_decoder *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), + const struct labcomm_reader_action action, void *reader_context); int labcomm_decoder_decode_one( struct labcomm_decoder *decoder); diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c index 6940e1c..09bfc3c 100644 --- a/lib/c/labcomm_fd_reader.c +++ b/lib/c/labcomm_fd_reader.c @@ -6,72 +6,79 @@ #define BUFFER_SIZE 2048 -int labcomm_fd_reader( - labcomm_reader_t *r, - labcomm_reader_action_t action, - ...) +static int fd_alloc(struct labcomm_reader *r, char *version) { - int result = -EINVAL; + int result; +#ifndef LABCOMM_FD_OMIT_VERSION int *fd = r->context; + char *tmp = strdup(version); - switch (action) { - case labcomm_reader_alloc: { -#ifndef LABCOMM_FD_OMIT_VERSION - va_list ap; - va_start(ap, action); - char *version = va_arg(ap, char *); - char *tmp = strdup(version); - - read(*fd, tmp, strlen(version)); - free(tmp); -#endif - r->data = malloc(BUFFER_SIZE); - if (r->data) { - r->data_size = BUFFER_SIZE; - result = r->data_size; - } else { - r->data_size = 0; - result = -ENOMEM; - } - r->count = 0; - r->pos = 0; -#ifndef LABCOMM_FD_OMIT_VERSION - va_end(ap); + read(*fd, tmp, strlen(version)); + free(tmp); #endif - } break; - case labcomm_reader_start: - case labcomm_reader_continue: { - if (r->pos < r->count) { - result = r->count - r->pos; - } else { - int err; + r->data = malloc(BUFFER_SIZE); + if (r->data) { + r->data_size = BUFFER_SIZE; + result = r->data_size; + } else { + r->data_size = 0; + result = -ENOMEM; + } + r->count = 0; + r->pos = 0; + + return result; +} + +static int fd_free(struct labcomm_reader *r) +{ + free(r->data); + r->data = 0; + r->data_size = 0; + r->count = 0; + r->pos = 0; - r->pos = 0; - err = read(*fd, r->data, r->data_size); - if (err <= 0) { - r->count = 0; - result = -1; - } else { - r->count = err; - result = r->count - r->pos; - } - } - } break; - case labcomm_reader_end: { - result = 0; - } break; - case labcomm_reader_free: { - free(r->data); - r->data = 0; - r->data_size = 0; + return 0; +} + +static int fd_fill(struct labcomm_reader *r) +{ + int result; + int *fd = r->context; + + if (r->pos < r->count) { + result = r->count - r->pos; + } else { + int err; + + r->pos = 0; + err = read(*fd, r->data, r->data_size); + if (err <= 0) { r->count = 0; - r->pos = 0; - result = 0; - } break; - case labcomm_reader_ioctl: { - result = -ENOTSUP; + result = -EPIPE; + } else { + r->count = err; + result = r->count - r->pos; } } return result; } +static int fd_start(struct labcomm_reader *r) +{ + return fd_fill(r); +} + +static int fd_end(struct labcomm_reader *r) +{ + return 0; +} + +const struct labcomm_reader_action labcomm_fd_reader = { + .alloc = fd_alloc, + .free = fd_free, + .start = fd_start, + .fill = fd_fill, + .end = fd_end, + .ioctl = NULL +}; diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h index c06cb3a..55882cf 100644 --- a/lib/c/labcomm_fd_reader.h +++ b/lib/c/labcomm_fd_reader.h @@ -3,10 +3,7 @@ #include "labcomm.h" -extern int labcomm_fd_reader( - labcomm_reader_t *reader, - labcomm_reader_action_t action, - ...); +extern const struct labcomm_reader_action labcomm_fd_reader; #endif diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 36c122e..fd1068c 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -90,7 +90,7 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, type result; int i; \ for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \ if (r->pos >= r->count) { \ - r->read(r, labcomm_reader_continue); \ + r->action.fill(r); \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -108,7 +108,7 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, type result; int i; \ for (i = 0 ; i < sizeof(type) ; i++) { \ if (r->pos >= r->count) { \ - r->read(r, labcomm_reader_continue); \ + r->action.fill(r); \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -129,56 +129,6 @@ LABCOMM_DECODE(long, long long) LABCOMM_DECODE(float, float) LABCOMM_DECODE(double, double) -#if 0 -/* - * Unpack a 32 bit unsigned number from a sequence bytes, where the - * first byte is prefixed with a variable length bit pattern that - * indicates the number of bytes used for encoding. The encoding - * is inspired by the UTF-8 encoding. - * - * 0b0 - 1 byte (0x00000000 - 0x0000007f) - * 0b10 - 2 bytes (0x00000080 - 0x00003fff) - * 0b110 - 3 bytes (0x00004000 - 0x001fffff) - * 0b1110 - 4 bytes (0x00200000 - 0x0fffffff) - * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused] - */ -static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r) -{ - unsigned int result = 0; - int n, i; - unsigned char tag; - - if (r->pos >= r->count) { - r->read(r, labcomm_reader_continue); - } - tag = r->data[r->pos]; - r->pos++; - if (tag < 0x80) { - n = 1; - result = tag; - } else if (tag < 0xc0) { - n = 2; - result = tag & 0x3f; - } else if (tag < 0xe0) { - n = 3; - result = tag & 0x1f; - } else if (tag < 0xf0) { - n = 4; - result = tag & 0x0f; - } else { - n = 5; - } - for (i = 1 ; i < n ; i++) { - if (r->pos >= r->count) { - r->read(r, labcomm_reader_continue); - } - result = (result << 8) | r->data[r->pos]; - r->pos++; - } - return result; -} -#endif - static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r) { unsigned int result = 0; @@ -187,7 +137,7 @@ static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r) unsigned char tmp; if (r->pos >= r->count) { - r->read(r, labcomm_reader_continue); + r->action.fill(r); } tmp = r->data[r->pos]; r->pos++; @@ -213,7 +163,7 @@ static inline char *labcomm_read_string(labcomm_reader_t *r) result = malloc(length + 1); for (i = 0 ; i < length ; i++) { if (r->pos >= r->count) { - r->read(r, labcomm_reader_continue); + r->action.fill(r); } result[i] = r->data[r->pos]; r->pos++; diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c index 270796e..2efad6f 100644 --- a/lib/c/test/test_labcomm_basic_type_encoding.c +++ b/lib/c/test/test_labcomm_basic_type_encoding.c @@ -43,8 +43,7 @@ static labcomm_decoder_t decoder = { .data_size = sizeof(buffer), .count = 0, .pos = 0, - .read = test_read, - .ioctl = NULL, + .action = { NULL, NULL, NULL, NULL, NULL, NULL }, .on_error = NULL, }, .do_register = NULL, diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c index 6548978..f539111 100644 --- a/lib/c/test/test_labcomm_generated_encoding.c +++ b/lib/c/test/test_labcomm_generated_encoding.c @@ -11,12 +11,6 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...) exit(1); } -int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...) -{ - fprintf(stderr, "test_read should not be called\n"); - exit(1); -} - #define IOCTL_WRITER_ASSERT_BYTES 4096 #define IOCTL_WRITER_RESET 4097 diff --git a/test/Makefile b/test/Makefile index de2dd41..0bce5a9 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,6 +2,8 @@ TESTS=basic simple nested LABCOMM_JAR=../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) +CFLAGS=-O3 -Wall -Werror + all: test: $(TESTS:%=test_%) -- GitLab