#pragma once #include "FileStream.hpp" #include "cplt_fwd.hpp" #include #include #include #include class BaseDataStream { private: std::endian mEndian = std::endian::big; public: std::endian GetEndianness() const; void SetEndianness(std::endian endianness); }; class InputDataStream : public BaseDataStream { private: InputFileStream mBackend; public: static constexpr bool IsSerializer() { return false; } InputDataStream(InputFileStream stream); void ReadBytes(size_t byteCount, std::byte* buffer); void ReadBytes(size_t byteCount, char* buffer); void ReadBytes(size_t byteCount, signed char* buffer); void ReadBytes(size_t byteCount, unsigned char* buffer); template void ReadBytes(size_t byteCount, TInserter&& inserter) { for (size_t i = 0; i < byteCount; ++i) { uint8_t byte; Read(byte); inserter = byte; } } void Read(int8_t& n); void Read(int16_t& n); void Read(int32_t& n); void Read(int64_t& n); void Read(uint8_t& n); void Read(uint16_t& n); void Read(uint32_t& n); void Read(uint64_t& n); void Read(float& n); void Read(double& n); template requires std::is_enum_v void ReadEnum(TEnum& e) { std::underlying_type_t n; Read(n); e = static_cast(e); } template void ReadObject(TObject& obj) { obj.ReadFromDataStream(*this); } template void ReadObjectAdapted(TObject& obj) { TAdapter::ReadFromDataStream(*this, obj); } public: // Proxy functions for writing templated IO functions template void Bytes(size_t byteCount, T* buffer) { ReadBytes(byteCount, buffer); } template void Value(T& t) { Read(t); } template void Enum(T& t) { ReadEnum(t); } template void Object(T& obj) { ReadObject(obj); } template void ObjectAdapted(TObject& obj) { ReadObjectAdapted(obj); } }; class OutputDataStream : public BaseDataStream { private: OutputFileStream mBackend; public: static constexpr bool IsSerializer() { return true; } OutputDataStream(OutputFileStream stream); void WriteBytes(size_t byteCount, const std::byte* buffer); void WriteBytes(size_t byteCount, const char* buffer); void WriteBytes(size_t byteCount, const signed char* buffer); void WriteBytes(size_t byteCount, const unsigned char* buffer); template void WriteBytes(TIterator&& begin, TIterator&& end) { for (; begin != end; ++begin) { uint8_t byte = *begin; Write(byte); } } void Write(int8_t n); void Write(int16_t n); void Write(int32_t n); void Write(int64_t n); void Write(uint8_t n); void Write(uint16_t n); void Write(uint32_t n); void Write(uint64_t n); void Write(float n); void Write(double n); template requires std::is_enum_v void WriteEnum(TEnum e) { auto n = static_cast>(e); Write(n); } template void WriteObject(const TObject& obj) { obj.WriteToDataStream(*this); } template void WriteObjectAdapted(const TObject& obj) { TAdapter::WriteToDataStream(*this, obj); } public: // Proxy functions for writing templated IO functions template void Bytes(size_t byteCount, T* buffer) { WriteBytes(byteCount, buffer); } template void Value(T t) { Write(t); } template void Enum(T t) { WriteEnum(t); } template void Object(T& obj) { WriteObject(obj); } template void ObjectAdapted(TObject& obj) { WriteObjectAdapted(obj); } };