#include "Archive.hpp" constexpr uint8_t kMagicNumbers[] = { 0x98, 0xd8, 0xa4, 0x65, 0x18, 0xa2, 0xd6, 0xa0 }; constexpr size_t kMagicNumberCount = std::size(kMagicNumbers); constexpr uint8_t kByteOrderMark = []() { switch (std::endian::native) { case std::endian::little: return 0; case std::endian::big: return 1; } }(); std::optional DataArchive::SaveFile(const std::filesystem::path& path) { auto archive = DataArchive(DataStream(std::fstream(path))); auto& stream = archive.mStream; stream.WriteBytes(kMagicNumberCount, kMagicNumbers); stream.Write(kByteOrderMark); stream.SetEndianness(std::endian::native); return archive; } std::optional DataArchive::LoadFile(const std::filesystem::path& path) { auto archive = DataArchive(DataStream(std::fstream(path))); auto& stream = archive.mStream; uint8_t magicNumbers[kMagicNumberCount]; stream.ReadBytes(kMagicNumberCount, magicNumbers); for (size_t i = 0; i < kMagicNumberCount; ++i) { if (magicNumbers[i] != kMagicNumbers[i]) { return {}; } } uint8_t byteOrderMark; stream.Read(byteOrderMark); switch (byteOrderMark) { case 0: stream.SetEndianness(std::endian::little); break; case 1: stream.SetEndianness(std::endian::big); break; default: std::abort(); } return archive; } const DataStream& DataArchive::GetStream() const { return mStream; } DataStream& DataArchive::GetStream() { return mStream; } DataArchive::DataArchive(DataStream stream) : mStream(std::move(stream)) { }