diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index 169c7fd934..9bb9b67143 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -48,12 +48,14 @@ std::unique_ptr makeBsaArchive(const std::filesystem::path& path) case Bsa::BSAVER_UNKNOWN: std::cerr << '"' << path << "\" is unknown BSA archive" << std::endl; return nullptr; - case Bsa::BSAVER_UNCOMPRESSED: - return std::make_unique(path); case Bsa::BSAVER_COMPRESSED: + return std::make_unique::type>(path); case Bsa::BSAVER_BA2_GNRL: + return std::make_unique::type>(path); case Bsa::BSAVER_BA2_DX10: - return std::make_unique(path); + return std::make_unique::type>(path); + case Bsa::BSAVER_UNCOMPRESSED: + return std::make_unique::type>(path); } std::cerr << '"' << path << "\" is unsupported BSA archive" << std::endl; diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp deleted file mode 100644 index 3de393c120..0000000000 --- a/components/vfs/bsaarchive.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "bsaarchive.hpp" - -#include -#include - -namespace VFS -{ - - BsaArchive::BsaArchive(const std::filesystem::path& filename) - { - 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()); - } - } - - BsaArchive::BsaArchive() {} - - BsaArchive::~BsaArchive() {} - - void BsaArchive::listResources(std::map& out, char (*normalize_function)(char)) - { - for (std::vector::iterator it = mResources.begin(); it != mResources.end(); ++it) - { - std::string ent = it->mInfo->name(); - std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); - - out[ent] = &*it; - } - } - - bool BsaArchive::contains(const std::string& file, char (*normalize_function)(char)) const - { - for (const auto& it : mResources) - { - std::string ent = it.mInfo->name(); - std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); - if (file == ent) - return true; - } - return false; - } - - std::string BsaArchive::getDescription() const - { - return std::string{ "BSA: " } + mFile->getFilename(); - } - - // ------------------------------------------------------------------------------ - - BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::BSAFile* bsa) - : mInfo(info) - , mFile(bsa) - { - } - - Files::IStreamPtr BsaArchiveFile::open() - { - return mFile->getFile(mInfo); - } - - CompressedBsaArchive::CompressedBsaArchive(const std::filesystem::path& filename) - : Archive() - { - mCompressedFile = std::make_unique(); - mCompressedFile->open(filename); - - const Bsa::BSAFile::FileList& filelist = mCompressedFile->getList(); - for (Bsa::BSAFile::FileList::const_iterator it = filelist.begin(); it != filelist.end(); ++it) - { - mCompressedResources.emplace_back(&*it, mCompressedFile.get()); - } - } - - void CompressedBsaArchive::listResources(std::map& out, char (*normalize_function)(char)) - { - for (std::vector::iterator it = mCompressedResources.begin(); - it != mCompressedResources.end(); ++it) - { - std::string ent = it->mInfo->name(); - std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); - - out[ent] = &*it; - } - } - - bool CompressedBsaArchive::contains(const std::string& file, char (*normalize_function)(char)) const - { - for (const auto& it : mCompressedResources) - { - std::string ent = it.mInfo->name(); - std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); - if (file == ent) - return true; - } - return false; - } - - std::string CompressedBsaArchive::getDescription() const - { - return std::string{ "BSA: " } + mCompressedFile->getFilename(); - } - - CompressedBsaArchiveFile::CompressedBsaArchiveFile( - const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa) - : mInfo(info) - , mCompressedFile(bsa) - { - } - - Files::IStreamPtr CompressedBsaArchiveFile::open() - { - return mCompressedFile->getFile(mInfo); - } - -} diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index 9d1b6123e5..019715518e 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -3,66 +3,108 @@ #include "archive.hpp" +#include +#include #include #include namespace VFS { + template class BsaArchiveFile : public File { public: - BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::BSAFile* bsa); + BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, FileType* bsa) + : mInfo(info) + , mFile(bsa) + { + } - Files::IStreamPtr open() override; + Files::IStreamPtr open() override { return mFile->getFile(mInfo); } std::filesystem::path getPath() override { return mInfo->name(); } const Bsa::BSAFile::FileStruct* mInfo; - Bsa::BSAFile* mFile; - }; - - class CompressedBsaArchiveFile : public File - { - public: - CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa); - - Files::IStreamPtr open() override; - - std::filesystem::path getPath() override { return mInfo->name(); } - - const Bsa::BSAFile::FileStruct* mInfo; - Bsa::CompressedBSAFile* mCompressedFile; + FileType* mFile; }; + template class BsaArchive : public Archive { public: - BsaArchive(const std::filesystem::path& filename); - BsaArchive(); - virtual ~BsaArchive(); - void listResources(std::map& out, char (*normalize_function)(char)) override; - bool contains(const std::string& file, char (*normalize_function)(char)) const override; - std::string getDescription() const override; + BsaArchive(const std::filesystem::path& filename) + : Archive() + { + mFile = std::make_unique(); + mFile->open(filename); - protected: - std::unique_ptr mFile; - std::vector mResources; - }; + 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()); + } + } - class CompressedBsaArchive : public Archive - { - public: - CompressedBsaArchive(const std::filesystem::path& filename); - virtual ~CompressedBsaArchive() {} - void listResources(std::map& out, char (*normalize_function)(char)) override; - bool contains(const std::string& file, char (*normalize_function)(char)) const override; - std::string getDescription() const override; + virtual ~BsaArchive() {} + + void listResources(std::map& out, char (*normalize_function)(char)) override + { + for (auto& resource : mResources) + { + std::string ent = resource.mInfo->name(); + std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); + + out[ent] = &resource; + } + } + + bool contains(const std::string& file, char (*normalize_function)(char)) const override + { + for (const auto& it : mResources) + { + std::string ent = it.mInfo->name(); + std::transform(ent.begin(), ent.end(), ent.begin(), normalize_function); + if (file == ent) + return true; + } + return false; + } + + std::string getDescription() const override { return std::string{ "BSA: " } + mFile->getFilename(); } private: - std::unique_ptr mCompressedFile; - std::vector mCompressedResources; + 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 diff --git a/components/vfs/registerarchives.cpp b/components/vfs/registerarchives.cpp index 4897c45fa2..9dbe878bca 100644 --- a/components/vfs/registerarchives.cpp +++ b/components/vfs/registerarchives.cpp @@ -28,9 +28,15 @@ namespace VFS Bsa::BsaVersion bsaVersion = Bsa::BSAFile::detectVersion(archivePath); if (bsaVersion == Bsa::BSAVER_COMPRESSED) - vfs->addArchive(std::make_unique(archivePath)); + vfs->addArchive(std::make_unique::type>(archivePath)); + else if (bsaVersion == Bsa::BSAVER_BA2_GNRL) + vfs->addArchive(std::make_unique::type>(archivePath)); + else if (bsaVersion == Bsa::BSAVER_BA2_DX10) + vfs->addArchive(std::make_unique::type>(archivePath)); + else if (bsaVersion == Bsa::BSAVER_UNCOMPRESSED) + vfs->addArchive(std::make_unique::type>(archivePath)); else - vfs->addArchive(std::make_unique(archivePath)); + throw std::runtime_error("Unknown archive type '" + *archive + "'"); } else {