Commit 898fea44 authored by Sven Gestegård Robertz's avatar Sven Gestegård Robertz
Browse files

updated labcomm_sig_parser to current protocol

parent c297fdde
......@@ -30,8 +30,12 @@ ifeq ($(LABCOMM_EXPERIMENTAL),true)
experimental/labcomm_thr_reader_writer.o \
experimental/ThrottleDrv/ethernet_drv.o \
experimental/ThrottleDrv/throttle_drv.o \
experimental/labcomm_udp_reader_writer.o\
experimental/labcomm_sig_parser.o
experimental/labcomm_udp_reader_writer.o
endif
# Enable experimental objects by `make LABCOMM_SIG_PARSER=true`
ifeq ($(LABCOMM_SIG_PARSER),true)
OBJS += experimental/labcomm_sig_parser.o
endif
LABCOMM_JAR=../../../compiler/labcomm$(LIBVERSION)_compiler.jar
......@@ -84,8 +88,8 @@ distclean: clean
../liblabcomm$(LIBVERSION).a: $(OBJS)
ar -r $@ $^
# Enable experimental objects by `make LABCOMM_EXPERIMENTAL=true`
ifeq ($(LABCOMM_EXPERIMENTAL),true)
# Enable sig parser objects by `make LABCOMM_SIG_PARSER=true`
ifeq ($(LABCOMM_SIG_PARSER),true)
experimental/test_sig_parser : experimental/labcomm_sig_parser.o experimental/test_sig_parser.c
endif
......
......@@ -15,8 +15,6 @@
* - The RETURN_STRINGS and where/if to allocate strings is to be decided, it
* is currently not used
*
* - TYPE_DECL is not tested (is it ever sent?)
*
* - The dynamic allocation of the parser is not quite dynamic, the sizes are
* set through the init function, and are then static.
* This should be adapted when allocation is parameterized/user-definable
......@@ -66,7 +64,7 @@ static int unpack_varint(unsigned char *buf,
unsigned char cont = TRUE;
do {
char c = buf[idx+i];
unsigned char c = buf[idx+i];
res = (res << 7) | (c & 0x7f);
cont = c & 0x80;
i++;
......@@ -218,6 +216,7 @@ void getStr(labcomm_sig_parser_t *b, unsigned char *dest, size_t size) {
if( size > rem )
size = rem;
strncpy((char *)dest, (char *)&b->c[b->idx], size);
dest[size] = 0;
b->idx += size;
}
......@@ -271,6 +270,7 @@ static size_t labcomm_sizeof_primitive(unsigned int type)
return 2;
case TYPE_INTEGER :
case TYPE_FLOAT :
case TYPE_SAMPLE_REF :
return 4;
case TYPE_LONG :
case TYPE_DOUBLE :
......@@ -340,7 +340,65 @@ int encoded_size_parse_sig(struct labcomm_signature *sig, void *sample)
return -1;
}
static int accept_signature(labcomm_sig_parser_t *d)
static int accept_signature(labcomm_sig_parser_t *d,
labcomm_type type,
unsigned int start,
unsigned int uid, char *name)
{
get_varint(d); // ignore sig len
VERBOSE_PRINTF("\ntype = ");
accept_type(d);
//printf(" : ");
//unsigned int dt = pop(d);
#ifdef USE_TYPE_AND_SIZE
unsigned int type = pop_val(d);
unsigned int enc_size = pop_val(d);
#else
pop_val(d); // unsigned int type
pop_val(d); // unsigned int enc_size
#endif
if(type != PKG_SAMPLE_DECL) {
if(type == PKG_SAMPLE_REF) {
INFO_PRINTF("accept_signature: ignoring sample ref\n");
return TRUE;
} else if (type == PKG_TYPE_DECL) {
INFO_PRINTF("accept_signature: ignoring typedef\n");
return TRUE;
} else {
error("decl is neither sample, ref, or typedef???");
return FALSE;
}
}
unsigned int end = d->idx;
unsigned int len = end-start;
struct labcomm_signature *newsig = get_sig_t(d, uid);
// newsig->type = type;
if(len <= d->max_sig_len) {
d->signatures_length[uid-LABCOMM_USER] = len;
memcpy(d->signatures[uid-LABCOMM_USER], &d->c[start], len);
newsig->size = len;
newsig->signature = d->signatures[uid-LABCOMM_USER];
newsig->name = name;
} else {
error("sig longer than max length (this ought to be dynamic...)");
}
VERBOSE_PRINTF("signature for uid %x: %s (start=%x,end=%x,len=%d)\n", uid, get_signature_name(d, uid), start,end, len);
INFO_PRINTF("accept_signature: %s\n", newsig->name);
#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
if(! d->current_decl_is_varsize) {
newsig->cached_encoded_size = enc_size;
newsig->encoded_size = encoded_size_static;
INFO_PRINTF(".... is static size = %d\n", enc_size);
} else {
newsig->cached_encoded_size = -1;
newsig->encoded_size = encoded_size_parse_sig;
INFO_PRINTF(".... is variable size\n");
}
#endif
return TRUE;
}
static int accept_decl(labcomm_sig_parser_t *d, labcomm_type type)
{
if(accept_user_id(d)) {
unsigned int uid = pop_val(d);
......@@ -354,54 +412,24 @@ static int accept_signature(labcomm_sig_parser_t *d)
free(str);
#endif
unsigned char lenlen = labcomm_varint_sizeof(nlen);
get_varint(d); // ignore sig len
VERBOSE_PRINTF("\ntype = ");
accept_type(d);
//printf(" : ");
//unsigned int dt = pop(d);
#ifdef USE_TYPE_AND_SIZE
unsigned int type = pop_val(d);
unsigned int enc_size = pop_val(d);
#else
pop_val(d); // unsigned int type
pop_val(d); // unsigned int enc_size
#endif
unsigned int end = d->idx;
unsigned int len = end-start;
struct labcomm_signature *newsig = get_sig_t(d, uid);
// newsig->type = type;
if(len <= d->max_sig_len) {
d->signatures_length[uid-LABCOMM_USER] = len;
memcpy(d->signatures[uid-LABCOMM_USER], &d->c[start], len);
newsig->size = len;
newsig->signature = d->signatures[uid-LABCOMM_USER];
} else {
error("sig longer than max length (this ought to be dynamic...)");
}
if(type != PKG_SAMPLE_DECL) {
// don't record typedefs and samplerefs (for now)
// to avoid number clashes with sample defs
// in the parser struct
return accept_signature(d, type, start, uid, (char *) &d->c[nstart+lenlen]);
}
if(nlen < d->max_name_len) { // leave 1 byte for terminating NULL
char *name;
d->signatures_name_length[uid-LABCOMM_USER] = nlen;
memcpy(d->signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen], nlen);
d->signatures_name[uid-LABCOMM_USER][nlen]=0;
newsig->name = d->signatures_name[uid-LABCOMM_USER];
name = d->signatures_name[uid-LABCOMM_USER];
return accept_signature(d, type, start, uid, name);
} else {
error("sig name longer than max length (this ought to be dynamic...");
return FALSE;
}
VERBOSE_PRINTF("signature for uid %x: %s (start=%x,end=%x, nlen=%d,len=%d)\n", uid, get_signature_name(d, uid), start,end, nlen, len);
INFO_PRINTF("SIG: %s\n", newsig->name);
#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
if(! d->current_decl_is_varsize) {
newsig->cached_encoded_size = enc_size;
newsig->encoded_size = encoded_size_static;
INFO_PRINTF(".... is static size = %d\n", enc_size);
} else {
newsig->cached_encoded_size = -1;
newsig->encoded_size = encoded_size_parse_sig;
INFO_PRINTF(".... is variable size\n");
}
#endif
return TRUE;
} else {
error("sample_decl with uid < LABCOMM_USER");
return FALSE;
......@@ -412,7 +440,7 @@ static int accept_signature(labcomm_sig_parser_t *d)
int accept_packet(labcomm_sig_parser_t *d) {
size_t nbytes;
unsigned int type = peek_varint(d, &nbytes) ;
if(type == VERSION ) {
if(type == PKG_VERSION ) {
advancen(d, nbytes);//consume type field
get_varint(d); //ignore length field
VERBOSE_PRINTF("got version.\n");
......@@ -422,19 +450,37 @@ int accept_packet(labcomm_sig_parser_t *d) {
char *str = (char *) pop_ptr(d);
free(str);
#endif
}else if(type == TYPE_DECL ) {
//XXX is this used? If so, is it correct?
} else if (type == PKG_SAMPLE_DECL) {
d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
advancen(d, nbytes);
VERBOSE_PRINTF("sample_decl ");
get_varint(d); //ignore length field
accept_decl(d, type);
} else if (type == PKG_SAMPLE_REF) {
d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
VERBOSE_PRINTF("type_decl ");
advancen(d, nbytes);
VERBOSE_PRINTF("sample_ref ");
get_varint(d); //ignore length field
accept_signature(d);
} else if (type == SAMPLE_DECL) {
accept_decl(d, type);
}else if(type == PKG_TYPE_DECL ) {
d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
advancen(d, nbytes);//consume type field
VERBOSE_PRINTF("type_decl ");
get_varint(d); //ignore length field
accept_decl(d, type);
} else if (type == PKG_TYPE_BINDING) {
VERBOSE_PRINTF("type_binding ");
advancen(d, nbytes);
VERBOSE_PRINTF("sample_decl ");
get_varint(d); //ignore length field
accept_signature(d);
#ifdef VERBOSE
int sid =
#endif
get_varint(d); //ignore sample id field
#ifdef VERBOSE
int tid =
#endif
get_varint(d); //ignore type id field
VERBOSE_PRINTF("sid=0x%x, tid=0x%x\n ", sid, tid);
} else if(type >= LABCOMM_USER) {
#ifdef EXIT_WHEN_RECEIVING_DATA
printf("*** got sample data, exiting\n");
......@@ -447,7 +493,7 @@ int accept_packet(labcomm_sig_parser_t *d) {
error("got unknown type (<LABCOMM_USER)");
exit(1);
#else
int len = get_varint(d); //ignore length field
int len = get_varint(d); // length field
printf("got unknown tag: 0x%x, skipping %d bytes\n",type, len);
advancen(d, len);
#endif
......@@ -464,13 +510,14 @@ static int accept_user_id(labcomm_sig_parser_t *d){
push_val(d, uid);
return TRUE;
} else {
error("uid < LABCOMM_USER");
return FALSE;
}
}
static int accept_string(labcomm_sig_parser_t *d){
unsigned int len = get_varint(d);
unsigned char *str=malloc(len);
unsigned char *str=malloc(len+1); // len is without terminating null
getStr(d, str, len);
VERBOSE_PRINTF("%s", str);
#ifdef RETURN_STRINGS
......@@ -527,6 +574,11 @@ static int accept_type(labcomm_sig_parser_t *d){
labcomm_sig_parser_t_set_varsize(d);
push_val(d, 0);
break;
case TYPE_SAMPLE_REF :
VERBOSE_PRINTF("sample\n");
advancen(d, nbytes);
push_val(d, 4);
break;
case ARRAY_DECL :
accept_array_decl(d);
pop_val(d); // ignore element type
......@@ -537,7 +589,10 @@ static int accept_type(labcomm_sig_parser_t *d){
// push(d, pop(d) is a NOP --> leave size on stack
break;
default :
printf("accept_type default (type==%x) should not happen\n", type);
//should we distinguish between SAMPLE_DEF and TYPE_DEF here?
//printf("accept_type default (type==%x) should not happen\n", type);
VERBOSE_PRINTF("user type 0x%x\n",type);
advancen(d, nbytes);
push_val(d, 0);
push_val(d, type);
return FALSE;
......@@ -601,7 +656,11 @@ static int accept_struct_decl(labcomm_sig_parser_t *d){
if(tid == STRUCT_DECL) {
advancen(d, nbytes);
unsigned int nf = get_varint(d);
VERBOSE_PRINTF("%d field struct:\n", nf);
if(nf == 0) {
VERBOSE_PRINTF("void\n");
} else {
VERBOSE_PRINTF("%d field struct:\n", nf);
}
int i;
#ifdef USE_UNUSED_VARS
int numVar=0;
......@@ -708,7 +767,7 @@ static int skip_array(labcomm_sig_parser_t *d, unsigned char *sig, int len, int
int skip_struct(labcomm_sig_parser_t *d, unsigned char *sig, unsigned int len, int *pos) {
size_t nbytes;
unsigned int nFields = unpack_varint(sig,*pos, &nbytes);
int nFields = unpack_varint(sig,*pos, &nbytes);
*pos += nbytes;
unsigned int i;
unsigned int skipped=0;
......@@ -719,7 +778,7 @@ int skip_struct(labcomm_sig_parser_t *d, unsigned char *sig, unsigned int len, i
#ifdef DEBUG
VERBOSE_PRINTF("field #%d:\n----namelen==%d\n",i,namelen);
char name[namelen+1]; //HERE BE DRAGONS. alloca?
strncpy(name, sig+*pos+nbytes, namelen);
strncpy(name, (const char *)sig+*pos+nbytes, namelen);
name[namelen]=0;
VERBOSE_PRINTF("----name = %s\n",name);
#endif
......@@ -797,7 +856,7 @@ int skip_type(unsigned int type, labcomm_sig_parser_t *d,
}
#else
int skip_type(unsigned int type, labcomm_sig_parser_t *d,
unsigned char *sig, unsigned int len, int *pos)
const char *sig, unsigned int len, int *pos)
{
int skipped=0;
VERBOSE_PRINTF("skip_type %x\n", type);
......@@ -849,7 +908,7 @@ int skip_packed_sample_data(labcomm_sig_parser_t *d, struct labcomm_signature *s
unsigned int skipped = 0; //skipped byte counter
while(pos < sig->size) {
size_t nbytes;
unsigned int type = unpack_varint(sig->signature,pos, &nbytes);
int type = unpack_varint(sig->signature,pos, &nbytes);
pos+=nbytes;
skipped += skip_type(type, d, sig->signature, sig->size, &pos);
}
......
......@@ -8,14 +8,18 @@
#ifndef LABCOMM_SIG_PARSER_H
#define LABCOMM_SIG_PARSER_H
#include "../labcomm.h"
#include "../labcomm_private.h"
#undef DEBUG
#undef QUIET_STACK // don't print anything for push/pop
#define DEBUG
#define QUIET_STACK // don't print anything for push/pop
#undef DEBUG_STACK_VERBOSE // dump stack, otherwise just print value of top
#undef QUIET //just print type and size when skipping data
// #undef VERBOSE // print in great detail
#define VERBOSE // print in great detail
#undef SKIP_BY_PARSING
#undef STATIC_ALLOCATION //dynamic allocation not completely implemented
......@@ -24,6 +28,7 @@
#define MAX_SIGNATURES 16
#define MAX_NAME_LEN 32
#define MAX_SIG_LEN 128
#define TYPEDEF_BASE MAX_SIGNATURES
#endif
......@@ -43,21 +48,24 @@ typedef struct {
size_t max_signatures; // set by init(...)
size_t max_name_len;
size_t max_sig_len;
// arrays for signatures and typedefs
// signatures start at index 0
// typedefs start at index MAX_SIGNATURES
#ifdef STATIC_ALLOCATION
struct labcomm_signature sig_ts[MAX_SIGNATURES];
struct labcomm_signature sig_ts[2*MAX_SIGNATURES];
unsigned int signatures_length[MAX_SIGNATURES];
unsigned int signatures_name_length[MAX_SIGNATURES];
unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN];
unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN];
unsigned int signatures_length[2*MAX_SIGNATURES];
unsigned int signatures_name_length[2*MAX_SIGNATURES];
unsigned char signatures_name[2*MAX_SIGNATURES][MAX_NAME_LEN];
unsigned char signatures[2*MAX_SIGNATURES][MAX_SIG_LEN];
#else
struct labcomm_signature *sig_ts; // [MAX_SIGNATURES]
struct labcomm_signature *sig_ts; // [2*MAX_SIGNATURES]
unsigned int *signatures_length; // [MAX_SIGNATURES]
unsigned char **signatures; // [MAX_SIGNATURES][MAX_SIG_LEN];
unsigned int *signatures_length; // [2*MAX_SIGNATURES]
unsigned char **signatures; // [2*MAX_SIGNATURES][MAX_SIG_LEN];
unsigned int *signatures_name_length; // [MAX_SIGNATURES]
char **signatures_name; // [MAX_SIGNATURES][MAX_NAME_LEN];
unsigned int *signatures_name_length; // [2*MAX_SIGNATURES]
char **signatures_name; // [2*MAX_SIGNATURES][MAX_NAME_LEN];
#endif
} labcomm_sig_parser_t;
......@@ -104,17 +112,12 @@ int skip_packed_sample_data(labcomm_sig_parser_t *p, struct labcomm_signature *s
#undef RETURN_STRINGS // not really tested
#ifndef TRUE
#define FALSE 0
#define TRUE 1
#endif
typedef enum{
VERSION = LABCOMM_VERSION,
SAMPLE_DECL = LABCOMM_SAMPLE_DEF,
TYPE_DECL = LABCOMM_TYPEDEF,
PKG_VERSION = LABCOMM_VERSION,
PKG_SAMPLE_DECL = LABCOMM_SAMPLE_DEF,
PKG_SAMPLE_REF = LABCOMM_SAMPLE_REF,
PKG_TYPE_DECL = LABCOMM_TYPE_DEF,
PKG_TYPE_BINDING = LABCOMM_TYPE_BINDING,
ARRAY_DECL = LABCOMM_ARRAY,
STRUCT_DECL = LABCOMM_STRUCT,
......@@ -126,6 +129,7 @@ typedef enum{
TYPE_LONG = LABCOMM_LONG,
TYPE_FLOAT = LABCOMM_FLOAT,
TYPE_DOUBLE = LABCOMM_DOUBLE,
TYPE_STRING = LABCOMM_STRING
TYPE_STRING = LABCOMM_STRING,
TYPE_SAMPLE_REF = LABCOMM_REF
} labcomm_type ;
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment