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 436 additions and 487 deletions
/* Hack to get a link error with (hopefully) useful information if not linked
with -Tlabcomm.linkscript */
"You need to link with '-Tlabcomm.linkscript'"=0;
SECTIONS {
labcomm : {
labcomm_first_signature = ABSOLUTE(.) ;
*(labcomm)
labcomm_last_signature = ABSOLUTE(.) ;
}
}
INSERT AFTER .data;
#ifndef __LABCOMM_ERROR_H__
#define __LABCOMM_ERROR_H__
enum labcomm_error {
#define LABCOMM_ERROR(name, description) name ,
#include "labcomm_error.h"
#undef LABCOMM_ERROR
};
#endif
#ifdef LABCOMM_ERROR
LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE,
"Encoder has no registration for this signature")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
"The labcomm buffer is full")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
"Decoder: Unknown datatype")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_INDEX_MISMATCH,
"Decoder: index mismatch")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
"Decoder: type not found")
LABCOMM_ERROR(LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
"This function is not yet implemented")
LABCOMM_ERROR(LABCOMM_ERROR_MEMORY,
"Could not allocate memory")
LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF,
"User defined error")
#endif
#include <errno.h>
#include <pthread.h>
#include "labcomm.h"
#include "labcomm_private.h"
struct labcomm_pthread_mutex_lock {
struct labcomm_lock lock;
pthread_mutex_t mutex;
pthread_cond_t cond;
};
int do_free(struct labcomm_lock *l)
{
struct labcomm_pthread_mutex_lock *lock = l->context;
struct labcomm_memory *memory = l->memory;
pthread_cond_destroy(&lock->cond);
pthread_mutex_destroy(&lock->mutex);
labcomm_memory_free(memory, 0, lock);
return 0;
}
int do_acquire(struct labcomm_lock *l)
{
struct labcomm_pthread_mutex_lock *lock = l->context;
if (pthread_mutex_lock(&lock->mutex) != 0) {
return -errno;
}
return 0;
}
int do_release(struct labcomm_lock *l)
{
struct labcomm_pthread_mutex_lock *lock = l->context;
if (pthread_mutex_unlock(&lock->mutex) != 0) {
return -errno;
}
return 0;
}
int do_wait(struct labcomm_lock *l, useconds_t usec)
{
struct labcomm_pthread_mutex_lock *lock = l->context;
if (usec <= 0) {
if (pthread_cond_wait(&lock->cond, &lock->mutex) != 0) {
return -errno;
}
} else {
struct timespec abstime;
time_t sec = usec / 1000000;
long nsec = (usec % 1000000) * 1000;
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_nsec += nsec;
abstime.tv_sec += sec + abstime.tv_nsec / 1000000000;
abstime.tv_nsec %= 1000000000;
if (pthread_cond_timedwait(&lock->cond, &lock->mutex, &abstime) != 0) {
return -errno;
}
}
return 0;
}
int do_notify(struct labcomm_lock *l)
{
struct labcomm_pthread_mutex_lock *lock = l->context;
if (pthread_cond_broadcast(&lock->cond) != 0) {
return -errno;
}
return 0;
}
static struct labcomm_lock_action action = {
.free = do_free,
.acquire = do_acquire,
.release = do_release,
.wait = do_wait,
.notify = do_notify
};
struct labcomm_lock *labcomm_pthread_mutex_lock_new(
struct labcomm_memory *memory)
{
struct labcomm_lock *result = NULL;
struct labcomm_pthread_mutex_lock *lock;
lock = labcomm_memory_alloc(memory, 0, sizeof(*lock));
if (lock == NULL) {
goto out;
}
if (pthread_mutex_init(&lock->mutex, NULL) != 0) {
goto free_lock;
}
if (pthread_cond_init(&lock->cond, NULL) != 0) {
goto destroy_mutex;
}
lock->lock.memory = memory;
lock->lock.action = &action;
lock->lock.context = lock;
result = &lock->lock;
goto out;
destroy_mutex:
pthread_mutex_destroy(&lock->mutex);
free_lock:
labcomm_memory_free(memory, 0, lock);
out:
return result;
}
INPUT(liblabcomm.so.1)
/* Hack to get a link error with (hopefully) useful information if not linked
with -Tlabcomm.linkscript */
"You need to link with '-Tlabcomm.linkscript'"+=1;
/*INPUT(liblabcomm.a)*/
## 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
#include "CUnit/Basic.h"
#include "CUnit/Console.h"
#include <stdbool.h>
#include <stdlib.h>
#include <labcomm.h>
#include <labcomm_mem_writer.h>
#include <labcomm_mem_reader.h>
#include "test/testdata/gen/test_sample.h"
#define TEST_BUFFER_SIZE (50)
void test_error_handler(enum labcomm_error error_id, size_t nbr_va_args, ...);
int init_suit_labcomm()
{
return 0;
}
int clean_suit_labcomm()
{
return 0;
}
void setup_connected_encoder_decoder(struct labcomm_encoder **enc,
labcomm_mem_writer_context_t *enc_ctx,
struct labcomm_decoder **dec,
labcomm_mem_reader_context_t *dec_ctx)
{
enc_ctx->write_pos = 0;
enc_ctx->buf = malloc(TEST_BUFFER_SIZE);
enc_ctx->length = TEST_BUFFER_SIZE;
*enc = labcomm_encoder_new(labcomm_mem_writer, enc_ctx);
dec_ctx->size = 0;
dec_ctx->enc_data = enc_ctx->buf;
*dec = labcomm_decoder_new(labcomm_mem_reader, dec_ctx);
labcomm_register_error_handler_decoder(*dec, test_error_handler);
labcomm_register_error_handler_encoder(*enc, test_error_handler);
}
static bool in_error = false;
static enum labcomm_error in_error_id = LABCOMM_ERROR_ENUM_BEGIN_GUARD;
void test_error_handler(enum labcomm_error error_id, size_t nbr_va_args, ...)
{
in_error = true;
in_error_id = error_id;
}
static bool got_sample = false;
void test_decoder_handle_test_sample_test_var(test_sample_test_var *v, void *ctx)
{
got_sample = true;
}
void test_decoder_decode_sig()
{
labcomm_mem_writer_context_t enc_ctx;
struct labcomm_encoder *encoder;
labcomm_mem_reader_context_t dec_ctx;
struct labcomm_decoder *decoder;
setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
labcomm_encoder_register_test_sample_test_var(encoder);
dec_ctx.size = enc_ctx.write_pos;
labcomm_decoder_register_test_sample_test_var(decoder,
test_decoder_handle_test_sample_test_var, NULL);
labcomm_decoder_decode_one(decoder);
CU_ASSERT_FALSE(in_error);
enc_ctx.write_pos = 0;
test_sample_test_var var = 1;
labcomm_encode_test_sample_test_var(encoder, &var);
dec_ctx.size = enc_ctx.write_pos;
labcomm_decoder_decode_one(decoder);
CU_ASSERT_FALSE(in_error);
CU_ASSERT_FALSE(got_sample);
labcomm_decoder_free(decoder);
labcomm_encoder_free(encoder);
free(enc_ctx.buf);
in_error = false;
in_error_id = LABCOMM_ERROR_ENUM_BEGIN_GUARD;
got_sample = false;
}
static bool got_new_datatype = false;
static labcomm_signature_t new_sig;
int test_new_datatype(struct labcomm_decoder *decoder,
labcomm_signature_t *sig)
{
got_new_datatype = true;
memcpy(&new_sig, sig, sizeof(labcomm_signature_t));
return 0;
}
void test_decode_unreg_signature_handle()
{
labcomm_mem_writer_context_t enc_ctx;
struct labcomm_encoder *encoder;
labcomm_mem_reader_context_t dec_ctx;
struct labcomm_decoder *decoder;
setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
labcomm_encoder_register_test_sample_test_var(encoder);
dec_ctx.size = enc_ctx.write_pos;
labcomm_decoder_register_new_datatype_handler(decoder, test_new_datatype);
labcomm_decoder_decode_one(decoder);
CU_ASSERT_TRUE(got_new_datatype);
CU_ASSERT_EQUAL(
memcmp(new_sig.signature, dec_ctx.enc_data, dec_ctx.size), 0);
got_new_datatype = false;
labcomm_decoder_free(decoder);
labcomm_encoder_free(encoder);
free(enc_ctx.buf);
}
void test_decode_unreg_signature_error()
{
labcomm_mem_writer_context_t enc_ctx;
struct labcomm_encoder *encoder;
labcomm_mem_reader_context_t dec_ctx;
struct labcomm_decoder *decoder;
setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
labcomm_encoder_register_test_sample_test_var(encoder);
dec_ctx.size = enc_ctx.write_pos;
labcomm_decoder_decode_one(decoder);
CU_ASSERT_TRUE(in_error);
CU_ASSERT_EQUAL(in_error_id, LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE);
got_new_datatype = false;
labcomm_decoder_free(decoder);
labcomm_encoder_free(encoder);
free(enc_ctx.buf);
}
int main()
{
CU_pSuite suite_decoder = NULL;
// Initialize CUnit test registry.
if (CUE_SUCCESS != CU_initialize_registry()) {
return CU_get_error();
}
// Add our test suites.
suite_decoder = CU_add_suite("transport_enc_dec",
init_suit_labcomm, clean_suit_labcomm);
if (suite_decoder == NULL) {
CU_cleanup_registry();
return CU_get_error();
}
if (
(CU_add_test(suite_decoder, "test_decoder_decode_sig",
test_decoder_decode_sig) == NULL)
||
(CU_add_test(suite_decoder, "test_decode_unreg_signature_handle",
test_decode_unreg_signature_handle) == NULL)
||
(CU_add_test(suite_decoder, "test_decode_unreg_signature_error",
test_decode_unreg_signature_error) == NULL)
) {
CU_cleanup_registry();
return CU_get_error();
}
// Set verbosity.
CU_basic_set_mode(CU_BRM_VERBOSE);
/*CU_console_run_tests();*/
// Run all test suites.
CU_basic_run_tests();
// Clean up.
CU_cleanup_registry();
return CU_get_error();
}
sample int test_var;
#!/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=LabCommDispatcher \
LabCommDecoderRegistry \
LabComm \
LabCommSample \
LabCommHandler \
LabCommEncoderRegistry \
LabCommDecoder \
LabCommType \
LabCommEncoderChannel \
LabCommEncoder \
LabCommDecoderChannel \
MODULES=Constant\
Decoder \
DecoderChannel \
DecoderRegistry \
Encoder \
EncoderChannel \
EncoderRegistry \
RenamingDecoder \
RenamingEncoder \
RenamingRegistry \
Sample \
SampleDispatcher \
SampleHandler \
SampleType \
WrappingDecoder \
WrappingEncoder
all: labcomm.dll
.PHONY: all
all: labcomm2014.dll
labcomm.dll: $(MODULES:%=se/lth/control/labcomm/%.cs) Makefile
labcomm2014.dll: $(MODULES:%=se/lth/control/labcomm2014/%.cs) Makefile
mcs -out:$@ -target:library $(filter %.cs, $^)
.PHONY: test
test:
.PHONY: clean
clean:
rm -f labcomm.dll
.PHONY: distclean
distclean:
rm -f labcomm2014.dll
namespace se.lth.control.labcomm {
public interface LabCommHandler {
}
}
\ No newline at end of file
public interface LabCommSample {
}
public interface LabCommType {
}
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
public class LabComm {
public class Constant {
public const string VERSION = "LabComm2013";
public const string CURRENT_VERSION = "LabComm2014";
/*
* Predeclared aggregate type indices
/*
* 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 */
/*
* Predefined aggregate type indices
*/
public const int TYPEDEF = 0x01;
public const int SAMPLE = 0x02;
public const int ARRAY = 0x10;
public const int STRUCT = 0x11;
......@@ -23,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 = 0x40;
}
}
using System;
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
public interface LabCommDecoder {
public interface Decoder {
void register(LabCommDispatcher dispatcher,
LabCommHandler handler);
void runOne();
void run();
void register(SampleDispatcher dispatcher,
SampleHandler handler);
void registerSampleRef(SampleDispatcher dispatcher);
bool decodeBoolean();
byte decodeByte();
......@@ -16,6 +19,7 @@ namespace se.lth.control.labcomm {
double decodeDouble();
String decodeString();
int decodePacked32();
SampleDispatcher decodeSampleRef();
}
......
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
public class LabCommDecoderChannel : LabCommDecoder {
public class DecoderChannel : Decoder {
private Stream stream;
private LabCommDecoderRegistry registry = new LabCommDecoderRegistry();
private DecoderRegistry def_registry = new DecoderRegistry();
private DecoderRegistry ref_registry = new DecoderRegistry();
byte[] buf = new byte[8];
public LabCommDecoderChannel(Stream stream) {
public DecoderChannel(Stream stream) {
this.stream = stream;
String version = decodeString();
if (version != LabComm.VERSION) {
throw new IOException("LabComm version mismatch " +
version + " != " + LabComm.VERSION);
}
}
public void runOne() {
bool done = false;
while (!done) {
int tag = decodePacked32();
int length = decodePacked32();
switch (tag) {
case LabComm.TYPEDEF:
case LabComm.SAMPLE: {
case Constant.VERSION: {
String version = decodeString();
if (version != Constant.CURRENT_VERSION) {
throw new IOException("LabComm version mismatch " +
version + " != " + Constant.CURRENT_VERSION);
}
} break;
case Constant.SAMPLE_DEF: {
int index = decodePacked32();
String name = decodeString();
MemoryStream signature = new MemoryStream();
collectFlatSignature(new LabCommEncoderChannel(signature, false));
registry.add(index, name, signature.ToArray());
String name = decodeIntentions();
int signature_length = decodePacked32();
byte[] signature = new byte[signature_length];
ReadBytes(signature, signature_length);
def_registry.add(index, name, signature);
} break;
case Constant.SAMPLE_REF: {
int index = decodePacked32();
String name = decodeIntentions();
int signature_length = decodePacked32();
byte[] signature = new byte[signature_length];
ReadBytes(signature, signature_length);
ref_registry.add(index, name, signature);
} break;
case Constant.TYPE_DEF:
case Constant.TYPE_BINDING: {
for(int i=0; i<length;i++){
decodeByte();
}
} break;
default: {
LabCommDecoderRegistry.Entry e = registry.get(tag);
DecoderRegistry.Entry e = def_registry.get(tag);
if (e == null) {
throw new IOException("Unhandled tag " + tag);
}
LabCommDispatcher d = e.getDispatcher();
SampleDispatcher d = e.getSampleDispatcher();
if (d == null) {
throw new IOException("No dispatcher for '" + e.getName() + "'" + e.getSignature());
}
LabCommHandler h = e.getHandler();
SampleHandler h = e.getHandler();
if (h == null) {
throw new IOException("No handler for '" + e.getName() +"'");
}
......@@ -59,45 +77,13 @@ namespace se.lth.control.labcomm {
}
}
private void collectFlatSignature(LabCommEncoder e) {
int type = decodePacked32();
e.encodePacked32(type);
switch (type) {
case LabComm.ARRAY: {
int dimensions = decodePacked32();
e.encodePacked32(dimensions);
for (int i = 0 ; i < dimensions ; i++) {
e.encodePacked32(decodePacked32());
}
collectFlatSignature(e);
} break;
case LabComm.STRUCT: {
int fields = decodePacked32();
e.encodePacked32(fields);
for (int i = 0 ; i < fields ; i++) {
e.encodeString(decodeString());
collectFlatSignature(e);
}
} 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: {
throw new IOException("Unimplemented type=" + type);
}
}
e.end(null);
public void register(SampleDispatcher dispatcher,
SampleHandler handler) {
def_registry.add(dispatcher, handler);
}
public void register(LabCommDispatcher dispatcher,
LabCommHandler handler) {
registry.add(dispatcher, handler);
public void registerSampleRef(SampleDispatcher dispatcher) {
ref_registry.add(dispatcher, null);
}
private void ReadBytes(byte[] result, int length) {
......@@ -106,7 +92,7 @@ namespace se.lth.control.labcomm {
int count = stream.Read(result, offset, length - offset);
if (count <= 0)
throw new EndOfStreamException(
String.Format("End of stream reached with {0} bytes left to read",
String.Format("End of stream reached with {0} bytes left to read",
length - offset));
offset += count;
}
......@@ -129,7 +115,7 @@ namespace se.lth.control.labcomm {
public byte decodeByte() {
return (byte)ReadInt(1);
}
public short decodeShort() {
return (short)ReadInt(2);
}
......@@ -137,11 +123,11 @@ namespace se.lth.control.labcomm {
public int decodeInt() {
return (int)ReadInt(4);
}
public long decodeLong() {
return (long)ReadInt(8);
}
[StructLayout(LayoutKind.Explicit)]
private struct Int32SingleUnion {
......@@ -155,7 +141,7 @@ namespace se.lth.control.labcomm {
u.AsInt = (int)ReadInt(4);
return u.AsFloat;
}
public double decodeDouble() {
return BitConverter.Int64BitsToDouble(ReadInt(8));
}
......@@ -169,7 +155,7 @@ namespace se.lth.control.labcomm {
public int decodePacked32() {
Int64 res = 0;
bool cont = true;
bool cont = true;
do {
Int64 c = decodeByte();
......@@ -179,5 +165,41 @@ namespace se.lth.control.labcomm {
return (int) (res & 0xffffffff);
}
private byte[] decodeBytes() {
int len = decodePacked32();
byte[] result = new byte[len];
for(int i=0; i<len; i++) {
result[i] = decodeByte();
}
return result;
}
private String decodeIntentions() {
int numIntentions = decodePacked32();
string name = "";
for(int i = 0; i<numIntentions; i++) {
byte[] key = decodeBytes();
byte[] val = decodeBytes();
if(key.Length == 0) {
name = Encoding.UTF8.GetString(val, 0, val.Length);
}
}
return name;
}
}
public SampleDispatcher decodeSampleRef() {
int index = (int)ReadInt(4);
try {
DecoderRegistry.Entry e = ref_registry.get(index);
return e.getSampleDispatcher();
} catch (NullReferenceException) {
return null;
}
}
}
}
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
using System;
using System.Collections.Generic;
public class LabCommDecoderRegistry {
public class DecoderRegistry {
public class Entry {
private LabCommDispatcher dispatcher;
private LabCommHandler handler;
private SampleDispatcher dispatcher;
private SampleHandler handler;
private int index;
private String name;
private byte[] signature;
public Entry(LabCommDispatcher dispatcher,
LabCommHandler handler) {
public Entry(SampleDispatcher dispatcher,
SampleHandler handler) {
this.dispatcher = dispatcher;
this.name = dispatcher.getName();
this.signature = dispatcher.getSignature();
......@@ -27,19 +27,19 @@ namespace se.lth.control.labcomm {
this.signature = signature;
}
public LabCommDispatcher getDispatcher() {
public SampleDispatcher getSampleDispatcher() {
return dispatcher;
}
public void setDispatcher(LabCommDispatcher dispatcher) {
public void setSampleDispatcher(SampleDispatcher dispatcher) {
this.dispatcher = dispatcher;
}
public LabCommHandler getHandler() {
public SampleHandler getHandler() {
return handler;
}
public void setHandler(LabCommHandler handler) {
public void setHandler(SampleHandler handler) {
this.handler = handler;
}
......@@ -90,26 +90,26 @@ namespace se.lth.control.labcomm {
}
}
private Dictionary<Type, Entry> byClass;
private Dictionary<SampleDispatcher, Entry> byDispatcher;
private Dictionary<int, Entry> byIndex;
public LabCommDecoderRegistry() {
byClass = new Dictionary<Type, Entry>();
public DecoderRegistry() {
byDispatcher = new Dictionary<SampleDispatcher, Entry>();
byIndex = new Dictionary<int, Entry>();
}
public void add(LabCommDispatcher dispatcher,
LabCommHandler handler) {
public void add(SampleDispatcher dispatcher,
SampleHandler handler) {
lock(this) {
Entry e;
byClass.TryGetValue(dispatcher.getSampleClass(), out e);
byDispatcher.TryGetValue(dispatcher, out e);
if (e != null) {
e.check(dispatcher.getName(), dispatcher.getSignature());
e.setHandler(handler);
} else {
foreach (Entry e2 in byIndex.Values) {
if (e2.match(dispatcher.getName(), dispatcher.getSignature())) {
e2.setDispatcher(dispatcher);
e2.setSampleDispatcher(dispatcher);
e2.setHandler(handler);
e = e2;
break;
......@@ -117,7 +117,7 @@ namespace se.lth.control.labcomm {
}
if (e == null) {
e = new Entry(dispatcher, handler);
byClass.Add(dispatcher.getSampleClass(), e);
byDispatcher.Add(dispatcher, e);
}
}
}
......@@ -132,7 +132,7 @@ namespace se.lth.control.labcomm {
if (e != null) {
e.check(name, signature);
} else {
foreach (Entry e2 in byClass.Values) {
foreach (Entry e2 in byDispatcher.Values) {
if (e2.match(name, signature)) {
e2.setIndex(index);
e = e2;
......
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
using System;
public interface LabCommEncoder {
public interface Encoder {
void register(LabCommDispatcher dispatcher);
void begin(Type c);
void end(Type c);
void register(SampleDispatcher dispatcher);
void registerSampleRef(SampleDispatcher dispatcher);
void begin(SampleDispatcher dispatcher);
void end(SampleDispatcher dispatcher);
void encodeBoolean(bool value);
void encodeByte(byte value);
......@@ -17,6 +18,7 @@ namespace se.lth.control.labcomm {
void encodeDouble(double value);
void encodeString(String value);
void encodePacked32(Int64 value);
void encodeSampleRef(SampleDispatcher value);
}
......
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
public class LabCommEncoderChannel : LabCommEncoder {
public class EncoderChannel : Encoder {
private Stream writer;
private MemoryStream bytes = new MemoryStream();
private LabCommEncoderRegistry registry = new LabCommEncoderRegistry();
private EncoderRegistry def_registry = new EncoderRegistry();
private EncoderRegistry ref_registry = new EncoderRegistry();
byte[] buf = new byte[8];
private int current_tag;
public LabCommEncoderChannel(Stream writer, bool emitVersion) {
public EncoderChannel(Stream writer) {
this.writer = writer;
if (emitVersion) {
encodeString(LabComm.VERSION);
}
begin(Constant.VERSION);
encodeString(Constant.CURRENT_VERSION);
end(null);
}
public LabCommEncoderChannel(Stream writer) : this(writer, true) {
public void register(SampleDispatcher dispatcher) {
int index = def_registry.add(dispatcher);
begin(Constant.SAMPLE_DEF);
encodePacked32(index);
encodeIntentions(dispatcher.getName());
byte[] signature = dispatcher.getSignature();
encodePacked32(signature.Length);
for (int i = 0 ; i < signature.Length ; i++) {
encodeByte(signature[i]);
}
end(null);
}
public void register(LabCommDispatcher dispatcher) {
int index = registry.add(dispatcher);
encodePacked32(LabComm.SAMPLE);
public void registerSampleRef(SampleDispatcher dispatcher) {
int index = ref_registry.add(dispatcher);
begin(Constant.SAMPLE_REF);
encodePacked32(index);
encodeString(dispatcher.getName());
encodeIntentions(dispatcher.getName());
byte[] signature = dispatcher.getSignature();
encodePacked32(signature.Length);
for (int i = 0 ; i < signature.Length ; i++) {
encodeByte(signature[i]);
}
end(null);
}
public void begin(Type c) {
encodePacked32(registry.getTag(c));
private void begin(int tag) {
current_tag = tag;
bytes.SetLength(0);
}
public void begin(SampleDispatcher identity) {
begin(def_registry.getTag(identity));
}
public void end(Type c) {
public void end(SampleDispatcher identity) {
WritePacked32(writer, current_tag);
WritePacked32(writer, bytes.Length);
bytes.WriteTo(writer);
bytes.SetLength(0);
writer.Flush();
}
private void WritePacked32(Stream s, Int64 value) {
Int64 v = value & 0xffffffff;
int i;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
buf[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
}
for (i = i - 1 ; i >= 0 ; i--) {
s.WriteByte(buf[i]);
}
}
private void WriteInt(Int64 value, int length) {
for (int i = length - 1 ; i >= 0 ; i--) {
buf[i] = (byte)(value & 0xff);
......@@ -96,16 +129,23 @@ namespace se.lth.control.labcomm {
}
public void encodePacked32(Int64 value) {
byte[] tmp = new byte[5];
Int64 v = value & 0xffffffff;
int i;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp[i] = (byte)(v & 0x7f);
}
for (i = i - 1 ; i >= 0 ; i--) {
encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
WritePacked32(bytes, value);
}
private void encodeIntentions(String name) {
encodePacked32(1); // one intention field
encodePacked32(0); // empty key: name
encodeString(name);
}
public void encodeSampleRef(SampleDispatcher value) {
int index = 0;
try {
index = ref_registry.getTag(value);
} catch (NullReferenceException) {
}
WriteInt(index, 4);
}
}
}
namespace se.lth.control.labcomm {
namespace se.lth.control.labcomm2014 {
using System;
using System.Collections.Generic;
public class LabCommEncoderRegistry {
public class EncoderRegistry {
public class Entry {
private LabCommDispatcher dispatcher;
private SampleDispatcher dispatcher;
private int index;
public Entry(LabCommDispatcher dispatcher, int index) {
public Entry(SampleDispatcher dispatcher, int index) {
this.dispatcher = dispatcher;
this.index = index;
}
public LabCommDispatcher getDispatcher() {
public SampleDispatcher getSampleDispatcher() {
return dispatcher;
}
......@@ -25,30 +25,30 @@ namespace se.lth.control.labcomm {
}
private int userIndex = LabComm.FIRST_USER_INDEX;
private Dictionary<Type, Entry> byClass;
private int userIndex = Constant.FIRST_USER_INDEX;
private Dictionary<SampleDispatcher, Entry> byDispatcher;
public LabCommEncoderRegistry() {
byClass = new Dictionary<Type, Entry>();
public EncoderRegistry() {
byDispatcher = new Dictionary<SampleDispatcher, Entry>();
}
public int add(LabCommDispatcher dispatcher) {
public int add(SampleDispatcher dispatcher) {
lock(this) {
Entry e;
byClass.TryGetValue(dispatcher.getSampleClass(), out e);
byDispatcher.TryGetValue(dispatcher, out e);
if (e == null) {
e = new Entry(dispatcher, userIndex);
byClass.Add(dispatcher.getSampleClass(), e);
byDispatcher.Add(dispatcher, e);
userIndex++;
}
return e.getIndex();
}
}
public int getTag(Type sample) {
public int getTag(SampleDispatcher sample) {
lock(this) {
Entry e;
byClass.TryGetValue(sample, out e);
byDispatcher.TryGetValue(sample, out e);
if (e == null) {
throw new Exception("'" +
sample.ToString() +
......@@ -60,4 +60,4 @@ namespace se.lth.control.labcomm {
}
}
\ No newline at end of file
}