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