Commit b5a801be authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Changed reader interface from a funtion to a [const] vtable struct.

parent 72e28000
......@@ -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
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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
};
......@@ -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
......@@ -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++;
......
......@@ -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,
......
......@@ -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
......
......@@ -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_%)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment