Commit 36839bac authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Changed encoding of packed32 to be coded big endian with use of

continuation bit. C# is currently (intentionally) broken. 
Java and Python are untested.
parent 274eddf0
...@@ -38,27 +38,18 @@ aspect Signature { ...@@ -38,27 +38,18 @@ aspect Signature {
} }
public void addInt(int value, String comment) { public void addInt(int value, String comment) {
byte[] packed = new byte[5]; byte[] tmp = new byte[5];
long v = value & 0xffffffff;
// System.out.println("addInt: "+value); int i, j;
int tmp = value;
int len = 0; for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp[i] = (byte)(v & 0x7f);
while( tmp >= 0x80 ) { }
packed[len] = (byte) ((tmp & 0x7f) | 0x80 ) ; byte[] packed = new byte[i];
tmp >>>= 7; for (i = i - 1, j = 0 ; i >= 0 ; i--, j++) {
len++; packed[j] = (byte)(tmp[i] | (i!=0?0x80:0x00));
} }
packed[len] = (byte) (tmp & 0x7f); add(packed, comment);
// System.out.println("packed: "+packed[len]+ "len = "+len);
add(java.util.Arrays.copyOf(packed, len+1), comment);
// byte[] data = new byte[4];
// for (int i = 0 ; i < 4 ; i++) {
// data[3 - i] = (byte)((value >> (8 * i)) & 0xff);
// }
// add(data, comment);
} }
public void addString(String value, String comment) { public void addString(String value, String comment) {
......
...@@ -57,14 +57,17 @@ static inline unsigned int get32(labcomm_sig_parser_t *b) { ...@@ -57,14 +57,17 @@ static inline unsigned int get32(labcomm_sig_parser_t *b) {
/* aux method for reading labcomm varint from a char* /* aux method for reading labcomm varint from a char*
size is an out parameter: if not NULL the number of bytes read will be written here size is an out parameter: if not NULL the number of bytes read will be written here
*/ */
static int unpack_varint(unsigned char *buf, unsigned int idx, unsigned char *size) { static unsigned int unpack_varint(unsigned char *buf,
unsigned int idx,
unsigned char *size)
{
unsigned int res = 0; unsigned int res = 0;
unsigned int i=0; unsigned int i=0;
unsigned char cont = TRUE; unsigned char cont = TRUE;
do { do {
unsigned char c = buf[idx+i]; unsigned char c = buf[idx+i];
res |= (c & 0x7f) << 7*i; res = (res << 7) | (c & 0x7f);
cont = c & 0x80; cont = c & 0x80;
i++; i++;
} while(cont); } while(cont);
......
...@@ -124,6 +124,7 @@ LABCOMM_DECODE(long, long long) ...@@ -124,6 +124,7 @@ LABCOMM_DECODE(long, long long)
LABCOMM_DECODE(float, float) LABCOMM_DECODE(float, float)
LABCOMM_DECODE(double, double) LABCOMM_DECODE(double, double)
#if 0
/* /*
* Unpack a 32 bit unsigned number from a sequence bytes, where the * Unpack a 32 bit unsigned number from a sequence bytes, where the
* first byte is prefixed with a variable length bit pattern that * first byte is prefixed with a variable length bit pattern that
...@@ -136,7 +137,7 @@ LABCOMM_DECODE(double, double) ...@@ -136,7 +137,7 @@ LABCOMM_DECODE(double, double)
* 0b1110 - 4 bytes (0x00200000 - 0x0fffffff) * 0b1110 - 4 bytes (0x00200000 - 0x0fffffff)
* 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused] * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
*/ */
static inline unsigned int labcomm_unpack32(labcomm_reader_t *r) static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r)
{ {
unsigned int result = 0; unsigned int result = 0;
int n, i; int n, i;
...@@ -171,10 +172,31 @@ static inline unsigned int labcomm_unpack32(labcomm_reader_t *r) ...@@ -171,10 +172,31 @@ static inline unsigned int labcomm_unpack32(labcomm_reader_t *r)
} }
return result; return result;
} }
#endif
static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r)
{
unsigned int result = 0;
while (1) {
unsigned char tmp;
if (r->pos >= r->count) {
r->read(r, labcomm_reader_continue);
}
tmp = r->data[r->pos];
r->pos++;
result = (result << 7) | (tmp & 0x7f);
if ((tmp & 0x80) == 0) {
break;
}
}
return result;
}
static inline unsigned int labcomm_decode_packed32(labcomm_decoder_t *d) static inline unsigned int labcomm_decode_packed32(labcomm_decoder_t *d)
{ {
return labcomm_unpack32(&d->reader); return labcomm_read_unpacked32(&d->reader);
} }
static inline char *labcomm_read_string(labcomm_reader_t *r) static inline char *labcomm_read_string(labcomm_reader_t *r)
...@@ -182,7 +204,7 @@ static inline char *labcomm_read_string(labcomm_reader_t *r) ...@@ -182,7 +204,7 @@ static inline char *labcomm_read_string(labcomm_reader_t *r)
char *result; char *result;
int length, i; int length, i;
length = labcomm_unpack32(r); length = labcomm_read_unpacked32(r);
result = malloc(length + 1); result = malloc(length + 1);
for (i = 0 ; i < length ; i++) { for (i = 0 ; i < length ; i++) {
if (r->pos >= r->count) { if (r->pos >= r->count) {
...@@ -248,7 +270,7 @@ int labcomm_internal_encode( ...@@ -248,7 +270,7 @@ int labcomm_internal_encode(
return 0; \ return 0; \
} \ } \
static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \ static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
return labcomm_write_##name(&e->writer, data); \ return labcomm_write_##name(&e->writer, data); \
} }
#else #else
...@@ -268,7 +290,7 @@ int labcomm_internal_encode( ...@@ -268,7 +290,7 @@ int labcomm_internal_encode(
return 0; \ return 0; \
} \ } \
static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \ static inline int labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
return labcomm_write_##name(&e->writer, data); \ return labcomm_write_##name(&e->writer, data); \
} }
#endif #endif
...@@ -281,6 +303,7 @@ LABCOMM_ENCODE(long, long long) ...@@ -281,6 +303,7 @@ LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE(float, float) LABCOMM_ENCODE(float, float)
LABCOMM_ENCODE(double, double) LABCOMM_ENCODE(double, double)
#if 0
/* /*
* Pack the 32 bit unsigned number data as a sequence bytes, where the * Pack the 32 bit unsigned number data as a sequence bytes, where the
* first byte is prefixed with a variable length bit pattern that * first byte is prefixed with a variable length bit pattern that
...@@ -294,7 +317,7 @@ LABCOMM_ENCODE(double, double) ...@@ -294,7 +317,7 @@ LABCOMM_ENCODE(double, double)
* 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused] * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
*/ */
static inline int labcomm_write_packed32(labcomm_writer_t *w, static inline int labcomm_write_packed32(labcomm_writer_t *w,
unsigned int data) unsigned int data)
{ {
int n; int n;
unsigned char tag; unsigned char tag;
...@@ -367,6 +390,28 @@ static inline int labcomm_write_packed32(labcomm_writer_t *w, ...@@ -367,6 +390,28 @@ static inline int labcomm_write_packed32(labcomm_writer_t *w,
} }
return 0; return 0;
} }
#endif
static inline int labcomm_write_packed32(labcomm_writer_t *w,
unsigned int data)
{
unsigned char tmp[5];
int i;
for (i = 0 ; i == 0 || data ; i++, data = (data >> 7)) {
tmp[i] = data & 0x7f;
}
for (i = i - 1 ; i >= 0 ; i--) {
if (w->pos >= w->count) {
int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
}
w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
}
return 0;
}
static inline int labcomm_encode_packed32(labcomm_encoder_t *e, static inline int labcomm_encode_packed32(labcomm_encoder_t *e,
unsigned int data) unsigned int data)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include "labcomm_private.h" #include "labcomm_private.h"
static int line;
int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...) int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
{ {
...@@ -11,7 +12,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...) ...@@ -11,7 +12,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...) int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
{ {
fprintf(stderr, "test_read should not be called\n"); fprintf(stderr, "test_read should not be called %s:%d\n", __FILE__, line);
exit(1); exit(1);
} }
...@@ -57,9 +58,10 @@ typedef unsigned char byte; ...@@ -57,9 +58,10 @@ typedef unsigned char byte;
#define TEST_WRITE_READ(type, format, value, expect_count, expect_bytes) \ #define TEST_WRITE_READ(type, format, value, expect_count, expect_bytes) \
{ \ { \
type decoded; \ type decoded; \
line = __LINE__; \
encoder.writer.pos = 0; \ encoder.writer.pos = 0; \
labcomm_encode_##type(&encoder, value); \ labcomm_encode_##type(&encoder, value); \
writer_assert(#type, __LINE__, expect_count, (uint8_t*)expect_bytes); \ writer_assert(#type, expect_count, (uint8_t*)expect_bytes); \
decoder.reader.count = encoder.writer.pos; \ decoder.reader.count = encoder.writer.pos; \
decoder.reader.pos = 0; \ decoder.reader.pos = 0; \
decoded = labcomm_decode_##type(&decoder); \ decoded = labcomm_decode_##type(&decoder); \
...@@ -71,7 +73,6 @@ typedef unsigned char byte; ...@@ -71,7 +73,6 @@ typedef unsigned char byte;
} }
static void writer_assert(char *type, static void writer_assert(char *type,
int line,
int count, int count,
uint8_t *bytes) uint8_t *bytes)
{ {
...@@ -101,14 +102,14 @@ int main(void) ...@@ -101,14 +102,14 @@ int main(void)
{ {
TEST_WRITE_READ(packed32, "%d", 0x0, 1, "\x00"); TEST_WRITE_READ(packed32, "%d", 0x0, 1, "\x00");
TEST_WRITE_READ(packed32, "%d", 0x7f, 1, "\x7f"); TEST_WRITE_READ(packed32, "%d", 0x7f, 1, "\x7f");
TEST_WRITE_READ(packed32, "%d", 0x80, 2, "\x80\x80"); TEST_WRITE_READ(packed32, "%d", 0x80, 2, "\x81\x00");
TEST_WRITE_READ(packed32, "%d", 0x3fff, 2, "\xbf\xff"); TEST_WRITE_READ(packed32, "%d", 0x3fff, 2, "\xff\x7f");
TEST_WRITE_READ(packed32, "%d", 0x4000, 3, "\xc0\x40\x00"); TEST_WRITE_READ(packed32, "%d", 0x4000, 3, "\x81\x80\x00");
TEST_WRITE_READ(packed32, "%d", 0x1fffff, 3, "\xdf\xff\xff"); TEST_WRITE_READ(packed32, "%d", 0x1fffff, 3, "\xff\xff\x7f");
TEST_WRITE_READ(packed32, "%d", 0x200000, 4, "\xe0\x20\x00\x00"); TEST_WRITE_READ(packed32, "%d", 0x200000, 4, "\x81\x80\x80\x00");
TEST_WRITE_READ(packed32, "%d", 0xfffffff, 4, "\xef\xff\xff\xff"); TEST_WRITE_READ(packed32, "%d", 0xfffffff, 4, "\xff\xff\xff\x7f");
TEST_WRITE_READ(packed32, "%d", 0x10000000, 5, "\xf0\x10\x00\x00\x00"); TEST_WRITE_READ(packed32, "%d", 0x10000000, 5, "\x81\x80\x80\x80\x00");
TEST_WRITE_READ(packed32, "%d", 0xffffffff, 5, "\xf0\xff\xff\xff\xff"); TEST_WRITE_READ(packed32, "%d", 0xffffffff, 5, "\x8f\xff\xff\xff\x7f");
TEST_WRITE_READ(boolean, "%d", 0, 1, "\x00"); TEST_WRITE_READ(boolean, "%d", 0, 1, "\x00");
TEST_WRITE_READ(boolean, "%d", 1, 1, "\x01"); TEST_WRITE_READ(boolean, "%d", 1, 1, "\x01");
TEST_WRITE_READ(byte, "%d", 0, 1, "\x00"); TEST_WRITE_READ(byte, "%d", 0, 1, "\x00");
......
...@@ -163,6 +163,7 @@ namespace se.lth.control.labcomm { ...@@ -163,6 +163,7 @@ namespace se.lth.control.labcomm {
} }
public int decodePacked32() { public int decodePacked32() {
TODO: Correct byteorder
Int64 res = 0; Int64 res = 0;
byte i = 0; byte i = 0;
bool cont = true; bool cont = true;
......
...@@ -90,7 +90,7 @@ namespace se.lth.control.labcomm { ...@@ -90,7 +90,7 @@ namespace se.lth.control.labcomm {
public void encodePacked32(Int64 value) { public void encodePacked32(Int64 value) {
Int64 tmp = value; Int64 tmp = value;
TODO: Correct byteorder
while(tmp >= 0x80) { while(tmp >= 0x80) {
encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) ); encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) );
tmp >>= 7; tmp >>= 7;
......
...@@ -141,7 +141,7 @@ public class LabCommDecoderChannel implements LabCommDecoder { ...@@ -141,7 +141,7 @@ public class LabCommDecoderChannel implements LabCommDecoder {
do { do {
byte c = in.readByte(); byte c = in.readByte();
res |= (c & 0x7f) << 7*i; res = (res << 7) | (c & 0x7f);
cont = (c & 0x80) != 0; cont = (c & 0x80) != 0;
i++; i++;
} while(cont); } while(cont);
......
...@@ -94,13 +94,16 @@ public class LabCommEncoderChannel implements LabCommEncoder { ...@@ -94,13 +94,16 @@ public class LabCommEncoderChannel implements LabCommEncoder {
} }
public void encodePacked32(long value) throws IOException { public void encodePacked32(long value) throws IOException {
long tmp = value; byte[] tmp = new byte[5];
long v = value & 0xffffffff;
int i;
while( tmp >= 0x80 ) { for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) ); tmp[i] = (byte)(v & 0x7f);
tmp >>>= 7; }
for (i = i - 1 ; i >= 0 ; i--) {
encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
} }
encodeByte( (byte) (tmp & 0x7f) );
} }
} }
...@@ -89,13 +89,10 @@ ...@@ -89,13 +89,10 @@
#?? +----+----+----+----+ #?? +----+----+----+----+
# #
# #
# type numbers and lengths do not have a fixed lenght, but are packed into sequences # type numbers and lengths do not have a fixed lenght, but are packed into
# of 7 bit chunks, represented in bytes with the high bit meaning that more data # sequences of 7 bit chunks, represented in bytes with the high bit meaning
# is to come. # that more data is to come.
#
# The chunks are sent "little endian": each 7 bit chunk is more significant than
# the previous. See encode_packed32 and decode_packed32 in in Codec classes below.
import struct as packer import struct as packer
i_TYPEDEF = 0x01 i_TYPEDEF = 0x01
...@@ -580,12 +577,14 @@ class Encoder(Codec): ...@@ -580,12 +577,14 @@ class Encoder(Codec):
decl.encode_decl(self) decl.encode_decl(self)
def encode_packed32(self, v): def encode_packed32(self, v):
tmp = v & 0xffffffff; v = v & 0xffffffff
tmp = [ v & 0x7f ]
while(tmp >= 0x80 ): v = v >> 7
self.encode_byte( (tmp & 0x7f) | 0x80 ) while v:
tmp >>= 7 tmp.append(v & 0x7f | 0x80)
self.encode_byte(tmp & 0x7f) v = v >> 7
for c in reversed(tmp):
self.encode_byte(c)
def encode_type(self, index): def encode_type(self, index):
self.encode_packed32(index) self.encode_packed32(index)
...@@ -666,14 +665,13 @@ class Decoder(Codec): ...@@ -666,14 +665,13 @@ class Decoder(Codec):
return result return result
def decode_packed32(self): def decode_packed32(self):
res = 0 result = 0
i = 0 while True:
cont = True tmp = self.decode_byte()
while (cont): result = (result << 7) | (tmp & 0x7f)
c = self.decode_byte() if (tmp & 0x80) == 0:
res |= (c & 0x7f) << 7*i break
cont = (c & 0x80) != 0; return result
return res
def decode_type_number(self): def decode_type_number(self):
return self.decode_packed32() return self.decode_packed32()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment