diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index caf57e950ccc978ea6207f9155df013d814ae2a8..1efc0a385b45b216302a9705853b255e3932bae9 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -496,7 +496,8 @@ aspect C_Decoder {
   }
 
   public void VariableSize.C_emitDecoderDecodeLimit(C_env env, int i) {
-    env.println(env.qualid + ".n_" + i + " = labcomm_decode_int(d);");
+    //env.println(env.qualid + ".n_" + i + " = labcomm_decode_int(d);");
+    env.println(env.qualid + ".n_" + i + " = labcomm_decode_packed32(d);");
   }
 
   public void ArrayType.C_emitDecoderDecodeLimit(C_env env) {
@@ -721,7 +722,8 @@ aspect C_Encoder {
   }
 
   public void VariableSize.C_emitEncoderEncodeLimit(C_env env, int i) {
-    env.println("labcomm_encode_int(e, " + env.qualid + ".n_" + i + ");");
+    //env.println("labcomm_encode_int(e, " + env.qualid + ".n_" + i + ");");
+    env.println("labcomm_encode_packed32(e, " + env.qualid + ".n_" + i + ");");
   }
 
   public void ArrayType.C_emitEncoderEncodeLimit(C_env env) {
diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag
index 40c0e1b26c42550424a5dfdf07b715b5a04b5e53..3331299b0ac6e80e8b513cffbc4dca1ec2fe5518 100644
--- a/compiler/Java_CodeGen.jrag
+++ b/compiler/Java_CodeGen.jrag
@@ -578,7 +578,7 @@ aspect Java_Class {
   }
 
   public void VariableSize.Java_emitDecoder(Java_env env) {
-    env.print("d.decodeInt()");
+    env.print("d.decodePacked32()");
   }
 
   public void StructType.Java_emitDecoder(Java_env env, String name) {
diff --git a/compiler/Signature.jrag b/compiler/Signature.jrag
index fb65987c267994ea994bb00c294729519ce5001f..6d5f16e8aa7881be0a61627cb74bddbc8a55a7af 100644
--- a/compiler/Signature.jrag
+++ b/compiler/Signature.jrag
@@ -38,11 +38,27 @@ aspect Signature {
     }
 
     public void addInt(int value, String comment) {
-      byte[] data = new byte[4];
-      for (int i = 0 ; i < 4 ; i++) {
-        data[3 - i] = (byte)((value >> (8 * i)) & 0xff);
-      }
-      add(data, comment);
+	byte[] packed = new byte[5];
+	
+//	System.out.println("addInt: "+value);
+	int tmp = value;
+	int len = 0;
+
+	while( tmp >= 0x80 ) {
+		packed[len] = (byte) ((tmp & 0x7f) | 0x80 ) ;
+		tmp >>>= 7;
+		len++;
+	}
+	packed[len] = (byte) (tmp & 0x7f);
+//	System.out.println("packed: "+packed[len]+ "len = "+len);
+
+	add(java.util.Arrays.copyOf(packed, len+1), comment);
+
+//      byte[] data = new byte[4];
+//      for (int i = 0 ; i < 4 ; i++) {
+//        data[3 - i] = (byte)((value >> (8 * i)) & 0xff);
+//      }
+//      add(data, comment);
     }
 
     public void addString(String value, String comment) {
@@ -196,4 +212,4 @@ aspect Signature {
     return "_";
   }
 
-}
\ No newline at end of file
+}
diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java
index 278c5aa8b293678ac34e6f8d99d1a5ee0322f6d0..c059df247e3822aa78f92b68c5620d3e82de275b 100644
--- a/examples/simple/Decoder.java
+++ b/examples/simple/Decoder.java
@@ -5,7 +5,7 @@ import java.io.InputStream;
 import se.lth.control.labcomm.LabCommDecoderChannel;
 
 public class Decoder
-  implements TwoInts.Handler, IntString.Handler 
+  implements TwoInts.Handler, IntString.Handler, TwoArrays.Handler
 {
 
   LabCommDecoderChannel decoder;
@@ -16,6 +16,7 @@ public class Decoder
     decoder = new LabCommDecoderChannel(in);
     TwoInts.register(decoder, this);
     IntString.register(decoder, this);
+    TwoArrays.register(decoder, this);
 
     try {
       System.out.println("Running decoder.");
@@ -33,6 +34,18 @@ public class Decoder
     System.out.println("Got IntString, x="+d.x+", s="+d.s);
   }
 
+  public void handle_TwoArrays(TwoArrays d) throws java.io.IOException {
+    System.out.println("Got TwoArrays:");
+    for(int i=0; i<d.fixed.length; i++) {
+	System.out.print(d.fixed[i]+" ");
+    }
+    System.out.println();
+    for(int i=0; i<d.variable[0].length; i++) {
+	System.out.print(d.variable[0][i]+" ");
+	System.out.print(d.variable[1][i]+" ");
+    }
+    System.out.println();
+  }
 
   public static void main(String[] arg) throws Exception {
     Decoder example = new Decoder(
diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c
index bfe8430ab604e71a652b499dd8b80f3fe112aa59..9aa6b40ab1317820b1bc1f6233de10917b796522 100644
--- a/examples/simple/example_decoder.c
+++ b/examples/simple/example_decoder.c
@@ -12,6 +12,20 @@ static void handle_simple_IntString(simple_IntString *v,void *context) {
   printf("Got IntString. x=%d, s=%s\n", v->x, v->s);
 }
 
+static void handle_simple_TwoArrays(simple_TwoArrays *d,void *context) {
+  printf("Got TwoArrays:");
+    int i;
+    for(i=0; i<2; i++) {
+        printf("%d ",d->fixed.a[i]);
+    }
+    printf("\n");
+    for(i=0; i<d->variable.n_1; i++) {
+        printf("%d ",d->variable.a[0+2*i]);
+        printf("%d ",d->variable.a[1+2*i]);
+    }
+    printf("\n");
+}
+
 int main(int argc, char *argv[]) {
   int fd;
   struct labcomm_decoder *decoder;
@@ -29,6 +43,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);
 
   printf("Decoding:\n");
   labcomm_decoder_run(decoder);
diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c
index c62058833d8736bb17dd781f7997041dc903f506..70a38c8756e91945d01e6543cf3ad7636e29116f 100644
--- a/examples/simple/example_encoder.c
+++ b/examples/simple/example_encoder.c
@@ -15,6 +15,7 @@ int main(int argc, char *argv[]) {
   encoder = labcomm_encoder_new(labcomm_fd_writer, &fd);
   labcomm_encoder_register_simple_TwoInts(encoder);
   labcomm_encoder_register_simple_IntString(encoder);
+  labcomm_encoder_register_simple_TwoArrays(encoder);
   simple_IntString is;
   is.x = 24;
   is.s = "Hello, LabComm!";
@@ -26,4 +27,27 @@ int main(int argc, char *argv[]) {
   ti.b = 37;
   printf("Encoding TwoInts, a=%d, b=%d\n", ti.a, ti.b);
   labcomm_encode_simple_TwoInts(encoder, &ti);
+
+  int foo[20];
+
+  simple_TwoArrays ta;
+  ta.fixed.a[0] = 17;
+  ta.fixed.a[1] = 42;
+  ta.variable.n_1 = 10;
+  ta.variable.a = foo;
+  
+  int k;
+  for(k=0; k<20; k++) {
+	foo[k] = k;
+  }
+
+  printf("Encoding TwoArrays...\n");
+  labcomm_encode_simple_TwoArrays(encoder, &ta);
+
+  ti.a = 23;
+  ti.b = 47;
+  printf("Encoding TwoInts, a=%d, b=%d\n", ti.a, ti.b);
+  labcomm_encode_simple_TwoInts(encoder, &ti);
+
+
 }
diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc
index 2da6c48ee0842a6206372d6f733745db0b332d4a..2adfb2e44714bd17a0bd2d3ce4a4b53311996081 100644
--- a/examples/simple/simple.lc
+++ b/examples/simple/simple.lc
@@ -12,3 +12,8 @@ sample struct {
   double x;
   double y;
 } TwoDoubles;
+
+sample struct {
+  int fixed[2];
+  int variable[2,_];
+} TwoArrays;
diff --git a/lib/c/experimental/labcomm_parser.c b/lib/c/experimental/labcomm_parser.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa24f48c248505c7271dccf1317ea75be25671f2
--- /dev/null
+++ b/lib/c/experimental/labcomm_parser.c
@@ -0,0 +1,677 @@
+/* labcomm_parser.c:
+ * an example parser for labcomm signatures, illustrating how to skip samples
+ * based on their signature. Intended as an embryo for introducing this 
+ * functionality into the lib to allow a channel to survive types with no
+ * registered handler.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG 
+
+#define FALSE 0
+#define TRUE 1
+
+#define	USER_ID_BASE	0x00000080
+
+typedef enum{
+	TYPE_DECL = 0x00000001,
+	SAMPLE_DECL = 0x00000002,
+
+	ARRAY_DECL = 0x00000010,
+	STRUCT_DECL = 0x00000011,
+
+	TYPE_BOOLEAN  = 0x00000020,
+	TYPE_BYTE  = 0x00000021,
+	TYPE_SHORT  = 0x00000022,
+	TYPE_INTEGER  = 0x00000023,
+	TYPE_LONG  = 0x00000024,
+	TYPE_FLOAT  = 0x00000025,
+	TYPE_DOUBLE  = 0x00000026,
+	TYPE_STRING  = 0x00000027
+} labcomm_type ;
+
+void error(char *s) {
+	fprintf(stderr, "%s", s);
+	fprintf(stderr, "\nexiting\n");
+	exit(1);
+}
+
+#define BUF_SIZE 1024
+#define STACK_SIZE 16
+
+/* internal type: stack for the parser */
+typedef struct {
+	unsigned char* c;
+	unsigned int size;
+	unsigned int capacity;
+	unsigned int idx;
+	unsigned int* stack;
+	unsigned int top;
+} buffer;
+
+/* aux method for reading a big endian uint32 from a char* (i.e. ntohl but for explicit char*) */
+static int unpack32(unsigned char *c, unsigned int idx) {
+	unsigned int b0=(c[idx]) << 3 ; 
+	unsigned int b1=(c[idx+1]) << 2 ;
+	unsigned int b2=(c[idx+2]) << 1 ;
+	unsigned int b3=c[idx+3];
+
+	return  b0 | b1 | b2 | b3;
+}
+
+void dumpStack(buffer *b) {
+#ifdef DEBUG
+	int i;
+	printf("=== stack: ");
+	for(i=0; i<STACK_SIZE; i++) { //HERE BE DRAGONS
+		printf("%2.2x ", b->stack[i]);
+	}
+	printf("    top==%d\n", b->top);
+#endif
+}
+
+void push(buffer *b, unsigned int e) {
+	b->stack[b->top]=e;
+	b->top=b->top-1;
+	dumpStack(b);
+}
+unsigned int pop(buffer *b) {
+	b->top=b->top+1;
+	return b->stack[b->top];
+}
+	
+int init_buffer(buffer *b, size_t size, size_t stacksize) {
+	b->c = malloc(size);
+	b->capacity = size;
+	b->idx = 0;
+
+	b->stack = calloc(stacksize, sizeof(b->stack));
+	b->top = stacksize-1;
+
+	return b->c == NULL || b->stack == NULL;
+}
+
+int more(buffer *b) 
+{
+	return b->idx < b->size;
+}
+
+unsigned char get(buffer *b) {
+	return b->c[b->idx++];
+}
+
+unsigned char peek(buffer *b) {
+	return b->c[b->idx];
+}
+
+void advance(buffer *b) {
+	b->idx++;
+}
+
+void advancen(buffer *b, size_t n) {
+	b->idx+=n;
+}
+
+unsigned int peek32(buffer *b) {
+	return unpack32(b->c, b->idx);
+}
+
+void advance32(buffer *b) {
+	b->idx+=4;
+}
+
+unsigned int get32(buffer *b) {
+	unsigned int res = peek32(b);
+	advance32(b);
+	return res;
+}
+
+void getStr(buffer *b, char *dest, size_t size) {
+	int rem = b->size - b->idx;
+	if( size > rem ) 
+		size = rem;
+	strncpy(dest, &b->c[b->idx], size);
+	b->idx += size;
+}
+
+//XXX experimental
+#define MAX_SIGNATURES 10
+#define MAX_NAME_LEN 32 
+#define MAX_SIG_LEN 128
+unsigned int signatures_length[MAX_SIGNATURES];
+unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN]; //HERE BE DRAGONS: add range checks
+unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN]; 
+
+unsigned int get_signature_len(unsigned int uid){
+	return signatures_length[uid-USER_ID_BASE];
+}
+unsigned char* get_signature_name(unsigned int uid){
+	return &signatures_name[uid-USER_ID_BASE][1];
+}
+unsigned char* get_signature(unsigned int uid){
+	return signatures[uid-USER_ID_BASE];
+}
+
+void dump_signature(unsigned int uid){
+	int i;
+	unsigned int len = get_signature_len(uid);
+	printf("signature for uid %x : %s (len=%d):\n", uid, get_signature_name(uid), len);
+	unsigned char* sig = get_signature(uid);
+	for(i=0; i<len; i++) {
+		printf("%2.2x ",sig[i]);
+		if( (i+1)%8==0 ) printf("\n");
+	}
+	printf("\n");
+}
+
+int labcomm_sizeof(unsigned int type)
+{
+	switch(type) {
+		case TYPE_BOOLEAN :
+		case TYPE_BYTE : 
+			return 1;
+		case TYPE_SHORT : 
+			return 2;
+		case TYPE_INTEGER :
+		case TYPE_FLOAT : 
+			return 4;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			return 8;
+		default:
+			printf("labcomm_sizeof(%x)\n", type);
+		 	error("labcomm_sizeof should only be called for primitive types");
+	}
+}
+
+int accept_packet(buffer *d);
+int accept_type_decl(buffer *d);
+int accept_sample_decl(buffer *d);
+int accept_user_id(buffer *d);
+int accept_string(buffer *d);
+int accept_string_length(buffer *d);
+int accept_char(buffer *d);
+int accept_type(buffer *d);
+int accept_basic_type(buffer *d);
+int accept_boolean_type(buffer *d);
+int accept_byte_type(buffer *d);
+int accept_short_type(buffer *d);
+int accept_integer_type(buffer *d);
+int accept_long_type(buffer *d);
+int accept_float_type(buffer *d);
+int accept_long_type(buffer *d);
+int accept_string_type(buffer *d);
+int accept_array_decl(buffer *d);
+int accept_number_of_indices(buffer *d);
+int accept_indices(buffer *d);
+int accept_variable_index(buffer *d);
+int accept_fixed_index(buffer *d);
+int accept_struct_decl(buffer *d);
+int accept_number_of_fields(buffer *d);
+int accept_field(buffer *d);
+int accept_sample_data(buffer *d);
+int accept_packed_sample_data(buffer *d);
+
+int read_file(FILE *f, buffer *b) {
+	int s = fread(b->c, sizeof(char), b->capacity, f);
+	b->size = s;
+	b->idx=0;
+	return s;
+}
+
+void test_read(buffer *buf) {
+	int r = read_file(stdin, buf);
+	printf("read %d bytes:\n\n", r);
+	int i;
+	for(i=0; i<r; i++) {
+		printf("%x ", buf->c[i]);
+		if(i%8 == 7) printf("\n");
+	}
+	printf("\n");
+}
+int main() {
+	buffer buf;
+
+	if( init_buffer(&buf, BUF_SIZE, STACK_SIZE) ) {
+		printf("failed to init buffer\n");
+		exit(1);
+	}
+	test_read(&buf);
+	do{
+		printf("trying to read another packet\n");
+	} while(more(&buf) && accept_packet(&buf)); 
+	printf("done\n");
+}
+
+	
+int accept_packet(buffer *d) {
+	if(accept_type_decl(d)) {
+		printf("*** got type decl\n");
+	} else if(accept_sample_decl(d)) {
+		printf("*** got sample decl\n");
+	} else if(accept_sample_data(d)) {
+		printf("*** got sample data\n");
+	} else {
+//	error("unexpected %x, expecting packet", d->c[d->idx]); 
+		error("packet");
+	}
+}
+int accept_type_decl(buffer *d){
+	unsigned int type = peek32(d) ;
+	if(type == TYPE_DECL ) {
+		advance32(d);
+		accept_user_id(d);
+		unsigned int uid = pop(d);
+		accept_string(d);
+		// ignore, for now. This should do something as
+		// char *name = (char*) pop(d);
+		// store or print name
+		// free(name)
+		accept_type(d);
+		unsigned int type = pop(d);
+
+		//push(d, type);
+		return TRUE;
+	}else {
+		return FALSE;
+	}
+}
+
+int accept_sample_decl(buffer *d){
+	unsigned int type = peek32(d) ;
+	if (type == SAMPLE_DECL) {
+		advance32(d);
+		accept_user_id(d);
+		unsigned int nstart = d->idx;
+		unsigned int uid = pop(d);
+		accept_string(d);
+		unsigned int start = d->idx;
+		unsigned int nlen = pop(d);
+		accept_type(d);
+		unsigned int dt = pop(d);
+		unsigned int end = d->idx;
+		unsigned int len = end-start;
+		if(len <= MAX_SIG_LEN) {
+			signatures_length[uid-USER_ID_BASE] = len;
+			memcpy(signatures_name[uid-USER_ID_BASE], &d->c[nstart+3], nlen+1);
+		} else {
+			error("sig longer than max length (this ought to be dynamic...)");
+		}
+		if(nlen < MAX_NAME_LEN) { // reserve space for terminating NULL
+			signatures_name[uid-USER_ID_BASE][nlen+1]=0;
+			memcpy(signatures[uid-USER_ID_BASE], &d->c[start], len);
+		} else {
+			error("sig name longer than max length (this ought to be dynamic...");
+		}
+		printf("signature for uid %x: %s (start=%x,end=%x, nlen=%d,len=%d)\n", uid, get_signature_name(uid), start,end, nlen, len);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+int accept_user_id(buffer *d){
+	unsigned int uid = peek32(d);
+	if(uid >= USER_ID_BASE) {
+		push(d, uid);
+		advance32(d);
+		//printf("uid = %x\n", uid);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+int accept_string(buffer *d){
+	unsigned int len = get32(d);
+	push(d, len);
+	char *str=malloc(len);
+	getStr(d, str, len);
+	printf("%s\n", str);
+#ifdef RETURN_STRINGS
+	push(d, str);
+#else
+	free(str);
+#endif
+	return TRUE;
+}
+// included above
+// int accept_string_length(buffer *d){
+//	unsigned int uid = get32(d);
+//	return TRUE;
+//}
+//int accept_char(buffer *d){
+//}
+
+int accept_type(buffer *d){
+	if(accept_basic_type(d)) {
+	} else if(accept_user_id(d)) {
+		//printf("user_id \n");
+	} else if(accept_array_decl(d)) {
+		//printf("array_decl \n");
+	} else if(accept_struct_decl(d)) {
+		//printf("struct_decl \n");
+	} else {	
+		return FALSE;
+	}
+}
+int accept_basic_type(buffer *d){
+	unsigned int type = peek32(d);
+	switch(type) {
+		case TYPE_BOOLEAN :
+			//printf("boolean \n");
+			break;
+		case TYPE_BYTE :
+			//printf("byte \n");
+			break;
+		case TYPE_SHORT :
+			//printf("short \n");
+			break;
+		case TYPE_INTEGER :
+			//printf("integer \n");
+			break;
+		case TYPE_LONG :
+			//printf("long \n");
+			break;
+		case TYPE_FLOAT :
+			//printf("float \n");
+			break;
+		case TYPE_DOUBLE :
+			//printf("double \n");
+			break;
+		case TYPE_STRING :
+			//printf("string \n");
+			break;
+		default :
+			return FALSE;
+	}
+	advance32(d);
+	push(d,type);
+	return TRUE;
+}
+#if 0 // handle all basic types above
+int accept_boolean_type(buffer *d){
+}
+int accept_byte_type(buffer *d){
+}
+int accept_short_type(buffer *d){
+}
+int accept_integer_type(buffer *d){
+}
+int accept_long_type(buffer *d){
+}
+int accept_float_type(buffer *d){
+}
+int accept_string_type(buffer *d){
+}
+#endif
+int accept_array_decl(buffer *d){
+	unsigned int tid = peek32(d);
+	if(tid == ARRAY_DECL) {
+		advance32(d);
+		unsigned int nidx = get32(d);
+		printf("%d dim array: ", nidx);
+		int i;
+		unsigned int numVar=0;
+		unsigned int size=1;
+		for(i=0; i<nidx; i++) {
+			unsigned int idx = get32(d);
+			if(idx == 0) {
+				numVar++;
+				printf("variable index (numVar=%d), ",numVar);
+			} else {
+				printf("fixed index: %d, ", idx);
+				size*=idx;
+			}
+			printf("\n");
+		}
+		unsigned int et=accept_type(d);
+		printf("array element type: %x\n", et);
+		pop(d);
+		//push(d,tid);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+#if 0
+int accept_number_of_indices(buffer *d){
+}
+int accept_indices(buffer *d){
+}
+int accept_variable_index(buffer *d){
+}
+int accept_fixed_index(buffer *d){
+}
+#endif
+int accept_struct_decl(buffer *d){
+	unsigned int tid = peek32(d);
+	if(tid == STRUCT_DECL) {
+		advance32(d);
+		unsigned int nf = get32(d);
+		printf("%d field struct: ", nf);
+		int i;
+		int numVar=0;
+		int size=0;
+		for(i=0; i<nf; i++) {
+			accept_field(d);
+		}
+		push(d,tid);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+#if 0
+int accept_number_of_fields(buffer *d){
+}
+#endif
+int accept_field(buffer *d){
+	accept_string(d);
+	// ignore, for now
+	accept_type(d);
+	unsigned int type = pop(d);
+	printf("field: %x \n", type);
+}
+int accept_sample_data(buffer *d){
+	accept_user_id(d);
+	unsigned int uid = pop(d);	
+	printf("sample data... %x\n", uid);
+#ifdef DEBUG
+	dump_signature(uid);
+#endif
+	unsigned int siglen = get_signature_len(uid);
+	unsigned char *sig = get_signature(uid);
+	skip_packed_sample_data(d, sig, siglen);
+	return TRUE;
+}
+//int accept_packed_sample_data(buffer *d){
+
+int skip_type(unsigned int,buffer*,unsigned char*,unsigned int,unsigned int*) ;
+
+int skip_array(buffer *d, unsigned char *sig, unsigned int len, unsigned int *pos) {
+	unsigned int skip = 0;
+	unsigned int tot_nbr_elem_tmp = 1;
+	unsigned int nIdx = unpack32(sig, *pos);
+	printf("skip_array: nIdx = %d\n", nIdx);
+	*pos +=4;
+	unsigned int idx[nIdx];
+	unsigned int nVar=0;
+
+	unsigned int i;
+
+	for(i=0; i<nIdx; i++) {
+		idx[i] = unpack32(sig, *pos);
+		*pos += 4;
+		printf("skip_array: idx[%d]=%d\n", i, idx[i]);
+		if(idx[i] == 0) {
+			nVar++;
+		} else {
+			tot_nbr_elem_tmp *= idx[i];
+		}
+	}
+	unsigned int var[nVar];
+
+	for(i=0; i<nVar; i++) {
+		var[i] = get32(d);	
+		printf("skip_array: var[%d]=%d\n", i, var[i]);
+	}
+
+	unsigned int type = unpack32(sig, *pos);
+	*pos+=4;
+
+	unsigned int elemSize = labcomm_sizeof(type);
+
+	skip = elemSize * tot_nbr_elem_tmp;
+
+	printf("skip_array: skip: %d * %d = %d\n", elemSize, tot_nbr_elem_tmp, skip);
+	
+	advancen(d, skip);
+
+	skip += nVar;
+
+	return skip;
+}
+
+int skip_struct(buffer *d, unsigned char *sig, unsigned int len, unsigned int *pos) {
+	unsigned int nFields = unpack32(sig,*pos);
+	*pos += 4;
+	unsigned int i;
+	unsigned int skipped=0;
+	printf("skip_struct (%d fields)\n", nFields);
+	for(i=0; i<nFields; i++) {
+		//skip name 
+		unsigned int namelen = unpack32(sig, *pos);
+		*pos += (4+namelen); // 32bit len + actual string
+#ifdef DEBUG
+		printf("namelen==%d \n",namelen);
+#endif
+		unsigned int type = unpack32(sig, *pos);
+		*pos += 4;
+#ifdef DEBUG
+		printf("type == %x\n", type);
+#endif
+		skipped += skip_type(type, d, sig, len, pos);
+	}
+	return skipped;
+}
+#ifndef QUIET
+/* print and skip */
+int skip_type(unsigned int type, buffer *d, 
+		unsigned char *sig, unsigned int len, unsigned int *pos) 
+{
+	int skipped=0;
+	printf("skip_type %x:", type);
+	switch(type) {
+		case TYPE_BOOLEAN :
+			printf("boolean [%d]\n", get(d));
+			skipped++;
+			break;
+		case TYPE_BYTE : 
+			printf("byte [%d]\n", get(d));
+			skipped++;
+			break;
+		case TYPE_SHORT : 
+			//XXX not supported
+			advancen(d,2); 
+			skipped+=2;
+			break;
+		case TYPE_INTEGER :
+			printf("integer [%d]\n", get32(d));
+			skipped +=4;
+			break;
+		case TYPE_FLOAT : 
+			//XXX not supported
+			advancen(d,4); 
+			skipped+=4;
+			break;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			//XXX not supported
+			advancen(d,8); 
+			skipped+=8;
+			break;
+		case TYPE_STRING :
+			{unsigned int len = get32(d);
+			//advancen(d,len);
+			int i;
+			printf("string [");
+			for(i=0; i<len; i++)
+				printf("%c", get(d));
+			printf("]\n");
+			skipped+=len+4;
+			break;}
+		case ARRAY_DECL :
+			printf("array\n");
+			skipped += skip_array(d, sig, len, pos);
+		case STRUCT_DECL :
+			printf("struct\n");
+			skipped += skip_struct(d, sig, len, pos);
+			break;
+		default:
+			printf("ERROR: skip_type: type = %x\n", type);
+			exit(1);
+	}
+	return skipped;
+}
+#else
+int skip_type(unsigned int type, buffer *d, 
+		unsigned char *sig, unsigned int len, unsigned int *pos) 
+{
+	int skipped=0;
+	printf("skip_type %x\n", type);
+	switch(type) {
+		case TYPE_BOOLEAN :
+		case TYPE_BYTE : 
+			advancen(d,1); 
+			skipped++;
+			break;
+		case TYPE_SHORT : 
+			advancen(d,2); 
+			skipped+=2;
+			break;
+		case TYPE_INTEGER :
+		case TYPE_FLOAT : 
+			advancen(d,4); 
+			skipped+=4;
+			break;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			advancen(d,8); 
+			skipped+=8;
+			break;
+		case TYPE_STRING :
+			{unsigned int len = get32(d);
+			advancen(d,len);
+			skipped+=len+4;
+			break;}
+		case ARRAY_DECL :
+			printf("array\n");
+			skipped += skip_array(d, sig, len, pos);
+		case STRUCT_DECL :
+			skipped += skip_struct(d, sig, len, pos);
+			break;
+		default:
+			printf("ERROR: skip_type: type = %x\n", type);
+			exit(1);
+	}
+	return skipped;
+}
+#endif
+
+/* parse signature and skip the corresponding bytes in the buffer 
+ */
+int skip_packed_sample_data(buffer *d, unsigned char *sig, unsigned int siglen) {
+	unsigned int pos = 0; 		//current position in signature
+	unsigned int skipped = 0;	//skipped byte counter
+	while(pos < siglen) {
+		unsigned int type = unpack32(sig,pos);
+		pos+=4;
+		skipped += skip_type(type, d, sig, siglen, &pos);
+	}	
+	printf("skipped %d bytes\n", skipped);
+	return TRUE;
+}
diff --git a/lib/c/experimental/labcomm_sig_parser.c b/lib/c/experimental/labcomm_sig_parser.c
new file mode 100644
index 0000000000000000000000000000000000000000..b56c0be9d8006a07892567e7cf0192703306d1b1
--- /dev/null
+++ b/lib/c/experimental/labcomm_sig_parser.c
@@ -0,0 +1,658 @@
+/* labcomm_parser.c:
+ * an example parser for labcomm signatures, illustrating how to skip samples
+ * based on their signature. Intended as an embryo for introducing this 
+ * functionality into the lib to allow a channel to survive types with no
+ * registered handler.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG 
+#undef DEBUG_STACK
+#undef DEBUG_READ
+
+#undef EXIT_WHEN_RECEIVING_DATA //arrays (at least varsize not working)
+
+#define FALSE 0
+#define TRUE 1
+
+#define	USER_ID_BASE	0x00000080
+
+typedef enum{
+	TYPE_DECL = 0x00000001,
+	SAMPLE_DECL = 0x00000002,
+
+	ARRAY_DECL = 0x00000010,
+	STRUCT_DECL = 0x00000011,
+
+	TYPE_BOOLEAN  = 0x00000020,
+	TYPE_BYTE  = 0x00000021,
+	TYPE_SHORT  = 0x00000022,
+	TYPE_INTEGER  = 0x00000023,
+	TYPE_LONG  = 0x00000024,
+	TYPE_FLOAT  = 0x00000025,
+	TYPE_DOUBLE  = 0x00000026,
+	TYPE_STRING  = 0x00000027
+} labcomm_type ;
+
+void error(char *s) {
+	fprintf(stderr, "%s", s);
+	fprintf(stderr, "\nexiting\n");
+	exit(1);
+}
+
+#define BUF_SIZE 1024
+#define STACK_SIZE 16
+
+/* internal type: stack for the parser */
+typedef struct {
+	unsigned char* c;
+	unsigned int size;
+	unsigned int capacity;
+	unsigned int idx;
+	unsigned int* stack;
+	unsigned int top;
+} buffer;
+
+/* aux method for reading a big endian uint32 from a char* (i.e. ntohl but for explicit char*) */
+static int unpack32(unsigned char *c, unsigned int idx) {
+	unsigned int b0=(c[idx]) << 3 ; 
+	unsigned int b1=(c[idx+1]) << 2 ;
+	unsigned int b2=(c[idx+2]) << 1 ;
+	unsigned int b3=c[idx+3];
+
+	return  b0 | b1 | b2 | b3;
+}
+
+void dumpStack(buffer *b) {
+#ifdef DEBUG_STACK
+	int i;
+	printf("=== stack: ");
+	for(i=0; i<STACK_SIZE; i++) { //HERE BE DRAGONS
+		printf("%2.2x ", b->stack[i]);
+	}
+	printf("    top==%d\n", b->top);
+#endif
+}
+
+void push(buffer *b, unsigned int e) {
+	b->stack[b->top]=e;
+	b->top=b->top-1;
+	dumpStack(b);
+}
+unsigned int pop(buffer *b) {
+	b->top=b->top+1;
+	return b->stack[b->top];
+}
+	
+int init_buffer(buffer *b, size_t size, size_t stacksize) {
+	b->c = malloc(size);
+	b->capacity = size;
+	b->idx = 0;
+
+	b->stack = calloc(stacksize, sizeof(b->stack));
+	b->top = stacksize-1;
+
+	return b->c == NULL || b->stack == NULL;
+}
+
+int more(buffer *b) 
+{
+	return b->idx < b->size;
+}
+
+unsigned char get(buffer *b) {
+	return b->c[b->idx++];
+}
+
+unsigned char peek(buffer *b) {
+	return b->c[b->idx];
+}
+
+void advance(buffer *b) {
+	b->idx++;
+}
+
+void advancen(buffer *b, size_t n) {
+	b->idx+=n;
+}
+
+unsigned int peek32(buffer *b) {
+	return unpack32(b->c, b->idx);
+}
+
+void advance32(buffer *b) {
+	b->idx+=4;
+}
+
+unsigned int get32(buffer *b) {
+	unsigned int res = peek32(b);
+	advance32(b);
+	return res;
+}
+
+void getStr(buffer *b, char *dest, size_t size) {
+	int rem = b->size - b->idx;
+	if( size > rem ) 
+		size = rem;
+	strncpy(dest, &b->c[b->idx], size);
+	b->idx += size;
+}
+
+//XXX experimental
+#define MAX_SIGNATURES 10
+#define MAX_NAME_LEN 32 
+#define MAX_SIG_LEN 128
+unsigned int signatures_length[MAX_SIGNATURES];
+unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN]; //HERE BE DRAGONS: add range checks
+unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN]; 
+
+unsigned int get_signature_len(unsigned int uid){
+	return signatures_length[uid-USER_ID_BASE];
+}
+unsigned char* get_signature_name(unsigned int uid){
+	return &signatures_name[uid-USER_ID_BASE][1];
+}
+unsigned char* get_signature(unsigned int uid){
+	return signatures[uid-USER_ID_BASE];
+}
+
+void dump_signature(unsigned int uid){
+	int i;
+	unsigned int len = get_signature_len(uid);
+	printf("signature for uid %x : %s (len=%d):\n", uid, get_signature_name(uid), len);
+	unsigned char* sig = get_signature(uid);
+	for(i=0; i<len; i++) {
+		printf("%2.2x ",sig[i]);
+		if( (i+1)%8==0 ) printf("\n");
+	}
+	printf("\n");
+}
+
+int labcomm_sizeof(unsigned int type)
+{
+	switch(type) {
+		case TYPE_BOOLEAN :
+		case TYPE_BYTE : 
+			return 1;
+		case TYPE_SHORT : 
+			return 2;
+		case TYPE_INTEGER :
+		case TYPE_FLOAT : 
+			return 4;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			return 8;
+		default:
+			printf("labcomm_sizeof(%x)\n", type);
+		 	error("labcomm_sizeof should only be called for primitive types");
+	}
+}
+
+int accept_packet(buffer *d);
+int accept_type_decl(buffer *d);
+int accept_sample_decl(buffer *d);
+int accept_user_id(buffer *d);
+int accept_string(buffer *d);
+int accept_string_length(buffer *d);
+int accept_char(buffer *d);
+int accept_type(buffer *d);
+int accept_boolean_type(buffer *d);
+int accept_byte_type(buffer *d);
+int accept_short_type(buffer *d);
+int accept_integer_type(buffer *d);
+int accept_long_type(buffer *d);
+int accept_float_type(buffer *d);
+int accept_long_type(buffer *d);
+int accept_string_type(buffer *d);
+int accept_array_decl(buffer *d);
+int accept_number_of_indices(buffer *d);
+int accept_indices(buffer *d);
+int accept_variable_index(buffer *d);
+int accept_fixed_index(buffer *d);
+int accept_struct_decl(buffer *d);
+int accept_number_of_fields(buffer *d);
+int accept_field(buffer *d);
+int accept_sample_data(buffer *d);
+int accept_packed_sample_data(buffer *d);
+
+int do_parse(buffer *d) {
+	unsigned int type = peek32(d) ;
+	if(type == TYPE_DECL ) {
+		advance32(d);
+		accept_user_id(d);
+		unsigned int uid = pop(d);
+		printf(", name = ");
+		accept_string(d);
+		pop(d); // ignore, for now. This should do something as
+		// char *name = (char*) pop(d);
+		// store or print name
+		// free(name)
+		printf(" : ");
+		accept_type(d);
+		unsigned int type = pop(d);
+
+		//push(d, type);
+		printf("\n");
+		return TRUE;
+	} else if (type == SAMPLE_DECL) {
+		advance32(d);
+		printf("sample_decl ");
+		accept_user_id(d);
+		unsigned int nstart = d->idx;
+		unsigned int uid = pop(d);
+		printf(", name = ");
+		accept_string(d);
+		unsigned int start = d->idx;
+		unsigned int nlen = pop(d);
+		accept_type(d);
+		//printf(" : ");
+		//unsigned int dt = pop(d);
+		unsigned int end = d->idx;
+		unsigned int len = end-start;
+
+		if(len <= MAX_SIG_LEN) {
+			signatures_length[uid-USER_ID_BASE] = len;
+			memcpy(signatures[uid-USER_ID_BASE], &d->c[start], len);
+		} else {
+			error("sig longer than max length (this ought to be dynamic...)");
+		}
+
+		if(nlen < MAX_NAME_LEN) { // leave 1 byte for terminating NULL
+			signatures_name[uid-USER_ID_BASE][0] = nlen;
+			memcpy(signatures_name[uid-USER_ID_BASE], &d->c[nstart+3], nlen);
+			signatures_name[uid-USER_ID_BASE][nlen+1]=0;
+		} else {
+			error("sig name longer than max length (this ought to be dynamic...");
+		}
+		//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 {
+#ifdef EXIT_WHEN_RECEIVING_DATA
+		printf("*** got sample data, exiting\n");
+		exit(0);
+#else
+		accept_sample_data(d);
+#endif
+	}
+}
+
+int accept_user_id(buffer *d){
+	unsigned int uid = peek32(d);
+	if(uid >= USER_ID_BASE) {
+		advance32(d);
+		printf("uid = %x ", uid);
+		push(d, uid);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+int accept_string(buffer *d){
+	unsigned int len = get32(d);
+	push(d, len);
+	char *str=malloc(len);
+	getStr(d, str, len);
+	printf("%s", str);
+#ifdef RETURN_STRINGS
+	push(d, str);
+#else
+	free(str);
+#endif
+	return TRUE;
+}
+// included above
+// int accept_string_length(buffer *d){
+//	unsigned int uid = get32(d);
+//	return TRUE;
+//}
+//int accept_char(buffer *d){
+//}
+
+int accept_type(buffer *d){
+	unsigned int type = peek32(d);
+	switch(type) {
+		case TYPE_BOOLEAN :
+			printf("boolean");
+			advance32(d);
+			break;
+		case TYPE_BYTE :
+			printf("byte");
+			advance32(d);
+			break;
+		case TYPE_SHORT :
+			printf("short");
+			advance32(d);
+			break;
+		case TYPE_INTEGER :
+			printf("integer");
+			advance32(d);
+			break;
+		case TYPE_LONG :
+			printf("long");
+			advance32(d);
+			break;
+		case TYPE_FLOAT :
+			printf("float");
+			advance32(d);
+			break;
+		case TYPE_DOUBLE :
+			printf("double");
+			advance32(d);
+			break;
+		case TYPE_STRING :
+			printf("string");
+			advance32(d);
+			break;
+		case ARRAY_DECL :
+			accept_array_decl(d);
+			break;
+		case STRUCT_DECL :
+			accept_struct_decl(d);
+			break;
+		default :
+			printf("accept_basic_type default (type==%x) should not happen\n", type);
+			return FALSE;
+	}
+	//push(d,type);
+	return TRUE;
+}
+
+int accept_array_decl(buffer *d){
+	unsigned int tid = peek32(d);
+	if(tid == ARRAY_DECL) {
+		advance32(d);
+		unsigned int nidx = get32(d);
+		printf("%d dim array", nidx);
+		int i;
+		unsigned int numVar=0;
+		unsigned int size=1;
+		for(i=0; i<nidx; i++) {
+			unsigned int idx = get32(d);
+			if(idx == 0) {
+				numVar++;
+				printf("[_] ");
+			} else {
+				printf("[%d] ", idx);
+				size*=idx;
+			}
+		}
+		printf(" of ");
+		unsigned int et=accept_type(d);
+		//pop(d);
+		//push(d,tid);
+		return TRUE;
+	} else {
+		printf("accept_array_decl: type=%x, should not happen\n",tid);
+		return FALSE;
+	}
+}
+int accept_struct_decl(buffer *d){
+	unsigned int tid = peek32(d);
+	if(tid == STRUCT_DECL) {
+		advance32(d);
+		unsigned int nf = get32(d);
+		printf(", %d field struct:\n", nf);
+		int i;
+		int numVar=0;
+		int size=0;
+		for(i=0; i<nf; i++) {
+			printf("\t");
+			accept_field(d);
+		}
+//		push(d,tid);
+		return TRUE;
+	} else {
+		printf("accept_struct_decl: type=%x, should not happen\n",tid);
+		return FALSE;
+	}
+}
+int accept_field(buffer *d){
+	printf("field ");
+	accept_string(d);
+	pop(d); // ignore, for now
+	printf(" : ");
+	accept_type(d);
+	printf("\n");
+}
+int accept_sample_data(buffer *d){
+	accept_user_id(d);
+	unsigned int uid = pop(d);	
+	printf("sample data... %x\n", uid);
+#ifdef DEBUG
+	dump_signature(uid);
+#endif
+	unsigned int siglen = get_signature_len(uid);
+	unsigned char *sig = get_signature(uid);
+	skip_packed_sample_data(d, sig, siglen);
+	return TRUE;
+}
+//int accept_packed_sample_data(buffer *d){
+
+int skip_type(unsigned int,buffer*,unsigned char*,unsigned int,unsigned int*) ;
+
+int skip_array(buffer *d, unsigned char *sig, unsigned int len, unsigned int *pos) {
+	unsigned int skip = 0;
+	unsigned int tot_nbr_elem_tmp = 1;
+	unsigned int nIdx = unpack32(sig, *pos);
+	printf("skip_array: nIdx = %d (from sig)\n", nIdx);
+	*pos +=4;
+	unsigned int idx[nIdx];
+	unsigned int nVar=0;
+
+	unsigned int i;
+
+	for(i=0; i<nIdx; i++) {
+		idx[i] = unpack32(sig, *pos);
+		*pos += 4;
+		printf("skip_array: idx[%d]=%d (from sig)\n", i, idx[i]);
+		if(idx[i] == 0) {
+			nVar++;
+		} else {
+			tot_nbr_elem_tmp *= idx[i];
+		}
+	}
+	unsigned int var[nVar];
+
+	for(i=0; i<nVar; i++) {
+		var[i] = get32(d);	
+		printf("skip_array: var[%d]=%d (from sample)\n", i, var[i]);
+		tot_nbr_elem_tmp *= var[i];
+	}
+
+	unsigned int type = unpack32(sig, *pos);
+	*pos+=4;
+
+	unsigned int elemSize = labcomm_sizeof(type);
+
+	skip = elemSize * tot_nbr_elem_tmp;
+
+	printf("skip_array: skip: %d * %d = %d\n", tot_nbr_elem_tmp, elemSize ,skip);
+	
+	advancen(d, skip);
+
+	return skip + 4*nVar;
+}
+
+int skip_struct(buffer *d, unsigned char *sig, unsigned int len, unsigned int *pos) {
+	unsigned int nFields = unpack32(sig,*pos);
+	*pos += 4;
+	unsigned int i;
+	unsigned int skipped=0;
+	printf("skip_struct (%d fields)\n", nFields);
+	for(i=0; i<nFields; i++) {
+		//skip name 
+		unsigned int namelen = unpack32(sig, *pos);
+#ifdef DEBUG
+		printf("namelen==%d",namelen);
+		char name[namelen+1];
+		name[namelen]=0;
+		strncpy(name, sig+*pos+4, namelen);
+		printf(", name = %s",name);
+#endif
+		*pos += (4+namelen); // 32bit len + actual string
+
+		unsigned int type = unpack32(sig, *pos);
+		*pos += 4;
+#ifdef DEBUG
+		printf(": type == %x\n", type);
+#endif
+		skipped += skip_type(type, d, sig, len, pos);
+	}
+	return skipped;
+}
+#ifndef QUIET
+/* print and skip */
+int skip_type(unsigned int type, buffer *d, 
+		unsigned char *sig, unsigned int len, unsigned int *pos) 
+{
+	int skipped=0;
+	printf("skip_type %x:", type);
+	switch(type) {
+		case TYPE_BOOLEAN :
+			printf("boolean [%d]\n", get(d));
+			skipped++;
+			break;
+		case TYPE_BYTE : 
+			printf("byte [%d]\n", get(d));
+			skipped++;
+			break;
+		case TYPE_SHORT : 
+			//XXX not supported
+			advancen(d,2); 
+			skipped+=2;
+			break;
+		case TYPE_INTEGER :
+			printf("integer [%d]\n", get32(d));
+			skipped +=4;
+			break;
+		case TYPE_FLOAT : 
+			//XXX not supported
+			advancen(d,4); 
+			skipped+=4;
+			break;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			//XXX not supported
+			advancen(d,8); 
+			skipped+=8;
+			break;
+		case TYPE_STRING :
+			{unsigned int len = get32(d);
+			//advancen(d,len);
+			int i;
+			printf("string [");
+			for(i=0; i<len; i++)
+				printf("%c", get(d));
+			printf("]\n");
+			skipped+=len+4;
+			break;}
+		case ARRAY_DECL :
+			printf("array\n");
+			skipped += skip_array(d, sig, len, pos);
+			break;
+		case STRUCT_DECL :
+			printf("struct\n");
+			skipped += skip_struct(d, sig, len, pos);
+			break;
+		default:
+			printf("ERROR: skip_type: type = %x\n", type);
+			exit(1);
+	}
+	return skipped;
+}
+#else
+int skip_type(unsigned int type, buffer *d, 
+		unsigned char *sig, unsigned int len, unsigned int *pos) 
+{
+	int skipped=0;
+	printf("skip_type %x\n", type);
+	switch(type) {
+		case TYPE_BOOLEAN :
+		case TYPE_BYTE : 
+			advancen(d,1); 
+			skipped++;
+			break;
+		case TYPE_SHORT : 
+			advancen(d,2); 
+			skipped+=2;
+			break;
+		case TYPE_INTEGER :
+		case TYPE_FLOAT : 
+			advancen(d,4); 
+			skipped+=4;
+			break;
+		case TYPE_LONG :
+		case TYPE_DOUBLE : 
+			advancen(d,8); 
+			skipped+=8;
+			break;
+		case TYPE_STRING :
+			{unsigned int len = get32(d);
+			advancen(d,len);
+			skipped+=len+4;
+			break;}
+		case ARRAY_DECL :
+			skipped += skip_array(d, sig, len, pos);
+			break;
+		case STRUCT_DECL :
+			skipped += skip_struct(d, sig, len, pos);
+			break;
+		default:
+			printf("ERROR: skip_type: type = %x\n", type);
+			exit(1);
+	}
+	return skipped;
+}
+#endif
+
+/* parse signature and skip the corresponding bytes in the buffer 
+ */
+int skip_packed_sample_data(buffer *d, unsigned char *sig, unsigned int siglen) {
+	unsigned int pos = 0; 		//current position in signature
+	unsigned int skipped = 0;	//skipped byte counter
+	while(pos < siglen) {
+		unsigned int type = unpack32(sig,pos);
+		pos+=4;
+		skipped += skip_type(type, d, sig, siglen, &pos);
+	}	
+	printf("skipped %d bytes\n", skipped);
+	return TRUE;
+}
+
+int read_file(FILE *f, buffer *b) {
+	int s = fread(b->c, sizeof(char), b->capacity, f);
+	b->size = s;
+	b->idx=0;
+	return s;
+}
+
+void test_read(buffer *buf) {
+	int r = read_file(stdin, buf);
+#ifdef DEBUG_READ
+	printf("read %d bytes:\n\n", r);
+	int i;
+	for(i=0; i<r; i++) {
+		printf("%x ", buf->c[i]);
+		if(i%8 == 7) printf("\n");
+	}
+	printf("\n");
+#endif
+}
+int main() {
+	buffer buf;
+
+	if( init_buffer(&buf, BUF_SIZE, STACK_SIZE) ) {
+		printf("failed to init buffer\n");
+		exit(1);
+	}
+	test_read(&buf);
+	do{
+		printf("------------\n");
+	} while(more(&buf) && do_parse(&buf)); 
+	printf("done\n");
+}
+
+	
diff --git a/lib/c/experimental/pack.c b/lib/c/experimental/pack.c
new file mode 100644
index 0000000000000000000000000000000000000000..06636e399bbb1b036aa4f26c5d6b41425f7cf314
--- /dev/null
+++ b/lib/c/experimental/pack.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+
+typedef unsigned int number;
+
+unsigned char do_pack(unsigned char *buf, number i) 
+{
+	printf("do_pack %lu == %lx\n", i, i);
+
+	number tmp = i;
+	unsigned char res = 0;
+
+	while ( tmp >= 0x80 ) {
+		buf[res] = (tmp & 0x7f) | 0x80;
+	        tmp >>= 7;
+		res++;
+	}
+	buf[res] = tmp;
+	return res+1;
+}
+
+number do_unpack(unsigned char *buf) 
+{
+	number res=0;
+	unsigned char i=0;
+	unsigned char cont=1;
+	do {
+		unsigned char c = buf[i];
+		res |= (c & 0x7f) << 7*i; 
+		cont = c & 0x80;
+		i++;
+	} while(cont);
+
+	return res;
+}
+
+void print_packed(unsigned char *buf, unsigned char len)
+{
+	int i;
+	
+	for(i=0; i<len;i++) {
+		printf("%2x   ", buf[i]);
+	}
+	printf("\n");
+}
+
+int main()
+{
+	unsigned char buf[10];
+	unsigned char len;
+
+	len = do_pack(buf, 10);
+	print_packed(buf, len);
+	printf("... unpacks to %u\n\n", do_unpack(buf));
+
+	len = do_pack(buf, 100);
+	print_packed(buf, len);
+	printf("... unpacks to %u\n\n", do_unpack(buf));
+
+	len = do_pack(buf, 1000);
+	print_packed(buf, len);
+	printf("... unpacks to %u\n\n", do_unpack(buf));
+
+	len = do_pack(buf, 100000);
+	print_packed(buf, len);
+	printf("... unpacks to %u\n\n", do_unpack(buf));
+
+	len = do_pack(buf, 2345678901);
+	print_packed(buf, len);
+	printf("... unpacks to %u\n\n", do_unpack(buf));
+
+	len = do_pack(buf, 0xffffffff);
+	print_packed(buf, len);
+	printf("... unpacks to %lx\n", do_unpack(buf));
+
+	return 0;
+}
diff --git a/lib/c/experimental/throttlenet/throttlenet.lc b/lib/c/experimental/throttlenet/throttlenet.lc
new file mode 100644
index 0000000000000000000000000000000000000000..e747d074120dabb29379b8e5d734a939df8d2923
--- /dev/null
+++ b/lib/c/experimental/throttlenet/throttlenet.lc
@@ -0,0 +1,75 @@
+typedef long number_t; // placeholder for protocol buffers like encoding
+typedef byte eth_addr[6];
+
+// *** Service registration,  lookup, and channel allocation
+
+typedef struct { 
+	string creatorId;
+	string svcId;
+	int version;		//unique
+	string versionName;	//human readable
+} serviceID; // Should probably be a PalCom[_]like struct
+
+typedef struct {
+	string key;
+	byte value[_];
+} property_t; // used for type info, grounding, etc.
+
+typedef struct {
+	string name;
+	property_t properties[_];
+} param_t;
+
+typedef struct {
+	string name;
+	property_t properties[_];
+	param_t params[_];
+} command_t;
+
+typedef struct {
+	serviceID svcID;
+	string   name;
+        command_t commands[_];
+	byte data_description[_];
+} serviceDescription; // d:o PalCom
+
+typedef struct {
+	eth_addr device; // or more generic, as in PalCom?
+	serviceID svcID;
+	number_t  instanceID;
+	string instance_name;
+} service_instance;
+
+sample struct {
+	service_instance svc;
+	number_t chnID;   // the channel to use for connecting to the service
+} service_register;
+
+sample boolean ack;
+
+sample struct {
+	short dummy;
+} services_query;
+
+sample struct {
+	service_instance svcs[_];
+} services_list;
+
+sample struct {
+	service_instance svc;
+	number_t bytes_per_period;
+	number_t period_time; //microseconds
+	// importance?
+} service_allocate_channel; // client [_]> GlobeThrottle to request connection
+
+sample struct {
+	number_t chnId;
+	eth_addr remote_device;	
+	number_t remote_chnId; 
+} service_channel_open; // sent as response to service_allocate_channel (sent to both sides)
+
+sample struct {
+	short max_utilization; // in percent
+	// min period?
+} service_channel_NACK;
+
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 76324dad45aa9b27d2fbafac51d704efaf510062..ac8cf561b5df02c2b9003b763d03ac5a36d805f8 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -199,7 +199,7 @@ static void do_encoder_register(struct labcomm_encoder *e,
       context->sample = sample;
 
       e->writer.write(&e->writer, labcomm_writer_start);
-      labcomm_encode_int(e, signature->type);
+      labcomm_encode_packed32(e, signature->type);
       labcomm_encode_type_index(e, signature);
       labcomm_encode_string(e, signature->name);
       for (i = 0 ; i < signature->size ; i++) {
@@ -309,7 +309,7 @@ void labcomm_encoder_free(labcomm_encoder_t* e)
 void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s)
 {
   int index = get_encoder_index(e, s);
-  labcomm_encode_int(e, index);
+  labcomm_encode_packed32(e, index);
 }
 
 static int signature_writer(
@@ -354,27 +354,33 @@ static void collect_flat_signature(
   labcomm_decoder_t *decoder,
   labcomm_encoder_t *signature_writer)
 {
-  int type = labcomm_decode_int(decoder);
+  //int type = labcomm_decode_int(decoder); 
+  int type = labcomm_decode_packed32(decoder); 
+//  printf("%s: type=%x\n", __FUNCTION__, type);
   if (type >= LABCOMM_USER) {
-    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 2, "Implement %s\n", __FUNCTION__);
+    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
   } else {
-    labcomm_encode_int(signature_writer, type);
+    //labcomm_encode_int(signature_writer, type); 
+    labcomm_encode_packed32(signature_writer, type); 
     switch (type) {
       case LABCOMM_ARRAY: {
 	int dimensions, i;
 
-	dimensions = labcomm_decode_int(decoder);
-	labcomm_encode_int(signature_writer, dimensions);
+	dimensions = labcomm_decode_packed32(decoder); //labcomm_decode_int(decoder); //unpack32
+	labcomm_encode_packed32(signature_writer, dimensions); //pack32
 	for (i = 0 ; i < dimensions ; i++) {
-	  int n = labcomm_decode_int(decoder);
-	  labcomm_encode_int(signature_writer, n);
+	  int n = labcomm_decode_packed32(decoder); //labcomm_decode_int(decoder);
+	  labcomm_encode_packed32(signature_writer, n); // labcomm_encode_int(signature_writer, n);
 	}
 	collect_flat_signature(decoder, signature_writer);
       } break;
       case LABCOMM_STRUCT: {
 	int fields, i;
-	fields = labcomm_decode_int(decoder);
-	labcomm_encode_int(signature_writer, fields);
+	//fields = labcomm_decode_int(decoder); 
+	//labcomm_encode_int(signature_writer, fields); 
+	fields = labcomm_decode_packed32(decoder); 
+	labcomm_encode_packed32(signature_writer, fields); 
 	for (i = 0 ; i < fields ; i++) {
 	  char *name = labcomm_decode_string(decoder);
 	  labcomm_encode_string(signature_writer, name);
@@ -392,7 +398,8 @@ static void collect_flat_signature(
       case LABCOMM_STRING: {
       } break;
       default: {
-        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 2, "Implement %s\n", __FUNCTION__);
+        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
       } break;
     }
   }
@@ -431,7 +438,9 @@ static int do_decode_one(labcomm_decoder_t *d)
     if (result > 0) {
       labcomm_decoder_context_t *context = d->context;
 
-      result = labcomm_decode_int(d);
+//      printf("do_decode_one: result = %x\n", result);
+      result = labcomm_decode_packed32(d);
+//      printf("do_decode_one: result(2) = %x\n", result);
       if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) {
 	labcomm_encoder_t *e = labcomm_encoder_new(signature_writer, 0);
 	labcomm_signature_t signature;
@@ -440,8 +449,9 @@ static int do_decode_one(labcomm_decoder_t *d)
 
 	e->writer.write(&e->writer, labcomm_writer_start);
 	signature.type = result;
-	index = labcomm_decode_int(d);
+	index = labcomm_decode_packed32(d); //int
 	signature.name = labcomm_decode_string(d);
+//	printf("do_decode_one: result = %x, index = %x, name=%s\n", result, index, signature.name);
 	collect_flat_signature(d, e);
 	signature.size = e->writer.pos;
 	signature.signature = e->writer.data;
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index bd5dcfa237f178921a1705ae40cbb9a73ce9aa81..57239ff07134227aa24b5b09f6430e118cf4f0f7 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -39,7 +39,7 @@
 /*
  * Start index for user defined types
  */
-#define LABCOMM_USER     0x80
+#define LABCOMM_USER     0x60
 
 /*
  * Semi private decoder declarations
@@ -120,12 +120,45 @@ LABCOMM_DECODE(int, int)
 LABCOMM_DECODE(long, long long)
 LABCOMM_DECODE(float, float)
 LABCOMM_DECODE(double, double)
+
+static inline unsigned int labcomm_unpack32(labcomm_reader_t *r)
+{
+  unsigned int res=0;
+  unsigned char i=0;
+  unsigned char cont=1;
+  do {
+    if (r->pos >= r->count) {	
+      r->read(r, labcomm_reader_continue);
+    }
+#ifdef IDIOTDEBUG
+    {
+	int k;
+	for(k=0; k<=r->pos; k++) printf("%2x\n", r->data[k]);
+    }
+#endif
+    unsigned char c = r->data[r->pos];
+    res |= (c & 0x7f) << 7*i;
+    cont = c & 0x80;
+#ifdef IDIOTDEBUG
+    printf("unpack32: %x (%x, %d, %d)\n", res, c, i, cont);
+#endif
+    i++;
+    r->pos++;
+  } while(cont);
+  return res;
+}
+
+static inline unsigned int labcomm_decode_packed32(labcomm_decoder_t *d) 
+{
+    return labcomm_unpack32(&d->reader);
+}
+
 static inline char *labcomm_read_string(labcomm_reader_t *r)
 {
   char *result;
   int length, i; 
   
-  length = labcomm_read_int(r);
+  length = labcomm_unpack32(r);
   result = malloc(length + 1);
   for (i = 0 ; i < length ; i++) {
     if (r->pos >= r->count) {	
@@ -247,12 +280,43 @@ LABCOMM_ENCODE(int, int)
 LABCOMM_ENCODE(long, long long)
 LABCOMM_ENCODE(float, float)
 LABCOMM_ENCODE(double, double)
+
+/* 
+ * Pack the 32 bit number data as a sequence of 7 bit chunks, represented in bytes 
+ * with the high bit meaning that more data is to come.
+ *
+ * The chunks are sent "little endian": each 7 bit chunk is more significant than
+ * the previous.
+ */ 
+static inline void labcomm_pack32(labcomm_writer_t *w, unsigned int data)
+{
+  unsigned int tmp, i; 
+
+  tmp = data;
+
+  while (tmp >= 0x80) {
+    if (w->pos >= w->count) {	
+      w->write(w, labcomm_writer_continue);
+    }
+    w->data[w->pos] = (tmp & 0x7f) | 0x80;
+    w->pos++;
+    tmp >>= 7;
+  } 
+  w->data[w->pos] = tmp; 
+  w->pos++;
+}
+
+static inline void labcomm_encode_packed32(labcomm_encoder_t *e, unsigned int data) 
+{ 
+    labcomm_pack32(&e->writer, data);				
+}
+
 static inline void labcomm_write_string(labcomm_writer_t *w, char *s)
 {
   int length, i; 
 
   length = strlen((char*)s);
-  labcomm_write_int(w, length);
+  labcomm_pack32(w, length);
   for (i = 0 ; i < length ; i++) {
     if (w->pos >= w->count) {	
       w->write(w, labcomm_writer_continue);
diff --git a/lib/csharp/se/lth/control/labcomm/LabComm.cs b/lib/csharp/se/lth/control/labcomm/LabComm.cs
index 2354b50ea6ae9e52300869dacaaff376362dc16c..d37db36d05850c7bbdfe1d236306d1c93f530ee5 100644
--- a/lib/csharp/se/lth/control/labcomm/LabComm.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabComm.cs
@@ -25,7 +25,7 @@ namespace se.lth.control.labcomm {
     /*
      * start of user defined types 
      */
-    public const int FIRST_USER_INDEX = 0x80;
+    public const int FIRST_USER_INDEX = 0x60;
 
   }
 
diff --git a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
index 3255371840e1bd77bef2c83ffa084321a778bec1..08b365c457f6c9900a02185e30f73db3faa19da1 100644
--- a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs
@@ -18,11 +18,11 @@ namespace se.lth.control.labcomm {
     public void runOne() {
       bool done = false;
       while (!done) {
-	int tag = decodeInt();
+	int tag = decodePacked32();
 	switch (tag) {
 	case LabComm.TYPEDEF:
         case LabComm.SAMPLE: {
-          int index = decodeInt();
+          int index = decodePacked32();
           String name = decodeString();
 	  MemoryStream signature = new MemoryStream();
 	  collectFlatSignature(new LabCommEncoderChannel(signature));
@@ -55,19 +55,19 @@ namespace se.lth.control.labcomm {
     }
 
     private void collectFlatSignature(LabCommEncoder e) {
-      int type = decodeInt();
-      e.encodeInt(type);
+      int type = decodePacked32();
+      e.encodePacked32(type);
       switch (type) {
       case LabComm.ARRAY: {
-        int dimensions = decodeInt();
-        e.encodeInt(dimensions);
+        int dimensions = decodePacked32();
+        e.encodePacked32(dimensions);
         for (int i = 0 ; i < dimensions ; i++) {
-          e.encodeInt(decodeInt());
+          e.encodePacked32(decodePacked32());
         }
         collectFlatSignature(e);
       } break;
       case LabComm.STRUCT: {
-        int fields = decodeInt();
+        int fields = decodePacked32();
         e.encodeInt(fields);
         for (int i = 0 ; i < fields ; i++) {
           e.encodeString(decodeString());
@@ -155,12 +155,26 @@ namespace se.lth.control.labcomm {
     }
 
     public String decodeString() {
-      int length = (int)ReadInt(4);
+      //int length = (int)ReadInt(4);
+      int length = decodePacked32();
       byte[] buf = new byte[length];
       ReadBytes(buf, length);
       return Encoding.UTF8.GetString(buf);
     }
 
-  }
+    public int decodePacked32() {
+      Int64 res = 0;
+      byte i = 0;
+      bool cont = true; 
+
+      do {
+        byte c = decodeByte();
+	res |= (uint) ((c & 0x7f) << 7*i);
+        cont = (c & 0x80) != 0;
+        i++;
+      } while(cont);
 
+      return (int) (res & 0xffffffff);
+    }
+  }
 } 
diff --git a/lib/csharp/se/lth/control/labcomm/LabCommEncoder.cs b/lib/csharp/se/lth/control/labcomm/LabCommEncoder.cs
index 87008c80243a26c318734c8050c9b0d8895f1135..1ddadd260ec2abfdf2dd69ae2b14d9376d1ddc79 100644
--- a/lib/csharp/se/lth/control/labcomm/LabCommEncoder.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabCommEncoder.cs
@@ -15,6 +15,7 @@ namespace se.lth.control.labcomm {
     void encodeFloat(float value);
     void encodeDouble(double value);
     void encodeString(String value);
+    void encodePacked32(Int64 value);
     
   }
 
diff --git a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
index 27cc8cbb650bf960bd919f40527168b1f64ae705..73ee9047b49569f37f81355d2a4c619aac719023 100644
--- a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs
@@ -18,8 +18,8 @@ namespace se.lth.control.labcomm {
 
     public void register(LabCommDispatcher dispatcher) {
       int index = registry.add(dispatcher);
-      encodeInt(LabComm.SAMPLE);
-      encodeInt(index);
+      encodePacked32(LabComm.SAMPLE);
+      encodePacked32(index);
       encodeString(dispatcher.getName());
       byte[] signature = dispatcher.getSignature();
       for (int i = 0 ; i < signature.Length ; i++) {
@@ -29,7 +29,7 @@ namespace se.lth.control.labcomm {
     }
 
     public void begin(Type c) {
-      encodeInt(registry.getTag(c));
+      encodePacked32(registry.getTag(c));
     }
 
     public void end(Type c) {
@@ -84,9 +84,18 @@ namespace se.lth.control.labcomm {
 
     public void encodeString(String value) {
       byte[] buf = Encoding.UTF8.GetBytes(value);
-      WriteInt(buf.Length, 4);
+      encodePacked32(buf.Length);
       bytes.Write(buf, 0, buf.Length);
     }
 
+    public void encodePacked32(Int64 value) {
+      Int64 tmp = value;
+
+      while(tmp >= 0x80) {
+        encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) );
+        tmp >>= 7;           
+      }
+      encodeByte( (byte) (tmp & 0x7f) );
+    }
   }
-}
\ No newline at end of file
+}
diff --git a/lib/java/se/lth/control/labcomm/LabComm.java b/lib/java/se/lth/control/labcomm/LabComm.java
index bb69df857a2028efe7c5b906e8fc58d835fa80be..7a82e76657809760a1485f9589adfc8316a33e5b 100644
--- a/lib/java/se/lth/control/labcomm/LabComm.java
+++ b/lib/java/se/lth/control/labcomm/LabComm.java
@@ -25,6 +25,6 @@ public class LabComm {
   /*
    * Start of 
    */
-  public static final int FIRST_USER_INDEX = 0x80;
+  public static final int FIRST_USER_INDEX = 0x60;
 
-}
\ No newline at end of file
+}
diff --git a/lib/java/se/lth/control/labcomm/LabCommDecoder.java b/lib/java/se/lth/control/labcomm/LabCommDecoder.java
index e8f6b8f1e8c36e567fedda50d61be210ca31e86a..a40fb8531f43c8b064835ca2de4b904325b838ca 100644
--- a/lib/java/se/lth/control/labcomm/LabCommDecoder.java
+++ b/lib/java/se/lth/control/labcomm/LabCommDecoder.java
@@ -14,5 +14,6 @@ public interface LabCommDecoder {
   public float decodeFloat() throws IOException;
   public double decodeDouble() throws IOException;
   public String decodeString() throws IOException;
+  public int decodePacked32() throws IOException;
 
-}
\ No newline at end of file
+}
diff --git a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
index 4096d47abd9245a142d3c3391c2831418d50f386..d783bd32048a948f275015de91cbee7ff3c2fc57 100644
--- a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java
@@ -18,11 +18,11 @@ public class LabCommDecoderChannel implements LabCommDecoder {
   public void runOne() throws Exception {
     boolean done = false;
     while (!done) {
-      int tag = decodeInt();
+      int tag = decodePacked32();
       switch (tag) {
 	case LabComm.TYPEDEF:
 	case LabComm.SAMPLE: {
-	  int index = decodeInt();
+	  int index = decodePacked32();
 	  String name = decodeString();
 	  ByteArrayOutputStream signature = new ByteArrayOutputStream();
 	  collectFlatSignature(new LabCommEncoderChannel(signature));
@@ -55,20 +55,20 @@ public class LabCommDecoderChannel implements LabCommDecoder {
   }
 
   private void collectFlatSignature(LabCommEncoder out) throws IOException {
-    int type = decodeInt();
-    out.encodeInt(type);
+    int type = decodePacked32();
+    out.encodePacked32(type);
     switch (type) {
       case LabComm.ARRAY: {
-	int dimensions = decodeInt();
-	out.encodeInt(dimensions);
+	int dimensions = decodePacked32();
+	out.encodePacked32(dimensions);
 	for (int i = 0 ; i < dimensions ; i++) {
-	  out.encodeInt(decodeInt());
+	  out.encodePacked32(decodePacked32());
 	}
 	collectFlatSignature(out);
       } break;
       case LabComm.STRUCT: {
-	int fields = decodeInt();
-	out.encodeInt(fields);
+	int fields = decodePacked32();
+	out.encodePacked32(fields);
 	for (int i = 0 ; i < fields ; i++) {
 	  out.encodeString(decodeString());
 	  collectFlatSignature(out);
@@ -124,9 +124,29 @@ public class LabCommDecoderChannel implements LabCommDecoder {
   }
 
   public String decodeString() throws IOException {
-    in.readShort(); // HACK
-    return in.readUTF();
+    //in.readShort(); // HACK
+    //return in.readUTF();
+    int len = decodePacked32() & 0xffffffff;
+    byte[] chars = new byte[len];
+    for(int i=0; i<len; i++) {
+      chars[i] = in.readByte();
+    }
+    return new String(chars);
   }
 
+  public int decodePacked32() throws IOException {
+    long res=0;
+    byte i=0;
+    boolean cont=true;
+
+    do {
+      byte c = in.readByte();
+      res |= (c & 0x7f) << 7*i;
+      cont = (c & 0x80) != 0;
+      i++;
+    } while(cont);
+
+    return (int) (res & 0xffffffff);
+  }
 }
 
diff --git a/lib/java/se/lth/control/labcomm/LabCommEncoder.java b/lib/java/se/lth/control/labcomm/LabCommEncoder.java
index 66584db4f6379db4d713d8e020dd348105b79861..f332d78784cf6281befe30a1eb099fdaea7c175c 100644
--- a/lib/java/se/lth/control/labcomm/LabCommEncoder.java
+++ b/lib/java/se/lth/control/labcomm/LabCommEncoder.java
@@ -15,5 +15,6 @@ public interface LabCommEncoder {
   public void encodeFloat(float value) throws IOException;
   public void encodeDouble(double value) throws IOException;
   public void encodeString(String value) throws IOException;
+  public void encodePacked32(long value) throws IOException;
 
-}
\ No newline at end of file
+}
diff --git a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
index b339c9f44d9250366ebc0b9efc0ab5f3731d76ec..cbb4bd78311755119c78519ef27fe698105e9435 100644
--- a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java
@@ -21,8 +21,8 @@ public class LabCommEncoderChannel implements LabCommEncoder {
 
   public void register(LabCommDispatcher dispatcher) throws IOException {
     int index = registry.add(dispatcher);
-    encodeInt(LabComm.SAMPLE);
-    encodeInt(index);
+    encodePacked32(LabComm.SAMPLE);
+    encodePacked32(index);
     encodeString(dispatcher.getName());
     byte[] signature = dispatcher.getSignature();
     for (int i = 0 ; i < signature.length ; i++) {
@@ -32,7 +32,7 @@ public class LabCommEncoderChannel implements LabCommEncoder {
   }
 
   public void begin(Class<? extends LabCommSample> c) throws IOException {
-    encodeInt(registry.getTag(c));
+    encodePacked32(registry.getTag(c));
   }
 
   public void end(Class<? extends LabCommSample> c) throws IOException {
@@ -70,9 +70,31 @@ public class LabCommEncoderChannel implements LabCommEncoder {
   }
 
   public void encodeString(String value) throws IOException {
-    data.writeShort(0); // HACK...
-    data.writeUTF(value);
+    //data.writeShort(0); // HACK...
+    //data.writeUTF(value);
+
+    //kludge, to replace above hack with packed length
+    ByteArrayOutputStream tmpb = new ByteArrayOutputStream();
+    DataOutputStream tmps = new DataOutputStream(tmpb);
+
+    tmps.writeUTF(value);
+    tmps.flush();
+    byte[] tmp = tmpb.toByteArray();
+  
+    encodePacked32(tmp.length-2);
+    for (int i = 2 ; i < tmp.length ; i++) {
+      encodeByte(tmp[i]);
+    }
   }
 
+  public void encodePacked32(long value) throws IOException {
+    long tmp = value;
+
+    while( tmp >= 0x80 ) {
+      encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) );
+      tmp >>>= 7;
+    }
+    encodeByte( (byte) (tmp & 0x7f) );
+  }
 }
 
diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py
index dada9ecd55218129d3a44c79a35c8a2fd365cd9c..24a757c0ddc28985bea0dc689eb16181f0a2fbef 100644
--- a/lib/python/labcomm/LabComm.py
+++ b/lib/python/labcomm/LabComm.py
@@ -44,7 +44,7 @@
 # User data:
 #
 #   +----+----+----+----+
-#   | id >= 0x00000080  |
+#   | id >= 0x00000060  |
 #   +----+----+----+----+
 #   | user data
 #   | ...
@@ -89,6 +89,12 @@
 #??  +----+----+----+----+
 #  
 #   
+# type numbers and lengths do not have a fixed lenght, but are packed into sequences 
+# of 7 bit chunks, represented in bytes with the high bit meaning that more data 
+# is to come.
+#
+# The chunks are sent "little endian": each 7 bit chunk is more significant than
+# the previous. See encode_packed32 and decode_packed32 in in Codec classes below.
 
 import struct as packer
 
@@ -107,7 +113,7 @@ i_FLOAT   = 0x25
 i_DOUBLE  = 0x26
 i_STRING  = 0x27
 
-i_USER    = 0x80
+i_USER    = 0x60
 
 def indent(i, s):
     return ("\n%s" % (" " * i)).join(s.split("\n"))
@@ -306,9 +312,9 @@ class array(object):
         
     def encode_decl(self, encoder):
         encoder.encode_type(i_ARRAY)
-        encoder.encode_int(len(self.indices))
+        encoder.encode_packed32(len(self.indices))
         for i in self.indices:
-            encoder.encode_int(i)
+            encoder.encode_packed32(i)
         encoder.encode_type_number(self.decl)
 
     def min_max_shape(self, l, depth=0, shape=[]):
@@ -344,7 +350,7 @@ class array(object):
                             (shape, self.indices))
         for i in range(len(self.indices)):
             if self.indices[i] == 0:
-                encoder.encode_int(shape[i])
+                encoder.encode_packed32(shape[i])
             elif self.indices[i] != shape[i]:
                 raise Exception("Actual dimension %d in %s differs from %s" %
                                 (i, shape, self.indices))
@@ -362,10 +368,10 @@ class array(object):
         self.encode_value(encoder, value, depth)
 
     def decode_decl(self, decoder):
-        n_indices = decoder.decode_int()
+        n_indices = decoder.decode_packed32()
         indices = []
         for i in range(n_indices):
-            index = decoder.decode_int()
+            index = decoder.decode_packed32()
             indices.append(index)
         elem_decl = decoder.decode_decl()
         return array(indices, elem_decl)
@@ -383,7 +389,7 @@ class array(object):
         indices = []
         for i in self.indices:
             if i == 0:
-                i = decoder.decode_int()
+                i = decoder.decode_packed32()
             indices.append(i)
         return self.decode_value(decoder, indices)
 
@@ -400,7 +406,7 @@ class array(object):
         indices = []
         for i in self.indices:
             if i == 0:
-                i = decoder.decode_int()
+                i = decoder.decode_packed32()
             indices.append(i)
         return self.new_instance_value(indices)
     
@@ -414,7 +420,7 @@ class struct:
 
     def encode_decl(self, encoder):
         encoder.encode_type(i_STRUCT)
-        encoder.encode_int(len(self.field))
+        encoder.encode_packed32(len(self.field))
         for (name, decl) in self.field:
             encoder.encode_string(name)
             encoder.encode_type_number(decl)
@@ -429,7 +435,7 @@ class struct:
                 decl.encode(encoder, obj.__getattribute__(name))
 
     def decode_decl(self, decoder):
-        n_field = decoder.decode_int()
+        n_field = decoder.decode_packed32()
         field = []
         for i in range(n_field):
             name = decoder.decode_string()
@@ -540,7 +546,7 @@ class Codec(object):
         index.sort()
         for i in index:
             e = self.index_to_decl[i]
-            if i >= 0x80 and isinstance(e, sample):
+            if i >= i_USER and isinstance(e, sample):
                 result.append(e)
         return result
         
@@ -573,8 +579,17 @@ class Encoder(Codec):
         except KeyError:
             decl.encode_decl(self)
             
+    def encode_packed32(self, v):
+        tmp = v & 0xffffffff;
+        
+        while(tmp >= 0x80 ):
+          self.encode_byte( (tmp & 0x7f) | 0x80 ) 
+          tmp >>= 7
+        self.encode_byte(tmp & 0x7f)
+
     def encode_type(self, index):
-        self.pack("!i", index)
+        self.encode_packed32(index)
+#        self.pack("!i", index)
             
     def encode_boolean(self, v):
         if v:
@@ -602,7 +617,9 @@ class Encoder(Codec):
 
     def encode_string(self, v):
         s = v.encode("utf8")
-        self.pack("!i%ds" % len(s), len(s), s)
+	self.encode_packed32(len(s));
+	self.pack("%ds" % len(s),s)
+#        self.pack("!i%ds" % len(s), len(s), s)
 
 class Decoder(Codec):
     def __init__(self, reader):
@@ -648,8 +665,18 @@ class Decoder(Codec):
 
         return result
     
+    def decode_packed32(self):
+        res = 0
+        i = 0
+        cont = True
+        while (cont):
+          c = self.decode_byte()
+          res |=  (c & 0x7f) << 7*i
+          cont = (c & 0x80) != 0;
+        return res
+
     def decode_type_number(self):
-        return self.unpack("!i")
+        return self.decode_packed32()
         
     def decode_boolean(self):
         return self.unpack("!b") != 0
@@ -673,7 +700,7 @@ class Decoder(Codec):
         return self.unpack("!d")
     
     def decode_string(self):
-        length = self.unpack("!i")
+        length =  self.decode_packed32()
         return self.unpack("!%ds" % length).decode("utf8")