diff options
Diffstat (limited to 'src/object/xdrstream.cc')
-rw-r--r-- | src/object/xdrstream.cc | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/object/xdrstream.cc b/src/object/xdrstream.cc new file mode 100644 index 0000000..9dc5a1b --- /dev/null +++ b/src/object/xdrstream.cc @@ -0,0 +1,166 @@ +/* + * Copyright 2020 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include "object/xdrstream.h" + +XDRStream & XDRStream::operator<<(unsigned char c) +{ + *this << (uint32_t)c; + return *this; +} + +XDRStream & XDRStream::operator<<(char c) +{ + *this << (int32_t)c; + return *this; +} + +XDRStream & XDRStream::operator<<(uint16_t number) +{ + *this << (uint32_t)number; + return *this; +} + +XDRStream & XDRStream::operator<<(int16_t number) +{ + *this << (int32_t)number; + 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; + // 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; + *this << v.i; + return *this; +} + +XDRStream & XDRStream::operator<<(double number) +{ + union { + uint64_t i; + double d; + } v; + // Setting one member of a union and then reading another is undefined + // behaviour, but works as intended in nearly any (embedded) compiler + 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++) % 4 != 0){ + put('\0'); + } + return *this; +} + +template<uint32_t TSize> +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++) % 4 != 0){ + put('\0'); + } + return *this; +} + +XDRStream & XDRStream::operator<<(XDRStream & (*fkt) (XDRStream &)) +{ + return fkt(*this); +} + +XDRStream & flush(XDRStream & os) +{ + os.flush(); + return os; +} + +XDRStream & term(XDRStream & os) +{ + os.put('\0'); + os.flush(); + return os; +} + +template<int N> +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; +} |