From df9405e0886254752b5e51cdd8765dc998064dc5 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Tue, 14 Oct 2014 13:06:09 +0200
Subject: [PATCH] 20141009 passes first tests, lots of cleanup still to do.

---
 compiler/C_CodeGen.jrag                       | 36 +++++++---
 compiler/Python_CodeGen.jrag                  | 16 +++--
 lib/c/labcomm.c                               | 15 ++++
 lib/c/labcomm.h                               |  3 +-
 lib/c/labcomm_decoder.c                       | 14 ++--
 lib/c/labcomm_encoder.c                       | 35 +++++++--
 lib/c/labcomm_private.h                       | 12 +++-
 lib/c/test/test_labcomm.c                     | 12 ++--
 lib/c/test/test_labcomm_generated_encoding.c  | 10 +--
 .../control/labcomm/LabCommDecoderChannel.cs  | 15 +++-
 .../control/labcomm/LabCommEncoderChannel.cs  | 44 ++++++++----
 .../labcomm/LabCommDecoderChannel.java        | 25 ++++++-
 .../labcomm/LabCommEncoderChannel.java        | 37 ++++++++--
 lib/python/labcomm/LabComm.py                 | 72 ++++++++-----------
 lib/python/labcomm/__init__.py                |  1 -
 15 files changed, 245 insertions(+), 102 deletions(-)

diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index 25d5fed..1c72a7d 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -1188,12 +1188,12 @@ aspect C_Signature {
       }
     }
     env.println("};");
+    C_emitSizeofValue(env);
     env.println("struct labcomm"+env.verStr+"_signature labcomm"+env.verStr+"_signature_" + 
 		env.prefix + getName() + " = {");
     env.indent();
-    env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
-    env.println("(int (*)(struct labcomm"+env.verStr+"_signature *, void *))labcomm"+env.verStr+"_sizeof_" + 
-		env.prefix + getName() + ",");
+    env.println("\"" + getName() + "\",");
+    env.println("sizeof_" + env.prefix + getName() + ",");
     env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
     env.println("signature_bytes_" + env.prefix + getName() + ",");
     env.println("0");
@@ -1260,6 +1260,22 @@ aspect C_Sizeof {
     return getType().C_fixedSizeof();
   }
 
+  public void Decl.C_emitSizeof(C_env env) {
+  }
+
+  public void SampleDecl.C_emitSizeof(C_env env) {
+    env = env.nestStruct("(*v)");
+    env.println("int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() +
+		"(" + env.prefix + getName() + " *v)");
+    env.println("{");
+    env.indent();
+    env.println("return labcomm_internal_sizeof(" +
+                "&labcomm" + env.verStr+"_signature_" + env.prefix + getName() +
+                ", v);");
+    env.unindent();
+    env.println("}");
+  }
+
   public int Type.C_fixedSizeof() {
     throw new Error(this.getClass().getName() + 
 		    ".C_fixedSizeof()" + 
@@ -1308,18 +1324,17 @@ aspect C_Sizeof {
     return getType().C_fixedSizeof() * elements;
   }
 
-  public void Decl.C_emitSizeof(C_env env) {
+  public void Decl.C_emitSizeofValue(C_env env) {
   }
 
-  public void SampleDecl.C_emitSizeof(C_env env) {
+  public void SampleDecl.C_emitSizeofValue(C_env env) {
     env = env.nestStruct("(*v)");
-    env.println("int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() +
-		"(" + env.prefix + getName() + " *v)");
+    env.println("static int sizeof_" + env.prefix + getName() + "(void *vv)");
     env.println("{");
     env.indent();
-    env.println("int result = labcomm"+env.verStr+"_size_packed32(labcomm"+env.verStr+"_signature_" + 
-                env.prefix + getName() +".index);");
+    env.println("int result = 0;");
     if (C_isDynamic()) {
+      env.println(env.prefix + getName() + " *v = vv;");
       getType().C_emitSizeof(env);
     } else {
       env.println("result += " + C_fixedSizeof() + ";");
@@ -1338,7 +1353,8 @@ aspect C_Sizeof {
   public void PrimType.C_emitSizeof(C_env env) {
     switch (getToken()) {
       case LABCOMM_STRING: { 
-	env.println("result += 0 + strlen(" + env.qualid + ");"); 
+        env.print("{ int length = strlen(" + env.qualid + "); ");
+	env.println("result += labcomm_size_packed32(length) + length; }"); 
       } break;
       default: { 
 	throw new Error(this.getClass().getName() + 
diff --git a/compiler/Python_CodeGen.jrag b/compiler/Python_CodeGen.jrag
index ff6cef0..7a41813 100644
--- a/compiler/Python_CodeGen.jrag
+++ b/compiler/Python_CodeGen.jrag
@@ -83,6 +83,7 @@ aspect Python_CodeGen {
     env.println("import labcomm");
     env.println();
     Python_genTypes(env);
+/* Typedefs curenntly disabled
     env.println("typedef = [");
     env.indent();
     for (int i = 0 ; i < getNumDecl() ; i++) {
@@ -90,6 +91,7 @@ aspect Python_CodeGen {
     }
     env.unindent();
     env.println("]");
+*/
     env.println("sample = [");
     env.indent();
     for (int i = 0 ; i < getNumDecl() ; i++) {
@@ -105,11 +107,7 @@ aspect PythonTypes {
   
   public void Program.Python_genTypes(Python_env env) {
     for (int i = 0 ; i < getNumDecl() ; i++) {
-      env.println("class " + getDecl(i).getName() + "(object):");
-      env.indent();
       getDecl(i).Python_genSignature(env);
-      env.unindent();
-      env.println();
     }
   }
 
@@ -120,19 +118,29 @@ aspect PythonTypes {
   }
 
   public void TypeDecl.Python_genSignature(Python_env env) {
+/*
+    env.println("class " + getName() + "(object):");
+    env.indent();
     env.println("signature = labcomm.typedef('" + getName() + "',");
     env.indent();
     getType().Python_genSignature(env);
     env.unindent();
     env.println(")");
+    env.unindent();
+    env.println();
+*/
   }
 
   public void SampleDecl.Python_genSignature(Python_env env) {
+    env.println("class " + getName() + "(object):");
+    env.indent();
     env.println("signature = labcomm.sample('" + getName() + "', ");
     env.indent();
     getType().Python_genSignature(env);
     env.unindent();
     env.println(")");
+    env.unindent();
+    env.println();
   }
 
   public void UserType.Python_genSignature(Python_env env) {
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 3ec7d88..fb51d38 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -260,3 +260,18 @@ int labcomm_get_local_index(struct labcomm_signature *signature)
   }
   return signature->index;
 }
+
+int labcomm_internal_sizeof(struct labcomm_signature *signature,
+                            void *v)
+{
+  int length = signature->encoded_size(v);
+  fprintf(stderr, "SIZEOF(%s) = %d %d %d\n",
+          signature->name, 
+          labcomm_size_packed32(signature->index),
+          labcomm_size_packed32(length),
+          length);
+  return (labcomm_size_packed32(signature->index) +
+          labcomm_size_packed32(length) +
+          length);
+}
+
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 0c264bc..ce28ac5 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -43,9 +43,8 @@ struct labcomm_decoder;
  * Signature entry
  */
 struct labcomm_signature {
-  int type;
   char *name;
-  int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample *
+  int (*encoded_size)(void *); /* void* refers to sample_data */
   int size;
   unsigned char *signature; 
   int index;
diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c
index ee433d9..2ff78fb 100644
--- a/lib/c/labcomm_decoder.c
+++ b/lib/c/labcomm_decoder.c
@@ -187,7 +187,7 @@ static int decode_sample(struct labcomm_decoder *d, int kind)
     .error = 0,
   };
   struct labcomm_signature signature, *local_signature;
-  int remote_index, local_index, err;
+  int remote_index, local_index, err, length;
   
   local_signature = NULL;
   local_index = 0;
@@ -195,7 +195,8 @@ static int decode_sample(struct labcomm_decoder *d, int kind)
   labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL);
   remote_index = labcomm_read_packed32(d->reader);
   signature.name = labcomm_read_string(d->reader);
-  signature.type = kind;
+  length = labcomm_read_packed32(d->reader);
+  fprintf(stderr, "SIGNATURE_LENGTH=%d\n", length);
   collect_flat_signature(d, &writer);
   labcomm_writer_end(&writer, writer.action_context);
   err = writer_ioctl(&writer, 
@@ -228,7 +229,6 @@ static int decode_sample(struct labcomm_decoder *d, int kind)
       s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
 				      d->local,  struct sample_entry, i);
       if (s->signature &&
-	  s->signature->type == signature.type &&
 	  s->signature->size == signature.size &&
 	  strcmp(s->signature->name, signature.name) == 0 &&
 	  memcmp((void*)s->signature->signature, (void*)signature.signature,
@@ -302,7 +302,7 @@ static void reader_alloc(struct labcomm_decoder *d)
 
 int labcomm_decoder_decode_one(struct labcomm_decoder *d)
 {
-  int result, remote_index;
+  int result, remote_index, length;
 
   reader_alloc(d);
   remote_index = labcomm_read_packed32(d->reader);
@@ -310,6 +310,12 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d)
     result = d->reader->error;
     goto out;
   }
+  length = labcomm_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  fprintf(stderr, "LENGTH=%d\n", length);
   if (remote_index == LABCOMM_SAMPLE) {
     result = decode_sample(d, remote_index); 
   } else {
diff --git a/lib/c/labcomm_encoder.c b/lib/c/labcomm_encoder.c
index 3983e43..19c326e 100644
--- a/lib/c/labcomm_encoder.c
+++ b/lib/c/labcomm_encoder.c
@@ -75,11 +75,10 @@ int labcomm_internal_encoder_register(
   labcomm_encoder_function encode)
 {
   int result = -EINVAL;
-  int index, *done, err, i;
+  int index, *done, err, i, length;
 
   index = labcomm_get_local_index(signature);
   labcomm_scheduler_writer_lock(e->scheduler);
-  if (signature->type != LABCOMM_SAMPLE) { goto out; }
   if (index <= 0) { goto out; }
   done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
   if (*done) { goto out; }
@@ -88,9 +87,26 @@ int labcomm_internal_encoder_register(
 			     index, signature, NULL);
   if (err == -EALREADY) { result = 0; goto out; }
   if (err != 0) { result = err; goto out; }
-  labcomm_write_packed32(e->writer, signature->type);
+  labcomm_write_packed32(e->writer, LABCOMM_SAMPLE);
+  length = (labcomm_size_packed32(index) +
+            labcomm_size_string(signature->name) +
+            labcomm_size_packed32(signature->size) +
+            signature->size);
+  {
+    fprintf(stderr, "LENGTH(%s, %d)=%d %d %d %d -> %d\n", 
+            signature->name, index,
+            labcomm_size_packed32(index),
+            labcomm_size_string(signature->name),
+            labcomm_size_packed32(signature->size),
+            signature->size,
+            length);
+
+  }
+
+  labcomm_write_packed32(e->writer, length);
   labcomm_write_packed32(e->writer, index);
   labcomm_write_string(e->writer, signature->name);
+  labcomm_write_packed32(e->writer, signature->size);
   for (i = 0 ; i < signature->size ; i++) {
     if (e->writer->pos >= e->writer->count) {
       labcomm_writer_flush(e->writer, e->writer->action_context);
@@ -111,16 +127,25 @@ int labcomm_internal_encode(
   labcomm_encoder_function encode,
   void *value)
 {
-  int result;
-  int index;
+  int result, index, length;
 
   index = labcomm_get_local_index(signature);
+  /* FIXME: try to gt rid of labcomm_size_packed32(index) in 
+            labcomm_sizeof_* (since that calculation is currently
+            wrong [length field not accounted for]) */
+  length = (signature->encoded_size(value));
+  {
+    fprintf(stderr, "LENGTH(%s, %d)=%d\n", 
+            signature->name, index,
+            length);
+  }
   labcomm_scheduler_writer_lock(e->scheduler);
   result = labcomm_writer_start(e->writer, e->writer->action_context, 
 				index, signature, value);
   if (result == -EALREADY) { result = 0; goto no_end; }
   if (result != 0) { goto out; }
   result = labcomm_write_packed32(e->writer, index);
+  result = labcomm_write_packed32(e->writer, length);
   if (result != 0) { goto out; }
   result = encode(e->writer, value);
 out:
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index e615799..c9d3c03 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -377,6 +377,9 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
 				   struct labcomm_signature *signature,
 				   uint32_t ioctl_action, va_list args);
 
+int labcomm_internal_sizeof(struct labcomm_signature *signature,
+                            void *v);
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_ENCODE(name, type)					\
@@ -445,7 +448,7 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
 {
   int length, i, err; 
 
-  length = strlen((char*)s);
+  length = strlen(s);
   err = labcomm_write_packed32(w, length);
   if (err != 0) { return err; }
   for (i = 0 ; i < length ; i++) {
@@ -473,6 +476,13 @@ static inline int labcomm_size_packed32(unsigned int data)
 
 }
 
+static inline int labcomm_size_string(char *s)
+{
+  int length = strlen(s);
+  
+  return labcomm_size_packed32(length) + length;
+}
+
 /*
  * Macros for handling arrays indexed by signature index
  */
diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c
index b14f814..a199c10 100644
--- a/lib/c/test/test_labcomm.c
+++ b/lib/c/test/test_labcomm.c
@@ -193,19 +193,19 @@ int main(void)
   labcomm_encoder_register_test_sample_test_var(encoder);
   err = test_decode_one(decoder);
   fprintf(stderr, "decode of register -> index %d\n", err);
-  test_encode_decode(encoder, decoder, 7, 1, 1);
+  test_encode_decode(encoder, decoder, 8, 1, 1);
   if (decoder_var.a[0] != encoder_var.a[0]) {
     fprintf(stderr, "Failed to decode correct value %d != %d\n", 
 	    encoder_var.a[0], decoder_var.a[0]);
     exit(1);
   }
-  test_encode_decode(encoder, decoder, 19, 2, 2);
-  test_encode_decode(encoder, decoder, 3, 0, 0);
+  test_encode_decode(encoder, decoder, 20, 2, 2);
+  test_encode_decode(encoder, decoder, 4, 0, 0);
   for (i = 1 ; i <= 4 ; i++) {
-    test_encode_decode(encoder, decoder, 2+i, 0, (1<<(7*i))-1);
-    test_encode_decode(encoder, decoder, 3+i, 0, (1<<(7*i)));
+    test_encode_decode(encoder, decoder, 3+i, 0, (1<<(7*i))-1);
+    test_encode_decode(encoder, decoder, 4+i, 0, (1<<(7*i)));
   }
-  test_encode_decode(encoder, decoder, 7, 0, 4294967295);
+  test_encode_decode(encoder, decoder, 8, 0, 4294967295);
   return 0;
 }
 
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 670b824..6b9e8a3 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -190,23 +190,25 @@ int main(void)
     labcomm_pthread_scheduler_new(labcomm_default_memory));
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  /* Register twice to make sure that only one registration gets encoded */
   labcomm_encoder_register_generated_encoding_V(encoder);
   labcomm_encoder_register_generated_encoding_V(encoder);
-  EXPECT({ 0x02, -1, 0x01, 'V', 0x11, 0x00 });
+  EXPECT({ 0x02, 0x06, -1, 0x01, 'V', 0x02, 0x11, 0x00 });
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  /* Register twice to make sure that only one registration gets encoded */
   labcomm_encoder_register_generated_encoding_B(encoder);
   labcomm_encoder_register_generated_encoding_B(encoder);
-  EXPECT({0x02, -1, 0x01, 'B', 0x21});
+  EXPECT({0x02, 0x05, -1, 0x01, 'B',0x01, 0x21});
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   // was: labcomm_encode_generated_encoding_V(encoder, &V);
   labcomm_encode_generated_encoding_V(encoder);
-  EXPECT({-1});
+  EXPECT({-1, 0x00 });
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   labcomm_encode_generated_encoding_B(encoder, &B);
-  EXPECT({-1, 1});
+  EXPECT({-1, 0x01, 1});
 
   return 0;
 }
diff --git a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
index 76fa4e9..427106f 100644
--- a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
@@ -24,13 +24,22 @@ namespace se.lth.control.labcomm {
       bool done = false;
       while (!done) {
 	int tag = decodePacked32();
+        int length = decodePacked32();
+        Console.Error.WriteLine(" tag=" + tag + "length=" + length);
 	switch (tag) {
         case LabComm.SAMPLE: {
           int index = decodePacked32();
           String name = decodeString();
-	  MemoryStream signature = new MemoryStream();
-	  collectFlatSignature(new LabCommEncoderChannel(signature, false));
-	  registry.add(index, name, signature.ToArray());
+          int signature_length = decodePacked32();
+//	  MemoryStream signature = new MemoryStream();
+          byte[] signature = new byte[signature_length];
+//	  collectFlatSignature(new LabCommEncoderChannel(signature, false));
+          ReadBytes(signature, signature_length);
+          Console.Error.WriteLine("REMOTE:" + name + " " + 
+                                   signature_length + " " + 
+                                   signature);
+//	  registry.add(index, name, signature.ToArray());
+	  registry.add(index, name, signature);
         } break;
         default: {
           LabCommDecoderRegistry.Entry e = registry.get(tag);
diff --git a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
index 6cabb59..daea085 100644
--- a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
@@ -11,11 +11,15 @@ namespace se.lth.control.labcomm {
     private MemoryStream bytes = new MemoryStream();
     private LabCommEncoderRegistry registry = new LabCommEncoderRegistry();
     byte[] buf = new byte[8];
+    private int current_tag; 
 
     public LabCommEncoderChannel(Stream writer, bool emitVersion) {
       this.writer = writer;
       if (emitVersion) {
 	encodeString(LabComm.VERSION);
+        bytes.WriteTo(writer);
+        bytes.SetLength(0);
+        writer.Flush();
       }
     }
 
@@ -24,26 +28,51 @@ namespace se.lth.control.labcomm {
 
     public void register(LabCommDispatcher dispatcher) {
       int index = registry.add(dispatcher);
-      encodePacked32(LabComm.SAMPLE);
+      begin(LabComm.SAMPLE);
       encodePacked32(index);
       encodeString(dispatcher.getName());
       byte[] signature = dispatcher.getSignature();
+      encodePacked32(signature.Length);
       for (int i = 0 ; i < signature.Length ; i++) {
 	encodeByte(signature[i]);
       }
       end(null);
     }
 
+    private void begin(int tag) {
+      current_tag = tag;
+      bytes.SetLength(0);
+      Console.Error.WriteLine("BEGIN CURRENT=" + current_tag + " TAG=" + tag + 
+                              "LENGTH=" + bytes.Length);
+    }
+
     public void begin(Type c) {
-      encodePacked32(registry.getTag(c));
+      begin(registry.getTag(c));
     }
 
     public void end(Type c) {
+      Console.Error.WriteLine("END CURRENT=" + current_tag + 
+                              "LENGTH=" + bytes.Length);
+      WritePacked32(writer, current_tag);
+      WritePacked32(writer, bytes.Length);
       bytes.WriteTo(writer);
       bytes.SetLength(0);
       writer.Flush();
     }
 
+    private void WritePacked32(Stream s, Int64 value) {
+      Console.Error.WriteLine("PACKED=" + value);
+      Int64 v = value & 0xffffffff;
+      int i;
+  
+      for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
+        buf[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
+      }
+      for (i = i - 1 ; i >= 0 ; i--) {
+        s.WriteByte(buf[i]);
+      }      
+    }
+
     private void WriteInt(Int64 value, int length) {
       for (int i = length - 1 ; i >= 0 ; i--) {
 	buf[i] = (byte)(value & 0xff);
@@ -96,16 +125,7 @@ namespace se.lth.control.labcomm {
     }
 
     public void encodePacked32(Int64 value) {
-      byte[] tmp = new byte[5];
-      Int64 v = value & 0xffffffff;
-      int i;
-  
-      for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
-        tmp[i] = (byte)(v & 0x7f);
-      }
-      for (i = i - 1 ; i >= 0 ; i--) {
-        encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
-      }
+      WritePacked32(bytes, value);
     }
   }
 }
diff --git a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
index 6054875..d383f9e 100644
--- a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
@@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.EOFException;
 
 public class LabCommDecoderChannel implements LabCommDecoder {
 
@@ -25,13 +26,18 @@ public class LabCommDecoderChannel implements LabCommDecoder {
     boolean done = false;
     while (!done) {
       int tag = decodePacked32();
+      int length = decodePacked32();
       switch (tag) {
 	case LabComm.SAMPLE: {
 	  int index = decodePacked32();
 	  String name = decodeString();
-	  ByteArrayOutputStream signature = new ByteArrayOutputStream();
-	  collectFlatSignature(new LabCommEncoderChannel(signature, false));
-	  registry.add(index, name, signature.toByteArray());
+          int signature_length = decodePacked32();
+//	  ByteArrayOutputStream signature = new ByteArrayOutputStream();
+          byte[] signature = new byte[signature_length];
+//	  collectFlatSignature(new LabCommEncoderChannel(signature, false));
+          ReadBytes(signature, signature_length);
+//	  registry.add(index, name, signature.toByteArray());
+	  registry.add(index, name, signature);
 	} break;
 	default: {
 	  LabCommDecoderRegistry.Entry e = registry.get(tag);
@@ -100,6 +106,19 @@ public class LabCommDecoderChannel implements LabCommDecoder {
     registry.add(dispatcher, handler);
   }
 
+  private void ReadBytes(byte[] result, int length) throws IOException {
+      int offset = 0;
+      while (offset < length) {
+	int count = in.read(result, offset, length - offset);
+	if (count <= 0) {
+	  throw new EOFException(
+	    "End of stream reached with " +
+            (length - offset) + " bytes left to read");
+        }
+	offset += count;
+      }
+    }
+
   public boolean decodeBoolean() throws IOException {
     return in.readBoolean();
   }
diff --git a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
index d9b163e..cd3edcd 100644
--- a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
@@ -11,6 +11,7 @@ public class LabCommEncoderChannel implements LabCommEncoder {
   private ByteArrayOutputStream bytes;
   private DataOutputStream data;
   private LabCommEncoderRegistry registry;
+  private int current_tag; 
 
   public LabCommEncoderChannel(LabCommWriter writer, 
 			       boolean emitVersion) throws IOException {
@@ -20,6 +21,9 @@ public class LabCommEncoderChannel implements LabCommEncoder {
     registry = new LabCommEncoderRegistry();
     if (emitVersion) {
       encodeString(LabComm.VERSION);
+      data.flush();
+      writer.write(bytes.toByteArray());
+      bytes.reset();
     }
   }
 
@@ -38,28 +42,53 @@ public class LabCommEncoderChannel implements LabCommEncoder {
 
   public void register(LabCommDispatcher dispatcher) throws IOException {
     int index = registry.add(dispatcher);
-    encodePacked32(LabComm.SAMPLE);
+    begin(LabComm.SAMPLE);
     encodePacked32(index);
     encodeString(dispatcher.getName());
     byte[] signature = dispatcher.getSignature();
+    encodePacked32(signature.length);
     for (int i = 0 ; i < signature.length ; i++) {
       encodeByte(signature[i]);
     }
     end(null);
   }
 
+  private void begin(int tag) {
+    current_tag = tag;
+    bytes.reset();
+    System.err.println("BEGIN CURRENT=" + current_tag + " TAG=" + tag + 
+                       "LENGTH=" + bytes.size());
+  }
+
   public void begin(Class<? extends LabCommSample> c) throws IOException {
-    encodePacked32(registry.getTag(c));
+    begin(registry.getTag(c));
   }
 
   public void end(Class<? extends LabCommSample> c) throws IOException {
     data.flush();
-    //XXX when writer was a stream, it was probably a bit more GC efficient:
-    //bytes.writeTo(writer);
+    System.err.println("END CURRENT=" + current_tag + " " + 
+                       "LENGTH=" + bytes.size());
+    WritePacked32(writer, current_tag);
+    WritePacked32(writer, bytes.size());
     writer.write(bytes.toByteArray());
     bytes.reset();
   }
 
+  private void WritePacked32(LabCommWriter s, long value) throws IOException {
+    byte[] tmp1 = new byte[5];
+    byte[] tmp2 = new byte[1];
+    long v = value & 0xffffffff;
+    int i;
+    
+    for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
+      tmp1[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
+    }
+    for (i = i - 1 ; i >= 0 ; i--) {
+      tmp2[0] = tmp1[i];
+      writer.write(tmp2);
+    }      
+  }
+
   public void encodeBoolean(boolean value) throws IOException{
     data.writeBoolean(value);
   }
diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py
index 5f8ab13..d78efc3 100644
--- a/lib/python/labcomm/LabComm.py
+++ b/lib/python/labcomm/LabComm.py
@@ -110,27 +110,24 @@ def usePacketLength(version):
 
 class length_encoder:
     def __init__(self, encoder):
-        import sys
         self.encoder = encoder
         self.data = ""
-        print>>sys.stderr, "INIT", self, self.encoder, self.encoder.writer
 
     def start(self, encoder, version):
         self.version = version
-        pass
     
     def write(self, data):
-        import sys
-        print>>sys.stderr, [ data ]
-        print>>sys.stderr, "WRITE", self, self.encoder, self.encoder.writer
+        self.data += data
 
     def __enter__(self):
         return Encoder(self)
 
     def __exit__(self, type, value, traceback):
-        print>>sys.stderr, "EXIT", value
-        
-        pass
+        import sys
+        print>>sys.stderr, [ len(self.data), self.data ]
+        if usePacketLength(self.version):
+             self.encoder.encode_packed32(len(self.data))
+        self.encoder.pack("%ds" % len(self.data), self.data)
 
 i_TYPEDEF = 0x01
 i_SAMPLE  = 0x02
@@ -290,16 +287,20 @@ class STRING(primitive):
 #
 # Aggregate types
 #
-class sample_or_typedef(object):
+class sample(object):
     def __init__(self, name, decl):
         self.name = name
         self.decl = decl
 
-    def encode_decl_tail(self, encoder):
-#        with length_encoder(encoder) as e:
-        encoder.encode_type_number(self)
-        encoder.encode_string(self.name)
-        encoder.encode_type_number(self.decl)
+    def encode_decl(self, encoder):
+#        encoder.encode_type(i_SAMPLE)
+#        self.encode_decl_tail(encoder)
+        encoder.encode_type(i_SAMPLE)
+        with length_encoder(encoder) as e1:
+            e1.encode_type(encoder.decl_to_index[self])
+            e1.encode_string(self.name)
+            with length_encoder(e1) as e2:
+                self.decl.encode_decl(e2)
 
     def encode(self, encoder, object):
         self.decl.encode(encoder, object)
@@ -307,6 +308,8 @@ class sample_or_typedef(object):
     def decode_decl(self, decoder):
         index = decoder.decode_type_number()
         name = decoder.decode_string()
+        if usePacketLength(decoder.version):
+            length = decoder.decode_packed32()
         decl = decoder.decode_decl()
         result = self.__class__.__new__(self.__class__)
         result.__init__(name, decl)
@@ -322,30 +325,9 @@ class sample_or_typedef(object):
         return self.decl.new_instance()
 
     def __repr__(self):
-        return "'%s', %s" % (self.name, self.decl)
-
-class sample(sample_or_typedef):
-    def encode_decl(self, encoder):
-#        with length_encoder(encoder) as e:
-#            e.encode_type(i_SAMPLE)
-#            self.encode_decl_tail(e)
-        import sys
-        print>>sys.stderr, "AFTER"
- 
-        encoder.encode_type(i_SAMPLE)
-        self.encode_decl_tail(encoder)
+        return "sample('%s', %s)" % (self.name, self.decl)
 
-    def __repr__(self):
-        return "labcomm.sample(%s)" % super(sample, self).__repr__()
-        
-class typedef(sample_or_typedef):
-    def encode_decl(self, encoder):
-        encoder.encode_type(i_TYPEDEF)
-        self.encode_decl_tail(encoder)
 
-    def __repr__(self):
-        return "labcomm.typedef(%s)" % super(typedef, self).__repr__()
-        
 class array(object):
     def __init__(self, indices, decl):
         self.indices = indices
@@ -516,7 +498,6 @@ class struct:
         return result
 
 SAMPLE = sample(None, None)
-TYPEDEF = typedef(None, None)
 
 ARRAY = array(None, None)
 STRUCT = struct({})
@@ -545,7 +526,6 @@ class Codec(object):
         self.predefined_types()
 
     def predefined_types(self):
-        self.add_decl(TYPEDEF, i_TYPEDEF)
         self.add_decl(SAMPLE, i_SAMPLE)
 
         self.add_decl(ARRAY, i_ARRAY)
@@ -607,7 +587,9 @@ class Encoder(Codec):
             name = self.type_to_name[object.__class__]
             decl = self.name_to_decl[name]
         self.encode_type_number(decl)
-        decl.encode(self, object)
+        with length_encoder(self) as e:
+            decl.encode(e, object)
+#        decl.encode(self, object)
         self.writer.mark()
 
     def encode_type_number(self, decl):
@@ -687,15 +669,19 @@ class Decoder(Codec):
         result = self.index_to_decl[index]
         if index < i_USER:
             result = result.decode_decl(self)
+        else:
+            raise Exception('Should not be used')
         return result
 
     def decode(self):
-        value = None
         index = self.decode_type_number()
-        decl = self.index_to_decl[index]
+        if usePacketLength(self.version):
+            length = self.decode_packed32()
         if index == i_SAMPLE:
-            decl = decl.decode_decl(self)
+            decl = self.index_to_decl[index].decode_decl(self)
+            value = None
         else:
+            decl = self.index_to_decl[index]
             value = decl.decode(self)
         self.reader.mark(value, decl)
         return (value, decl)
diff --git a/lib/python/labcomm/__init__.py b/lib/python/labcomm/__init__.py
index 52a5911..9eee0b7 100644
--- a/lib/python/labcomm/__init__.py
+++ b/lib/python/labcomm/__init__.py
@@ -7,7 +7,6 @@ Decoder = labcomm.LabComm.Decoder
 Encoder = labcomm.LabComm.Encoder
 
 sample = labcomm.LabComm.sample
-typedef = labcomm.LabComm.typedef
 
 array = labcomm.LabComm.array
 struct = labcomm.LabComm.struct
-- 
GitLab