From 5ad89bf02ae90e897ef0b771a77a69fee8d76ade Mon Sep 17 00:00:00 2001 From: Sven Robertz <sven@cs.lth.se> Date: Fri, 12 Apr 2013 14:08:32 +0200 Subject: [PATCH] changed generated length to be without user_id field + started changing the sig_parser to build signature_t objects --- compiler/C_CodeGen.jrag | 6 +- examples/simple/Decoder.java | 18 +++- examples/simple/example_decoder.c | 15 +++ examples/simple/example_encoder.c | 6 ++ examples/simple/simple.lc | 5 + lib/c/experimental/labcomm_sig_parser.c | 117 +++++++++++++++++++++--- lib/c/experimental/labcomm_sig_parser.h | 3 +- lib/c/labcomm.h | 1 + 8 files changed, 153 insertions(+), 18 deletions(-) diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index a936285..d445088 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -970,11 +970,11 @@ aspect C_Sizeof { env.println("{"); env.indent(); if (C_isDynamic()) { - env.println("int result = 4;"); + env.println("int result = 0;"); getType().C_emitSizeof(env); env.println("return result;"); } else { - env.println("return " + (4 + C_fixedSizeof()) + ";"); + env.println("return " + (0 + C_fixedSizeof()) + ";"); } env.unindent(); env.println("}"); @@ -989,7 +989,7 @@ aspect C_Sizeof { public void PrimType.C_emitSizeof(C_env env) { switch (getToken()) { case LABCOMM_STRING: { - env.println("result += 4 + strlen(" + env.qualid + ");"); + env.println("result += 0 + strlen(" + env.qualid + ");"); } break; default: { throw new Error(this.getClass().getName() + diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java index c059df2..b4947f8 100644 --- a/examples/simple/Decoder.java +++ b/examples/simple/Decoder.java @@ -5,7 +5,8 @@ import java.io.InputStream; import se.lth.control.labcomm.LabCommDecoderChannel; public class Decoder - implements TwoInts.Handler, IntString.Handler, TwoArrays.Handler + implements TwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler + { LabCommDecoderChannel decoder; @@ -17,6 +18,7 @@ public class Decoder TwoInts.register(decoder, this); IntString.register(decoder, this); TwoArrays.register(decoder, this); + TwoFixedArrays.register(decoder, this); try { System.out.println("Running decoder."); @@ -47,6 +49,20 @@ public class Decoder System.out.println(); } + public void handle_TwoFixedArrays(TwoFixedArrays d) throws java.io.IOException { + System.out.println("Got TwoFixedArrays:"); + for(int i=0; i<d.a.length; i++) { + System.out.print(d.a[i]+" "); + } + System.out.println(); + for(int i=0; i<d.b[0].length; i++) { + System.out.print(d.b[0][i]+" "); + System.out.print(d.b[1][i]+" "); + } + System.out.println(); + } + + public static void main(String[] arg) throws Exception { Decoder example = new Decoder( new FileInputStream(new File(arg[0])) diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c index 9aa6b40..50d2530 100644 --- a/examples/simple/example_decoder.c +++ b/examples/simple/example_decoder.c @@ -26,6 +26,20 @@ static void handle_simple_TwoArrays(simple_TwoArrays *d,void *context) { printf("\n"); } +static void handle_simple_TwoFixedArrays(simple_TwoFixedArrays *d,void *context) { + printf("Got TwoFixedArrays:"); + int i; + for(i=0; i<2; i++) { + printf("%d ",d->a.a[i]); + } + printf("\n"); + for(i=0; i<3; i++) { + printf("%d ",d->b.a[0+2*i]); + printf("%d ",d->b.a[1+2*i]); + } + printf("\n"); +} + int main(int argc, char *argv[]) { int fd; struct labcomm_decoder *decoder; @@ -44,6 +58,7 @@ int main(int argc, char *argv[]) { labcomm_decoder_register_simple_TwoInts(decoder, handle_simple_TwoInts, context); labcomm_decoder_register_simple_IntString(decoder, handle_simple_IntString, context); labcomm_decoder_register_simple_TwoArrays(decoder, handle_simple_TwoArrays, context); + labcomm_decoder_register_simple_TwoFixedArrays(decoder, handle_simple_TwoFixedArrays, context); printf("Decoding:\n"); labcomm_decoder_run(decoder); diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c index 33b5c4c..8192f56 100644 --- a/examples/simple/example_encoder.c +++ b/examples/simple/example_encoder.c @@ -51,4 +51,10 @@ int main(int argc, char *argv[]) { labcomm_encode_simple_TwoInts(encoder, &ti); + simple_TwoFixedArrays tfa; + + printf("Encoding TwoFixedArrays...\n"); + labcomm_encoder_register_simple_TwoFixedArrays(encoder); + labcomm_encode_simple_TwoFixedArrays(encoder, &tfa); + } diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc index 2adfb2e..9bb352f 100644 --- a/examples/simple/simple.lc +++ b/examples/simple/simple.lc @@ -17,3 +17,8 @@ sample struct { int fixed[2]; int variable[2,_]; } TwoArrays; + +sample struct { + int a[2]; + int b[2,3]; +} TwoFixedArrays; diff --git a/lib/c/experimental/labcomm_sig_parser.c b/lib/c/experimental/labcomm_sig_parser.c index 66e828f..a56081f 100644 --- a/lib/c/experimental/labcomm_sig_parser.c +++ b/lib/c/experimental/labcomm_sig_parser.c @@ -156,6 +156,13 @@ unsigned char* get_signature(unsigned int uid){ return signatures[uid-LABCOMM_USER]; } +labcomm_signature_t sig_ts[MAX_SIGNATURES]; + +labcomm_signature_t *get_sig_t(unsigned int uid) +{ + return &sig_ts[uid-LABCOMM_USER]; +} + void dump_signature(unsigned int uid){ int i; unsigned int len = get_signature_len(uid); @@ -168,7 +175,11 @@ void dump_signature(unsigned int uid){ printf("\n"); } -int labcomm_sizeof(unsigned int type) +static inline void buffer_set_varsize(buffer *b) +{ + b->current_decl_is_varsize = TRUE; +} +size_t labcomm_sizeof_primitive(unsigned int type) { switch(type) { case TYPE_BOOLEAN : @@ -183,14 +194,15 @@ int labcomm_sizeof(unsigned int type) case TYPE_DOUBLE : return 8; default: - printf("labcomm_sizeof(%x)\n", type); - error("labcomm_sizeof should only be called for primitive types"); + printf("labcomm_sizeof_primitive(%x)\n", type); + error("labcomm_sizeof_primitive should only be called for primitive types"); } } -static int accept_packet(buffer *d); -static int accept_type_decl(buffer *d); -static int accept_sample_decl(buffer *d); +//these are inlined in do_parse +//static int accept_packet(buffer *d); +//static int accept_type_decl(buffer *d); +//static int accept_sample_decl(buffer *d); static int accept_user_id(buffer *d); static int accept_string(buffer *d); static int accept_string_length(buffer *d); @@ -227,6 +239,28 @@ static unsigned char labcomm_varint_sizeof(unsigned int i) } } +int encoded_size_static(labcomm_signature_t *sig, void *unused) +{ + if(sig->cached_size == -1) { + error("encoded_size_static called for var_size sample or uninitialized signature\n"); + } + return sig->cached_size; +} + +/* This function probably never will be implemented, as it would be + similar to skip_packed_sample_data. And if unregistered variable size + samples is to be handled, the proper way is to generate and register + a handler. Thus, the most probable use of the encoded_size function + on the receiver side, is to skip unhandled samples. +*/ + +int encoded_size_parse_sig(labcomm_signature_t *sig, void *sample) +{ + printf("Warning: encoded_size_parse_sig not implemented\n"); + return -1; +} + +// HERE BE DRAGONS! what does the return value mean? int do_parse(buffer *d) { unsigned char nbytes; unsigned int type = peek_varint(d, &nbytes) ; @@ -249,11 +283,14 @@ int do_parse(buffer *d) { VERBOSE_PRINTF("\n"); return TRUE; } else if (type == SAMPLE_DECL) { + d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in buffer advancen(d, nbytes); VERBOSE_PRINTF("sample_decl "); accept_user_id(d); unsigned int nstart = d->idx; unsigned int uid = (unsigned int) (unsigned long) pop(d); + labcomm_signature_t *newsig = get_sig_t(uid); + newsig->type = type; VERBOSE_PRINTF(", name = "); accept_string(d); unsigned int start = d->idx; @@ -266,12 +303,16 @@ int do_parse(buffer *d) { accept_type(d); //printf(" : "); //unsigned int dt = pop(d); + pop(d); // ignore type, for now + unsigned int enc_size = (unsigned int) (unsigned long) pop(d); unsigned int end = d->idx; unsigned int len = end-start; if(len <= MAX_SIG_LEN) { signatures_length[uid-LABCOMM_USER] = len; memcpy(signatures[uid-LABCOMM_USER], &d->c[start], len); + newsig->size = len; + newsig->signature = signatures[uid-LABCOMM_USER]; } else { error("sig longer than max length (this ought to be dynamic...)"); } @@ -280,17 +321,31 @@ int do_parse(buffer *d) { signatures_name[uid-LABCOMM_USER][0] = nlen; memcpy(signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen-1], nlen+1); signatures_name[uid-LABCOMM_USER][nlen+1]=0; + newsig->name = signatures_name[uid-LABCOMM_USER]; } else { error("sig name longer than max length (this ought to be dynamic..."); } VERBOSE_PRINTF("signature for uid %x: %s (start=%x,end=%x, nlen=%d,len=%d)\n", uid, get_signature_name(uid), start,end, nlen, len); - } else { + INFO_PRINTF("SIG: %s\n", newsig->name); + if(! d->current_decl_is_varsize) { + newsig->cached_size = enc_size; + newsig->encoded_size = encoded_size_static; + INFO_PRINTF(".... is static size = %d\n", enc_size); + } else { + newsig->cached_size = -1; + newsig->encoded_size = encoded_size_parse_sig; + INFO_PRINTF(".... is variable size\n"); + } + } else if(type >= LABCOMM_USER) { #ifdef EXIT_WHEN_RECEIVING_DATA printf("*** got sample data, exiting\n"); exit(0); #else accept_sample_data(d); #endif + } else { + error("got unknown type (<LABCOMM_USER)\n"); + exit(1); } } @@ -327,46 +382,58 @@ static int accept_type(buffer *d){ case TYPE_BOOLEAN : VERBOSE_PRINTF("boolean"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 1); break; case TYPE_BYTE : VERBOSE_PRINTF("byte"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 1); break; case TYPE_SHORT : VERBOSE_PRINTF("short"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 2); break; case TYPE_INTEGER : VERBOSE_PRINTF("integer"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 4); break; case TYPE_LONG : VERBOSE_PRINTF("long"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 8); break; case TYPE_FLOAT : VERBOSE_PRINTF("float"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 4); break; case TYPE_DOUBLE : VERBOSE_PRINTF("double"); advancen(d, nbytes); + push(d, (void *) (unsigned long) 8); break; case TYPE_STRING : VERBOSE_PRINTF("string"); advancen(d, nbytes); + buffer_set_varsize(d); + push(d, (void *) (unsigned long)0); break; case ARRAY_DECL : accept_array_decl(d); + //push(d, pop(d)) == NOP break; case STRUCT_DECL : accept_struct_decl(d); + //push(d, pop(d)) == NOP break; default : printf("accept_basic_type default (type==%x) should not happen\n", type); + push(d, (void *) (unsigned long)0); return FALSE; } - //push(d,type); + push(d,(void *) (unsigned long) type); return TRUE; } @@ -385,18 +452,32 @@ static int accept_array_decl(buffer *d){ if(idx == 0) { numVar++; VERBOSE_PRINTF("[_] "); + buffer_set_varsize(d); } else { VERBOSE_PRINTF("[%d] ", idx); size*=idx; } } VERBOSE_PRINTF(" of "); - unsigned int et=accept_type(d); + accept_type(d); + unsigned int et= (unsigned int) (unsigned long) pop(d); + unsigned int es= (unsigned int) (unsigned long) pop(d); +#ifdef DEBUG + printf("accept_array_decl: et = %x\n", et); +#endif + if(numVar == 0) { +#ifdef DEBUG + printf("size=%d, es=%d\n", size, s); +#endif + push(d, (void *) (unsigned long) (size*es)); + } //pop(d); - //push(d,tid); + push(d,(void *) (unsigned long) tid); return TRUE; } else { printf("accept_array_decl: type=%x, should not happen\n",tid); + push(d,(void *) (unsigned long) 0); + push(d,(void *) (unsigned long) tid); return FALSE; } } @@ -410,27 +491,34 @@ static int accept_struct_decl(buffer *d){ int i; int numVar=0; int size=0; + unsigned int fieldsizes=0; for(i=0; i<nf; i++) { VERBOSE_PRINTF("\t"); accept_field(d); + fieldsizes += (unsigned int) (unsigned long) pop(d); } -// push(d,tid); + push(d, (void *) (unsigned long) fieldsizes); +// push(d, (void *) (unsigned long)tid); return TRUE; } else { printf("accept_struct_decl: type=%x, should not happen\n",tid); + push(d, (void *) (unsigned long)0); + push(d, (void *) (unsigned long) tid); return FALSE; } } static int accept_field(buffer *d){ VERBOSE_PRINTF("field "); accept_string(d); - pop(d); // ignore, for now + pop(d); // ignore length, for now #ifdef RETURN_STRINGS char *str = (char *) pop(d); free(str); #endif VERBOSE_PRINTF(" : "); accept_type(d); + pop(d); // ignore type, for now + //push(d, pop(d) == NOP VERBOSE_PRINTF("\n"); } static int accept_sample_data(buffer *d){ @@ -440,6 +528,9 @@ static int accept_sample_data(buffer *d){ #ifdef DEBUG dump_signature(uid); #endif + labcomm_signature_t *sigt = get_sig_t(uid); + int encoded_size = sigt->encoded_size(sigt, NULL); + INFO_PRINTF("encoded_size from sig: %d\n", encoded_size); unsigned int siglen = get_signature_len(uid); unsigned char *sig = get_signature(uid); skip_packed_sample_data(d, sig, siglen); @@ -484,7 +575,7 @@ static int skip_array(buffer *d, unsigned char *sig, unsigned int len, unsigned unsigned int type = unpack_varint(sig, *pos, &nbytes); *pos+=nbytes; - unsigned int elemSize = labcomm_sizeof(type); + unsigned int elemSize = labcomm_sizeof_primitive(type); skip = elemSize * tot_nbr_elem_tmp; diff --git a/lib/c/experimental/labcomm_sig_parser.h b/lib/c/experimental/labcomm_sig_parser.h index cae7473..d7f994f 100644 --- a/lib/c/experimental/labcomm_sig_parser.h +++ b/lib/c/experimental/labcomm_sig_parser.h @@ -33,7 +33,7 @@ #undef EXIT_WHEN_RECEIVING_DATA -#undef RETURN_STRINGS // highly experimental, and not used +#define RETURN_STRINGS // not really tested #ifndef TRUE @@ -68,6 +68,7 @@ typedef struct { void** stack; size_t stacksize; unsigned int top; + int current_decl_is_varsize; } buffer; int init_buffer(buffer *b, size_t size, size_t stacksize) ; diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index ee0a589..04ec13f 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -29,6 +29,7 @@ typedef struct labcomm_signature{ int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample * int size; unsigned char *signature; + int cached_size; // -1 if not initialized or type is variable size } labcomm_signature_t; /* -- GitLab