diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 17:01:04 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 17:01:04 +0100 |
commit | a863f9af9fff0ecb276c6769149d9672961b7533 (patch) | |
tree | 9f7bc499df30e651ae0cc6c2ffca0dd64b4e3769 /modules/codec/c++/stream_value.h | |
parent | 8da0229a7e172a86c023edc6bb25ba803c68f5d3 (diff) |
codec: Moving structure around
Diffstat (limited to 'modules/codec/c++/stream_value.h')
-rw-r--r-- | modules/codec/c++/stream_value.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/modules/codec/c++/stream_value.h b/modules/codec/c++/stream_value.h new file mode 100644 index 0000000..09203cb --- /dev/null +++ b/modules/codec/c++/stream_value.h @@ -0,0 +1,64 @@ +#pragma once + +#include "schema.h" + +#include <forstio/core/buffer.h> +#include <forstio/core/error.h> + +#include <cstdint> +#include <cstring> + +namespace saw { +/** + * Helper class to encode/decode any primtive type into/from litte endian. + * The shift class does this by shifting bytes. This type of procedure is + * platform independent. So it does not matter if the memory layout is + * little endian or big endian + */ +template<typename T> class shift_stream_value { + static_assert(always_false<T>, "Shift Stream Value only supports Primitives"); +}; + +template <typename T, size_t N> class shift_stream_value<schema::Primitive<T,N>> { +public: + inline static error_or<void> decode(typename native_data_type<schema::Primitive<T,N>>::type &val, buffer &buff) { + if (buff.read_composite_length() < N) { + return make_error<err::buffer_exhausted>(); + } + + typename native_data_type<schema::Primitive<schema::UnsignedInteger,N>>::type raw = 0; + + for (size_t i = 0; i < N; ++i) { + raw |= (static_cast<typename native_data_type<schema::Primitive<T,N>>::type>(buff.read(i)) << (i * 8)); + } + + memcpy(&val, &raw, N); + buff.read_advance(N); + + return void_t{}; + } + + inline static error_or<void> encode(const typename native_data_type<schema::Primitive<T,N>>::type &val, buffer &buff) { + error err = buff.write_require_length(N); + if (err.failed()) { + return err; + } + + typename native_data_type<schema::Primitive<schema::UnsignedInteger,N>>::type raw{}; + memcpy(&raw, &val, N); + + for (size_t i = 0; i < N; ++i) { + buff.write(i) = raw >> (i * 8); + } + + buff.write_advance(N); + + return void_t{}; + } + + inline static size_t size() { return N; } +}; + +template <typename T> using stream_value = shift_stream_value<T>; + +} // namespace saw |