#ifndef VFS_BSAARCHIVE_HPP_ #define VFS_BSAARCHIVE_HPP_ #include "archive.hpp" #include "file.hpp" #include "pathutil.hpp" #include #include #include #include namespace VFS { template class BsaArchiveFile : public File { public: BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, FileType* bsa) : mInfo(info) , mFile(bsa) { } Files::IStreamPtr open() override { return mFile->getFile(mInfo); } std::filesystem::path getPath() override { return mInfo->name(); } const Bsa::BSAFile::FileStruct* mInfo; FileType* mFile; }; template class BsaArchive : public Archive { public: BsaArchive(const std::filesystem::path& filename) : Archive() { mFile = std::make_unique(); mFile->open(filename); const Bsa::BSAFile::FileList& filelist = mFile->getList(); for (Bsa::BSAFile::FileList::const_iterator it = filelist.begin(); it != filelist.end(); ++it) { mResources.emplace_back(&*it, mFile.get()); } } virtual ~BsaArchive() {} void listResources(FileMap& out) override { for (auto& resource : mResources) { std::string ent = resource.mInfo->name(); Path::normalizeFilenameInPlace(ent); out[ent] = &resource; } } bool contains(std::string_view file) const override { for (const auto& it : mResources) { if (Path::pathEqual(file, it.mInfo->name())) return true; } return false; } std::string getDescription() const override { return std::string{ "BSA: " } + mFile->getFilename(); } private: std::unique_ptr mFile; std::vector> mResources; }; template struct ArchiveSelector { }; template <> struct ArchiveSelector { using type = BsaArchive; }; template <> struct ArchiveSelector { using type = BsaArchive; }; template <> struct ArchiveSelector { using type = BsaArchive; }; template <> struct ArchiveSelector { using type = BsaArchive; }; } #endif