aboutsummaryrefslogtreecommitdiff
path: root/app/source/Cplt/Utils/IO/Archive.cpp
blob: f6e7b2721e6a89e3b54c38799df1793688a6155d (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
#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::span<const uint8_t, 8> DataArchive::GetMagicNumbers()
{
	return std::span<const uint8_t, 8>{ kMagicNumbers };
}

std::optional<InputDataStream> DataArchive::LoadFile(const std::filesystem::path& path)
{
	InputFileStream fileStream(path);
	fileStream.SetReadInSize(1024);
	InputDataStream stream(std::move(fileStream));

	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)
{
	OutputFileStream fileStream(path, OutputFileStream::TruncateFile);
	fileStream.SetMaxBufferSize(1024);
	OutputDataStream stream(std::move(fileStream));

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

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

	return stream;
}