aboutsummaryrefslogtreecommitdiff
path: root/core/src/Utils/IO/Archive.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-08-21 19:12:02 -0700
committerrtk0c <[email protected]>2021-08-21 19:12:02 -0700
commitf7abb9021e071abee27b0fba2c1ffe989be2003e (patch)
treeac66ce9cdb01decf0b735ab0fd54037c6882c8d6 /core/src/Utils/IO/Archive.cpp
parent16539032ceec2746aa3778b1c5db9e4485d274d0 (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.cpp65
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))
+{
+}