1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-06 00:40:04 +00:00

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.
This commit is contained in:
Bo Svensson 2021-10-14 12:46:44 +00:00 committed by GitHub
parent e86b9a7b89
commit db3d938ee9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 17 additions and 73 deletions

View File

@ -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

View File

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

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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;
};

View File

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