diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c index 4eac10df2f2146a3fc7174a460e79a6906ca6d00..531d2efc4fa4bef056c365577670cfaba7770bab 100644 --- a/examples/simple/example_decoder.c +++ b/examples/simple/example_decoder.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { char *filename = argv[1]; printf("C decoder reading from %s\n", filename); fd = open(filename, O_RDONLY); - decoder = labcomm_decoder_new(labcomm_fd_reader, &fd, NULL, NULL); + decoder = labcomm_decoder_new(labcomm_fd_reader_new(fd, 1), NULL, NULL); if (!decoder) { printf("Failed to allocate decoder %s:%d\n", __FUNCTION__, __LINE__); return 1; diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c index 5270c2bdbb7893d86d0be97c2d984a73af4f6f9a..eed3f3fdb4ca04b6f80723680ae1086c46d46fd2 100644 --- a/examples/simple/example_encoder.c +++ b/examples/simple/example_encoder.c @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) { char *filename = argv[1]; printf("C encoder writing to %s\n", filename); fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); - encoder = labcomm_encoder_new(labcomm_fd_writer, &fd, NULL, NULL); + encoder = labcomm_encoder_new(labcomm_fd_writer_new(fd, 1), NULL, NULL); labcomm_encoder_register_simple_theTwoInts(encoder); labcomm_encoder_register_simple_anotherTwoInts(encoder); labcomm_encoder_register_simple_IntString(encoder); diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 2a86b0e3a7a14097dbe800a420e2d81c4905fc7d..e02cf3f9b65d5cd7b583a4f80b55b0b257991f5c 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -38,7 +38,7 @@ struct labcomm_decoder { void *context; - struct labcomm_reader reader; + struct labcomm_reader *reader; struct { void *context; const struct labcomm_lock_action *action; @@ -49,7 +49,7 @@ struct labcomm_decoder { struct labcomm_encoder { void *context; - struct labcomm_writer writer; + struct labcomm_writer *writer; struct { void *context; const struct labcomm_lock_action *action; @@ -88,13 +88,13 @@ struct labcomm_decoder_context { void labcomm_register_error_handler_encoder(struct labcomm_encoder *encoder, labcomm_error_handler_callback callback) { encoder->on_error = callback; - encoder->writer.on_error = callback; + encoder->writer->on_error = callback; } void labcomm_register_error_handler_decoder(struct labcomm_decoder *decoder, labcomm_error_handler_callback callback) { decoder->on_error = callback; - decoder->reader.on_error = callback; + decoder->reader->on_error = callback; } /* Error strings. _must_ be the same order as in enum labcomm_error */ @@ -251,19 +251,19 @@ static void labcomm_encode_signature(struct labcomm_encoder *e, int i, index; index = get_encoder_index(e, signature); - e->writer.action.start(&e->writer, e, index, signature, NULL); - labcomm_write_packed32(&e->writer, signature->type); - labcomm_write_packed32(&e->writer, index); + e->writer->action->start(e->writer, e, index, signature, NULL); + labcomm_write_packed32(e->writer, signature->type); + labcomm_write_packed32(e->writer, index); - labcomm_write_string(&e->writer, signature->name); + labcomm_write_string(e->writer, signature->name); for (i = 0 ; i < signature->size ; i++) { - if (e->writer.pos >= e->writer.count) { - e->writer.action.flush(&e->writer); + if (e->writer->pos >= e->writer->count) { + e->writer->action->flush(e->writer); } - e->writer.data[e->writer.pos] = signature->signature[i]; - e->writer.pos++; + e->writer->data[e->writer->pos] = signature->signature[i]; + e->writer->pos++; } - e->writer.action.end(&e->writer); + e->writer->action->end(e->writer); } #ifdef LABCOMM_ENCODER_LINEAR_SEARCH @@ -356,8 +356,7 @@ static struct labcomm_sample_entry *encoder_get_sample_by_signature_address( */ struct labcomm_encoder *labcomm_encoder_new( - const struct labcomm_writer_action writer, - void *writer_context, + struct labcomm_writer *writer, const struct labcomm_lock_action *lock, void *lock_context) { @@ -373,18 +372,17 @@ struct labcomm_encoder *labcomm_encoder_new( context->by_section = NULL; #endif result->context = context; - result->writer.data = 0; - result->writer.data_size = 0; - result->writer.count = 0; - result->writer.pos = 0; - result->writer.error = 0; - result->writer.action = writer; - result->writer.context = writer_context; + result->writer = writer; + result->writer->data = 0; + result->writer->data_size = 0; + result->writer->count = 0; + result->writer->pos = 0; + result->writer->error = 0; result->lock.action = lock; result->lock.context = lock_context; - result->writer.on_error = on_error_fprintf; + result->writer->on_error = on_error_fprintf; result->on_error = on_error_fprintf; - result->writer.action.alloc(&result->writer, LABCOMM_VERSION); + result->writer->action->alloc(result->writer, LABCOMM_VERSION); } return result; } @@ -424,21 +422,21 @@ int labcomm_internal_encode( int index; index = get_encoder_index(e, signature); - result = e->writer.action.start(&e->writer, e, index, signature, value); + result = e->writer->action->start(e->writer, e, index, signature, value); if (result == -EALREADY) { result = 0; goto no_end; } if (result != 0) { goto out; } - result = labcomm_write_packed32(&e->writer, index); + result = labcomm_write_packed32(e->writer, index); if (result != 0) { goto out; } - result = encode(&e->writer, value); + result = encode(e->writer, value); out: - e->writer.action.end(&e->writer); + e->writer->action->end(e->writer); no_end: return result; } void labcomm_encoder_free(struct labcomm_encoder* e) { - e->writer.action.free(&e->writer); + e->writer->action->free(e->writer); struct labcomm_encoder_context *context = (struct labcomm_encoder_context *) e->context; #ifdef LABCOMM_ENCODER_LINEAR_SEARCH @@ -462,11 +460,11 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, { int result = -ENOTSUP; - if (encoder->writer.action.ioctl != NULL) { + if (encoder->writer->action->ioctl != NULL) { va_list va; va_start(va, action); - result = encoder->writer.action.ioctl(&encoder->writer, action, NULL, va); + result = encoder->writer->action->ioctl(encoder->writer, action, NULL, va); va_end(va); } return result; @@ -478,11 +476,11 @@ static int labcomm_writer_ioctl(struct labcomm_writer *writer, { int result = -ENOTSUP; - if (writer->action.ioctl != NULL) { + if (writer->action->ioctl != NULL) { va_list va; va_start(va, action); - result = writer->action.ioctl(writer, action, NULL, va); + result = writer->action->ioctl(writer, action, NULL, va); va_end(va); } return result; @@ -495,9 +493,9 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, { int result = -ENOTSUP; - if (encoder->writer.action.ioctl != NULL) { - result = encoder->writer.action.ioctl(&encoder->writer, action, - signature, va); + if (encoder->writer->action->ioctl != NULL) { + result = encoder->writer->action->ioctl(encoder->writer, action, + signature, va); } return result; } @@ -506,7 +504,7 @@ static void collect_flat_signature( struct labcomm_decoder *decoder, struct labcomm_writer *writer) { - int type = labcomm_read_packed32(&decoder->reader); + int type = labcomm_read_packed32(decoder->reader); if (type >= LABCOMM_USER) { decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3, "Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type); @@ -516,10 +514,10 @@ static void collect_flat_signature( case LABCOMM_ARRAY: { int dimensions, i; - dimensions = labcomm_read_packed32(&decoder->reader); + dimensions = labcomm_read_packed32(decoder->reader); labcomm_write_packed32(writer, dimensions); for (i = 0 ; i < dimensions ; i++) { - int n = labcomm_read_packed32(&decoder->reader); + int n = labcomm_read_packed32(decoder->reader); labcomm_write_packed32(writer, n); } collect_flat_signature(decoder, writer); @@ -527,10 +525,10 @@ static void collect_flat_signature( case LABCOMM_STRUCT: { int fields, i; - fields = labcomm_read_packed32(&decoder->reader); + fields = labcomm_read_packed32(decoder->reader); labcomm_write_packed32(writer, fields); for (i = 0 ; i < fields ; i++) { - char *name = labcomm_read_string(&decoder->reader); + char *name = labcomm_read_string(decoder->reader); labcomm_write_string(writer, name); free(name); collect_flat_signature(decoder, writer); @@ -554,8 +552,7 @@ static void collect_flat_signature( } struct labcomm_decoder *labcomm_decoder_new( - const struct labcomm_reader_action reader, - void *reader_context, + struct labcomm_reader *reader, const struct labcomm_lock_action *lock, void *lock_context) { @@ -565,18 +562,17 @@ struct labcomm_decoder *labcomm_decoder_new( (struct labcomm_decoder_context *)malloc(sizeof(*context)); context->sample = 0; result->context = context; - result->reader.data = 0; - result->reader.data_size = 0; - result->reader.count = 0; - result->reader.pos = 0; - result->reader.action = reader; - result->reader.context = reader_context; - result->reader.on_error = on_error_fprintf; + result->reader = reader; + result->reader->data = 0; + result->reader->data_size = 0; + result->reader->count = 0; + result->reader->pos = 0; + result->reader->on_error = on_error_fprintf; result->lock.action = lock; result->lock.context = lock_context; result->on_error = on_error_fprintf; result->on_new_datatype = on_new_datatype; - result->reader.action.alloc(&result->reader, LABCOMM_VERSION); + result->reader->action->alloc(result->reader, LABCOMM_VERSION); } return result; } @@ -608,87 +604,83 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) { int result; - do { - result = d->reader.action.start(&d->reader); - if (result > 0) { - struct labcomm_decoder_context *context = d->context; - - result = labcomm_read_packed32(&d->reader); - if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) { - /* TODO: should the labcomm_dynamic_buffer_writer be - a permanent part of labcomm_decoder? */ - struct labcomm_writer writer = { - .context = NULL, - .data = NULL, - .data_size = 0, - .count = 0, - .pos = 0, - .error = 0, - .action = labcomm_dynamic_buffer_writer, - .on_error = NULL - }; - struct labcomm_signature signature; - struct labcomm_sample_entry *entry = NULL; - int index, err; - - writer.action.alloc(&writer, ""); - writer.action.start(&writer, NULL, 0, NULL, NULL); - index = labcomm_read_packed32(&d->reader); //int - signature.name = labcomm_read_string(&d->reader); - signature.type = result; - collect_flat_signature(d, &writer); - writer.action.end(&writer); - err = labcomm_writer_ioctl(&writer, - LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, - &signature.size); - if (err < 0) { - printf("Failed to get size: %s\n", strerror(-err)); - goto free_signature_name; - } - err = labcomm_writer_ioctl(&writer, - LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER, - &signature.signature); - if (err < 0) { - printf("Failed to get pointer: %s\n", strerror(-err)); - goto free_signature_name; - } - entry = get_sample_by_signature_value(context->sample, &signature); - if (! entry) { - /* Unknown datatype, bail out */ - d->on_new_datatype(d, &signature); - } else if (entry->index && entry->index != index) { - d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, - "%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", - __FUNCTION__, signature.name, entry->index, index); - } else { - // TODO unnessesary, since entry->index == index in above if statement - entry->index = index; - } - free_signature_name: - free(signature.name); - writer.action.free(&writer); - if (!entry) { - // No handler for found type, bail out (after cleanup) - result = -ENOENT; - } + result = d->reader->action->start(d->reader); + if (result > 0) { + struct labcomm_decoder_context *context = d->context; + + result = labcomm_read_packed32(d->reader); + if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) { + /* TODO: should the labcomm_dynamic_buffer_writer be + a permanent part of labcomm_decoder? */ + struct labcomm_writer writer = { + .context = NULL, + .data = NULL, + .data_size = 0, + .count = 0, + .pos = 0, + .error = 0, + .action = labcomm_dynamic_buffer_writer_action, + .on_error = NULL + }; + struct labcomm_signature signature; + struct labcomm_sample_entry *entry = NULL; + int index, err; + + writer.action->alloc(&writer, ""); + writer.action->start(&writer, NULL, 0, NULL, NULL); + index = labcomm_read_packed32(d->reader); //int + signature.name = labcomm_read_string(d->reader); + signature.type = result; + collect_flat_signature(d, &writer); + writer.action->end(&writer); + err = labcomm_writer_ioctl(&writer, + LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, + &signature.size); + if (err < 0) { + printf("Failed to get size: %s\n", strerror(-err)); + goto free_signature_name; + } + err = labcomm_writer_ioctl(&writer, + LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER, + &signature.signature); + if (err < 0) { + printf("Failed to get pointer: %s\n", strerror(-err)); + goto free_signature_name; + } + entry = get_sample_by_signature_value(context->sample, &signature); + if (! entry) { + /* Unknown datatype, bail out */ + d->on_new_datatype(d, &signature); + } else if (entry->index && entry->index != index) { + d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, + "%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", + __FUNCTION__, signature.name, entry->index, index); } else { - struct labcomm_sample_entry *entry; - - entry = get_sample_by_index(context->sample, result); - if (!entry) { - // printf("Error: %s: type not found (id=0x%x)\n", - //__FUNCTION__, result); - d->on_error(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND, 3, "%s(): type not found (id=0x%x)\n", __FUNCTION__, result); - result = -ENOENT; - } else { - entry->decoder(&d->reader, entry->handler, entry->context); - } + // TODO unnessesary, since entry->index == index in above if statement + entry->index = index; + } + free_signature_name: + free(signature.name); + writer.action->free(&writer); + if (!entry) { + // No handler for found type, bail out (after cleanup) + result = -ENOENT; + } + } else { + struct labcomm_sample_entry *entry; + + entry = get_sample_by_index(context->sample, result); + if (!entry) { + // printf("Error: %s: type not found (id=0x%x)\n", + //__FUNCTION__, result); + d->on_error(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND, 3, "%s(): type not found (id=0x%x)\n", __FUNCTION__, result); + result = -ENOENT; + } else { + entry->decoder(d->reader, entry->handler, entry->context); } } - 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); + } + d->reader->action->end(d->reader); return result; } @@ -700,7 +692,7 @@ void labcomm_decoder_run(struct labcomm_decoder *d) void labcomm_decoder_free(struct labcomm_decoder* d) { - d->reader.action.free(&d->reader); + d->reader->action->free(d->reader); struct labcomm_decoder_context *context = (struct labcomm_decoder_context *) d->context; struct labcomm_sample_entry *entry = context->sample; struct labcomm_sample_entry *entry_next; @@ -721,11 +713,11 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, { int result = -ENOTSUP; - if (decoder->reader.action.ioctl != NULL) { + if (decoder->reader->action->ioctl != NULL) { va_list va; va_start(va, action); - result = decoder->reader.action.ioctl(&decoder->reader, action, NULL, va); + result = decoder->reader->action->ioctl(decoder->reader, action, NULL, va); va_end(va); } return result; @@ -738,8 +730,8 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, { int result = -ENOTSUP; - if (decoder->reader.action.ioctl != NULL) { - result = decoder->reader.action.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 97eaa4a813136ae9c7bde788519b4957df333c0d..e306493fe1b6938fdcd4fcfb3608ef65ce9aef28 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -92,32 +92,10 @@ struct labcomm_lock_action { /* * Decoder */ - struct labcomm_reader; -struct labcomm_reader_action { - int (*alloc)(struct labcomm_reader *r, char *labcomm_version); - int (*free)(struct labcomm_reader *r); - int (*start)(struct labcomm_reader *r); - int (*end)(struct labcomm_reader *r); - int (*fill)(struct labcomm_reader *r); - int (*ioctl)(struct labcomm_reader *r, int, struct labcomm_signature *, va_list); -}; - -struct labcomm_reader { - void *context; - unsigned char *data; - int data_size; - int count; - int pos; - int error; - struct labcomm_reader_action action; - labcomm_error_handler_callback on_error; -}; - struct labcomm_decoder *labcomm_decoder_new( - const struct labcomm_reader_action reader, - void *reader_context, + struct labcomm_reader *reader, const struct labcomm_lock_action *lock, void *lock_context); int labcomm_decoder_decode_one( @@ -137,34 +115,8 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, */ struct labcomm_writer; -struct labcomm_writer_action { - int (*alloc)(struct labcomm_writer *w, char *labcomm_version); - int (*free)(struct labcomm_writer *w); - int (*start)(struct labcomm_writer *w, - struct labcomm_encoder *encoder, - int index, struct labcomm_signature *signature, - void *value); - int (*end)(struct labcomm_writer *w); - int (*flush)(struct labcomm_writer *w); - int (*ioctl)(struct labcomm_writer *w, - int index, struct labcomm_signature *, - va_list); -}; - -struct labcomm_writer { - void *context; - unsigned char *data; - int data_size; - int count; - int pos; - int error; - struct labcomm_writer_action action; - labcomm_error_handler_callback on_error; -}; - struct labcomm_encoder *labcomm_encoder_new( - const struct labcomm_writer_action writer, - void *writer_context, + struct labcomm_writer *writer, const struct labcomm_lock_action *lock, void *lock_context); void labcomm_encoder_free( diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c index b58a711b726afcf08e096bb693881f88b178dfac..8c83dee956e710eaed59660c0c181949522c804a 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.c +++ b/lib/c/labcomm_dynamic_buffer_writer.c @@ -1,6 +1,8 @@ #include <errno.h> #include <stdlib.h> #include <stdarg.h> +#include "labcomm.h" +#include "labcomm_private.h" #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" @@ -93,7 +95,7 @@ static int dyn_ioctl(struct labcomm_writer *w, return result; } -const struct labcomm_writer_action labcomm_dynamic_buffer_writer = { +static const struct labcomm_writer_action action = { .alloc = dyn_alloc, .free = dyn_free, .start = dyn_start, @@ -101,3 +103,18 @@ const struct labcomm_writer_action labcomm_dynamic_buffer_writer = { .flush = dyn_flush, .ioctl = dyn_ioctl }; +const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action = + &action; + +struct labcomm_writer *labcomm_dynamic_buffer_writer_new() +{ + struct labcomm_writer *result; + + result = malloc(sizeof(*result)); + if (result != NULL) { + result->context = NULL; + result->action = &action; + } + return result; +} + diff --git a/lib/c/labcomm_dynamic_buffer_writer.h b/lib/c/labcomm_dynamic_buffer_writer.h index 63099ef1b41b7d25dea3df5b85fc9ec28ff0fa25..7f01a1dfd0eda72722d0cff97902617f523d70f6 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.h +++ b/lib/c/labcomm_dynamic_buffer_writer.h @@ -3,6 +3,6 @@ #include "labcomm.h" -extern const struct labcomm_writer_action labcomm_dynamic_buffer_writer; +extern const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action; #endif diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c index f49be47ac957ba549c5445b7f8f2cf9cee200841..f8b6f50f1cf86dd8c31fb22f6ee9c68e5ae5f1c2 100644 --- a/lib/c/labcomm_fd_reader.c +++ b/lib/c/labcomm_fd_reader.c @@ -7,6 +7,12 @@ #define BUFFER_SIZE 2048 +struct labcomm_fd_reader { + struct labcomm_reader reader; + int fd; + int close_fd_on_free; +}; + static int fd_alloc(struct labcomm_reader *r, char *version) { int result = 0; @@ -18,35 +24,46 @@ static int fd_alloc(struct labcomm_reader *r, char *version) r->data_size = 0; result = -ENOMEM; } else { - char *tmp; r->data_size = BUFFER_SIZE; - tmp = labcomm_read_string(r); - if (strcmp(tmp, version) != 0) { - result = -EINVAL; - } else { - result = r->data_size; + result = r->data_size; + if (version && version[0]) { + char *tmp; + + tmp = labcomm_read_string(r); + if (strcmp(tmp, version) != 0) { + result = -EINVAL; + } else { + result = r->data_size; + } + free(tmp); } - free(tmp); } return result; } static int fd_free(struct labcomm_reader *r) { + struct labcomm_fd_reader *context = r->context; + free(r->data); r->data = 0; r->data_size = 0; r->count = 0; r->pos = 0; + if (context->close_fd_on_free) { + close(context->fd); + } + free(context); + return 0; } static int fd_fill(struct labcomm_reader *r) { int result = 0; - int *fd = r->context; + struct labcomm_fd_reader *context = r->context; if (r->pos < r->count) { result = r->count - r->pos; @@ -54,7 +71,7 @@ static int fd_fill(struct labcomm_reader *r) int err; r->pos = 0; - err = read(*fd, r->data, r->data_size); + err = read(context->fd, r->data, r->data_size); if (err <= 0) { r->count = 0; result = -EPIPE; @@ -76,7 +93,7 @@ static int fd_end(struct labcomm_reader *r) return 0; } -const struct labcomm_reader_action labcomm_fd_reader = { +static const struct labcomm_reader_action action = { .alloc = fd_alloc, .free = fd_free, .start = fd_start, @@ -84,3 +101,19 @@ const struct labcomm_reader_action labcomm_fd_reader = { .end = fd_end, .ioctl = NULL }; + +struct labcomm_reader *labcomm_fd_reader_new(int fd, int close_fd_on_free) +{ + struct labcomm_fd_reader *result; + + result = malloc(sizeof(*result)); + if (result == NULL) { + return NULL; + } else { + result->fd = fd; + result->close_fd_on_free = close_fd_on_free; + result->reader.context = result; + result->reader.action = &action; + return &result->reader; + } +} diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h index 55882cf0e049fe6908677eecade680e5345d7c2a..8f526fa3d9f828b77f4838f1fdee12bd62160a6f 100644 --- a/lib/c/labcomm_fd_reader.h +++ b/lib/c/labcomm_fd_reader.h @@ -3,7 +3,7 @@ #include "labcomm.h" -extern const struct labcomm_reader_action labcomm_fd_reader; +struct labcomm_reader *labcomm_fd_reader_new(int fd, int close_fd_on_free); #endif diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c index ce3d8bdf5bf7ebab8ab03fe06003cd5e95632197..88a77805c7d7bbbdb85e1fb84aa0f5e1bdb5079a 100644 --- a/lib/c/labcomm_fd_writer.c +++ b/lib/c/labcomm_fd_writer.c @@ -8,6 +8,12 @@ #define BUFFER_SIZE 2048 +struct labcomm_fd_writer { + struct labcomm_writer writer; + int fd; + int close_fd_on_free; +}; + static int fd_flush(struct labcomm_writer *w); static int fd_alloc(struct labcomm_writer *w, char *version) @@ -22,8 +28,10 @@ static int fd_alloc(struct labcomm_writer *w, char *version) w->data_size = BUFFER_SIZE; w->count = BUFFER_SIZE; w->pos = 0; - labcomm_write_string(w, version); - fd_flush(w); + if (version && version[0]) { + labcomm_write_string(w, version); + fd_flush(w); + } } return w->error; @@ -31,12 +39,17 @@ static int fd_alloc(struct labcomm_writer *w, char *version) static int fd_free(struct labcomm_writer *w) { + struct labcomm_fd_writer *context = w->context; + free(w->data); w->data = 0; w->data_size = 0; w->count = 0; w->pos = 0; + if (context->close_fd_on_free) { + close(context->fd); + } return 0; } @@ -53,10 +66,10 @@ static int fd_start(struct labcomm_writer *w, static int fd_flush(struct labcomm_writer *w) { - int *fd = w->context; + struct labcomm_fd_writer *context = w->context; int err; - err = write(*fd, w->data, w->pos); + err = write(context->fd, w->data, w->pos); if (err < 0) { w->error = -errno; } else if (err == 0) { @@ -67,7 +80,7 @@ static int fd_flush(struct labcomm_writer *w) return w->error; } -const struct labcomm_writer_action labcomm_fd_writer = { +static const struct labcomm_writer_action action = { .alloc = fd_alloc, .free = fd_free, .start = fd_start, @@ -75,3 +88,19 @@ const struct labcomm_writer_action labcomm_fd_writer = { .flush = fd_flush, .ioctl = NULL }; + +struct labcomm_writer *labcomm_fd_writer_new(int fd, int close_fd_on_free) +{ + struct labcomm_fd_writer *result; + + result = malloc(sizeof(*result)); + if (result == NULL) { + return NULL; + } else { + result->fd = fd; + result->close_fd_on_free = close_fd_on_free; + result->writer.context = result; + result->writer.action = &action; + return &result->writer; + } +} diff --git a/lib/c/labcomm_fd_writer.h b/lib/c/labcomm_fd_writer.h index 39d0258955366330a42077223f5595b44539e5d0..e1c976a390c96ea3afc534b5f8a3543de3a1cd3c 100644 --- a/lib/c/labcomm_fd_writer.h +++ b/lib/c/labcomm_fd_writer.h @@ -3,7 +3,7 @@ #include "labcomm.h" -extern const struct labcomm_writer_action labcomm_fd_writer; +struct labcomm_writer *labcomm_fd_writer_new(int fd, int close_on_free); #endif diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 49363f0c084439a8a864b3bc2e662d6e00064e79..0f08ffbed338cdee5afe9bac5bd288b583fa4b33 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -54,6 +54,28 @@ typedef void (*labcomm_decoder_function)( labcomm_handler_function handler, void *context); +struct labcomm_reader_action { + int (*alloc)(struct labcomm_reader *r, char *labcomm_version); + int (*free)(struct labcomm_reader *r); + int (*start)(struct labcomm_reader *r); + int (*end)(struct labcomm_reader *r); + int (*fill)(struct labcomm_reader *r); + int (*ioctl)(struct labcomm_reader *r, int, struct labcomm_signature *, va_list); +}; + +struct labcomm_reader { + const struct labcomm_reader_action *action; + void *context; + unsigned char *data; + int data_size; + int count; + int pos; + int error; + labcomm_error_handler_callback on_error; +}; + + + /* * Non typesafe registration function to be called from * generated labcomm_decoder_register_* functions. @@ -77,7 +99,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->action.fill(r); \ + r->action->fill(r); \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -92,7 +114,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->action.fill(r); \ + r->action->fill(r); \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -118,7 +140,7 @@ static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r) unsigned char tmp; if (r->pos >= r->count) { - r->action.fill(r); + r->action->fill(r); } tmp = r->data[r->pos]; r->pos++; @@ -139,7 +161,7 @@ static inline char *labcomm_read_string(struct labcomm_reader *r) result = malloc(length + 1); for (i = 0 ; i < length ; i++) { if (r->pos >= r->count) { - r->action.fill(r); + r->action->fill(r); } result[i] = r->data[r->pos]; r->pos++; @@ -155,6 +177,33 @@ typedef int (*labcomm_encoder_function)( struct labcomm_writer *, void *value); +struct labcomm_writer; + +struct labcomm_writer_action { + int (*alloc)(struct labcomm_writer *w, char *labcomm_version); + int (*free)(struct labcomm_writer *w); + int (*start)(struct labcomm_writer *w, + struct labcomm_encoder *encoder, + int index, struct labcomm_signature *signature, + void *value); + int (*end)(struct labcomm_writer *w); + int (*flush)(struct labcomm_writer *w); + int (*ioctl)(struct labcomm_writer *w, + int index, struct labcomm_signature *, + va_list); +}; + +struct labcomm_writer { + const struct labcomm_writer_action *action; + void *context; + unsigned char *data; + int data_size; + int count; + int pos; + int error; + labcomm_error_handler_callback on_error; +}; + void labcomm_internal_encoder_register( struct labcomm_encoder *encoder, struct labcomm_signature *signature, @@ -166,6 +215,7 @@ int labcomm_internal_encode( labcomm_encoder_function encode, void *value); + int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, int ioctl_action, struct labcomm_signature *signature, @@ -179,7 +229,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \ if (w->pos >= w->count) { /*buffer is full*/ \ int err; \ - err = w->action.flush(w); \ + err = w->action->flush(w); \ if (err != 0) { return err; } \ } \ w->data[w->pos] = ((unsigned char*)(&data))[i]; \ @@ -196,7 +246,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, for (i = 0 ; i < sizeof(type) ; i++) { \ if (w->pos >= w->count) { \ int err; \ - err = w->action.flush(w); \ + err = w->action->flush(w); \ if (err != 0) { return err; } \ } \ w->data[w->pos] = ((unsigned char*)(&data))[i]; \ @@ -227,7 +277,7 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w, for (i = i - 1 ; i >= 0 ; i--) { if (w->pos >= w->count) { int err; - err = w->action.flush(w); + err = w->action->flush(w); if (err != 0) { return err; } } w->data[w->pos++] = tmp[i] | (i?0x80:0x00); @@ -245,7 +295,7 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s) for (i = 0 ; i < length ; i++) { if (w->pos >= w->count) { int err; - err = w->action.flush(w); + err = w->action->flush(w); if (err != 0) { return err; } } w->data[w->pos] = s[i]; diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c index ae57f1cd13263670cc2cbd0ca7e63ab429891c0c..9ca863eafcff28456ef944084035ac0b4e0eac08 100644 --- a/lib/c/test/test_labcomm_basic_type_encoding.c +++ b/lib/c/test/test_labcomm_basic_type_encoding.c @@ -14,7 +14,7 @@ static struct labcomm_writer writer = { .count = sizeof(buffer), .pos = 0, .error = 0, - .action = { NULL, NULL, NULL, NULL, NULL, NULL }, + .action = NULL, .on_error = NULL, }; @@ -24,7 +24,7 @@ static struct labcomm_reader reader = { .data_size = sizeof(buffer), .count = 0, .pos = 0, - .action = { NULL, NULL, NULL, NULL, NULL, NULL }, + .action = NULL, .on_error = NULL, }; diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c index 5b8cb66292adadee4f0b7f706257165cd51bf59c..1b0dd7fa522242f9be3558a335c4ce6ce9c1eb5f 100644 --- a/lib/c/test/test_labcomm_generated_encoding.c +++ b/lib/c/test/test_labcomm_generated_encoding.c @@ -101,7 +101,7 @@ static int buf_writer_ioctl( return result; } -const struct labcomm_writer_action buffer_writer = { +const struct labcomm_writer_action writer_action = { .alloc = buf_writer_alloc, .free = buf_writer_free, .start = buf_writer_start, @@ -110,6 +110,17 @@ const struct labcomm_writer_action buffer_writer = { .ioctl = buf_writer_ioctl }; +static struct labcomm_writer buffer_writer = { + .context = NULL, + .data = buffer, + .data_size = sizeof(buffer), + .count = sizeof(buffer), + .pos = 0, + .error = 0, + .action = &writer_action, + .on_error = NULL, +}; + void dump_encoder(struct labcomm_encoder *encoder) { int i; @@ -134,8 +145,8 @@ int main(void) generated_encoding_V V; generated_encoding_B B = 1; - struct labcomm_encoder *encoder = labcomm_encoder_new(buffer_writer, buffer, - NULL, NULL); + struct labcomm_encoder *encoder = labcomm_encoder_new(&buffer_writer, + NULL, NULL); labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET); labcomm_encoder_register_generated_encoding_V(encoder); diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py index 72978045dda49ac6d29f27cd68b844576bae6c72..75aaa46a476b2a3a4efb89e02f5092298bf87fbe 100755 --- a/test/relay_gen_c.py +++ b/test/relay_gen_c.py @@ -50,8 +50,8 @@ if __name__ == '__main__': | if (in < 0) { return 1; } | out = open(argv[2], O_WRONLY); | if (out < 0) { return 1; } - | e = labcomm_encoder_new(labcomm_fd_writer, &out, NULL, NULL); - | d = labcomm_decoder_new(labcomm_fd_reader, &in, NULL, NULL); + | e = labcomm_encoder_new(labcomm_fd_writer_new(out, 1), NULL, NULL); + | d = labcomm_decoder_new(labcomm_fd_reader_new(in, 1), NULL, NULL); """)) for func,arg in sample: result.extend(split_match('^[^|]*\|(.*)$', """