#pragma once #include "endian.hpp" #include "types.hpp" #include "../utils.hpp" #include #include namespace sibs { /** * Endian independent serializer */ class SafeSerializer { DISABLE_COPY(SafeSerializer); public: SafeSerializer(){} SafeSerializer(SafeSerializer &&other) { buffer = std::move(other.buffer); } template void add(const T &data) { usize offset = buffer.size(); buffer.resize(buffer.size() + sizeof(T)); #if BYTE_ORDER == BIG_ENDIAN switch(sizeof(T)) { case 1: *(T*)&buffer[offset] = data; break; case 2: *(u16*)&buffer[offset] = byteswap(*(u16*)&data); break; case 4: *(u32*)&buffer[offset] = byteswap(*(u32*)&data); break; case 8: *(u64*)&buffer[offset] = byteswap(*(u64*)&data); break; default: { for(int i = 0; i < sizeof(T); ++i) { buffer[offset + i] = ((char*)&data)[sizeof(T) - 1 - i]; } break; } } #else *(T*)&buffer[offset] = data; #endif } void add(const u8 *data, usize size) { if(size > 0) { usize offset = buffer.size(); buffer.resize(buffer.size() + size); memcpy(&buffer[offset], data, size); } } void add(const char *data, usize size) { add((const u8*)data, size); } std::vector& getBuffer() { return buffer; } usize getSize() const { return buffer.size(); } private: std::vector buffer; }; }