#ifndef TESFILE_READER_H #define TESFILE_READER_H #include "Stream.h" #include #include #include #include #include namespace TESFile { template concept ReaderHandler = requires(Handler& handler) { { handler.Group(std::declval()) } -> std::convertible_to; { handler.Form(std::declval()) } -> std::convertible_to; { handler.Chunk(std::declval()) } -> std::convertible_to; { handler.Data(std::declval()) }; }; template 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