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 "esx_reader.hpp"
#include <fstream>
#include <bit>
using namespace esxr;

View File

@@ -8,6 +8,7 @@
#include <compare> #include <compare>
#include <vector> #include <vector>
#include <type_traits> #include <type_traits>
#include <fstream>
#include "utility.hpp" #include "utility.hpp"
@@ -20,6 +21,14 @@ namespace esxr {
class GroupNode; class GroupNode;
class RecordNode; 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 // Enumerations
// //
@@ -135,6 +144,23 @@ struct RecordHeader {
uint16_t unknown; 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 // Classes
// //
@@ -162,6 +188,12 @@ private:
[[nodiscard]] std::optional<std::string_view> flag_to_description(Flag flag) noexcept; [[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; [[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 #endif

View File

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