cleans up BSAFile (#3177)

We currently build a large map of a BSAFile's contents unused by Open MW. We already map archive contents in VFS. With this PR we remove the map from BSAFile and reimplement its only current use in BSATool.
pull/3178/head
Bo Svensson 3 years ago committed by GitHub
parent e86b9a7b89
commit db3d938ee9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -233,7 +233,17 @@ int extract(std::unique_ptr<Bsa::BSAFile>& 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::BSAFile>& 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::BSAFile>& 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

@ -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<char*>(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<int>(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();

@ -27,9 +27,6 @@
#include <cstdint>
#include <string>
#include <vector>
#include <map>
#include <components/misc/stringops.hpp>
#include <components/files/constrainedfilestream.hpp>
@ -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<std::string, size_t, iltstr> 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.
*/

@ -47,6 +47,7 @@
#include <boost/iostreams/device/array.hpp>
#include <components/bsa/memorystream.hpp>
#include <components/misc/stringops.hpp>
namespace Bsa
{
@ -286,7 +287,6 @@ void CompressedBSAFile::readHeader()
mFiles[fileIndex].setNameInfos(mStringBuffOffset, &mStringBuf);
mLookup[reinterpret_cast<char*>(mStringBuf.data() + mStringBuffOffset)] = fileIndex;
mStringBuffOffset += stringLength + 1u;
}

@ -26,6 +26,8 @@
#ifndef BSA_COMPRESSED_BSA_FILE_H
#define BSA_COMPRESSED_BSA_FILE_H
#include <map>
#include <components/bsa/bsa_file.hpp>
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;
};

@ -1,6 +1,7 @@
#include "bsaarchive.hpp"
#include <memory>
#include <algorithm>
namespace VFS
{

Loading…
Cancel
Save