From 713c78f44c443da1e93a43d4a1a8684360d84613 Mon Sep 17 00:00:00 2001
From: Anders Nilsson <anders.nilsson@cs.lth.se>
Date: Thu, 20 Jan 2011 11:01:58 +0100
Subject: [PATCH] Added C library files.
---
.bzrignore | 19 ++
lib/c/labcomm.c | 437 ++++++++++++++++++++++++++++++++++++++++
lib/c/labcomm.h | 83 ++++++++
lib/c/labcomm_private.h | 290 ++++++++++++++++++++++++++
4 files changed, 829 insertions(+)
create mode 100644 .bzrignore
create mode 100644 lib/c/labcomm.c
create mode 100644 lib/c/labcomm.h
create mode 100644 lib/c/labcomm_private.h
diff --git a/.bzrignore b/.bzrignore
new file mode 100644
index 0000000..9aefbba
--- /dev/null
+++ b/.bzrignore
@@ -0,0 +1,19 @@
+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
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
new file mode 100644
index 0000000..ee93aec
--- /dev/null
+++ b/lib/c/labcomm.c
@@ -0,0 +1,437 @@
+#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);
+}
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
new file mode 100644
index 0000000..9fed697
--- /dev/null
+++ b/lib/c/labcomm.h
@@ -0,0 +1,83 @@
+#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
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
new file mode 100644
index 0000000..3bc5140
--- /dev/null
+++ b/lib/c/labcomm_private.h
@@ -0,0 +1,290 @@
+#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
--
GitLab