From 177c67030b9e90edc272ed5e3b9bb38b1f7be9c3 Mon Sep 17 00:00:00 2001 From: Sven Gestegard Robertz <sven.robertz@cs.lth.se> Date: Mon, 10 Nov 2014 14:24:14 +0100 Subject: [PATCH] minor preliminary refactoring/bringover from old branch --- lib/c/labcomm_decoder.c | 131 +++++++++++++----- lib/java/se/lth/control/labcomm/Constant.java | 4 +- .../lth/control/labcomm/DecoderChannel.java | 56 ++++++-- .../lth/control/labcomm/EncoderChannel.java | 2 +- lib/python/labcomm/LabComm.py | 61 ++++++-- 5 files changed, 196 insertions(+), 58 deletions(-) diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c index 8a3e1ba..0aa1de9 100644 --- a/lib/c/labcomm_decoder.c +++ b/lib/c/labcomm_decoder.c @@ -190,6 +190,96 @@ static void reader_alloc(struct labcomm_decoder *d) } } +static int decoder_skip(struct labcomm_decoder *d, int len, int tag) +{ + int i; + printf("got tag 0x%x, skipping %d bytes\n", tag, len); + for(i = 0; i <len; i++){ + labcomm_read_byte(d->reader); + if (d->reader->error < 0) { + return d->reader->error; + } + } + return tag; +} +/* d - decoder to read from + registry - decoder to lookup signatures (registry != d only if + nesting decoders, e.g., when decoding pragma) + len - length of the labcomm packet ) +*/ +static int decode_pragma(struct labcomm_decoder *d, + struct labcomm_decoder *registry, + 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; + result = decoder_skip(d, psize, LABCOMM_PRAGMA); +out: + return result; +} + +static labcomm_decoder_function lookup_h(struct labcomm_decoder *d, + struct call_handler_context *wrap, + int remote_index, + int **local_index) +{ + labcomm_decoder_function do_decode = NULL; + labcomm_scheduler_data_lock(d->scheduler); + *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, + d->remote_to_local, int, + remote_index); + if (**local_index != 0) { + struct sample_entry *entry; + + entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, + d->local, struct sample_entry, + **local_index); + wrap->local_index = **local_index; + wrap->signature = entry->signature; + wrap->handler = entry->handler; + wrap->context = entry->context; + do_decode = entry->decode; + } + labcomm_scheduler_data_unlock(d->scheduler); + return do_decode; +} +/* d - decoder to read from + registry - decoder to lookup signatures (registry != d only if + nesting decoders, e.g., when decoding pragma) + remote_index - received type index ) +*/ +static int decode_and_handle(struct labcomm_decoder *d, + struct labcomm_decoder *registry, + int remote_index) +{ + int result; + int *local_index; + struct call_handler_context wrap = { + .reader = d->reader, + .remote_index = remote_index, + .signature = NULL, + .handler = NULL, + .context = NULL, + }; + labcomm_decoder_function do_decode = lookup_h(registry, &wrap, remote_index, &local_index); + result = *local_index; + if (do_decode) { + do_decode(d->reader, call_handler, &wrap); + if (d->reader->error < 0) { + result = d->reader->error; + } + } else { + result = -ENOENT; + } + return result; +} int labcomm_decoder_decode_one(struct labcomm_decoder *d) { int result, remote_index, length; @@ -223,48 +313,13 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) result = -ECONNRESET; } else if (remote_index == LABCOMM_SAMPLE) { result = decode_sample(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, d, length); } else if (remote_index < LABCOMM_USER) { fprintf(stderr, "SKIP %d %d\n", remote_index, length); result = remote_index; } else { - int *local_index; - struct call_handler_context wrap = { - .reader = d->reader, - .remote_index = remote_index, - .signature = NULL, - .handler = NULL, - .context = NULL, - }; - labcomm_decoder_function do_decode = NULL; - - labcomm_scheduler_data_lock(d->scheduler); - local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, - d->remote_to_local, int, - remote_index); - if (*local_index != 0) { - struct sample_entry *entry; - - entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, - d->local, struct sample_entry, - *local_index); - wrap.local_index = *local_index; - wrap.signature = entry->signature; - wrap.handler = entry->handler; - wrap.context = entry->context; - do_decode = entry->decode; - result = *local_index; - } - labcomm_scheduler_data_unlock(d->scheduler); - if (do_decode) { - do_decode(d->reader, call_handler, &wrap); - if (d->reader->error < 0) { - result = d->reader->error; - } - } else { - result = -ENOENT; - } + result = decode_and_handle(d, d, remote_index); } out: return result; diff --git a/lib/java/se/lth/control/labcomm/Constant.java b/lib/java/se/lth/control/labcomm/Constant.java index 194ae8d..c5a580a 100644 --- a/lib/java/se/lth/control/labcomm/Constant.java +++ b/lib/java/se/lth/control/labcomm/Constant.java @@ -11,7 +11,9 @@ public class Constant { * Predeclared aggregate type indices */ public static final int VERSION = 0x01; - public static final int SAMPLE = 0x02; + public static final int SAMPLE_DEF = 0x02; + public static final int TYPE_DEF = 0x03; + public static final int TYPE_BINDING = 0x04; public static final int PRAGMA = 0x3f; public static final int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */ diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm/DecoderChannel.java index 6f7760f..c8d6925 100644 --- a/lib/java/se/lth/control/labcomm/DecoderChannel.java +++ b/lib/java/se/lth/control/labcomm/DecoderChannel.java @@ -11,9 +11,43 @@ public class DecoderChannel implements Decoder { private DataInputStream in; private DecoderRegistry registry; - public DecoderChannel(InputStream in) throws IOException { + private DecoderChannel(InputStream in, DecoderRegistry reg) throws IOException { this.in = new DataInputStream(in); - registry = new DecoderRegistry(); + registry = reg; + } + public DecoderChannel(InputStream in) throws IOException { + this(in, new DecoderRegistry()); + } + + private void processSampleDef() throws IOException { + int index = decodePacked32(); + String name = decodeString(); + int signature_length = decodePacked32(); + byte[] signature = new byte[signature_length]; + ReadBytes(signature, signature_length); + registry.add(index, name, signature); + } + + + private void processTypeDef(int len) throws IOException { + System.out.println("Got TypeDef: skipping "+len+" bytes"); + for(int i=0; i<len; i++) { + decodeByte(); + } + } + + private void processTypeBinding(int len) throws IOException { + System.out.println("Got TypeBinding: skipping "+len+" bytes"); + for(int i=0; i<len; i++) { + decodeByte(); + } + } + + private void processPragma(int len) throws IOException { + System.out.println("Got Pragma: skipping "+len+" bytes"); + for(int i=0; i<len; i++) { + decodeByte(); + } } public void runOne() throws Exception { @@ -29,13 +63,17 @@ public class DecoderChannel implements Decoder { version + " != " + Constant.CURRENT_VERSION); } } break; - case Constant.SAMPLE: { - int index = decodePacked32(); - String name = decodeString(); - int signature_length = decodePacked32(); - byte[] signature = new byte[signature_length]; - ReadBytes(signature, signature_length); - registry.add(index, name, signature); + case Constant.SAMPLE_DEF: { + processSampleDef(); + } break; + case Constant.TYPE_DEF: { + processTypeDef(length); + } break; + case Constant.TYPE_BINDING: { + processTypeBinding(length); + } break; + case Constant.PRAGMA: { + processPragma(length); } break; default: { DecoderRegistry.Entry e = registry.get(tag); diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java index e7c3e80..08ef0fc 100644 --- a/lib/java/se/lth/control/labcomm/EncoderChannel.java +++ b/lib/java/se/lth/control/labcomm/EncoderChannel.java @@ -30,7 +30,7 @@ public class EncoderChannel implements Encoder { public void register(SampleDispatcher dispatcher) throws IOException { int index = registry.add(dispatcher); - begin(Constant.SAMPLE); + begin(Constant.SAMPLE_DEF); encodePacked32(index); encodeString(dispatcher.getName()); byte[] signature = dispatcher.getSignature(); diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py index 9f854ec..dff29ce 100644 --- a/lib/python/labcomm/LabComm.py +++ b/lib/python/labcomm/LabComm.py @@ -11,7 +11,7 @@ # | ... # +----+-- # -# LabComm22014 SAMPLE: +# LabComm2014 SAMPLE_DEF: # # +----+----+----+----+ # | id = 0x02 (packed32) @@ -29,6 +29,37 @@ # | ... # +----+-- # +# LabComm2014 TYPE_DEF: (as SAMPLE_DEF, but signatures are hierarchical, +# i.e., may contain references to other types +# +# +----+----+----+----+ +# | id = 0x03 (packed32) +# +----+----+----+----+ +# | length (packed32) +# +----+----+----+----+ +# | type number (packed32) +# +----+----+----+----+ +# | type name (UTF8) +# | ... +# +----+----+----+----+ +# | signature length (packed32) +# +----+----+----+----+ +# | type signature +# | ... +# +----+-- +# +# LabComm2014 TYPE_BINDING +# +# +----+----+----+----+ +# | id = 0x04 (packed32) +# +----+----+----+----+ +# | length (packed32) +# +----+----+----+----+ +# | sample number (packed32) +# +----+----+----+----+ +# | type number (packed32) +# +----+----+----+----+ +# # LabComm2014 User data: # # +----+----+----+----+ @@ -123,10 +154,12 @@ import struct as packer DEFAULT_VERSION = "LabComm2014" # Allowed packet tags -i_VERSION = 0x01 -i_SAMPLE = 0x02 -i_PRAGMA = 0x3f -i_USER = 0x40 # ..0xffffffff +i_VERSION = 0x01 +i_SAMPLE_DEF = 0x02 +i_TYPE_DEF = 0x03 +i_TYPE_BINDING= 0x04 +i_PRAGMA = 0x3f +i_USER = 0x40 # ..0xffffffff # Predefined types i_ARRAY = 0x10 @@ -310,7 +343,7 @@ class sample(object): self.decl = decl def encode_decl(self, encoder): - encoder.encode_type(i_SAMPLE) + encoder.encode_type(i_SAMPLE_DEF) with length_encoder(encoder) as e1: e1.encode_type(encoder.decl_to_index[self]) e1.encode_string(self.name) @@ -512,7 +545,7 @@ class struct: result += "\n])" return result -SAMPLE = sample(None, None) +SAMPLE_DEF = sample(None, None) ARRAY = array(None, None) STRUCT = struct({}) @@ -541,7 +574,7 @@ class Codec(object): self.predefined_types() def predefined_types(self): - self.add_decl(SAMPLE, i_SAMPLE) + self.add_decl(SAMPLE_DEF, i_SAMPLE_DEF) self.add_decl(ARRAY, i_ARRAY) self.add_decl(STRUCT, i_STRUCT) @@ -693,6 +726,10 @@ class Decoder(Codec): raise Exception('Should not be used') return result + def skip(self, length): + for _ in xrange(length): + self.decode_byte() + def decode(self): while True: index = self.decode_type_number() @@ -705,9 +742,15 @@ class Decoder(Codec): if self.version != other_version: raise Exception("LabComm version mismatch %s != %s" % (version, other_version)) - if index == i_SAMPLE: + if index == i_SAMPLE_DEF: decl = self.index_to_decl[index].decode_decl(self) value = None + elif index == i_TYPE_DEF: + print "Got type_def, skipping %d bytes" % length + self.skip(length) + elif index == i_TYPE_BINDING: + print "Got type_binding, skipping %d bytes" % length + self.skip(length) else: decl = self.index_to_decl[index] value = decl.decode(self) -- GitLab