aboutsummaryrefslogtreecommitdiff
path: root/core/src/Utils/IO/Archive.cpp
blob: b6f806bbef5f49352fcd6c9aa9d12c3848a0185d (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
#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<InputDataStream> DataArchive::LoadFile(const std::filesystem::path& path)
{
	auto stream = InputDataStream(std::fstream(path));

	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 stream;
}

std::optional<OutputDataStream> DataArchive::SaveFile(const std::filesystem::path& path)
{
	auto stream = OutputDataStream(std::fstream(path));

	stream.WriteBytes(kMagicNumberCount, kMagicNumbers);
	stream.Write(kByteOrderMark);

	stream.SetEndianness(std::endian::native);

	return stream;
}