Commit 177c6703 authored by Sven Gestegård Robertz's avatar Sven Gestegård Robertz
Browse files

minor preliminary refactoring/bringover from old branch

parent 59729683
......@@ -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;
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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();
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment