summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-06-28 10:54:34 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-06-28 10:54:34 +0200
commite1058170fa9f221c827ab99d8856080648812a88 (patch)
treebc6f5e3be2b09f76c26751960adb29af8db132ed
parentbfd8f297e6af00841d93e807e3e33e5a6e6e226e (diff)
Switch to an OS-independent XDR implementation for protocol evaluations
-rw-r--r--include/lib/xdr.h66
-rw-r--r--include/lib/xdr16.h68
-rw-r--r--src/app/prototest/Makefile.inc4
-rw-r--r--src/app/prototest/main.cc8
-rw-r--r--src/lib/xdr.cc187
-rw-r--r--src/lib/xdr16.cc214
6 files changed, 539 insertions, 8 deletions
diff --git a/include/lib/xdr.h b/include/lib/xdr.h
new file mode 100644
index 0000000..c451a2f
--- /dev/null
+++ b/include/lib/xdr.h
@@ -0,0 +1,66 @@
+#ifndef XDR_H
+#define XDR_H
+
+#include <stdint.h>
+
+class XDRWriter
+{
+private:
+ XDRWriter(const XDRWriter &copy);
+ char *buffer;
+ uint32_t next_array_len;
+ uint32_t pos;
+ bool is_fixed_length;
+
+public:
+ XDRWriter(char *output_buf) : buffer(output_buf), next_array_len(0), pos(0) {}
+
+ inline void setNextArrayLen(uint32_t len) { next_array_len = len; }
+ inline void setFixedLength() { is_fixed_length = true; }
+ inline void setVariableLength() { is_fixed_length = false; }
+ inline void startList()
+ {
+ if (!is_fixed_length)
+ {
+ put(next_array_len);
+ }
+ }
+
+ inline void put(char c) { put((int32_t)c); }
+ inline void put(unsigned char c) { put((uint32_t)c); }
+ inline void put(uint16_t number) { put((int32_t)number); }
+ inline void put(int16_t number) { put((uint32_t)number); }
+ void put(uint32_t number);
+ void put(int32_t number);
+ void put(uint64_t number);
+ void put(int64_t number);
+ void put(float number);
+ void put(double number);
+ void put(char const *text);
+ template <uint32_t TSize>
+ void put(char const (&text)[TSize]);
+
+ inline uint32_t size() { return pos; }
+};
+
+class XDRReader
+{
+private:
+ XDRReader(const XDRReader &copy);
+ char *data;
+ uint32_t pos;
+
+public:
+ XDRReader(char *d) : pos(0) { data = d; }
+ uint32_t get_uint32();
+ int32_t get_int32();
+ uint64_t get_uint64();
+ int64_t get_int64();
+ float get_float();
+ double get_double();
+ uint32_t get_opaque_length();
+ char *get_opaque(uint32_t length);
+ void get_string(char *target);
+};
+
+#endif
diff --git a/include/lib/xdr16.h b/include/lib/xdr16.h
new file mode 100644
index 0000000..483efe4
--- /dev/null
+++ b/include/lib/xdr16.h
@@ -0,0 +1,68 @@
+#ifndef XDR16_H
+#define XDR16_H
+
+#include <stdint.h>
+
+class XDRWriter
+{
+private:
+ XDRWriter(const XDRWriter &copy);
+ char *buffer;
+ uint16_t next_array_len;
+ uint16_t pos;
+ bool is_fixed_length;
+
+public:
+ XDRWriter(char *output_buf) : buffer(output_buf), next_array_len(0), pos(0) {}
+
+ inline void setNextArrayLen(uint16_t len) { next_array_len = len; }
+ inline void setFixedLength() { is_fixed_length = true; }
+ inline void setVariableLength() { is_fixed_length = false; }
+ inline void startList()
+ {
+ if (!is_fixed_length)
+ {
+ put(next_array_len);
+ }
+ }
+
+ inline void put(char c) { put((int16_t)c); }
+ inline void put(unsigned char c) { put((uint16_t)c); }
+ void put(uint16_t number);
+ void put(int16_t number);
+ void put(uint32_t number);
+ void put(int32_t number);
+ void put(uint64_t number);
+ void put(int64_t number);
+ void put(float number);
+ void put(double number);
+ void put(char const *text);
+ template <uint16_t TSize>
+ void put(char const (&text)[TSize]);
+
+ inline uint16_t size() { return pos; }
+};
+
+class XDRReader
+{
+private:
+ XDRReader(const XDRReader &copy);
+ char *data;
+ uint32_t pos;
+
+public:
+ XDRReader(char *d) : pos(0) { data = d; }
+ int16_t get_int16();
+ uint16_t get_uint16();
+ uint32_t get_uint32();
+ int32_t get_int32();
+ uint64_t get_uint64();
+ int64_t get_int64();
+ float get_float();
+ double get_double();
+ uint32_t get_opaque_length();
+ char *get_opaque(uint32_t length);
+ void get_string(char *target);
+};
+
+#endif
diff --git a/src/app/prototest/Makefile.inc b/src/app/prototest/Makefile.inc
index ee509a7..c088f6b 100644
--- a/src/app/prototest/Makefile.inc
+++ b/src/app/prototest/Makefile.inc
@@ -69,12 +69,12 @@ endif
ifeq (${prototest_xdr}, 1)
COMMON_FLAGS += -DPROTOTEST_XDR
- CXX_TARGETS += src/os/object/xdrstream.cc src/os/object/xdrinput.cc
+ CXX_TARGETS += src/lib/xdr.cc
endif
ifeq (${prototest_xdr16}, 1)
COMMON_FLAGS += -DPROTOTEST_XDR16
- CXX_TARGETS += src/os/object/xdr16stream.cc src/os/object/xdr16input.cc
+ CXX_TARGETS += src/lib/xdr16.cc
endif
# Don't try to make .capnp from .capnp.c
diff --git a/src/app/prototest/main.cc b/src/app/prototest/main.cc
index ee5c958..7fc897e 100644
--- a/src/app/prototest/main.cc
+++ b/src/app/prototest/main.cc
@@ -35,14 +35,10 @@
#include "ubj.h"
#endif
#ifdef PROTOTEST_XDR
-#include "object/stdbuf.h"
-#include "object/xdrstream.h"
-#include "object/xdrinput.h"
+#include "lib/xdr.h"
#endif
#ifdef PROTOTEST_XDR16
-#include "object/stdbuf.h"
-#include "object/xdr16stream.h"
-#include "object/xdr16input.h"
+#include "lib/xdr16.h"
#endif
#include <stdint.h>
diff --git a/src/lib/xdr.cc b/src/lib/xdr.cc
new file mode 100644
index 0000000..180bff0
--- /dev/null
+++ b/src/lib/xdr.cc
@@ -0,0 +1,187 @@
+#include "lib/xdr.h"
+
+
+void XDRWriter::put(uint32_t number)
+{
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 4;
+}
+
+void XDRWriter::put(int32_t number)
+{
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 4;
+}
+
+void XDRWriter::put(uint64_t number)
+{
+ *buffer++ = ((number >> 56) & 0xffU);
+ *buffer++ = ((number >> 48) & 0xffU);
+ *buffer++ = ((number >> 40) & 0xffU);
+ *buffer++ = ((number >> 32) & 0xffU);
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 8;
+}
+
+void XDRWriter::put(int64_t number)
+{
+ *buffer++ = ((number >> 56) & 0xffU);
+ *buffer++ = ((number >> 48) & 0xffU);
+ *buffer++ = ((number >> 40) & 0xffU);
+ *buffer++ = ((number >> 32) & 0xffU);
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 8;
+}
+
+void XDRWriter::put(float number)
+{
+ union {
+ uint32_t i;
+ float f;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.f = number;
+ put(v.i);
+}
+
+void XDRWriter::put(double number)
+{
+ union {
+ uint64_t i;
+ double d;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.d = number;
+ put(v.i);
+}
+
+void XDRWriter::put(char const *data){
+ if (!is_fixed_length) {
+ put(next_array_len);
+ }
+ uint32_t i;
+ for (i = 0; i < next_array_len; i++) {
+ *buffer++ = data[i];
+ }
+ while ((i++) % 4 != 0){
+ *buffer++ = 0;
+ }
+ pos += i;
+}
+
+template<uint32_t TSize>
+void XDRWriter::put(char const (&data)[TSize]){
+ if (!is_fixed_length) {
+ put(TSize);
+ }
+ uint32_t i;
+ for (i = 0; i < TSize; i++) {
+ *buffer++ = data[i];
+ }
+ while ((i++) % 4 != 0){
+ *buffer++ = 0;
+ }
+ pos += i;
+}
+
+uint32_t XDRReader::get_uint32()
+{
+ uint32_t ret = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ return ret;
+}
+
+int32_t XDRReader::get_int32()
+{
+ int32_t ret = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ return ret;
+}
+
+uint64_t XDRReader::get_uint64()
+{
+ uint64_t ret0 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ uint64_t ret1 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ return (ret0 << 32) | ret1;
+}
+
+int64_t XDRReader::get_int64()
+{
+ int64_t ret0 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ int64_t ret1 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ return (ret0 << 32) | ret1;
+}
+
+float XDRReader::get_float()
+{
+ union {
+ uint32_t i;
+ float f;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.i = get_uint32();
+ return v.f;
+}
+
+double XDRReader::get_double()
+{
+ union {
+ uint64_t i;
+ double d;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.i = get_uint64();
+ return v.d;
+}
+
+uint32_t XDRReader::get_opaque_length()
+{
+ return get_uint32();
+}
+
+char *XDRReader::get_opaque(uint32_t length)
+{
+ char *ret = data + pos;
+ pos += length;
+ if (length % 4) {
+ pos += 4 - (length % 4);
+ }
+ return ret;
+}
+
+void XDRReader::get_string(char* target)
+{
+ uint16_t length = get_opaque_length();
+ uint16_t i;
+ for (i = 0; i < length; i++) {
+ target[i] = data[pos + i];
+ }
+ target[i] = 0;
+ pos += length;
+ if (length % 4) {
+ pos += 4 - (length % 4);
+ }
+}
diff --git a/src/lib/xdr16.cc b/src/lib/xdr16.cc
new file mode 100644
index 0000000..2f68463
--- /dev/null
+++ b/src/lib/xdr16.cc
@@ -0,0 +1,214 @@
+#include "lib/xdr16.h"
+
+void XDRWriter::put(uint16_t number)
+{
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 2;
+}
+
+void XDRWriter::put(int16_t number)
+{
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 2;
+}
+
+void XDRWriter::put(uint32_t number)
+{
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 4;
+}
+
+void XDRWriter::put(int32_t number)
+{
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 4;
+}
+
+void XDRWriter::put(uint64_t number)
+{
+ *buffer++ = ((number >> 56) & 0xffU);
+ *buffer++ = ((number >> 48) & 0xffU);
+ *buffer++ = ((number >> 40) & 0xffU);
+ *buffer++ = ((number >> 32) & 0xffU);
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 8;
+}
+
+void XDRWriter::put(int64_t number)
+{
+ *buffer++ = ((number >> 56) & 0xffU);
+ *buffer++ = ((number >> 48) & 0xffU);
+ *buffer++ = ((number >> 40) & 0xffU);
+ *buffer++ = ((number >> 32) & 0xffU);
+ *buffer++ = ((number >> 24) & 0xffU);
+ *buffer++ = ((number >> 16) & 0xffU);
+ *buffer++ = ((number >> 8) & 0xffU);
+ *buffer++ = (number & 0xffU);
+ pos += 8;
+}
+
+void XDRWriter::put(float number)
+{
+ union {
+ uint32_t i;
+ float f;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.f = number;
+ put(v.i);
+}
+
+void XDRWriter::put(double number)
+{
+ union {
+ uint64_t i;
+ double d;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.d = number;
+ put(v.i);
+}
+
+void XDRWriter::put(char const *data){
+ if (!is_fixed_length) {
+ put(next_array_len);
+ }
+ uint16_t i;
+ for (i = 0; i < next_array_len; i++) {
+ *buffer++ = data[i];
+ }
+ while ((i++) % 2 != 0){
+ *buffer++ = 0;
+ }
+ pos += i;
+}
+
+template<uint16_t TSize>
+void XDRWriter::put(char const (&data)[TSize]){
+ if (!is_fixed_length) {
+ put(TSize);
+ }
+ uint16_t i;
+ for (i = 0; i < TSize; i++) {
+ *buffer++ = data[i];
+ }
+ while ((i++) % 2 != 0){
+ *buffer++ = 0;
+ }
+ pos += i;
+}
+
+uint16_t XDRReader::get_uint16()
+{
+ uint16_t ret = ((uint8_t)data[pos]<<8) | (uint8_t)data[pos+1];
+ pos += 2;
+ return ret;
+}
+
+int16_t XDRReader::get_int16()
+{
+ int16_t ret = (data[pos]<<8) | data[pos+1];
+ pos += 2;
+ return ret;
+}
+
+uint32_t XDRReader::get_uint32()
+{
+ uint32_t ret = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ return ret;
+}
+
+int32_t XDRReader::get_int32()
+{
+ int32_t ret = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ return ret;
+}
+
+uint64_t XDRReader::get_uint64()
+{
+ uint64_t ret0 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ uint64_t ret1 = ((uint8_t)data[pos]<<24) | ((uint8_t)data[pos+1]<<16)
+ | ((uint8_t)data[pos+2]<<8) | (uint8_t)data[pos+3];
+ pos += 4;
+ return (ret0 << 32) | ret1;
+}
+
+int64_t XDRReader::get_int64()
+{
+ int64_t ret0 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ int64_t ret1 = (data[pos]<<24) | (data[pos+1]<<16) | (data[pos+2]<<8) | data[pos+3];
+ pos += 4;
+ return (ret0 << 32) | ret1;
+}
+
+float XDRReader::get_float()
+{
+ union {
+ uint32_t i;
+ float f;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.i = get_uint32();
+ return v.f;
+}
+
+double XDRReader::get_double()
+{
+ union {
+ uint64_t i;
+ double d;
+ } v;
+ // Setting one member of a struct and then reading another is undefined
+ // behaviour, but works as intended in nearly any (embedded) compiler
+ v.i = get_uint64();
+ return v.d;
+}
+
+uint32_t XDRReader::get_opaque_length()
+{
+ return get_uint16();
+}
+
+char *XDRReader::get_opaque(uint32_t length)
+{
+ char *ret = data + pos;
+ pos += length;
+ if (length % 2) {
+ pos += 2 - (length % 2);
+ }
+ return ret;
+}
+
+void XDRReader::get_string(char* target)
+{
+ uint16_t length = get_opaque_length();
+ uint16_t i;
+ for (i = 0; i < length; i++) {
+ target[i] = data[pos + i];
+ }
+ target[i] = 0;
+ pos += length;
+ if (length % 2) {
+ pos += 2 - (length % 2);
+ }
+}