#pragma once #include "schema.hpp" #include #include #include #include namespace saw { /** * Helper class to encode/decode any primitive 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 class shift_stream_value { static_assert(always_false, "Shift Stream Value only supports Primitives"); }; template class shift_stream_value> { public: inline static error_or decode(typename native_data_type>::type &val, buffer &buff) { if (buff.read_composite_length() < N) { return make_error(); } typename native_data_type>::type raw = 0; for (size_t i = 0; i < N; ++i) { raw |= (static_cast>::type>(buff.read(i)) << (i * 8)); } memcpy(&val, &raw, N); buff.read_advance(N); return void_t{}; } inline static error_or encode(const typename native_data_type>::type &val, buffer &buff) { error err = buff.write_require_length(N); if (err.failed()) { return err; } typename native_data_type>::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 using stream_value = shift_stream_value; } // namespace saw