diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index ecbea5e7d9..d5610bddae 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -290,11 +290,6 @@ Files::IStreamPtr BSAFile::getFile(const char *file) return Files::openConstrainedFileStream (mFilename.c_str (), fs.offset, fs.fileSize); } -Files::IStreamPtr BSAFile::getFile(const FileStruct *file) -{ - return Files::openConstrainedFileStream (mFilename.c_str (), file->offset, file->fileSize); -} - void Bsa::BSAFile::addFile(const std::string& filename, std::istream& file) { if (!mIsLoaded) diff --git a/components/bsa/bsa_file.hpp b/components/bsa/bsa_file.hpp index d30fc2feb0..9a76e1bd23 100644 --- a/components/bsa/bsa_file.hpp +++ b/components/bsa/bsa_file.hpp @@ -154,7 +154,10 @@ public: /** Open a file contained in the archive. * @note Thread safe. */ - virtual Files::IStreamPtr getFile(const FileStruct* file); + Files::IStreamPtr getFile(const FileStruct *file) + { + return Files::openConstrainedFileStream (mFilename.c_str (), file->offset, file->fileSize); + } virtual void addFile(const std::string& filename, std::istream& file); diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index ac6e6fdf78..ffd88fe044 100644 --- a/components/bsa/compressedbsafile.hpp +++ b/components/bsa/compressedbsafile.hpp @@ -93,7 +93,7 @@ namespace Bsa void readHeader() override; Files::IStreamPtr getFile(const char* filePath) override; - Files::IStreamPtr getFile(const FileStruct* fileStruct) override; + Files::IStreamPtr getFile(const FileStruct* fileStruct); void addFile(const std::string& filename, std::istream& file) override; }; } diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp index 90899ac612..86d21060c0 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -1,5 +1,5 @@ #include "bsaarchive.hpp" -#include + #include namespace VFS @@ -7,15 +7,7 @@ namespace VFS BsaArchive::BsaArchive(const std::string &filename) { - Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(filename); - - if (bsaVersion == Bsa::BSAVER_COMPRESSED) { - mFile = std::make_unique(Bsa::CompressedBSAFile()); - } - else { - mFile = std::make_unique(Bsa::BSAFile()); - } - + mFile = std::make_unique(Bsa::BSAFile()); mFile->open(filename); const Bsa::BSAFile::FileList &filelist = mFile->getList(); @@ -25,6 +17,10 @@ BsaArchive::BsaArchive(const std::string &filename) } } +BsaArchive::BsaArchive() +{ +} + BsaArchive::~BsaArchive() { } @@ -56,6 +52,31 @@ std::string BsaArchive::getDescription() const return std::string{"BSA: "} + mFile->getFilename(); } +CompressedBsaArchive::CompressedBsaArchive(const std::string &filename) + : BsaArchive() +{ + mFile = std::make_unique(Bsa::CompressedBSAFile()); + 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()); + mCompressedResources.emplace_back(&*it, static_cast(mFile.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; + } +} + // ------------------------------------------------------------------------------ BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::BSAFile* bsa) @@ -70,4 +91,16 @@ Files::IStreamPtr BsaArchiveFile::open() return mFile->getFile(mInfo); } +CompressedBsaArchiveFile::CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::CompressedBSAFile* bsa) + : BsaArchiveFile(info, bsa) + , mCompressedFile(bsa) +{ + +} + +Files::IStreamPtr CompressedBsaArchiveFile::open() +{ + return mCompressedFile->getFile(mInfo); +} + } diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index c979b5ce7e..1015f8d220 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -4,6 +4,7 @@ #include "archive.hpp" #include +#include namespace VFS { @@ -18,19 +19,43 @@ namespace VFS Bsa::BSAFile* mFile; }; + class CompressedBsaArchiveFile : public BsaArchiveFile + { + public: + CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa); + + Files::IStreamPtr open() override; + Bsa::CompressedBSAFile* mCompressedFile; + }; + + class BsaArchive : public Archive { public: BsaArchive(const std::string& 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; - private: + protected: std::unique_ptr mFile; std::vector mResources; }; + + class CompressedBsaArchive : public BsaArchive + { + public: + CompressedBsaArchive(const std::string& filename); + void listResources(std::map& out, char (*normalize_function) (char)) override; + virtual ~CompressedBsaArchive() {} + + private: + std::unique_ptr mCompressedFile; + std::vector mCompressedResources; + }; + } #endif diff --git a/components/vfs/registerarchives.cpp b/components/vfs/registerarchives.cpp index 80e639f350..4dc44fb25e 100644 --- a/components/vfs/registerarchives.cpp +++ b/components/vfs/registerarchives.cpp @@ -23,8 +23,12 @@ namespace VFS // Last BSA has the highest priority const std::string archivePath = collections.getPath(*archive).string(); Log(Debug::Info) << "Adding BSA archive " << archivePath; + Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(archivePath); - vfs->addArchive(new BsaArchive(archivePath)); + if (bsaVersion == Bsa::BSAVER_COMPRESSED) + vfs->addArchive(new CompressedBsaArchive(archivePath)); + else + vfs->addArchive(new BsaArchive(archivePath)); } else {