#pragma once #include "buffer.h" #include "error.h" #include #include 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 class ShiftStreamValue { public: inline static error_or decode(typename native_data_type>::type &val, buffer &buff) { if (buff.read_composite_length() < sizeof(T)) { return make_error(); } typename native_data_type>::type raw = 0; for (size_t i = 0; i < sizeof(T); ++i) { raw |= (static_cast(buff.read(i)) << (i * 8)); } memcpy(&val, &raw, sizeof(T)); buff.read_advance(sizeof(T)); return void_t{}; } inline static error_or encode(const typename native_data_type>::type &val, buffer &buff) { error err = buff.write_require_length(sizeof(T)); if (err.failed()) { return err; } typename native_data_type>::type raw{}; memcpy(&raw, &val, sizeof(T)); for (size_t i = 0; i < sizeof(T); ++i) { buffer.write(i) = raw >> (i * 8); } buffer.write_advance(sizeof(T)); return void_t{}; } inline static size_t size() const { return N; } }; template using stream_value = shift_stream_value; } // namespace saw