aboutsummaryrefslogtreecommitdiff
path: root/core/src/Utils/IO/Archive.cpp
blob: 559c476b76908624aa2f3b45c25802ea59cd408a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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))
{
}