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:
@@ -1,4 +1,8 @@
|
||||
#include "esx_reader.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <bit>
|
||||
|
||||
using namespace esxr;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user