Commit 713c78f4 authored by Anders Nilsson's avatar Anders Nilsson
Browse files

Added C library files.

parent b3a45cd4
AST
AST/*
LabComm.class
labComm.jar
lib/java/se/lth/control/labcomm/LabComm.class
lib/java/se/lth/control/labcomm/LabCommDecoderChannel.class
lib/java/se/lth/control/labcomm/LabCommDecoder.class
lib/java/se/lth/control/labcomm/LabCommDecoderRegistry.class
lib/java/se/lth/control/labcomm/LabCommDecoderRegistry$Entry.class
lib/java/se/lth/control/labcomm/LabCommDispatcher.class
lib/java/se/lth/control/labcomm/LabCommEncoderChannel.class
lib/java/se/lth/control/labcomm/LabCommEncoder.class
lib/java/se/lth/control/labcomm/LabCommEncoderRegistry.class
lib/java/se/lth/control/labcomm/LabCommEncoderRegistry$Entry.class
lib/java/se/lth/control/labcomm/LabCommHandler.class
lib/java/se/lth/control/labcomm/LabCommReader.class
lib/java/se/lth/control/labcomm/LabCommSample.class
lib/java/se/lth/control/labcomm/LabCommType.class
lib/java/se/lth/control/labcomm/LabCommWriter.class
#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
#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) { \