#pragma once #include #include #include #include namespace sp { namespace details { template void WriteBitField(DataBuffer& a_Buffer, std::uint64_t& a_DataRaw, std::size_t& a_Offset) { T filled = static_cast(a_DataRaw); ToNetwork(filled); a_Buffer << filled; a_Offset = 0; a_DataRaw = 0; } template void WriteField(DataBuffer& a_Buffer, const BitField& a_Data, std::uint64_t& a_DataRaw, std::size_t& a_Offset) { T cut = *a_Data & ((1 << a_Data.GetBitSize()) - 1); std::size_t pushCount = sizeof(T) * 8 - a_Offset - a_Data.GetBitSize(); a_DataRaw |= cut << pushCount; a_Offset += a_Data.GetBitSize(); if (a_Offset == sizeof(T) * 8) { WriteBitField(a_Buffer, a_DataRaw, a_Offset); } } template void WriteField(DataBuffer& a_Buffer, const T& a_Data, std::uint64_t& a_DataRaw, std::size_t& a_Offset) { T swapped = a_Data; ToNetwork(swapped); a_Buffer << swapped; } template void ReadField(DataBuffer& a_Buffer, BitField& a_Data, std::size_t& a_Offset) { a_Buffer >> *a_Data; FromNetwork(*a_Data); *a_Data >>= sizeof(T) * 8 - a_Offset - a_Data.GetBitSize(); *a_Data &= (1 << a_Data.GetBitSize()) - 1; if (a_Offset != sizeof(T) * 8) { a_Buffer.SetReadOffset(a_Buffer.GetReadOffset() - sizeof(T)); a_Offset += a_Data.GetBitSize(); } else { a_Offset = 0; } } template void ReadField(DataBuffer& a_Buffer, T& a_Data, std::size_t& a_Offset) { a_Buffer >> a_Data; FromNetwork(a_Data); } template DataBuffer WriteMessage(const TData& a_MessageData) { DataBuffer buffer; std::size_t currentOffset = 0; std::uint64_t dataRaw = 0; boost::pfr::for_each_field(a_MessageData, [&buffer, &dataRaw, ¤tOffset](const auto& a_Field) { WriteField(buffer, a_Field, dataRaw, currentOffset); }); return buffer; } template void ReadMessage(DataBuffer& a_Buffer, TData& a_MessageData) { std::size_t currentOffset = 0; boost::pfr::for_each_field( a_MessageData, [&a_Buffer, ¤tOffset](auto& a_Field) { ReadField(a_Buffer, a_Field, currentOffset); }); } } // namespace details } // namespace sp