From 366de880d6cd6b533c17dfcf545efd505b131964 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Thu, 18 Apr 2013 16:50:42 +0200 Subject: [PATCH] Use ioctl's instead of access to labcomm_dynamic_buffer_writer internal fields. --- lib/c/Makefile | 5 +-- lib/c/labcomm.c | 45 ++++++++++++++++++--------- lib/c/labcomm_dynamic_buffer_writer.c | 44 ++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/lib/c/Makefile b/lib/c/Makefile index 25c86bb..a4868f1 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -51,14 +51,15 @@ $(CREATED_DIRS): mkdir -p $@ ## NB! the tests need CUnit to be installed -run-test: $(TEST_DIR)/test_labcomm $(TEST_DIR)/test_labcomm_errors |$(TEST_DIR) +run-test: $(TEST_DIR)/test_labcomm $(TEST_DIR)/test_labcomm_errors \ + | $(TEST_DIR) test/test_labcomm test/test_labcomm_errors $(TEST_DIR)/%.o: $(TEST_DIR)/%.c $(CC) $(CFLAGS) -o $@ -c $< -$(TEST_DIR)/%: $(TEST_DIR)/%.o +$(TEST_DIR)/%: $(TEST_DIR)/%.o | liblabcomm.a $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST) $(TEST_GEN_DIR)/%.c $(TEST_GEN_DIR)/%.h: $(TESTDATA_DIR)/%.lc \ diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 7539be7..5256de8 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -432,38 +432,53 @@ static int do_decode_one(labcomm_decoder_t *d) result = labcomm_decode_packed32(d); // printf("do_decode_one: result(2) = %x\n", result); if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) { + /* TODO: should the labcomm_dynamic_buffer_writer be + a permanent part of labcomm_decoder? */ labcomm_encoder_t *e = labcomm_encoder_new( labcomm_dynamic_buffer_writer, 0); labcomm_signature_t signature; - labcomm_sample_entry_t *entry; - int index; + labcomm_sample_entry_t *entry = NULL; + int index, err; - e->writer.write(&e->writer, labcomm_writer_start); - signature.type = result; index = labcomm_decode_packed32(d); //int signature.name = labcomm_decode_string(d); -// printf("do_decode_one: result = %x, index = %x, name=%s\n", result, index, signature.name); + signature.type = result; + e->writer.write(&e->writer, labcomm_writer_start); + /* printf("do_decode_one: result = %x, index = %x, name=%s\n", + result, index, signature.name); */ collect_flat_signature(d, e); - signature.size = e->writer.pos; - signature.signature = e->writer.data; + e->writer.write(&e->writer, labcomm_writer_end); + err = labcomm_encoder_ioctl(e, 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_encoder_ioctl(e, 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_error(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE, 4, "%s(): unknown datatype '%s' (id=0x%x)\n", __FUNCTION__, signature.name, index);*/ - d->on_new_datatype(d, &signature); + /* 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); + 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 + // TODO unnessesary, since entry->index == index in above if statement entry->index = index; } + free_signature_name: free(signature.name); - e->writer.write(&e->writer, labcomm_writer_end); + labcomm_encoder_free(e); if (!entry) { // No handler for found type, bail out (after cleanup) result = -ENOENT; } - labcomm_encoder_free(e); } else { labcomm_sample_entry_t *entry; @@ -479,6 +494,8 @@ static int do_decode_one(labcomm_decoder_t *d) } } d->reader.read(&d->reader, labcomm_reader_end); + /* TODO: should we really loop, or is it OK to + return after a typedef/sample */ } while (result > 0 && result < LABCOMM_USER); return result; } diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c index c651f19..5e180ec 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.c +++ b/lib/c/labcomm_dynamic_buffer_writer.c @@ -1,5 +1,26 @@ +#include <errno.h> +#include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" +static int labcomm_dynamic_buffer_writer_ioctl( + struct labcomm_writer *w, int action, va_list arg) +{ + int result = -ENOTSUP; + switch (action) { + case LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN: { + int *value = va_arg(arg, int*); + *value = w->pos; + result = 0; + } break; + case LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER: { + void **value = va_arg(arg, void**); + *value = w->data; + result = 0; + } break; + } + return result; +} + int labcomm_dynamic_buffer_writer( labcomm_writer_t *w, labcomm_writer_action_t action, @@ -10,20 +31,37 @@ int labcomm_dynamic_buffer_writer( w->data_size = 1000; w->count = w->data_size; w->data = malloc(w->data_size); + if (w->data == NULL) { + w->error = -ENOMEM; + } w->pos = 0; + w->ioctl = labcomm_dynamic_buffer_writer_ioctl; } break; case labcomm_writer_start: case labcomm_writer_start_signature: { + void *tmp; w->data_size = 1000; w->count = w->data_size; - w->data = realloc(w->data, w->data_size); + tmp = realloc(w->data, w->data_size); + if (tmp != NULL) { + w->data = tmp; + w->error = 0; + } else { + w->error = -ENOMEM; + } w->pos = 0; } break; case labcomm_writer_continue: case labcomm_writer_continue_signature: { + void *tmp; w->data_size += 1000; w->count = w->data_size; - w->data = realloc(w->data, w->data_size); + tmp = realloc(w->data, w->data_size); + if (tmp != NULL) { + w->data = tmp; + } else { + w->error = -ENOMEM; + } } break; case labcomm_writer_end: case labcomm_writer_end_signature: { @@ -36,6 +74,6 @@ int labcomm_dynamic_buffer_writer( w->pos = 0; } break; } - return 0; + return w->error; } -- GitLab