diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app/prototest/Makefile.inc | 4 | ||||
-rw-r--r-- | src/app/prototest/main.cc | 8 | ||||
-rw-r--r-- | src/lib/xdr.cc | 187 | ||||
-rw-r--r-- | src/lib/xdr16.cc | 214 |
4 files changed, 405 insertions, 8 deletions
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); + } +} |