Implemented read_header with concept based constraints. Currently only provided in the best case scenario (readable directly from the file into the struct).

This commit is contained in:
2022-10-25 19:38:17 +11:00
parent 0a38900164
commit 50074b6f0d
3 changed files with 40 additions and 7 deletions

View File

@@ -1,4 +1,8 @@
#include "esx_reader.hpp"
#include <fstream>
#include <bit>
using namespace esxr;

View File

@@ -8,6 +8,7 @@
#include <compare>
#include <vector>
#include <type_traits>
#include <fstream>
#include "utility.hpp"
@@ -20,6 +21,14 @@ namespace esxr {
class GroupNode;
class RecordNode;
//
// Constants
//
static constexpr auto esx_endianness = std::endian::little;
static constexpr std::streamsize header_size = 24;
static constexpr bool same_endianness = std::endian::native == esx_endianness;
//
// Enumerations
//
@@ -135,6 +144,23 @@ struct RecordHeader {
uint16_t unknown;
};
//
// Concepts
//
template <typename T, size_t N>
concept packed = sizeof(T) == N;
template <typename T>
concept is_header = std::is_same_v<T, GroupHeader> || std::is_same_v<T, RecordHeader>;
template <typename T>
concept packed_header = is_header<T> && packed<T, static_cast<std::size_t>(header_size)>;
template <typename T>
concept directly_readable_header = packed_header<T> && same_endianness;
//
// Classes
//
@@ -162,6 +188,12 @@ private:
[[nodiscard]] std::optional<std::string_view> flag_to_description(Flag flag) noexcept;
[[nodiscard]] std::optional<std::string_view> refr_flag_to_description(RefrFlag refr_flag) noexcept;
void read_header(std::ifstream &in, directly_readable_header auto &out)
{
auto char_ptr = reinterpret_cast<char *>(&out);
in.read(char_ptr, header_size);
}
}
#endif

View File

@@ -24,10 +24,7 @@ static constexpr auto esm_name = "Skyrim.esm";
int main()
{
auto esm_fs = open_esm();
std::array<char, 4> fourcc{};
esm_fs.read(fourcc.data(), static_cast<std::streamsize>(fourcc.size()));
for (auto c : fourcc)
std::cout << c;
std::cout << '\n';
return 0;
esxr::RecordHeader header{};
esxr::read_header(esm_fs, header);
return static_cast<int>(header.type);
}