diff options
author | rtk0c <[email protected]> | 2021-08-21 19:12:02 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2021-08-21 19:12:02 -0700 |
commit | f7abb9021e071abee27b0fba2c1ffe989be2003e (patch) | |
tree | ac66ce9cdb01decf0b735ab0fd54037c6882c8d6 /core/src/Utils/IO/Archive.cpp | |
parent | 16539032ceec2746aa3778b1c5db9e4485d274d0 (diff) |
DataArchive system which saves in native endian (for better performance working with local files), but is also able to load in any endian depending on archive's header information
Diffstat (limited to 'core/src/Utils/IO/Archive.cpp')
-rw-r--r-- | core/src/Utils/IO/Archive.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/core/src/Utils/IO/Archive.cpp b/core/src/Utils/IO/Archive.cpp new file mode 100644 index 0000000..559c476 --- /dev/null +++ b/core/src/Utils/IO/Archive.cpp @@ -0,0 +1,65 @@ +#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> 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> 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)) +{ +} |