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
Select Git revision

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Select Git revision
Show changes
Showing
with 863 additions and 318 deletions
#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 ARRAY = 0x10;
public const int STRUCT = 0x11; public const int STRUCT = 0x11;
...@@ -21,11 +32,7 @@ namespace se.lth.control.labcomm { ...@@ -21,11 +32,7 @@ namespace se.lth.control.labcomm {
public const int FLOAT = 0x25; public const int FLOAT = 0x25;
public const int DOUBLE = 0x26; public const int DOUBLE = 0x26;
public const int STRING = 0x27; public const int STRING = 0x27;
public const int SAMPLE = 0x28;
/*
* start of user defined types
*/
public const int FIRST_USER_INDEX = 0x80;
} }
......
using System; 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(); bool decodeBoolean();
byte decodeByte(); byte decodeByte();
short decodeShort(); short decodeShort();
...@@ -14,6 +18,8 @@ namespace se.lth.control.labcomm { ...@@ -14,6 +18,8 @@ namespace se.lth.control.labcomm {
float decodeFloat(); float decodeFloat();
double decodeDouble(); double decodeDouble();
String decodeString(); String decodeString();
int decodePacked32();
SampleDispatcher decodeSampleRef();
} }
......
namespace se.lth.control.labcomm { namespace se.lth.control.labcomm2014 {
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
public class LabCommDecoderChannel : LabCommDecoder { public class DecoderChannel : Decoder {
private Stream stream; 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]; byte[] buf = new byte[8];
public LabCommDecoderChannel(Stream stream) { public DecoderChannel(Stream stream) {
this.stream = stream; this.stream = stream;
} }
public void runOne() { public void runOne() {
bool done = false; bool done = false;
while (!done) { while (!done) {
int tag = decodeInt(); int tag = decodePacked32();
int length = decodePacked32();
switch (tag) { switch (tag) {
case LabComm.TYPEDEF: case Constant.VERSION: {
case LabComm.SAMPLE: { String version = decodeString();
int index = decodeInt(); if (version != Constant.CURRENT_VERSION) {
String name = decodeString(); throw new IOException("LabComm version mismatch " +
MemoryStream signature = new MemoryStream(); version + " != " + Constant.CURRENT_VERSION);
collectFlatSignature(new LabCommEncoderChannel(signature)); }
registry.add(index, name, signature.ToArray()); } break;
case Constant.SAMPLE_DEF: {
int index = decodePacked32();
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; } break;
default: { default: {
LabCommDecoderRegistry.Entry e = registry.get(tag); DecoderRegistry.Entry e = def_registry.get(tag);
if (e == null) { if (e == null) {
throw new IOException("Unhandled tag " + tag); throw new IOException("Unhandled tag " + tag);
} }
LabCommDispatcher d = e.getDispatcher(); SampleDispatcher d = e.getSampleDispatcher();
if (d == null) { if (d == null) {
throw new IOException("No dispatcher for '" + e.getName() + "'" + e.getSignature()); throw new IOException("No dispatcher for '" + e.getName() + "'" + e.getSignature());
} }
LabCommHandler h = e.getHandler(); SampleHandler h = e.getHandler();
if (h == null) { if (h == null) {
throw new IOException("No handler for '" + e.getName() +"'"); throw new IOException("No handler for '" + e.getName() +"'");
} }
...@@ -54,45 +77,13 @@ namespace se.lth.control.labcomm { ...@@ -54,45 +77,13 @@ namespace se.lth.control.labcomm {
} }
} }
private void collectFlatSignature(LabCommEncoder e) { public void register(SampleDispatcher dispatcher,
int type = decodeInt(); SampleHandler handler) {
e.encodeInt(type); def_registry.add(dispatcher, handler);
switch (type) {
case LabComm.ARRAY: {
int dimensions = decodeInt();
e.encodeInt(dimensions);
for (int i = 0 ; i < dimensions ; i++) {
e.encodeInt(decodeInt());
}
collectFlatSignature(e);
} break;
case LabComm.STRUCT: {
int fields = decodeInt();
e.encodeInt(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(LabCommDispatcher dispatcher, public void registerSampleRef(SampleDispatcher dispatcher) {
LabCommHandler handler) { ref_registry.add(dispatcher, null);
registry.add(dispatcher, handler);
} }
private void ReadBytes(byte[] result, int length) { private void ReadBytes(byte[] result, int length) {
...@@ -108,10 +99,11 @@ namespace se.lth.control.labcomm { ...@@ -108,10 +99,11 @@ namespace se.lth.control.labcomm {
} }
private Int64 ReadInt(int length) { private Int64 ReadInt(int length) {
int result = 0; Int64 result = 0;
ReadBytes(buf, length); ReadBytes(buf, length);
for (int i = 0 ; i < length ; i++) { for (int i = 0 ; i < length ; i++) {
result = (result << 8) + buf[i]; result = (result << 8) + buf[i];
} }
return result; return result;
} }
...@@ -155,12 +147,59 @@ namespace se.lth.control.labcomm { ...@@ -155,12 +147,59 @@ namespace se.lth.control.labcomm {
} }
public String decodeString() { public String decodeString() {
int length = (int)ReadInt(4); int length = decodePacked32();
byte[] buf = new byte[length]; byte[] buf = new byte[length];
ReadBytes(buf, length); ReadBytes(buf, length);
return Encoding.UTF8.GetString(buf); return Encoding.UTF8.GetString(buf);
} }
public int decodePacked32() {
Int64 res = 0;
bool cont = true;
do {
Int64 c = decodeByte();
res = (res << 7) | (c & 0x7f);
cont = (c & 0x80) != 0;
} while(cont);
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;
using System.Collections.Generic; using System.Collections.Generic;
public class LabCommDecoderRegistry { public class DecoderRegistry {
public class Entry { public class Entry {
private LabCommDispatcher dispatcher; private SampleDispatcher dispatcher;
private LabCommHandler handler; private SampleHandler handler;
private int index; private int index;
private String name; private String name;
private byte[] signature; private byte[] signature;
public Entry(LabCommDispatcher dispatcher, public Entry(SampleDispatcher dispatcher,
LabCommHandler handler) { SampleHandler handler) {
this.dispatcher = dispatcher; this.dispatcher = dispatcher;
this.name = dispatcher.getName(); this.name = dispatcher.getName();
this.signature = dispatcher.getSignature(); this.signature = dispatcher.getSignature();
...@@ -27,19 +27,19 @@ namespace se.lth.control.labcomm { ...@@ -27,19 +27,19 @@ namespace se.lth.control.labcomm {
this.signature = signature; this.signature = signature;
} }
public LabCommDispatcher getDispatcher() { public SampleDispatcher getSampleDispatcher() {
return dispatcher; return dispatcher;
} }
public void setDispatcher(LabCommDispatcher dispatcher) { public void setSampleDispatcher(SampleDispatcher dispatcher) {
this.dispatcher = dispatcher; this.dispatcher = dispatcher;
} }
public LabCommHandler getHandler() { public SampleHandler getHandler() {
return handler; return handler;
} }
public void setHandler(LabCommHandler handler) { public void setHandler(SampleHandler handler) {
this.handler = handler; this.handler = handler;
} }
...@@ -90,26 +90,26 @@ namespace se.lth.control.labcomm { ...@@ -90,26 +90,26 @@ namespace se.lth.control.labcomm {
} }
} }
private Dictionary<Type, Entry> byClass; private Dictionary<SampleDispatcher, Entry> byDispatcher;
private Dictionary<int, Entry> byIndex; private Dictionary<int, Entry> byIndex;
public LabCommDecoderRegistry() { public DecoderRegistry() {
byClass = new Dictionary<Type, Entry>(); byDispatcher = new Dictionary<SampleDispatcher, Entry>();
byIndex = new Dictionary<int, Entry>(); byIndex = new Dictionary<int, Entry>();
} }
public void add(LabCommDispatcher dispatcher, public void add(SampleDispatcher dispatcher,
LabCommHandler handler) { SampleHandler handler) {
lock(this) { lock(this) {
Entry e; Entry e;
byClass.TryGetValue(dispatcher.getSampleClass(), out e); byDispatcher.TryGetValue(dispatcher, out e);
if (e != null) { if (e != null) {
e.check(dispatcher.getName(), dispatcher.getSignature()); e.check(dispatcher.getName(), dispatcher.getSignature());
e.setHandler(handler); e.setHandler(handler);
} else { } else {
foreach (Entry e2 in byIndex.Values) { foreach (Entry e2 in byIndex.Values) {
if (e2.match(dispatcher.getName(), dispatcher.getSignature())) { if (e2.match(dispatcher.getName(), dispatcher.getSignature())) {
e2.setDispatcher(dispatcher); e2.setSampleDispatcher(dispatcher);
e2.setHandler(handler); e2.setHandler(handler);
e = e2; e = e2;
break; break;
...@@ -117,7 +117,7 @@ namespace se.lth.control.labcomm { ...@@ -117,7 +117,7 @@ namespace se.lth.control.labcomm {
} }
if (e == null) { if (e == null) {
e = new Entry(dispatcher, handler); e = new Entry(dispatcher, handler);
byClass.Add(dispatcher.getSampleClass(), e); byDispatcher.Add(dispatcher, e);
} }
} }
} }
...@@ -132,7 +132,7 @@ namespace se.lth.control.labcomm { ...@@ -132,7 +132,7 @@ namespace se.lth.control.labcomm {
if (e != null) { if (e != null) {
e.check(name, signature); e.check(name, signature);
} else { } else {
foreach (Entry e2 in byClass.Values) { foreach (Entry e2 in byDispatcher.Values) {
if (e2.match(name, signature)) { if (e2.match(name, signature)) {
e2.setIndex(index); e2.setIndex(index);
e = e2; e = e2;
......
namespace se.lth.control.labcomm { namespace se.lth.control.labcomm2014 {
using System; using System;
public interface LabCommEncoder { public interface Encoder {
void register(SampleDispatcher dispatcher);
void registerSampleRef(SampleDispatcher dispatcher);
void begin(SampleDispatcher dispatcher);
void end(SampleDispatcher dispatcher);
void register(LabCommDispatcher dispatcher);
void begin(Type c);
void end(Type c);
void encodeBoolean(bool value); void encodeBoolean(bool value);
void encodeByte(byte value); void encodeByte(byte value);
void encodeShort(short value); void encodeShort(short value);
...@@ -15,6 +17,8 @@ namespace se.lth.control.labcomm { ...@@ -15,6 +17,8 @@ namespace se.lth.control.labcomm {
void encodeFloat(float value); void encodeFloat(float value);
void encodeDouble(double value); void encodeDouble(double value);
void encodeString(String 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;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public class LabCommEncoderChannel : LabCommEncoder { public class EncoderChannel : Encoder {
private Stream writer; private Stream writer;
private MemoryStream bytes = new MemoryStream(); 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]; byte[] buf = new byte[8];
private int current_tag;
public LabCommEncoderChannel(Stream writer) { public EncoderChannel(Stream writer) {
this.writer = writer; this.writer = writer;
begin(Constant.VERSION);
encodeString(Constant.CURRENT_VERSION);
end(null);
}
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) { public void registerSampleRef(SampleDispatcher dispatcher) {
int index = registry.add(dispatcher); int index = ref_registry.add(dispatcher);
encodeInt(LabComm.SAMPLE); begin(Constant.SAMPLE_REF);
encodeInt(index); encodePacked32(index);
encodeString(dispatcher.getName()); encodeIntentions(dispatcher.getName());
byte[] signature = dispatcher.getSignature(); byte[] signature = dispatcher.getSignature();
encodePacked32(signature.Length);
for (int i = 0 ; i < signature.Length ; i++) { for (int i = 0 ; i < signature.Length ; i++) {
encodeByte(signature[i]); encodeByte(signature[i]);
} }
end(null); end(null);
} }
public void begin(Type c) { private void begin(int tag) {
encodeInt(registry.getTag(c)); 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.WriteTo(writer);
bytes.SetLength(0); 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) { private void WriteInt(Int64 value, int length) {
...@@ -46,7 +86,7 @@ namespace se.lth.control.labcomm { ...@@ -46,7 +86,7 @@ namespace se.lth.control.labcomm {
} }
public void encodeBoolean(bool value) { public void encodeBoolean(bool value) {
WriteInt(value ? 0 : 1, 1); WriteInt(value ? 1 : 0, 1);
} }
public void encodeByte(byte value) { public void encodeByte(byte value) {
...@@ -84,9 +124,28 @@ namespace se.lth.control.labcomm { ...@@ -84,9 +124,28 @@ namespace se.lth.control.labcomm {
public void encodeString(String value) { public void encodeString(String value) {
byte[] buf = Encoding.UTF8.GetBytes(value); byte[] buf = Encoding.UTF8.GetBytes(value);
WriteInt(buf.Length, 4); encodePacked32(buf.Length);
bytes.Write(buf, 0, buf.Length); bytes.Write(buf, 0, buf.Length);
} }
public void encodePacked32(Int64 value) {
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;
using System.Collections.Generic; using System.Collections.Generic;
public class LabCommEncoderRegistry { public class EncoderRegistry {
public class Entry { public class Entry {
private LabCommDispatcher dispatcher; private SampleDispatcher dispatcher;
private int index; private int index;
public Entry(LabCommDispatcher dispatcher, int index) { public Entry(SampleDispatcher dispatcher, int index) {
this.dispatcher = dispatcher; this.dispatcher = dispatcher;
this.index = index; this.index = index;
} }
public LabCommDispatcher getDispatcher() { public SampleDispatcher getSampleDispatcher() {
return dispatcher; return dispatcher;
} }
...@@ -25,30 +25,30 @@ namespace se.lth.control.labcomm { ...@@ -25,30 +25,30 @@ namespace se.lth.control.labcomm {
} }
private int userIndex = LabComm.FIRST_USER_INDEX; private int userIndex = Constant.FIRST_USER_INDEX;
private Dictionary<Type, Entry> byClass; private Dictionary<SampleDispatcher, Entry> byDispatcher;
public LabCommEncoderRegistry() { public EncoderRegistry() {
byClass = new Dictionary<Type, Entry>(); byDispatcher = new Dictionary<SampleDispatcher, Entry>();
} }
public int add(LabCommDispatcher dispatcher) { public int add(SampleDispatcher dispatcher) {
lock(this) { lock(this) {
Entry e; Entry e;
byClass.TryGetValue(dispatcher.getSampleClass(), out e); byDispatcher.TryGetValue(dispatcher, out e);
if (e == null) { if (e == null) {
e = new Entry(dispatcher, userIndex); e = new Entry(dispatcher, userIndex);
byClass.Add(dispatcher.getSampleClass(), e); byDispatcher.Add(dispatcher, e);
userIndex++; userIndex++;
} }
return e.getIndex(); return e.getIndex();
} }
} }
public int getTag(Type sample) { public int getTag(SampleDispatcher sample) {
lock(this) { lock(this) {
Entry e; Entry e;
byClass.TryGetValue(sample, out e); byDispatcher.TryGetValue(sample, out e);
if (e == null) { if (e == null) {
throw new Exception("'" + throw new Exception("'" +
sample.ToString() + sample.ToString() +
......
namespace se.lth.control.labcomm2014 {
using System;
public class RenamingDecoder : WrappingDecoder {
private Decoder decoder;
private RenamingRegistry registry;
private Func<String,String> rename;
public RenamingDecoder(Decoder decoder,
RenamingRegistry registry,
Func<String,String> rename)
: base(decoder) {
this.decoder = decoder;
this.registry = registry;
this.rename = rename;
}
public override void register(SampleDispatcher dispatcher,
SampleHandler handler) {
decoder.register(registry.add(
dispatcher, rename(dispatcher.getName())), handler);
}
public override void registerSampleRef(SampleDispatcher dispatcher) {
decoder.registerSampleRef(registry.add(
dispatcher, rename(dispatcher.getName())));
}
}
}
namespace se.lth.control.labcomm2014 {
using System;
using System.Collections.Generic;
public class RenamingEncoder : WrappingEncoder {
private Encoder encoder;
private RenamingRegistry registry;
private Func<String,String> rename;
private Dictionary<SampleDispatcher, SampleDispatcher> alias;
public RenamingEncoder(Encoder encoder,
RenamingRegistry registry,
Func<String,String> rename)
: base(encoder) {
this.encoder = encoder;
this.registry = registry;
this.rename = rename;
alias = new Dictionary<SampleDispatcher, SampleDispatcher>();
}
private SampleDispatcher add(SampleDispatcher identity) {
SampleDispatcher renamed;
lock(this) {
if (! alias.TryGetValue(identity, out renamed)) {
renamed = registry.add(identity, rename(identity.getName()));
alias.Add(identity, renamed);
}
}
get(identity);
return renamed;
}
private SampleDispatcher get(SampleDispatcher identity) {
SampleDispatcher renamed;
lock(this) {
alias.TryGetValue(identity, out renamed);
}
return renamed;
}
public override void register(SampleDispatcher identity) {
encoder.register(add(identity));
}
public override void registerSampleRef(SampleDispatcher identity) {
encoder.registerSampleRef(add(identity));
}
public override void begin(SampleDispatcher identity) {
base.begin(get(identity));
}
public override void end(SampleDispatcher identity) {
base.end(get(identity));
}
}
}
namespace se.lth.control.labcomm2014 {
using System;
using System.Collections.Generic;
public class RenamingRegistry {
public class Dispatcher : SampleDispatcher, IEquatable<Dispatcher> {
private SampleDispatcher dispatcher;
private String name;
public Dispatcher(SampleDispatcher dispatcher,
String name) {
this.dispatcher = dispatcher;
this.name = name;
}
public String getName() {
return name;
}
public byte[] getSignature() {
return dispatcher.getSignature();
}
public void decodeAndHandle(Decoder decoder,
SampleHandler handler) {
dispatcher.decodeAndHandle(decoder, handler);
}
public bool Equals(Dispatcher obj) {
Dispatcher other = obj as Dispatcher;
return (other != null &&
dispatcher == other.dispatcher &&
name.Equals(other.name));
}
public override int GetHashCode() {
return dispatcher.GetHashCode() ^ name.GetHashCode();
}
public override string ToString() {
return "RenamingRegistry.Dispatcher(" + name + ")";
}
}
private Dictionary<Dispatcher, Dispatcher> registry;
public RenamingRegistry() {
registry = new Dictionary<Dispatcher, Dispatcher>();
}
public SampleDispatcher add(SampleDispatcher dispatcher,
String newName) {
Dispatcher result;
Dispatcher tmp = new Dispatcher(dispatcher, newName);
lock(this) {
registry.TryGetValue(tmp, out result);
if (result == null) {
registry.Add(tmp, tmp);
result = tmp;
}
}
return result;
}
}
}
namespace se.lth.control.labcomm2014 {
public interface Sample {
SampleDispatcher getDispatcher();
}
}
namespace se.lth.control.labcomm { namespace se.lth.control.labcomm2014 {
using System; using System;
public interface LabCommDispatcher { public interface SampleDispatcher {
Type getSampleClass();
String getName(); String getName();
byte[] getSignature(); byte[] getSignature();
void decodeAndHandle(LabCommDecoder decoder, void decodeAndHandle(Decoder decoder,
LabCommHandler handler); SampleHandler handler);
} }
......
namespace se.lth.control.labcomm2014 {
public interface SampleHandler {
}
}