diff --git a/apps/bsatool/bsatool.cpp b/apps/bsatool/bsatool.cpp index 8e8cf89186..4057d627c4 100644 --- a/apps/bsatool/bsatool.cpp +++ b/apps/bsatool/bsatool.cpp @@ -233,7 +233,17 @@ int extract(std::unique_ptr& bsa, Arguments& info) std::string extractPath = info.extractfile; Misc::StringUtils::replaceAll(extractPath, "\\", "/"); - if (!bsa->exists(archivePath.c_str())) + Files::IStreamPtr stream; + // Get a stream for the file to extract + for (auto it = bsa->getList().rbegin(); it != bsa->getList().rend(); ++it) + { + if (Misc::StringUtils::ciEqual(std::string(it->name()), archivePath)) + { + stream = bsa->getFile(&*it); + break; + } + } + if (!stream) { std::cout << "ERROR: file '" << archivePath << "' not found\n"; std::cout << "In archive: " << info.filename << std::endl; @@ -260,9 +270,6 @@ int extract(std::unique_ptr& bsa, Arguments& info) return 3; } - // Get a stream for the file to extract - Files::IStreamPtr stream = bsa->getFile(archivePath.c_str()); - bfs::ofstream out(target, std::ios::binary); // Write the file to disk @@ -296,8 +303,7 @@ int extractAll(std::unique_ptr& bsa, Arguments& info) } // Get a stream for the file to extract - // (inefficient because getFile iter on the list again) - Files::IStreamPtr data = bsa->getFile(file.name()); + Files::IStreamPtr data = bsa->getFile(&file); bfs::ofstream out(target, std::ios::binary); // Write the file to disk diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index d5610bddae..e5b730b4c4 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -189,13 +189,6 @@ void BSAFile::readHeader() return left.offset < right.offset; }); - for (size_t i = 0; i < filenum; i++) - { - FileStruct& fs = mFiles[i]; - // Add the file name to the lookup - mLookup[fs.name()] = i; - } - mIsLoaded = true; } @@ -237,18 +230,6 @@ void Bsa::BSAFile::writeHeader() output.write(reinterpret_cast(hashes.data()), sizeof(Hash)*hashes.size()); } -/// Get the index of a given file name, or -1 if not found -int BSAFile::getIndex(const char *str) const -{ - auto it = mLookup.find(str); - if(it == mLookup.end()) - return -1; - - size_t res = it->second; - assert(res < mFiles.size()); - return static_cast(res); -} - /// Open an archive file. void BSAFile::open(const std::string &file) { @@ -274,22 +255,9 @@ void Bsa::BSAFile::close() mFiles.clear(); mStringBuf.clear(); - mLookup.clear(); mIsLoaded = false; } -Files::IStreamPtr BSAFile::getFile(const char *file) -{ - assert(file); - int i = getIndex(file); - if(i == -1) - fail("File not found: " + std::string(file)); - - const FileStruct &fs = mFiles[i]; - - return Files::openConstrainedFileStream (mFilename.c_str (), fs.offset, fs.fileSize); -} - void Bsa::BSAFile::addFile(const std::string& filename, std::istream& file) { if (!mIsLoaded) @@ -338,8 +306,6 @@ void Bsa::BSAFile::addFile(const std::string& filename, std::istream& file) mHasChanged = true; - mLookup[filename.c_str()] = mFiles.size() - 1; - stream.seekp(0, std::ios::end); file.seekg(0, std::ios::beg); stream << file.rdbuf(); diff --git a/components/bsa/bsa_file.hpp b/components/bsa/bsa_file.hpp index 9a76e1bd23..f6c5d03139 100644 --- a/components/bsa/bsa_file.hpp +++ b/components/bsa/bsa_file.hpp @@ -27,9 +27,6 @@ #include #include #include -#include - -#include #include @@ -91,20 +88,6 @@ protected: /// Used for error messages std::string mFilename; - /// Case insensitive string comparison - struct iltstr - { - bool operator()(const std::string& s1, const std::string& s2) const - { return Misc::StringUtils::ciLess(s1, s2); } - }; - - /** A map used for fast file name lookup. The value is the index into - the files[] vector above. The iltstr ensures that file name - checks are case insensitive. - */ - typedef std::map Lookup; - Lookup mLookup; - /// Error handling [[noreturn]] void fail(const std::string &msg); @@ -112,10 +95,6 @@ protected: virtual void readHeader(); virtual void writeHeader(); - /// Get the index of a given file name, or -1 if not found - /// @note Thread safe. - int getIndex(const char *str) const; - public: /* ----------------------------------- * BSA management methods @@ -141,16 +120,6 @@ public: * ----------------------------------- */ - /// Check if a file exists - virtual bool exists(const char *file) const - { return getIndex(file) != -1; } - - /** Open a file contained in the archive. Throws an exception if the - file doesn't exist. - * @note Thread safe. - */ - virtual Files::IStreamPtr getFile(const char *file); - /** Open a file contained in the archive. * @note Thread safe. */ diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index f066489184..ae8209a39a 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -47,6 +47,7 @@ #include #include +#include namespace Bsa { @@ -286,7 +287,6 @@ void CompressedBSAFile::readHeader() mFiles[fileIndex].setNameInfos(mStringBuffOffset, &mStringBuf); - mLookup[reinterpret_cast(mStringBuf.data() + mStringBuffOffset)] = fileIndex; mStringBuffOffset += stringLength + 1u; } diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index ffd88fe044..f19815dcf3 100644 --- a/components/bsa/compressedbsafile.hpp +++ b/components/bsa/compressedbsafile.hpp @@ -26,6 +26,8 @@ #ifndef BSA_COMPRESSED_BSA_FILE_H #define BSA_COMPRESSED_BSA_FILE_H +#include + #include namespace Bsa @@ -92,7 +94,7 @@ namespace Bsa /// Read header information from the input source void readHeader() override; - Files::IStreamPtr getFile(const char* filePath) override; + Files::IStreamPtr getFile(const char* filePath); 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 86d21060c0..b0caa5c305 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -1,6 +1,7 @@ #include "bsaarchive.hpp" #include +#include namespace VFS {