aboutsummaryrefslogtreecommitdiff
path: root/libs/installer_bsplugins/src/TESFile/Reader.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/installer_bsplugins/src/TESFile/Reader.h')
-rw-r--r--libs/installer_bsplugins/src/TESFile/Reader.h67
1 files changed, 67 insertions, 0 deletions
diff --git a/libs/installer_bsplugins/src/TESFile/Reader.h b/libs/installer_bsplugins/src/TESFile/Reader.h
new file mode 100644
index 0000000..0479842
--- /dev/null
+++ b/libs/installer_bsplugins/src/TESFile/Reader.h
@@ -0,0 +1,67 @@
+#ifndef TESFILE_READER_H
+#define TESFILE_READER_H
+
+#include "Stream.h"
+
+#include <concepts>
+#include <cstdint>
+#include <filesystem>
+#include <istream>
+#include <utility>
+
+namespace TESFile
+{
+
+template <typename Handler>
+concept ReaderHandler = requires(Handler& handler) {
+ {
+ handler.Group(std::declval<GroupData>())
+ } -> std::convertible_to<bool>;
+ {
+ handler.Form(std::declval<FormData>())
+ } -> std::convertible_to<bool>;
+ {
+ handler.Chunk(std::declval<Type>())
+ } -> std::convertible_to<bool>;
+ {
+ handler.Data(std::declval<std::istream&>())
+ };
+};
+
+template <ReaderHandler Handler>
+class Reader
+{
+public:
+ void parse(const std::filesystem::path& path, Handler& handler);
+
+ void parse(std::istream& stream, Handler& handler);
+
+private:
+ enum HeaderSize
+ {
+ HeaderSize_Standard = sizeof(RecordHeader),
+ HeaderSize_Oblivion = 20,
+ HeaderSize_Morrowind = 16,
+ };
+
+ std::uint32_t parsePluginInfo(std::istream& stream, Handler& handler);
+
+ std::uint32_t parseRecord(std::istream& stream, Handler& handler);
+
+ std::uint32_t handleForm(std::istream& stream, const RecordHeader& header,
+ Handler& handler);
+
+ std::uint32_t handleGroup(std::istream& stream, const RecordHeader& header,
+ Handler& handler);
+
+ std::uint32_t parseChunk(std::istream& stream, Handler& handler);
+
+ TESFormat chunkFormat_;
+ int headerSize_;
+};
+
+} // namespace TESFile
+
+#include "Reader.inl"
+
+#endif // TESFILE_READER_H