Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Show changes
Showing
with 609 additions and 2286 deletions
/*
test_labcomm2014_renaming.c -- LabComm tests of renaming
Copyright 2015 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_renaming.h"
#include "labcomm2014_renaming_encoder.h"
#include "test/gen/generated_encoding.h"
#define IOCTL_WRITER_ASSERT_BYTES 4096
#define IOCTL_WRITER_RESET 4097
#define EXPECT(...) \
{ \
int expected[] = __VA_ARGS__; \
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, \
__LINE__, \
sizeof(expected)/sizeof(expected[0]), \
expected); \
}
#define VARIABLE(i) -(i + 1)
#define IS_VARIABLE(i) (i < 0)
static unsigned char buffer[128];
struct labcomm2014_writer *writer;
static int seen_variable[1024];
static int buf_writer_alloc(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
writer = w; /* Hack */
w->data_size = sizeof(buffer);
w->count = w->data_size;
w->data = buffer;
w->pos = 0;
return 0;
}
static int buf_writer_free(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_start(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index,
const struct labcomm2014_signature *signature,
void *value)
{
return 0;
}
static int buf_writer_end(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_flush(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
exit(1);
return 0;
}
static int buf_writer_ioctl(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int signature_index, const struct labcomm2014_signature *signature,
uint32_t action, va_list arg)
{
int result = -ENOTSUP;
switch (action) {
case IOCTL_WRITER_ASSERT_BYTES: {
int line = va_arg(arg, int);
int count = va_arg(arg, int);
int *expected = va_arg(arg, int *);
int i, mismatch;
mismatch = 0;
if (w->pos != count) {
fprintf(stderr, "Invalid length detected %d != %d (%s:%d)\n",
w->pos, count, __FILE__, line);
mismatch = 1;
}
for (i = 0 ; i < count ; i++) {
if (IS_VARIABLE(expected[i])) {
if (seen_variable[VARIABLE(expected[i])] == -1) {
seen_variable[VARIABLE(expected[i])] = buffer[i];
}
if (seen_variable[VARIABLE(expected[i])] != buffer[i]) {
fprintf(stderr, "Unexpected variable v%d (%02x: != %02x)\n",
VARIABLE(expected[i]),
seen_variable[VARIABLE(expected[i])], buffer[i]);
mismatch = 1;
}
} else if (expected[i] != buffer[i]) {
mismatch = 1;
}
}
if (mismatch) {
fprintf(stderr, "Encoder mismatch (%s:%d)\n",
__FILE__, line);
for (i = 0 ; i < w->pos ; i++) {
if (32 <= w->data[i] && w->data[i] < 127) {
printf("%2c ", w->data[i]);
} else {
printf("%2.2x ", w->data[i]);
}
}
printf("\n");
for (i = 0 ; i < w->pos ; i++) {
printf("%2.2x ", w->data[i]);
}
printf("\n");
for (i = 0 ; i < count ; i++) {
if (expected[i] < 0) {
printf("v%d ", VARIABLE(expected[i]));
} else {
printf("%2.2x ", expected[i] );
}
}
printf("\n");
if (mismatch) { exit(1); }
}
result = 0;
} break;
case IOCTL_WRITER_RESET: {
w->pos = 0;
result = 0;
}
}
return result;
}
const struct labcomm2014_writer_action writer_action = {
.alloc = buf_writer_alloc,
.free = buf_writer_free,
.start = buf_writer_start,
.end = buf_writer_end,
.flush = buf_writer_flush,
.ioctl = buf_writer_ioctl
};
static struct labcomm2014_writer_action_context action_context = {
.next = NULL,
.action = &writer_action,
.context = NULL
};
static struct labcomm2014_writer buffer_writer = {
.action_context = &action_context,
.data = buffer,
.data_size = sizeof(buffer),
.count = sizeof(buffer),
.pos = 0,
.error = 0,
};
void dump_encoder(struct labcomm2014_encoder *encoder)
{
int i;
for (i = 0 ; i < writer->pos ; i++) {
printf("%2.2x ", writer->data[i]);
}
printf("\n");
}
static int do_test(int argc, char *argv[])
{
struct labcomm2014_renaming_registry *registry;
struct labcomm2014_encoder *encoder, *prefix, *suffix;
int i;
for (i = 0 ; i < sizeof(seen_variable)/sizeof(seen_variable[0]) ; i++) {
seen_variable[i] = -1;
}
registry = labcomm2014_renaming_registry_new(
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
encoder = labcomm2014_encoder_new(
&buffer_writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
prefix = labcomm2014_renaming_encoder_new(encoder,
registry,
labcomm2014_renaming_prefix,
"p.");
suffix = labcomm2014_renaming_encoder_new(prefix,
registry,
labcomm2014_renaming_suffix,
".s");
EXPECT({ 0x01, 0x0c, 0x0b,
'L', 'a', 'b', 'C', 'o', 'm', 'm', '2','0', '1', '4' });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_register_generated_encoding_V(encoder);
labcomm2014_encoder_register_generated_encoding_V(encoder);
EXPECT({ 0x02, 0x08, VARIABLE(0), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00,
0x04, 0x0a, VARIABLE(1), 0x01, 0x00, 0x03, 'v', '_', 't', 0x02, 0x11, 0x00,
0x04, 0x07, VARIABLE(2), 0x01, 0x00, 0x01, 'V', 0x01, VARIABLE(1),
0x05, 0x02, VARIABLE(0), VARIABLE(2) });
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
labcomm2014_encoder_register_generated_encoding_V(prefix);
labcomm2014_encoder_register_generated_encoding_V(prefix);
EXPECT({ 0x02, 0x0a, VARIABLE(3), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x02, 0x11, 0x00,
0x04, 0x09, VARIABLE(4), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x01, VARIABLE(2),
0x05, 0x02, VARIABLE(3), VARIABLE(4) });
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
labcomm2014_encoder_register_generated_encoding_V(suffix);
labcomm2014_encoder_register_generated_encoding_V(suffix);
// XXX HERE BE DRAGONS! What does "BOGUS" man in the below renaming test?
// previous version (from merge conflict): VARIABLE(6) vs VARIABLE(2)
// <<<<<<< ours
// EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
// 0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2),
// 0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(6),
// =======
EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2), /* BOGUS */
0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(2),
0x05, 0x02, VARIABLE(5), VARIABLE(7) });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x08, VARIABLE(8), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(prefix,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(prefix,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x0a, VARIABLE(9), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(suffix,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(suffix,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x0c, VARIABLE(10), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(encoder);
EXPECT({VARIABLE(0), 0x00 });
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(prefix);
EXPECT({VARIABLE(3), 0x00 });
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(suffix);
EXPECT({VARIABLE(5), 0x00 });
labcomm2014_encoder_free(suffix);
labcomm2014_encoder_free(prefix);
labcomm2014_encoder_free(encoder);
labcomm2014_renaming_registry_free(registry);
return 0;
}
int main(int argc, char *argv[])
{
return do_test(argc, argv);
}
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <err.h>
#include "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_renaming.h"
#include "labcomm2014_renaming_private.h"
#include "test/gen/generated_encoding.h"
static int do_test(int argc, char **argv)
{
struct labcomm2014_renaming_registry *registry;
struct labcomm2014_renaming_rename *r1, *r2, *r3, *r4;
registry = labcomm2014_renaming_registry_new(
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
r1 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_signature_generated_encoding_R,
labcomm2014_renaming_prefix, "p:");
r2 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_renaming_rename_signature(r1),
labcomm2014_renaming_suffix, ":s");
r3 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_signature_generated_encoding_R,
labcomm2014_renaming_suffix, ":s");
r4 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_renaming_rename_signature(r3),
labcomm2014_renaming_prefix, "p:");
assert(r2 == r4);
labcomm2014_renaming_rename_free(registry, r1);
labcomm2014_renaming_rename_free(registry, r2);
labcomm2014_renaming_rename_free(registry, r3);
labcomm2014_renaming_rename_free(registry, r4);
labcomm2014_renaming_registry_free(registry);
return 0;
}
int main(int argc, char **argv)
{
return do_test(argc, argv);
}
sample int test_var[_,2,_];
#include <stdlib.h>
#include <stdio.h>
#include "labcomm2014_private.h"
#include "test/gen/another_encoding.h"
#include "test/gen/generated_encoding.h"
static void info(char *name, char *full_name,
const struct labcomm2014_signature *signature) {
printf("%s %s %p -> %d\n", name, full_name, signature,
labcomm2014_get_local_index(signature));
if (labcomm2014_get_local_index(signature) < 0x40) {
exit(1);
}
};
int main(int argc, char *argv[])
{
#define FUNC(name, full_name) \
info( #name, #full_name, labcomm2014_signature_##full_name)
LABCOMM_FORALL_SAMPLES_generated_encoding(FUNC, ;);
LABCOMM_FORALL_SAMPLES_another_encoding(FUNC, ;);
return 0;
}
CC = gcc
CFLAGS = -g -I .
VERSIONS=2014
liblabcomm.a : labcomm.o labcomm_fd_reader_writer.o experimental/labcomm_udp_reader_writer.o \
experimental/udp_hack.o experimental/ethaddr.o \
experimental/labcomm_thr_reader_writer.o \
experimental/ThrottleDrv/ethernet_drv.o experimental/ThrottleDrv/throttle_drv.o
ar -r liblabcomm.a $^
all:
labcomm.o : labcomm.c labcomm.h labcomm_private.h
%:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h
ethaddr.o: ethaddr.c
.PHONY: clean
clean:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
%o: %c %h
.PHONY: distclean
distclean:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
rm -f *.o *.so *.so.1 *.a
clean:
rm *.o experimental/*.o experimental/ThrottleDrv/*.o
distclean: clean
rm liblabcomm.a
/* 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;
}
/* 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");
}
#include <errno.h>
#include <string.h>
#include <stdio.h>
#ifndef __VXWORKS__
#include <strings.h>
#endif
#include <stdlib.h>
#ifdef __VXWORKS__
#if (CPU == PPC603)
#undef _LITTLE_ENDIAN
#endif
#if (CPU == PENTIUM4)
#undef _BIG_ENDIAN
#endif
#endif
#include "labcomm.h"
#include "labcomm_private.h"
typedef struct labcomm_sample_entry {
struct labcomm_sample_entry *next;
int index;
labcomm_signature_t *signature;
labcomm_decoder_typecast_t decoder;
labcomm_handler_typecast_t handler;
labcomm_encode_typecast_t encode;
void *context;
} labcomm_sample_entry_t;
typedef struct labcomm_encoder_context {
labcomm_sample_entry_t *sample;
int index;
} labcomm_encoder_context_t;
typedef struct labcomm_decoder_context {
labcomm_sample_entry_t *sample;
} labcomm_decoder_context_t;
static labcomm_sample_entry_t *get_sample_by_signature_address(
labcomm_sample_entry_t *head,
labcomm_signature_t *signature)
{
labcomm_sample_entry_t *p;
for (p = head ; p && p->signature != signature ; p = p->next) {
}
return p;
}
static labcomm_sample_entry_t *get_sample_by_signature_value(
labcomm_sample_entry_t *head,
labcomm_signature_t *signature)
{
labcomm_sample_entry_t *p;
for (p = head ; p ; p = p->next) {
if (p->signature->type == signature->type &&
p->signature->size == signature->size &&
strcmp(p->signature->name, signature->name) == 0 &&
bcmp((void*)p->signature->signature, (void*)signature->signature,
signature->size) == 0) {
break;
}
}
return p;
}
static labcomm_sample_entry_t *get_sample_by_index(
labcomm_sample_entry_t *head,
int index)
{
labcomm_sample_entry_t *p;
for (p = head ; p && p->index != index ; p = p->next) {
}
return p;
}
static int get_encoder_index(
labcomm_encoder_t *e,
labcomm_signature_t *s)
{
int result = 0;
labcomm_encoder_context_t *context = e->context;
labcomm_sample_entry_t *sample = context->sample;
while (sample) {
if (sample->signature == s) { break; }
sample = sample->next;
}
if (sample) {
result = sample->index;
}
return result;
}
static void do_encoder_register(struct labcomm_encoder *e,
labcomm_signature_t *signature,
labcomm_encode_typecast_t encode)
{
if (signature->type == LABCOMM_SAMPLE) {
if (get_encoder_index(e, signature) == 0) {
int i;
labcomm_encoder_context_t *context = e->context;
labcomm_sample_entry_t *sample =
(labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
sample->next = context->sample;
sample->index = context->index;
sample->signature = signature;
sample->encode = encode;
context->index++;
context->sample = sample;
e->writer.write(&e->writer, labcomm_writer_start);
labcomm_encode_int(e, signature->type);
labcomm_encode_type_index(e, signature);
labcomm_encode_string(e, signature->name);
for (i = 0 ; i < signature->size ; i++) {
if (e->writer.pos >= e->writer.count) {
e->writer.write(&e->writer, labcomm_writer_continue);
}
e->writer.data[e->writer.pos] = signature->signature[i];
e->writer.pos++;
}
e->writer.write(&e->writer, labcomm_writer_end);
}
}
}
static void do_encode(
labcomm_encoder_t *encoder,
labcomm_signature_t *signature,
void *value)
{
labcomm_encoder_context_t *context = encoder->context;
labcomm_sample_entry_t *sample;
sample = get_sample_by_signature_address(context->sample,
signature);
if (sample && sample->encode) {
sample->encode(encoder, value);
} else {
printf("Encoder has no registration for %s\n", signature->name);
}
}
labcomm_encoder_t *labcomm_encoder_new(
int (*writer)(labcomm_writer_t *, labcomm_writer_action_t),
void *writer_context)
{
labcomm_encoder_t *result = malloc(sizeof(labcomm_encoder_t));
if (result) {
labcomm_encoder_context_t *context;
context = malloc(sizeof(labcomm_encoder_context_t));
context->sample = 0;
context->index = LABCOMM_USER;
result->context = context;
result->writer.context = writer_context;
result->writer.data = 0;
result->writer.data_size = 0;
result->writer.count = 0;
result->writer.pos = 0;
result->writer.write = writer;
result->writer.write(&result->writer, labcomm_writer_alloc);
result->do_register = do_encoder_register;
result->do_encode = do_encode;
}
return result;
}
void labcomm_internal_encoder_register(
labcomm_encoder_t *e,
labcomm_signature_t *signature,
labcomm_encode_typecast_t encode)
{
if (e && e->do_register) {
e->do_register(e, signature, encode);
} else {
printf("Encoder is missing do_register\n");
}
}
void labcomm_internal_encode(
labcomm_encoder_t *e,
labcomm_signature_t *signature,
void *value)
{
if (e && e->do_encode) {
e->do_encode(e, signature, value);
} else {
printf("Encoder is missing do_encode\n");
}
}
void labcomm_internal_encoder_user_action(labcomm_encoder_t *e,
int action)
{
e->writer.write(&e->writer, action);
}
void labcomm_encoder_free(labcomm_encoder_t* e)
{
e->writer.write(&e->writer, labcomm_writer_free);
free(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);
}
static int signature_writer(
labcomm_writer_t *w,
labcomm_writer_action_t action)
{
switch (action) {
case labcomm_writer_alloc: {
w->data_size = 1000;
w->count = w->data_size;
w->data = malloc(w->data_size);
w->pos = 0;
} break;
case labcomm_writer_start: {
w->data_size = 1000;
w->count = w->data_size;
w->data = realloc(w->data, w->data_size);
w->pos = 0;
} break;
case labcomm_writer_continue: {
w->data_size += 1000;
w->count = w->data_size;
w->data = realloc(w->data, w->data_size);
} break;
case labcomm_writer_end: {
} break;
case labcomm_writer_free: {
free(w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} break;
case labcomm_writer_available: {
} break;
}
return 0;
}
static void collect_flat_signature(
labcomm_decoder_t *decoder,
labcomm_encoder_t *signature_writer)
{
int type = labcomm_decode_int(decoder);
if (type >= LABCOMM_USER) {
printf("Implement %s ...\n", __FUNCTION__);
} else {
labcomm_encode_int(signature_writer, type);
switch (type) {
case LABCOMM_ARRAY: {
int dimensions, i;
dimensions = labcomm_decode_int(decoder);
labcomm_encode_int(signature_writer, dimensions);
for (i = 0 ; i < dimensions ; i++) {
int n = labcomm_decode_int(decoder);
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);
for (i = 0 ; i < fields ; i++) {
char *name = labcomm_decode_string(decoder);
labcomm_encode_string(signature_writer, name);
free(name);
collect_flat_signature(decoder, signature_writer);
}
} break;
case LABCOMM_BOOLEAN:
case LABCOMM_BYTE:
case LABCOMM_SHORT:
case LABCOMM_INT:
case LABCOMM_LONG:
case LABCOMM_FLOAT:
case LABCOMM_DOUBLE:
case LABCOMM_STRING: {
} break;
default: {
printf("Implement %s ...\n", __FUNCTION__);
} break;
}
}
}
static void do_decoder_register(
labcomm_decoder_t *decoder,
labcomm_signature_t *signature,
labcomm_decoder_typecast_t type_decoder,
labcomm_handler_typecast_t handler,
void *handler_context)
{
labcomm_decoder_context_t *context = decoder->context;
labcomm_sample_entry_t *sample;
sample = get_sample_by_signature_address(context->sample,
signature);
if (!sample) {
sample = (labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
sample->next = context->sample;
context->sample = sample;
sample->index = 0;
sample->signature = signature;
}
sample->decoder = type_decoder;
sample->handler = handler;
sample->context = handler_context;
}
static int do_decode_one(labcomm_decoder_t *d)
{
int result;
do {
result = d->reader.read(&d->reader, labcomm_reader_start);
if (result > 0) {
labcomm_decoder_context_t *context = d->context;
result = labcomm_decode_int(d);
if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) {
labcomm_encoder_t *e = labcomm_encoder_new(signature_writer, 0);
labcomm_signature_t signature;
labcomm_sample_entry_t *entry;
int index;
e->writer.write(&e->writer, labcomm_writer_start);
signature.type = result;
index = labcomm_decode_int(d);
signature.name = labcomm_decode_string(d);
collect_flat_signature(d, e);
signature.size = e->writer.pos;
signature.signature = e->writer.data;
entry = get_sample_by_signature_value(context->sample, &signature);
if (! entry) {
// Unknown datatype, bail out
fprintf(stderr, "%s: unknown datatype '%s' (id=0x%x)\n",
__FUNCTION__, signature.name, index);
} else if (entry->index && entry->index != index) {
fprintf(stderr, "%s: index mismatch '%s' (id=0x%x != 0x%x)\n",
__FUNCTION__, signature.name, entry->index, index);
} else {
entry->index = index;
}
free(signature.name);
e->writer.write(&e->writer, labcomm_writer_end);
if (!entry) {
// No handler for found type, bail out (after cleanup)
result = -ENOENT;
}
labcomm_encoder_free(e);
} else {
labcomm_sample_entry_t *entry;
entry = get_sample_by_index(context->sample, result);
if (!entry) {
fprintf(stderr, "%s: type not found (id=0x%x)\n",
__FUNCTION__, result);
result = -ENOENT;
} else {
entry->decoder(d, entry->handler, entry->context);
}
}
}
d->reader.read(&d->reader, labcomm_reader_end);
} while (result > 0 && result < LABCOMM_USER);
return result;
}
labcomm_decoder_t *labcomm_decoder_new(
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
void *reader_context)
{
labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
if (result) {
labcomm_decoder_context_t *context =
(labcomm_decoder_context_t*)malloc(sizeof(labcomm_decoder_context_t));
context->sample = 0;
result->context = context;
result->reader.context = reader_context;
result->reader.data = 0;
result->reader.data_size = 0;
result->reader.count = 0;
result->reader.pos = 0;
result->reader.read = reader;
result->reader.read(&result->reader, labcomm_reader_alloc);
result->do_register = do_decoder_register;
result->do_decode_one = do_decode_one;
}
return result;
}
void labcomm_internal_decoder_register(
labcomm_decoder_t *d,
labcomm_signature_t *signature,
labcomm_decoder_typecast_t type_decoder,
labcomm_handler_typecast_t handler,
void *handler_context)
{
if (d && d->do_register) {
d->do_register(d, signature, type_decoder, handler, handler_context);
} else {
printf("Decoder is missing do_register\n");
}
}
int labcomm_decoder_decode_one(labcomm_decoder_t *d)
{
int result = -1;
if (d && d->do_decode_one)
{
result = d->do_decode_one(d);
}
else
{
printf("Decoder is missing do_decode_one\n");
}
return result;
}
void labcomm_decoder_run(labcomm_decoder_t *d)
{
while (labcomm_decoder_decode_one(d) > 0) {
}
}
void labcomm_decoder_free(labcomm_decoder_t* d)
{
d->reader.read(&d->reader, labcomm_reader_free);
free(d);
}
#ifndef _LABCOMM_H_
#define _LABCOMM_H_
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Signature entry
*/
typedef struct {
int type;
char *name;
int (*encoded_size)(void *);
int size;
unsigned char *signature;
} labcomm_signature_t;
/*
* Decoder
*/
struct labcomm_decoder;
typedef enum {
labcomm_reader_alloc,
labcomm_reader_free,
labcomm_reader_start,
labcomm_reader_continue,
labcomm_reader_end
} labcomm_reader_action_t;
typedef struct labcomm_reader {
void *context;
unsigned char *data;
int data_size;
int count;
int pos;
int (*read)(struct labcomm_reader *, labcomm_reader_action_t);
} labcomm_reader_t;
struct labcomm_decoder *labcomm_decoder_new(
int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
void *reader_context);
int labcomm_decoder_decode_one(
struct labcomm_decoder *decoder);
void labcomm_decoder_run(
struct labcomm_decoder *decoder);
void labcomm_decoder_free(
struct labcomm_decoder *decoder);
/*
* Encoder
*/
struct labcomm_encoder;
typedef enum {
labcomm_writer_alloc,
labcomm_writer_free,
labcomm_writer_start,
labcomm_writer_continue,
labcomm_writer_end,
labcomm_writer_available,
} labcomm_writer_action_t;
typedef struct labcomm_writer {
void *context;
unsigned char *data;
int data_size;
int count;
int pos;
int (*write)(struct labcomm_writer *, labcomm_writer_action_t);
} labcomm_writer_t;
struct labcomm_encoder;
struct labcomm_encoder *labcomm_encoder_new(
int (*writer)(labcomm_writer_t *, labcomm_writer_action_t),
void *writer_context);
void labcomm_encoder_free(
struct labcomm_encoder *encoder);
#endif
#include <errno.h>
#include <unistd.h>
#include "labcomm.h"
#define BUFFER_SIZE 2048
int labcomm_fd_reader(
labcomm_reader_t *r,
labcomm_reader_action_t action)
{
int result = -EINVAL;
int *fd = r->context;
switch (action) {
case labcomm_reader_alloc: {
r->data = malloc(BUFFER_SIZE);
if (r->data) {
r->data_size = BUFFER_SIZE;
result = r->data_size;
} else {
r->data_size = 0;
result = -ENOMEM;
}
r->count = 0;
r->pos = 0;
} break;
case labcomm_reader_start:
case labcomm_reader_continue: {
if (r->pos < r->count) {
result = r->count - r->pos;
} else {
int err;
r->pos = 0;
err = read(*fd, r->data, r->data_size);
if (err <= 0) {
r->count = 0;
result = -1;
} else {
r->count = err;
result = r->count - r->pos;
}
}
} break;
case labcomm_reader_end: {
result = 0;
} break;
case labcomm_reader_free: {
free(r->data);
r->data = 0;
r->data_size = 0;
r->count = 0;
r->pos = 0;
result = 0;
} break;
}
return result;
}
int labcomm_fd_writer(
labcomm_writer_t *w,
labcomm_writer_action_t action)
{
int result = 0;
int *fd = w->context;
switch (action) {
case labcomm_writer_alloc: {
w->data = malloc(BUFFER_SIZE);
if (! w->data) {
result = -ENOMEM;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} else {
w->data_size = BUFFER_SIZE;
w->count = BUFFER_SIZE;
w->pos = 0;
}
} break;
case labcomm_writer_free: {
free(w->data);
w->data = 0;
w->data_size = 0;
w->count = 0;
w->pos = 0;
} break;
case labcomm_writer_start: {
w->pos = 0;
} break;
case labcomm_writer_continue: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
case labcomm_writer_end: {
result = write(*fd, w->data, w->pos);
w->pos = 0;
} break;
case labcomm_writer_available: {
result = w->count - w->pos;
} break;
}
return result;
}
#include "labcomm.h"
extern int labcomm_fd_reader(
labcomm_reader_t *r,
labcomm_reader_action_t action);
extern int labcomm_fd_writer(
labcomm_writer_t *r,
labcomm_writer_action_t action);
#ifndef _LABCOMM_PRIVATE_H_
#define _LABCOMM_PRIVATE_H_
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "labcomm.h"
/*
* Predeclared aggregate type indices
*/
#define LABCOMM_TYPEDEF 0x01
#define LABCOMM_SAMPLE 0x02
#define LABCOMM_ARRAY 0x10
#define LABCOMM_STRUCT 0x11
/*
* Predeclared primitive type indices
*/
#define LABCOMM_BOOLEAN 0x20
#define LABCOMM_BYTE 0x21
#define LABCOMM_SHORT 0x22
#define LABCOMM_INT 0x23
#define LABCOMM_LONG 0x24
#define LABCOMM_FLOAT 0x25
#define LABCOMM_DOUBLE 0x26
#define LABCOMM_STRING 0x27
/*
* Start index for user defined types
*/
#define LABCOMM_USER 0x80
/*
* Semi private decoder declarations
*/
typedef void (*labcomm_handler_typecast_t)(void *, void *);
typedef void (*labcomm_decoder_typecast_t)(
struct labcomm_decoder *,
labcomm_handler_typecast_t,
void *);
typedef struct labcomm_decoder {
void *context;
labcomm_reader_t reader;
void (*do_register)(struct labcomm_decoder *,
labcomm_signature_t *,
labcomm_decoder_typecast_t,
labcomm_handler_typecast_t,
void *context);
int (*do_decode_one)(struct labcomm_decoder *decoder);
} labcomm_decoder_t;
/*
* Non typesafe registration function to be called from
* generated labcomm_decoder_register_* functions.
*/
void labcomm_internal_decoder_register(
labcomm_decoder_t *,
labcomm_signature_t *,
labcomm_decoder_typecast_t,
labcomm_handler_typecast_t,
void *context);
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_DECODE(name, type) \
static inline type labcomm_read_##name(labcomm_reader_t *r) { \
type result; int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (r->pos >= r->count) { \
r->read(r, labcomm_reader_continue); \
} \
((unsigned char*)(&result))[i] = r->data[r->pos]; \
r->pos++; \
} \
return result; \
} \
static inline type labcomm_decode_##name(labcomm_decoder_t *d) { \
return labcomm_read_##name(&d->reader); \
}
#else
#define LABCOMM_DECODE(name, type) \
static inline type labcomm_read_##name(labcomm_reader_t *r) { \
type result; int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \
if (r->pos >= r->count) { \
r->read(r, labcomm_reader_continue); \
} \
((unsigned char*)(&result))[i] = r->data[r->pos]; \
r->pos++; \
} \
return result; \
} \
static inline type labcomm_decode_##name(labcomm_decoder_t *d) { \
return labcomm_read_##name(&d->reader); \
}
#endif
LABCOMM_DECODE(boolean, unsigned char)
LABCOMM_DECODE(byte, unsigned char)
LABCOMM_DECODE(short, short)
LABCOMM_DECODE(int, int)
LABCOMM_DECODE(long, long long)
LABCOMM_DECODE(float, float)
LABCOMM_DECODE(double, double)
static inline char *labcomm_read_string(labcomm_reader_t *r)
{
char *result;
int length, i;
length = labcomm_read_int(r);
result = malloc(length + 1);
for (i = 0 ; i < length ; i++) {
if (r->pos >= r->count) {
r->read(r, labcomm_reader_continue);
}
result[i] = r->data[r->pos];
r->pos++;
}
result[length] = 0;
return result;
}
static inline char *labcomm_decode_string(labcomm_decoder_t *d)
{
return labcomm_read_string(&d->reader);
}
static inline int labcomm_buffer_read(struct labcomm_reader *r,
labcomm_reader_action_t action)
{
// If this gets called, it is an error,
// so note error and let producer proceed
r->context = r;
r->pos = 0;
return 0;
}
static inline int labcomm_buffer_reader_error(struct labcomm_reader *r)
{
return r->context != NULL;
}
static inline void labcomm_buffer_reader_setup(
labcomm_reader_t *r,
void *data,
int length)
{
r->context = NULL; // Used as errer flag
r->data = data;
r->data_size = length;
r->count = length;
r->pos = 0;
r->read = labcomm_buffer_read;
}
/*
* Semi private encoder declarations
*/
typedef void (*labcomm_encode_typecast_t)(
struct labcomm_encoder *,
void *value);
typedef struct labcomm_encoder {
void *context;
labcomm_writer_t writer;
void (*do_register)(struct labcomm_encoder *encoder,
labcomm_signature_t *signature,
labcomm_encode_typecast_t);
void (*do_encode)(struct labcomm_encoder *encoder,
labcomm_signature_t *signature,
void *value);
} labcomm_encoder_t;
void labcomm_internal_encoder_register(
labcomm_encoder_t *encoder,
labcomm_signature_t *signature,
labcomm_encode_typecast_t encode);
void labcomm_internal_encode(
labcomm_encoder_t *encoder,
labcomm_signature_t *signature,
void *value);
#define LABCOMM_USER_ACTION(i) (i + 100)
void labcomm_internal_encoder_user_action(struct labcomm_encoder *encoder,
int action);
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_ENCODE(name, type) \
static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (w->pos >= w->count) { \
w->write(w, labcomm_writer_continue); \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \
} \
} \
static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \
}
#else
#define LABCOMM_ENCODE(name, type) \
static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \
if (w->pos >= w->count) { \
w->write(w, labcomm_writer_continue); \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \
} \
} \
static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \
}
#endif
LABCOMM_ENCODE(boolean, unsigned char)
LABCOMM_ENCODE(byte, unsigned char)
LABCOMM_ENCODE(short, short)
LABCOMM_ENCODE(int, int)
LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE(float, float)
LABCOMM_ENCODE(double, double)
static inline void labcomm_write_string(labcomm_writer_t *w, char *s)
{
int length, i;
length = strlen((char*)s);
labcomm_write_int(w, length);
for (i = 0 ; i < length ; i++) {
if (w->pos >= w->count) {
w->write(w, labcomm_writer_continue);
}
w->data[w->pos] = s[i];
w->pos++;
}
}
static inline void labcomm_encode_string(labcomm_encoder_t *e,
char *s)
{
labcomm_write_string(&e->writer, s);
}
void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s);
static inline int labcomm_buffer_write(struct labcomm_writer *w,
labcomm_writer_action_t action)
{
// If this gets called, it is an error,
// so note error and let producer proceed
w->context = w;
w->pos = 0;
return 0;
}
static inline int labcomm_buffer_writer_error(struct labcomm_writer *w)
{
return w->context != NULL;
}
static inline void labcomm_buffer_writer_setup(struct labcomm_writer *w,
void *data,
int length)
{
w->context = NULL; // Used as error flag
w->data = data;
w->data_size = length;
w->count = length;
w->pos = 0;
w->write = labcomm_buffer_write;
}
#endif
## Macros
UNAME_S=$(shell uname -s)
VERSION=2014
LIBVERSION=2014
ifeq ($(UNAME_S),Linux)
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)gcc
CFLAGS=-std=c99 -g -Wall -Werror -O3 -I.
CFLAGS_TEST=$(CFLAGS) -Itest
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION) -lrt
LD_LIBRARY_PATH_NAME=LD_LIBRARY_PATH
MAKESHARED=gcc -o $1 -shared -Wl,-soname,$2 $3 -lc -lrt
else ifeq ($(UNAME_S),Darwin)
#CC=$(CROSS_COMPILE)clang
#LD=$(CROSS_COMPILE)ld
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)gcc
CFLAGS=-g -Wall -Werror -O3 -I. -Itest \
-DLABCOMM_COMPAT=\"labcomm$(VERSION)_compat_osx.h\" \
-DLABCOMM_OS_DARWIN=1 \
-Wno-unused-function
# -Wno-tautological-compare
CFLAGS+=-std=c99
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION)
LD_LIBRARY_PATH_NAME=DYLD_LIBRARY_PATH
MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc
else ifneq ($(findstring CYGWIN,$(UNAME_S)),)
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CFLAGS=-std=c99 -g -Wall -Werror -O3 -I.
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION) -lrt
ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # No -fPIC supported in windows?
else
$(error Unknown system $(UNAME_S))
endif
CFLAGS_TEST=$(CFLAGS) -Itest -DVERSION=$(VERSION)
ifeq ($(CROSS_COMPILE),i586-wrs-vxworks-)
ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # PIC is only supported for RTPs
CFLAGS:=$(CFLAGS) -DLABCOMM_COMPAT=\"labcomm_compat_vxworks.h\"
endif
#!/usr/bin/python
import os
import sys
import difflib
import re
class File:
def __init__(self, path, match, replacement):
def replace(s):
r = re.sub('[ \t]+', ' ', s).replace(match, replacement)
r = r.strip() + '\n'
return r
self.name = path.replace(match, replacement)
self.path = path
with open(path) as f:
self.lines = map(replace, f.readlines())
def __cmp__(self, other):
if other == None:
return cmp(self.name, other)
return cmp(self.name, other.name)
def readfiles(root, match, replacement):
result = []
for n in os.listdir(root):
path = os.path.join(root, n)
if os.path.islink(path):
pass
elif os.path.isdir(path):
for f in filter(None, readfiles(path, match, replacement)):
result.append(f)
else:
result.append(File(path, match, replacement))
for f in sorted(result):
yield f
yield None
if __name__ == '__main__':
A = readfiles(*sys.argv[1:4])
B = readfiles(*sys.argv[4:7])
a = A.next()
b = B.next()
while a != None or b != None:
if b == None or a.name < b.name:
print "Only in %s:" %sys.argv[1], a.path
a = A.next()
elif a == None or a.name > b.name:
print "Only in %s:" %sys.argv[4], b.path
b = B.next()
else:
equal = True
for l in difflib.unified_diff(a.lines, b.lines, a.path, b.path):
print l,
equal = False
if equal:
print "Identical", a.path, b.path
a = A.next()
b = B.next()
labcomm2014.dll
MODULES=Constant\
Decoder \
DecoderChannel \
DecoderRegistry \
Encoder \
EncoderChannel \
EncoderRegistry \
RenamingDecoder \
RenamingEncoder \
RenamingRegistry \
Sample \
SampleDispatcher \
SampleHandler \
SampleType \
WrappingDecoder \
WrappingEncoder
.PHONY: all
all: labcomm2014.dll
labcomm2014.dll: $(MODULES:%=se/lth/control/labcomm2014/%.cs) Makefile
mcs -out:$@ -target:library $(filter %.cs, $^)
.PHONY: test
test:
.PHONY: clean
clean:
.PHONY: distclean
distclean:
rm -f labcomm2014.dll
namespace se.lth.control.labcomm {
public interface LabCommHandler {
}
}
\ No newline at end of file
public interface LabCommSample {
}
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
public class LabComm {
public class Constant {
public const string CURRENT_VERSION = "LabComm2014";
/*
* Allowed packet tags
*/
public const int VERSION = 0x01;
public const int SAMPLE_DEF = 0x02;
public const int SAMPLE_REF = 0x03;
public const int TYPE_DEF = 0x04;
public const int TYPE_BINDING = 0x05;
public const int PRAGMA = 0x3f;
public const int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */
/*
* Predeclared aggregate type indices
* Predefined aggregate type indices
*/
public const int TYPEDEF = 0x01;
public const int SAMPLE = 0x02;
public const int ARRAY = 0x10;
public const int STRUCT = 0x11;
......@@ -21,12 +32,8 @@ namespace se.lth.control.labcomm {
public const int FLOAT = 0x25;
public const int DOUBLE = 0x26;
public const int STRING = 0x27;
public const int SAMPLE = 0x28;
/*
* start of user defined types
*/
public const int FIRST_USER_INDEX = 0x80;
}
}
using System;
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
public interface LabCommDecoder {
public interface Decoder {
void runOne();
void run();
void register(SampleDispatcher dispatcher,
SampleHandler handler);
void registerSampleRef(SampleDispatcher dispatcher);
void register(LabCommDispatcher dispatcher,
LabCommHandler handler);
bool decodeBoolean();
byte decodeByte();
short decodeShort();
......@@ -14,6 +18,8 @@ namespace se.lth.control.labcomm {
float decodeFloat();
double decodeDouble();
String decodeString();
int decodePacked32();
SampleDispatcher decodeSampleRef();
}
......