summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-05-12 15:00:44 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2021-05-12 15:00:44 +0200
commit13e18cf59686319efee0080d523c4bc2d948b591 (patch)
tree7160e04f94f33f261c04d9072d3bce3eb1378fc8
parent06e36ffaadecdebd1a043aec23e8a4f6e579a088 (diff)
add xdr
-rw-r--r--include/lib/xdr.h66
-rw-r--r--include/lib/xdr16.h68
-rw-r--r--src/lib/xdr.cc188
-rw-r--r--src/lib/xdr16.cc216
4 files changed, 538 insertions, 0 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/lib/xdr.cc b/src/lib/xdr.cc
new file mode 100644
index 0000000..b44471f
--- /dev/null
+++ b/src/lib/xdr.cc
@@ -0,0 +1,188 @@
+#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 - 1;
+}
+
+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 - 1;
+}
+
+uint32_t XDRReader::get_uint32()
+{
+ uint32_t ret = (((uint32_t)data[pos] & 0xffU) << 24) | (((uint32_t)data[pos + 1] & 0xffU) << 16) | (((uint32_t)data[pos + 2] & 0xffU) << 8) | ((uint32_t)data[pos + 3] & 0xffU);
+ pos += 4;
+ return ret;
+}
+
+int32_t XDRReader::get_int32()
+{
+ int32_t ret = (((int32_t)data[pos] & 0xff) << 24) | (((int32_t)data[pos + 1] & 0xff) << 16) | (((int32_t)data[pos + 2] & 0xff) << 8) | ((int32_t)data[pos + 3] & 0xff);
+ pos += 4;
+ return ret;
+}
+
+uint64_t XDRReader::get_uint64()
+{
+ uint64_t ret = (((uint64_t)data[pos] & 0xffU) << 56) | (((uint64_t)data[pos + 1] & 0xffU) << 48) | (((uint64_t)data[pos + 2] & 0xffU) << 40) | (((uint64_t)data[pos + 3] & 0xffU) << 32) | (((uint64_t)data[pos + 4] & 0xffU) << 24) | (((uint64_t)data[pos + 5] & 0xffU) << 16) | (((uint64_t)data[pos + 6] & 0xffU) << 8) | ((uint64_t)data[pos + 7] & 0xffU);
+ return ret;
+}
+
+int64_t XDRReader::get_int64()
+{
+ int64_t ret = (((int64_t)data[pos] & 0xff) << 56) | (((int64_t)data[pos + 1] & 0xff) << 48) | (((int64_t)data[pos + 2] & 0xff) << 40) | (((int64_t)data[pos + 3] & 0xff) << 32) | (((int64_t)data[pos + 4] & 0xff) << 24) | (((int64_t)data[pos + 5] & 0xff) << 16) | (((int64_t)data[pos + 6] & 0xff) << 8) | ((int64_t)data[pos + 7] & 0xff);
+ return ret;
+}
+
+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..b1fb7ca
--- /dev/null
+++ b/src/lib/xdr16.cc
@@ -0,0 +1,216 @@
+#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 - 1;
+}
+
+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 - 1;
+}
+
+uint16_t XDRReader::get_uint16()
+{
+ uint16_t ret = (((uint16_t)data[pos] & 0xffU) << 8) | ((uint16_t)data[pos + 1] & 0xffU);
+ pos += 2;
+ return ret;
+}
+
+int16_t XDRReader::get_int16()
+{
+ int16_t ret = (((int16_t)data[pos] & 0xff) << 8) | ((int16_t)data[pos + 1] & 0xff);
+ pos += 2;
+ return ret;
+}
+
+uint32_t XDRReader::get_uint32()
+{
+ uint32_t ret = (((uint32_t)data[pos] & 0xffU) << 24) | (((uint32_t)data[pos + 1] & 0xffU) << 16) | (((uint32_t)data[pos + 2] & 0xffU) << 8) | ((uint32_t)data[pos + 3] & 0xffU);
+ pos += 4;
+ return ret;
+}
+
+int32_t XDRReader::get_int32()
+{
+ int32_t ret = (((int32_t)data[pos] & 0xff) << 24) | (((int32_t)data[pos + 1] & 0xff) << 16) | (((int32_t)data[pos + 2] & 0xff) << 8) | ((int32_t)data[pos + 3] & 0xff);
+ pos += 4;
+ return ret;
+}
+
+uint64_t XDRReader::get_uint64()
+{
+ uint64_t ret = (((uint64_t)data[pos] & 0xffU) << 56) | (((uint64_t)data[pos + 1] & 0xffU) << 48) | (((uint64_t)data[pos + 2] & 0xffU) << 40) | (((uint64_t)data[pos + 3] & 0xffU) << 32) | (((uint64_t)data[pos + 4] & 0xffU) << 24) | (((uint64_t)data[pos + 5] & 0xffU) << 16) | (((uint64_t)data[pos + 6] & 0xffU) << 8) | ((uint64_t)data[pos + 7] & 0xffU);
+ return ret;
+}
+
+int64_t XDRReader::get_int64()
+{
+ int64_t ret = (((int64_t)data[pos] & 0xff) << 56) | (((int64_t)data[pos + 1] & 0xff) << 48) | (((int64_t)data[pos + 2] & 0xff) << 40) | (((int64_t)data[pos + 3] & 0xff) << 32) | (((int64_t)data[pos + 4] & 0xff) << 24) | (((int64_t)data[pos + 5] & 0xff) << 16) | (((int64_t)data[pos + 6] & 0xff) << 8) | ((int64_t)data[pos + 7] & 0xff);
+ return ret;
+}
+
+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);
+ }
+}