diff --git a/examples/wiki_example/example_decoder.py b/examples/wiki_example/example_decoder.py index 6c3828b52954c1916aba6e6ac79431aab27d52e7..3d40cf468e5764d1432b65c30a594fcd6fbd85ed 100755 --- a/examples/wiki_example/example_decoder.py +++ b/examples/wiki_example/example_decoder.py @@ -6,6 +6,14 @@ import sys class FileReader: def __init__(self, name): self.f = open(name) + pass + + def start(self, decoder, version): + other_version = decoder.decode_string() + if version != other_version: + raise Exception("LabComm version mismatch %s != %s" % + (version, other_version)) + pass def read(self, count): s = self.f.read(count) diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 260b3c6748640be932a71addecb7ff3f22c3966c..f58199a0a56637e2d8f1f7f73672d8b48e2349a6 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -34,7 +34,7 @@ #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" -#define LABCOMM_VERSION "\x0bLabComm2013" +#define LABCOMM_VERSION "LabComm2013" typedef struct labcomm_sample_entry { struct labcomm_sample_entry *next; diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c index 09bfc3c359a187898afd7269c9179aa2fa002922..f49be47ac957ba549c5445b7f8f2cf9cee200841 100644 --- a/lib/c/labcomm_fd_reader.c +++ b/lib/c/labcomm_fd_reader.c @@ -2,31 +2,33 @@ #include <unistd.h> #include <stdlib.h> #include <string.h> +#include "labcomm_private.h" #include "labcomm_fd_reader.h" #define BUFFER_SIZE 2048 static int fd_alloc(struct labcomm_reader *r, char *version) { - int result; -#ifndef LABCOMM_FD_OMIT_VERSION - int *fd = r->context; - char *tmp = strdup(version); + int result = 0; - read(*fd, tmp, strlen(version)); - free(tmp); -#endif + r->count = 0; + r->pos = 0; r->data = malloc(BUFFER_SIZE); - if (r->data) { - r->data_size = BUFFER_SIZE; - result = r->data_size; - } else { + if (! r->data) { r->data_size = 0; result = -ENOMEM; - } - r->count = 0; - r->pos = 0; + } else { + char *tmp; + r->data_size = BUFFER_SIZE; + tmp = labcomm_read_string(r); + if (strcmp(tmp, version) != 0) { + result = -EINVAL; + } else { + result = r->data_size; + } + free(tmp); + } return result; } @@ -43,7 +45,7 @@ static int fd_free(struct labcomm_reader *r) static int fd_fill(struct labcomm_reader *r) { - int result; + int result = 0; int *fd = r->context; if (r->pos < r->count) { diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c index 57f9248f0205de03b7a5aa44d0c072241899f5af..3c678691e419462c82e78f613af5e1d89d0a4dee 100644 --- a/lib/c/labcomm_fd_writer.c +++ b/lib/c/labcomm_fd_writer.c @@ -3,16 +3,15 @@ #include <string.h> #include <stdlib.h> #include <stdarg.h> +#include "labcomm_private.h" #include "labcomm_fd_writer.h" #define BUFFER_SIZE 2048 +static int fd_flush(struct labcomm_writer *w); + static int fd_alloc(struct labcomm_writer *w, char *version) { -#ifndef LABCOMM_FD_OMIT_VERSION - int *fd = w->context; - write(*fd, version, strlen(version)); -#endif w->data = malloc(BUFFER_SIZE); if (! w->data) { w->error = -ENOMEM; @@ -23,6 +22,8 @@ static int fd_alloc(struct labcomm_writer *w, char *version) w->data_size = BUFFER_SIZE; w->count = BUFFER_SIZE; w->pos = 0; + labcomm_write_string(w, version); + fd_flush(w); } return w->error; diff --git a/lib/csharp/se/lth/control/labcomm/LabComm.cs b/lib/csharp/se/lth/control/labcomm/LabComm.cs index 21f613cf98082ea677cffb5dcd92ead24d5c0758..93efe6813aa68f97dcdef394e2eaef9931973901 100644 --- a/lib/csharp/se/lth/control/labcomm/LabComm.cs +++ b/lib/csharp/se/lth/control/labcomm/LabComm.cs @@ -2,7 +2,9 @@ namespace se.lth.control.labcomm { public class LabComm { - /* + public const string VERSION = "LabComm2013"; + + /* * Predeclared aggregate type indices */ public const int TYPEDEF = 0x01; diff --git a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs index 953c910cff5df008a78a535ff87768d6e07cd4ae..2d6b8d4126daac41875ea3864e6eedfdf91bb54a 100644 --- a/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/LabCommDecoderChannel.cs @@ -13,6 +13,11 @@ namespace se.lth.control.labcomm { public LabCommDecoderChannel(Stream stream) { this.stream = stream; + String version = decodeString(); + if (version != LabComm.VERSION) { + throw new IOException("LabComm version mismatch " + + version + " != " + LabComm.VERSION); + } } public void runOne() { @@ -25,7 +30,7 @@ namespace se.lth.control.labcomm { int index = decodePacked32(); String name = decodeString(); MemoryStream signature = new MemoryStream(); - collectFlatSignature(new LabCommEncoderChannel(signature)); + collectFlatSignature(new LabCommEncoderChannel(signature, false)); registry.add(index, name, signature.ToArray()); } break; default: { @@ -156,7 +161,6 @@ namespace se.lth.control.labcomm { } public String decodeString() { - //int length = (int)ReadInt(4); int length = decodePacked32(); byte[] buf = new byte[length]; ReadBytes(buf, length); diff --git a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs index d13a236ea1cc0d71c206171060ac8b1cdf4fdab2..6cabb59bba22383ccc4fb36b103f33117aa794a5 100644 --- a/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs +++ b/lib/csharp/se/lth/control/labcomm/LabCommEncoderChannel.cs @@ -12,8 +12,14 @@ namespace se.lth.control.labcomm { private LabCommEncoderRegistry registry = new LabCommEncoderRegistry(); byte[] buf = new byte[8]; - public LabCommEncoderChannel(Stream writer) { + public LabCommEncoderChannel(Stream writer, bool emitVersion) { this.writer = writer; + if (emitVersion) { + encodeString(LabComm.VERSION); + } + } + + public LabCommEncoderChannel(Stream writer) : this(writer, true) { } public void register(LabCommDispatcher dispatcher) { diff --git a/lib/java/se/lth/control/labcomm/LabComm.java b/lib/java/se/lth/control/labcomm/LabComm.java index 07d17050e354dbdb0076b38a61e37a8b5008125f..99c74c201a8f7dee87776f23e534000617679aa7 100644 --- a/lib/java/se/lth/control/labcomm/LabComm.java +++ b/lib/java/se/lth/control/labcomm/LabComm.java @@ -2,6 +2,8 @@ package se.lth.control.labcomm; public class LabComm { + public static final String VERSION = "LabComm2013"; + /* * Predeclared aggregate type indices */ @@ -23,7 +25,7 @@ public class LabComm { public static final int STRING = 0x27; /* - * Start of + * Start of user declared types */ public static final int FIRST_USER_INDEX = 0x40; diff --git a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java index c3f698497418f336aa3dfb7119b562ae595d700b..0fe0e8261dee9977ccb510b814408796f1489ab5 100644 --- a/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java +++ b/lib/java/se/lth/control/labcomm/LabCommDecoderChannel.java @@ -13,6 +13,12 @@ public class LabCommDecoderChannel implements LabCommDecoder { public LabCommDecoderChannel(InputStream in) throws IOException { this.in = new DataInputStream(in); registry = new LabCommDecoderRegistry(); + String version = decodeString(); + if (! version.equals(LabComm.VERSION)) { + throw new IOException("LabComm version mismatch " + + version + " != " + LabComm.VERSION); + } + System.err.println(LabComm.VERSION); } public void runOne() throws Exception { @@ -25,7 +31,7 @@ public class LabCommDecoderChannel implements LabCommDecoder { int index = decodePacked32(); String name = decodeString(); ByteArrayOutputStream signature = new ByteArrayOutputStream(); - collectFlatSignature(new LabCommEncoderChannel(signature)); + collectFlatSignature(new LabCommEncoderChannel(signature, false)); registry.add(index, name, signature.toByteArray()); } break; default: { diff --git a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java index 204f6cc7abc0add837675828a6eb2258a0b636d5..d9b163ef394bf6e80bc68b680440f152d6b5b4fa 100644 --- a/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java +++ b/lib/java/se/lth/control/labcomm/LabCommEncoderChannel.java @@ -12,15 +12,28 @@ public class LabCommEncoderChannel implements LabCommEncoder { private DataOutputStream data; private LabCommEncoderRegistry registry; - public LabCommEncoderChannel(LabCommWriter writer) { + public LabCommEncoderChannel(LabCommWriter writer, + boolean emitVersion) throws IOException { this.writer = writer; bytes = new ByteArrayOutputStream(); data = new DataOutputStream(bytes); registry = new LabCommEncoderRegistry(); + if (emitVersion) { + encodeString(LabComm.VERSION); + } + } + + public LabCommEncoderChannel(LabCommWriter writer) throws IOException { + this(writer, true); + } + + public LabCommEncoderChannel(OutputStream writer, + boolean emitVersion) throws IOException { + this(new WriterWrapper(writer), emitVersion); } - public LabCommEncoderChannel(OutputStream writer) { - this(new WriterWrapper(writer)); + public LabCommEncoderChannel(OutputStream writer) throws IOException { + this(new WriterWrapper(writer), true); } public void register(LabCommDispatcher dispatcher) throws IOException { diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm/LabComm.py index b13792554fa54040783c4f7ba80aaa5e785376b9..604b90139fc443f4a057af93cbe48543f0fb4ff4 100644 --- a/lib/python/labcomm/LabComm.py +++ b/lib/python/labcomm/LabComm.py @@ -95,6 +95,8 @@ import struct as packer +VERSION = "LabComm2013" + i_TYPEDEF = 0x01 i_SAMPLE = 0x02 @@ -537,6 +539,7 @@ class Encoder(Codec): def __init__(self, writer): super(Encoder, self).__init__() self.writer = writer + self.writer.start(self, VERSION) def pack(self, format, *args): self.writer.write(packer.pack(format, *args)) @@ -609,6 +612,7 @@ class Decoder(Codec): def __init__(self, reader): super(Decoder, self).__init__() self.reader = reader + self.reader.start(self, VERSION) def unpack(self, format): size = packer.calcsize(format) diff --git a/test/Makefile b/test/Makefile index 0bce5a95de0f84985497daa1fb6abf243753db86..0edf4601dcabf160db0fedbcd26c6797afd90864 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ TESTS=basic simple nested LABCOMM_JAR=../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) -CFLAGS=-O3 -Wall -Werror +CFLAGS=-O3 -g -Wall -Werror all: @@ -52,7 +52,6 @@ gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile .PRECIOUS: gen/%/c_relay gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile $(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. \ - -DLABCOMM_FD_OMIT_VERSION \ -DLABCOMM_ENCODER_LINEAR_SEARCH \ gen/$*/c_code.c \ ../lib/c/labcomm.c \ diff --git a/test/test_encoder_decoder.py b/test/test_encoder_decoder.py index 96aaec8c8596c65e56492be3b4f9cf605f788636..6d8d4bcaaaef9858843227e0ad49bb8f5ca3d8d7 100755 --- a/test/test_encoder_decoder.py +++ b/test/test_encoder_decoder.py @@ -12,40 +12,6 @@ import subprocess import sys import threading -class hexwriter(object): - def __init__(self, outfile): - self.pos = 0 - self.ascii = '' - self.outfile = outfile - - def write(self, data): - for c in data: - if ' ' <= c and c <= '}': - self.ascii += c - else: - self.ascii += '.' - sys.stdout.write("%2.2x " % ord(c)) - self.pos += 1 - if self.pos >= 15: - sys.stdout.write("%s\n" % self.ascii) - self.pos = 0 - self.ascii = "" - #self.outfile.write(data) - - def mark(self): - self.flush() - pass - - def flush(self): - for i in range(self.pos, 15): - sys.stdout.write(" ") - sys.stdout.write("%s\n" % self.ascii) - self.pos = 0 - self.ascii = "" - if self.outfile: - self.outfile.flush() - - def generate(decl): if decl.__class__ == labcomm.sample: result = [] @@ -162,6 +128,9 @@ class Test: decoder = threading.Thread(target=self.decode, args=(p.stdout,)) decoder.start() class Writer: + def start(self, encoder, version): + encoder.encode_string(version) + pass def write(self, data): p.stdin.write(data) pass @@ -169,7 +138,6 @@ class Test: p.stdin.flush() pass pass - h = hexwriter(p.stdin) encoder = labcomm.Encoder(Writer()) for name,signature in self.signatures: encoder.add_decl(signature) @@ -197,6 +165,12 @@ class Test: def decode(self, f): class Reader: + def start(self, decoder, version): + other_version = decoder.decode_string() + if version != other_version: + raise Exception("LabComm version mismatch %s != %s" % + (version, other_version)) + pass def read(self, count): result = f.read(count) if len(result) == 0: