From 5aba36c4f0cb5a8a2db9e3e3a5577b144f96145b Mon Sep 17 00:00:00 2001
From: Sven Robertz <sven@cs.lth.se>
Date: Thu, 11 Apr 2013 13:14:41 +0200
Subject: [PATCH] adapted sig_parser to varint

---
 lib/c/experimental/labcomm_parser.c     | 677 ------------------------
 lib/c/experimental/labcomm_sig_parser.c | 291 ++++++----
 2 files changed, 183 insertions(+), 785 deletions(-)
 delete mode 100644 lib/c/experimental/labcomm_parser.c

diff --git a/lib/c/experimental/labcomm_parser.c b/lib/c/experimental/labcomm_parser.c
deleted file mode 100644
index fa24f48..0000000
--- a/lib/c/experimental/labcomm_parser.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/* 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
index b56c0be..e3c659e 100644
--- a/lib/c/experimental/labcomm_sig_parser.c
+++ b/lib/c/experimental/labcomm_sig_parser.c
@@ -1,4 +1,4 @@
-/* labcomm_parser.c:
+/* labcomm_sig_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
@@ -9,32 +9,39 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "../labcomm_private.h"
+
 #define DEBUG 
 #undef DEBUG_STACK
 #undef DEBUG_READ
 
-#undef EXIT_WHEN_RECEIVING_DATA //arrays (at least varsize not working)
+#undef EXIT_WHEN_RECEIVING_DATA 
+
+#define RETURN_STRINGS  // highly experimental, and not used
+
+#ifndef TRUE
 
 #define FALSE 0
 #define TRUE 1
 
-#define	USER_ID_BASE	0x00000080
+#endif
+
 
 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
+        TYPE_DECL = LABCOMM_TYPEDEF,
+        SAMPLE_DECL = LABCOMM_SAMPLE,
+
+        ARRAY_DECL = LABCOMM_ARRAY,
+        STRUCT_DECL = LABCOMM_STRUCT,
+
+        TYPE_BOOLEAN  = LABCOMM_BOOLEAN,
+        TYPE_BYTE  = LABCOMM_BYTE,
+        TYPE_SHORT  = LABCOMM_SHORT,
+        TYPE_INTEGER  = LABCOMM_INT,
+        TYPE_LONG  = LABCOMM_LONG,
+        TYPE_FLOAT  = LABCOMM_FLOAT,
+        TYPE_DOUBLE  = LABCOMM_DOUBLE,
+        TYPE_STRING  = LABCOMM_STRING
 } labcomm_type ;
 
 void error(char *s) {
@@ -52,18 +59,46 @@ typedef struct {
 	unsigned int size;
 	unsigned int capacity;
 	unsigned int idx;
-	unsigned int* stack;
+	void** 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];
+static unsigned 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;
+}
 
-	return  b0 | b1 | b2 | b3;
+static inline unsigned int get32(buffer *b) {
+       unsigned int res = unpack32(b->c, b->idx);
+       b->idx+=4;
+       return res;
+}
+
+
+/* aux method for reading labcomm varint from a char* 
+   size is an out parameter: if not NULL the number of bytes read will be written here
+*/
+static int unpack_varint(unsigned char *buf, unsigned int idx, unsigned char *size) {
+        unsigned int res = 0;
+        unsigned int i=0;
+        unsigned char cont = TRUE;
+
+        do {
+                unsigned char c = buf[idx+i];
+                res |= (c & 0x7f) << 7*i;
+                cont = c & 0x80;
+                i++;
+        } while(cont);
+
+	if(size != NULL)
+		*size = i; 
+        return res;
 }
 
 void dumpStack(buffer *b) {
@@ -77,12 +112,12 @@ void dumpStack(buffer *b) {
 #endif
 }
 
-void push(buffer *b, unsigned int e) {
+void push(buffer *b, void* e) {
 	b->stack[b->top]=e;
 	b->top=b->top-1;
 	dumpStack(b);
 }
-unsigned int pop(buffer *b) {
+void* pop(buffer *b) {
 	b->top=b->top+1;
 	return b->stack[b->top];
 }
@@ -119,18 +154,20 @@ void advancen(buffer *b, size_t n) {
 	b->idx+=n;
 }
 
-unsigned int peek32(buffer *b) {
-	return unpack32(b->c, b->idx);
+unsigned int peek_varint(buffer *b, unsigned char *size) {
+        return unpack_varint(b->c, b->idx, size);
 }
 
-void advance32(buffer *b) {
-	b->idx+=4;
+unsigned int get_varint(buffer *b) {
+        unsigned char size;
+        unsigned int res = peek_varint(b, &size);
+        advancen(b, size);
+        return res;
 }
-
-unsigned int get32(buffer *b) {
-	unsigned int res = peek32(b);
-	advance32(b);
-	return res;
+unsigned int get_varint_size(buffer *b, unsigned char *size) {
+        unsigned int res = peek_varint(b, size);
+        advancen(b, *size);
+        return res;
 }
 
 void getStr(buffer *b, char *dest, size_t size) {
@@ -150,13 +187,13 @@ unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN]; //HERE BE DRAGONS:
 unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN]; 
 
 unsigned int get_signature_len(unsigned int uid){
-	return signatures_length[uid-USER_ID_BASE];
+	return signatures_length[uid-LABCOMM_USER];
 }
 unsigned char* get_signature_name(unsigned int uid){
-	return &signatures_name[uid-USER_ID_BASE][1];
+	return &signatures_name[uid-LABCOMM_USER][1];
 }
 unsigned char* get_signature(unsigned int uid){
-	return signatures[uid-USER_ID_BASE];
+	return signatures[uid-LABCOMM_USER];
 }
 
 void dump_signature(unsigned int uid){
@@ -218,35 +255,54 @@ int accept_field(buffer *d);
 int accept_sample_data(buffer *d);
 int accept_packed_sample_data(buffer *d);
 
+static unsigned char labcomm_varint_sizeof(unsigned int i)
+{
+	if(i < 128) {
+		return 1;
+	} else {
+		unsigned char res = 1;
+		while (i >>= 7) ++res;
+
+		return res;
+	}
+}
+
 int do_parse(buffer *d) {
-	unsigned int type = peek32(d) ;
+        unsigned char nbytes;
+        unsigned int type = peek_varint(d, &nbytes) ;
 	if(type == TYPE_DECL ) {
-		advance32(d);
+		advancen(d, nbytes);
 		accept_user_id(d);
-		unsigned int uid = pop(d);
+		unsigned int uid = (unsigned int) (unsigned long) 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)
+		pop(d); // ignore, for now. 
+#ifdef RETURN_STRINGS
+		char *str = (char *) pop(d);
+		free(str);
+#endif
 		printf(" : ");
 		accept_type(d);
-		unsigned int type = pop(d);
+		unsigned int type = (unsigned int) (unsigned long) pop(d);
 
 		//push(d, type);
 		printf("\n");
 		return TRUE;
 	} else if (type == SAMPLE_DECL) {
-		advance32(d);
+		advancen(d, nbytes);
 		printf("sample_decl ");
 		accept_user_id(d);
 		unsigned int nstart = d->idx;
-		unsigned int uid = pop(d);
+		unsigned int uid = (unsigned int) (unsigned long) pop(d);
 		printf(", name = ");
 		accept_string(d);
 		unsigned int start = d->idx;
-		unsigned int nlen = pop(d);
+		unsigned int nlen = (unsigned int) (unsigned long) pop(d);
+#ifdef RETURN_STRINGS
+		char *str = (char *) pop(d);
+		free(str);
+#endif
+		unsigned char lenlen = labcomm_varint_sizeof(nlen);
 		accept_type(d);
 		//printf(" : ");
 		//unsigned int dt = pop(d);
@@ -254,20 +310,20 @@ int do_parse(buffer *d) {
 		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);
+			signatures_length[uid-LABCOMM_USER] = len;
+			memcpy(signatures[uid-LABCOMM_USER], &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;
+			signatures_name[uid-LABCOMM_USER][0] = nlen;
+			memcpy(signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen-1], nlen+1);
+			signatures_name[uid-LABCOMM_USER][nlen+1]=0;
 		} 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);
+		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");
@@ -279,11 +335,12 @@ int do_parse(buffer *d) {
 }
 
 int accept_user_id(buffer *d){
-	unsigned int uid = peek32(d);
-	if(uid >= USER_ID_BASE) {
-		advance32(d);
+        unsigned char nbytes;
+	unsigned int uid = peek_varint(d, &nbytes);
+	if(uid >= LABCOMM_USER) {
+		advancen(d, nbytes);
 		printf("uid = %x ", uid);
-		push(d, uid);
+		push(d, (void *) (unsigned long) uid);
 		return TRUE;
 	} else {
 		return FALSE;
@@ -291,8 +348,7 @@ int accept_user_id(buffer *d){
 }
 
 int accept_string(buffer *d){
-	unsigned int len = get32(d);
-	push(d, len);
+	unsigned int len = get_varint(d);
 	char *str=malloc(len);
 	getStr(d, str, len);
 	printf("%s", str);
@@ -301,50 +357,44 @@ int accept_string(buffer *d){
 #else
 	free(str);
 #endif
+	push(d, (void *) (unsigned long) len);
 	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);
+	unsigned char nbytes;
+        unsigned int type = peek_varint(d, &nbytes) ;
 	switch(type) {
 		case TYPE_BOOLEAN :
 			printf("boolean");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_BYTE :
 			printf("byte");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_SHORT :
 			printf("short");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_INTEGER :
 			printf("integer");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_LONG :
 			printf("long");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_FLOAT :
 			printf("float");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_DOUBLE :
 			printf("double");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case TYPE_STRING :
 			printf("string");
-			advance32(d);
+			advancen(d, nbytes);
 			break;
 		case ARRAY_DECL :
 			accept_array_decl(d);
@@ -361,16 +411,17 @@ int accept_type(buffer *d){
 }
 
 int accept_array_decl(buffer *d){
-	unsigned int tid = peek32(d);
+        unsigned char nbytes;
+        unsigned int tid = peek_varint(d, &nbytes) ;
 	if(tid == ARRAY_DECL) {
-		advance32(d);
-		unsigned int nidx = get32(d);
+		advancen(d, nbytes);
+		unsigned int nidx = get_varint(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);
+			unsigned int idx = get_varint(d);
 			if(idx == 0) {
 				numVar++;
 				printf("[_] ");
@@ -390,10 +441,11 @@ int accept_array_decl(buffer *d){
 	}
 }
 int accept_struct_decl(buffer *d){
-	unsigned int tid = peek32(d);
+	unsigned char nbytes;
+        unsigned int tid = peek_varint(d, &nbytes) ;
 	if(tid == STRUCT_DECL) {
-		advance32(d);
-		unsigned int nf = get32(d);
+		advancen(d, nbytes);
+		unsigned int nf = get_varint(d);
 		printf(", %d field struct:\n", nf);
 		int i;
 		int numVar=0;
@@ -413,13 +465,17 @@ int accept_field(buffer *d){
 	printf("field ");
 	accept_string(d);
 	pop(d); // ignore, for now
+#ifdef RETURN_STRINGS
+		char *str = (char *) pop(d);
+		free(str);
+#endif
 	printf(" : ");
 	accept_type(d);
 	printf("\n");
 }
 int accept_sample_data(buffer *d){
 	accept_user_id(d);
-	unsigned int uid = pop(d);	
+	unsigned int uid = (unsigned int) (unsigned long) pop(d);	
 	printf("sample data... %x\n", uid);
 #ifdef DEBUG
 	dump_signature(uid);
@@ -436,17 +492,18 @@ 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);
+	unsigned char nbytes;
+	unsigned int nIdx = unpack_varint(sig, *pos, &nbytes);
 	printf("skip_array: nIdx = %d (from sig)\n", nIdx);
-	*pos +=4;
+	*pos +=nbytes;
 	unsigned int idx[nIdx];
 	unsigned int nVar=0;
 
 	unsigned int i;
 
 	for(i=0; i<nIdx; i++) {
-		idx[i] = unpack32(sig, *pos);
-		*pos += 4;
+		idx[i] = unpack_varint(sig, *pos, &nbytes);
+		*pos += nbytes;
 		printf("skip_array: idx[%d]=%d (from sig)\n", i, idx[i]);
 		if(idx[i] == 0) {
 			nVar++;
@@ -456,14 +513,16 @@ int skip_array(buffer *d, unsigned char *sig, unsigned int len, unsigned int *po
 	}
 	unsigned int var[nVar];
 
+	unsigned char varSize=0; // total number of bytes required for var size fields
 	for(i=0; i<nVar; i++) {
-		var[i] = get32(d);	
+		var[i] = get_varint_size(d, &nbytes);	
+		varSize += nbytes;
 		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 type = unpack_varint(sig, *pos, &nbytes);
+	*pos+=nbytes;
 
 	unsigned int elemSize = labcomm_sizeof(type);
 
@@ -473,29 +532,31 @@ int skip_array(buffer *d, unsigned char *sig, unsigned int len, unsigned int *po
 	
 	advancen(d, skip);
 
-	return skip + 4*nVar;
+	//return skip + 4*nVar;
+	return skip + varSize;
 }
 
 int skip_struct(buffer *d, unsigned char *sig, unsigned int len, unsigned int *pos) {
-	unsigned int nFields = unpack32(sig,*pos);
-	*pos += 4;
+	unsigned char nbytes;
+	unsigned int nFields = unpack_varint(sig,*pos, &nbytes);
+	*pos += nbytes;
 	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);
+		unsigned int namelen = unpack_varint(sig, *pos, &nbytes);
 #ifdef DEBUG
 		printf("namelen==%d",namelen);
 		char name[namelen+1];
 		name[namelen]=0;
-		strncpy(name, sig+*pos+4, namelen);
+		strncpy(name, sig+*pos+nbytes, namelen);
 		printf(", name = %s",name);
 #endif
-		*pos += (4+namelen); // 32bit len + actual string
+		*pos += (nbytes+namelen); // 32bit len + actual string
 
-		unsigned int type = unpack32(sig, *pos);
-		*pos += 4;
+		unsigned int type = unpack_varint(sig, *pos, &nbytes);
+		*pos += nbytes;
 #ifdef DEBUG
 		printf(": type == %x\n", type);
 #endif
@@ -540,14 +601,15 @@ int skip_type(unsigned int type, buffer *d,
 			skipped+=8;
 			break;
 		case TYPE_STRING :
-			{unsigned int len = get32(d);
-			//advancen(d,len);
+			{
+			unsigned char nbytes;
+			unsigned int len = get_varint_size(d, &nbytes);
 			int i;
 			printf("string [");
 			for(i=0; i<len; i++)
 				printf("%c", get(d));
 			printf("]\n");
-			skipped+=len+4;
+			skipped+=len+nbytes;
 			break;}
 		case ARRAY_DECL :
 			printf("array\n");
@@ -590,9 +652,11 @@ int skip_type(unsigned int type, buffer *d,
 			skipped+=8;
 			break;
 		case TYPE_STRING :
-			{unsigned int len = get32(d);
+			{
+			unsigned char nbytes;
+			unsigned int len = get_varint_size(d, &nbytes);
 			advancen(d,len);
-			skipped+=len+4;
+			skipped+=len+nbytes;
 			break;}
 		case ARRAY_DECL :
 			skipped += skip_array(d, sig, len, pos);
@@ -614,8 +678,9 @@ 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;
+		unsigned char nbytes;
+		unsigned int type = unpack_varint(sig,pos, &nbytes);
+		pos+=nbytes;
 		skipped += skip_type(type, d, sig, siglen, &pos);
 	}	
 	printf("skipped %d bytes\n", skipped);
@@ -644,6 +709,16 @@ void test_read(buffer *buf) {
 int main() {
 	buffer buf;
 
+#ifdef DEBUG_VARINT_SIZEOF
+	printf("varint_sizeof 0 : %d\n", labcomm_varint_sizeof(0));
+	printf("varint_sizeof 1 : %d\n", labcomm_varint_sizeof(1));
+	printf("varint_sizeof 127 : %d\n", labcomm_varint_sizeof(127));
+	printf("varint_sizeof 128 : %d\n", labcomm_varint_sizeof(128));
+	printf("varint_sizeof 65536 : %d\n", labcomm_varint_sizeof(65536));
+	printf("varint_sizeof 1000000 : %d\n", labcomm_varint_sizeof(1000000));
+	printf("varint_sizeof 0xffffffff : %d\n", labcomm_varint_sizeof(0xffffffff));
+#endif
+
 	if( init_buffer(&buf, BUF_SIZE, STACK_SIZE) ) {
 		printf("failed to init buffer\n");
 		exit(1);
-- 
GitLab