diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index ce28ac521294af135827ec460a54142b3f4ffc25..07ff12d001a914d5adbb652cc1a4038eb77343f9 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -125,6 +125,21 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, uint32_t ioctl_action, ...); +/* pragma */ +struct labcomm_pragma_handler { + //struct labcomm_decoder_registry *registry; + //TODO: implement map (char * pragma_type) --> decoder_registry * + //to allow having different sets of handlers for different pragma types + int foo; +}; + +typedef int (*labcomm_handle_pragma_callback)( + struct labcomm_decoder *decoder, + char *pragma_type); + +void labcomm_decoder_register_pragma_handler(struct labcomm_decoder *d, + labcomm_handle_pragma_callback pragma_dispatcher); + /* * Encoder */ diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c index cb694e9902a90cb03afa092006340f317ce4cee2..90ce3c94535dce9948fa50d29fe60380c18e0a4e 100644 --- a/lib/c/labcomm_decoder.c +++ b/lib/c/labcomm_decoder.c @@ -25,6 +25,7 @@ #include "labcomm_private.h" #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" +#include "labcomm_bytearray_reader.h" struct sample_entry { int remote_index; @@ -75,7 +76,27 @@ struct labcomm_decoder *labcomm_decoder_new( } return result; } +#ifndef WITHOUT_PRAGMA +/* Internal aux function to allow temporary internal decoders + * to share the same memory. + * This function only frees the decoder, not the memory + */ +static void internal_labcomm_decoder_free(struct labcomm_decoder* d) +{ + struct labcomm_memory *memory = d->memory; + labcomm_reader_free(d->reader, d->reader->action_context); + LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry); + LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int); +} +void labcomm_decoder_free(struct labcomm_decoder* d) +{ + struct labcomm_memory *memory = d->memory; + internal_labcomm_decoder_free(d); + labcomm_memory_free(memory, 0, d); +} + +#else void labcomm_decoder_free(struct labcomm_decoder* d) { struct labcomm_memory *memory = d->memory; @@ -85,6 +106,7 @@ void labcomm_decoder_free(struct labcomm_decoder* d) LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int); labcomm_memory_free(memory, 0, d); } +#endif static int decode_sample_def(struct labcomm_decoder *d, int kind) { @@ -207,6 +229,57 @@ static int decode_version(struct labcomm_decoder *d, int remote_index) out: return result; } + +static int decoder_skip(struct labcomm_decoder *d, int len) +{ + int i; + for(i = 0; i <len; i++){ + labcomm_read_byte(d->reader); + if (d->reader->error < 0) { + return d->reader->error; + } + } + return 0; +} +static int decode_pragma(struct labcomm_decoder *d, int len) +{ + char *pragma_type; + int result; + pragma_type = labcomm_read_string(d->reader); + if (d->reader->error < 0) { + result = d->reader->error; + goto out; + } + int bytes = labcomm_size_string(pragma_type); + int psize = len-bytes; + if(0 /*d->pragma_handler*/) { + //read the entire packet to a buffer and then run + // decode on that through a bytearray_reader. + // (to easily handle multiple labcomm packets in one metadata packet) + int i; + unsigned char pragma_data[psize] ; + for(i=0; i<psize; i++) { + pragma_data[i] = labcomm_read_byte(d->reader); + if (d->reader->error < 0) { + result = d->reader->error; + goto out; + } + } + struct labcomm_reader *pr = labcomm_bytearray_reader_new( + d->reader->memory, pragma_data, psize); + struct labcomm_decoder *pd = labcomm_decoder_new( + pr, d->error, d->memory, d->scheduler); + /* d->prama_handler(pd, ptype, plen); */ + + internal_labcomm_decoder_free(pd); + result = 0; + } else { + result = decoder_skip(d, psize); + } +out: + return result; +} + int labcomm_decoder_decode_one(struct labcomm_decoder *d) { int result, remote_index, length; @@ -229,8 +302,8 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) result = -ECONNRESET; } else if (remote_index == LABCOMM_SAMPLE_DEF) { result = decode_sample_def(d, remote_index); - } else if (remote_index == LABCOMM_PRAGMA && 0 /* d->pragma_handler*/) { - /* d->prama_handler(...); */ + } else if (remote_index == LABCOMM_PRAGMA ){ + result = decode_pragma(d, length); } else if (remote_index < LABCOMM_USER) { fprintf(stderr, "SKIP %d %d\n", remote_index, length); result = remote_index;