From 2c001e655002ee713457342197a7005217cd16b4 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 26 Jun 2019 14:40:30 +0200 Subject: Add a 16-bit XDR variant --- include/object/xdr16input.h | 27 +++++++ include/object/xdr16stream.h | 50 +++++++++++++ src/app/prototest/Makefile.inc | 5 ++ src/app/prototest/main.cc | 5 ++ src/os/object/xdr16input.cc | 99 +++++++++++++++++++++++++ src/os/object/xdr16stream.cc | 161 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 347 insertions(+) create mode 100644 include/object/xdr16input.h create mode 100644 include/object/xdr16stream.h create mode 100644 src/os/object/xdr16input.cc create mode 100644 src/os/object/xdr16stream.cc diff --git a/include/object/xdr16input.h b/include/object/xdr16input.h new file mode 100644 index 0000000..66b2c56 --- /dev/null +++ b/include/object/xdr16input.h @@ -0,0 +1,27 @@ +#ifndef XDRINPUT_H +#define XDRINPUT_H + +#include + +class XDRInput { + private: + XDRInput(const XDRInput& copy); + char *data; + uint32_t pos; + + public: + XDRInput(char *d) : pos(0) { data = d; } + uint16_t get_uint16(); + int16_t get_int16(); + uint32_t get_uint32(); + int32_t get_int32(); + uint64_t get_uint64(); + int64_t get_int64(); + float get_float(); + double get_double(); + uint16_t get_opaque_length(); + char* get_opaque(uint16_t length); + void get_string(char *target); +}; + +#endif diff --git a/include/object/xdr16stream.h b/include/object/xdr16stream.h new file mode 100644 index 0000000..7cec1b1 --- /dev/null +++ b/include/object/xdr16stream.h @@ -0,0 +1,50 @@ +#ifndef XDRSTREAM_H +#define XDRSTREAM_H + +#include + +class XDRStream { + private: + XDRStream(const XDRStream& copy); + uint16_t next_array_len; + bool is_fixed_length; + + public: + XDRStream() : next_array_len(0) {} + void setNextArrayLen(uint16_t len) {next_array_len = len;} + void setFixedLength() { is_fixed_length = true; } + void setVariableLength() { is_fixed_length = false; } + + virtual void put(char c) = 0; + + virtual void flush() {} + + XDRStream & operator<<(char c); + XDRStream & operator<<(unsigned char c); + XDRStream & operator<<(uint16_t number); + XDRStream & operator<<(int16_t number); + XDRStream & operator<<(uint32_t number); + XDRStream & operator<<(int32_t number); + XDRStream & operator<<(uint64_t number); + XDRStream & operator<<(int64_t number); + XDRStream & operator<<(float number); + XDRStream & operator<<(double number); + XDRStream & operator<<(char const *text); + template XDRStream & operator<<(char const (&text)[TSize]); + XDRStream & operator<<(XDRStream & (*fun) (XDRStream &)); +}; + + +// FLUSH: flush XDRStream buffer +XDRStream & flush(XDRStream & os); + +// TERM: zero-termination +XDRStream & term(XDRStream & os); + +template +XDRStream & opaque(XDRStream & os); + +XDRStream & fixed(XDRStream & os); +XDRStream & variable(XDRStream & os); + +#endif //OUTPUTSTREAM_H diff --git a/src/app/prototest/Makefile.inc b/src/app/prototest/Makefile.inc index a33fd48..ee509a7 100644 --- a/src/app/prototest/Makefile.inc +++ b/src/app/prototest/Makefile.inc @@ -72,6 +72,11 @@ ifeq (${prototest_xdr}, 1) CXX_TARGETS += src/os/object/xdrstream.cc src/os/object/xdrinput.cc endif +ifeq (${prototest_xdr16}, 1) + COMMON_FLAGS += -DPROTOTEST_XDR16 + CXX_TARGETS += src/os/object/xdr16stream.cc src/os/object/xdr16input.cc +endif + # Don't try to make .capnp from .capnp.c %.capnp: ; diff --git a/src/app/prototest/main.cc b/src/app/prototest/main.cc index d470d59..ee5c958 100644 --- a/src/app/prototest/main.cc +++ b/src/app/prototest/main.cc @@ -39,6 +39,11 @@ #include "object/xdrstream.h" #include "object/xdrinput.h" #endif +#ifdef PROTOTEST_XDR16 +#include "object/stdbuf.h" +#include "object/xdr16stream.h" +#include "object/xdr16input.h" +#endif #include diff --git a/src/os/object/xdr16input.cc b/src/os/object/xdr16input.cc new file mode 100644 index 0000000..407f6ea --- /dev/null +++ b/src/os/object/xdr16input.cc @@ -0,0 +1,99 @@ +#include "object/xdr16input.h" + +uint16_t XDRInput::get_uint16() +{ + uint32_t ret = ((uint8_t)data[pos]<<8) | (uint8_t)data[pos+1]; + pos += 2; + return ret; +} + +int16_t XDRInput::get_int16() +{ + int32_t ret = (data[pos]<<8) | data[pos+1]; + pos += 2; + return ret; +} + +uint32_t XDRInput::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 XDRInput::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 XDRInput::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 XDRInput::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 XDRInput::get_float() +{ + union { + uint32_t i; + float f; + } v; + v.i = get_uint32(); + return v.f; +} + +double XDRInput::get_double() +{ + union { + uint64_t i; + double d; + } v; + v.i = get_uint64(); + return v.d; +} + +uint16_t XDRInput::get_opaque_length() +{ + return get_uint16(); +} + +char *XDRInput::get_opaque(uint16_t length) +{ + char *ret = data + pos; + pos += length; + if (length % 2) { + pos += 2 - (length % 2); + } + return ret; +} + +void XDRInput::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); + } +} diff --git a/src/os/object/xdr16stream.cc b/src/os/object/xdr16stream.cc new file mode 100644 index 0000000..082b2a3 --- /dev/null +++ b/src/os/object/xdr16stream.cc @@ -0,0 +1,161 @@ +#include "object/xdr16stream.h" + +XDRStream & XDRStream::operator<<(unsigned char c) +{ + *this << (uint16_t)c; + return *this; +} + +XDRStream & XDRStream::operator<<(char c) +{ + *this << (int16_t)c; + return *this; +} + +XDRStream & XDRStream::operator<<(uint16_t number) +{ + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(int16_t number) +{ + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(uint32_t number) +{ + put((number >> 24) & 0xffU); + put((number >> 16) & 0xffU); + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(int32_t number) +{ + put((number >> 24) & 0xffU); + put((number >> 16) & 0xffU); + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(uint64_t number) +{ + put((number >> 56) & 0xffU); + put((number >> 48) & 0xffU); + put((number >> 40) & 0xffU); + put((number >> 32) & 0xffU); + put((number >> 24) & 0xffU); + put((number >> 16) & 0xffU); + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(int64_t number) +{ + put((number >> 56) & 0xffU); + put((number >> 48) & 0xffU); + put((number >> 40) & 0xffU); + put((number >> 32) & 0xffU); + put((number >> 24) & 0xffU); + put((number >> 16) & 0xffU); + put((number >> 8) & 0xffU); + put(number & 0xffU); + return *this; +} + +XDRStream & XDRStream::operator<<(float number) +{ + union { + uint32_t i; + float f; + } v; + v.f = number; + *this << v.i; + return *this; +} + +XDRStream & XDRStream::operator<<(double number) +{ + union { + uint64_t i; + double d; + } v; + v.d = number; + *this << v.i; + return *this; +} + +XDRStream & XDRStream::operator<<(char const *data){ + if (!is_fixed_length) { + *this << next_array_len; + } + uint32_t i; + for (i = 0; i < next_array_len; i++) { + put(data[i]); + } + while ((i++) % 2 != 0){ + put('\0'); + } + return *this; +} + +template +XDRStream & XDRStream::operator<<(char const (&data)[TSize]){ + if (!is_fixed_length) { + *this << TSize; + } + uint32_t i; + for (i = 0; i < TSize; i++) { + put(data[i]); + } + while ((i++) % 2 != 0){ + put('\0'); + } + return *this; +} + +XDRStream & XDRStream::operator<<(XDRStream & (*fkt) (XDRStream &)) +{ + return fkt(*this); +} + +// FLUSH +XDRStream & flush(XDRStream & os) +{ + os.flush(); + return os; +} + +// TERM: null-termination +XDRStream & term(XDRStream & os) +{ + os.put('\0'); + os.flush(); + return os; +} + +template +XDRStream & opaque(XDRStream & os) +{ + os.setNextArrayLen(N); + return os; +} + +XDRStream & fixed(XDRStream & os) +{ + os.setFixedLength(); + return os; +} + +XDRStream & variable(XDRStream & os) +{ + os.setVariableLength(); + return os; +} -- cgit v1.2.3