Merge branch 'Newer-Bsa-formats-no-longer-load' into 'master'

#6651 Newer bsa formats no longer load

Closes #6651

See merge request OpenMW/openmw!1703
ccache_for_windows
psi29a 3 years ago
commit 3558196098

@ -151,62 +151,11 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return true; return true;
} }
int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info); template<typename File>
int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info); int list(std::unique_ptr<File>& bsa, Arguments& info)
int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
int add(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
int main(int argc, char** argv)
{
try
{
Arguments info;
if(!parseOptions (argc, argv, info))
return 1;
// Open file
std::unique_ptr<Bsa::BSAFile> bsa;
Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(info.filename);
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
bsa = std::make_unique<Bsa::CompressedBSAFile>(Bsa::CompressedBSAFile());
else
bsa = std::make_unique<Bsa::BSAFile>(Bsa::BSAFile());
if (info.mode == "create")
{
bsa->open(info.filename);
return 0;
}
bsa->open(info.filename);
if (info.mode == "list")
return list(bsa, info);
else if (info.mode == "extract")
return extract(bsa, info);
else if (info.mode == "extractall")
return extractAll(bsa, info);
else if (info.mode == "add")
return add(bsa, info);
else
{
std::cout << "Unsupported mode. That is not supposed to happen." << std::endl;
return 1;
}
}
catch (std::exception& e)
{
std::cerr << "ERROR reading BSA archive\nDetails:\n" << e.what() << std::endl;
return 2;
}
}
int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
{ {
// List all files // List all files
const Bsa::BSAFile::FileList &files = bsa->getList(); const auto &files = bsa->getList();
for (const auto& file : files) for (const auto& file : files)
{ {
if(info.longformat) if(info.longformat)
@ -225,7 +174,8 @@ int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
return 0; return 0;
} }
int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info) template<typename File>
int extract(std::unique_ptr<File>& bsa, Arguments& info)
{ {
std::string archivePath = info.extractfile; std::string archivePath = info.extractfile;
Misc::StringUtils::replaceAll(archivePath, "/", "\\"); Misc::StringUtils::replaceAll(archivePath, "/", "\\");
@ -281,7 +231,8 @@ int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
return 0; return 0;
} }
int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info) template<typename File>
int extractAll(std::unique_ptr<File>& bsa, Arguments& info)
{ {
for (const auto &file : bsa->getList()) for (const auto &file : bsa->getList())
{ {
@ -315,10 +266,62 @@ int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
return 0; return 0;
} }
int add(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info) template<typename File>
int add(std::unique_ptr<File>& bsa, Arguments& info)
{ {
boost::filesystem::fstream stream(info.addfile, std::ios_base::binary | std::ios_base::out | std::ios_base::in); boost::filesystem::fstream stream(info.addfile, std::ios_base::binary | std::ios_base::out | std::ios_base::in);
bsa->addFile(info.addfile, stream); bsa->addFile(info.addfile, stream);
return 0; return 0;
} }
template<typename File>
int call(Arguments& info)
{
std::unique_ptr<File> bsa = std::make_unique<File>();
if (info.mode == "create")
{
bsa->open(info.filename);
return 0;
}
bsa->open(info.filename);
if (info.mode == "list")
return list(bsa, info);
else if (info.mode == "extract")
return extract(bsa, info);
else if (info.mode == "extractall")
return extractAll(bsa, info);
else if (info.mode == "add")
return add(bsa, info);
else
{
std::cout << "Unsupported mode. That is not supposed to happen." << std::endl;
return 1;
}
}
int main(int argc, char** argv)
{
try
{
Arguments info;
if (!parseOptions(argc, argv, info))
return 1;
// Open file
Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(info.filename);
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
return call<Bsa::CompressedBSAFile>(info);
else
return call<Bsa::BSAFile>(info);
}
catch (std::exception& e)
{
std::cerr << "ERROR reading BSA archive\nDetails:\n" << e.what() << std::endl;
return 2;
}
}

@ -128,7 +128,7 @@ public:
return Files::openConstrainedFileStream (mFilename.c_str (), file->offset, file->fileSize); return Files::openConstrainedFileStream (mFilename.c_str (), file->offset, file->fileSize);
} }
virtual void addFile(const std::string& filename, std::istream& file); void addFile(const std::string& filename, std::istream& file);
/// Get a list of all files /// Get a list of all files
/// @note Thread safe. /// @note Thread safe.

@ -39,7 +39,7 @@ namespace Bsa
BSAVER_COMPRESSED = 0x415342 //B, S, A BSAVER_COMPRESSED = 0x415342 //B, S, A
}; };
class CompressedBSAFile : public BSAFile class CompressedBSAFile : private BSAFile
{ {
private: private:
//special marker for invalid records, //special marker for invalid records,
@ -85,6 +85,10 @@ namespace Bsa
static std::uint64_t generateHash(std::string stem, std::string extension) ; static std::uint64_t generateHash(std::string stem, std::string extension) ;
Files::IStreamPtr getFile(const FileRecord& fileRecord); Files::IStreamPtr getFile(const FileRecord& fileRecord);
public: public:
using BSAFile::open;
using BSAFile::getList;
using BSAFile::getFilename;
CompressedBSAFile(); CompressedBSAFile();
virtual ~CompressedBSAFile(); virtual ~CompressedBSAFile();
@ -96,7 +100,7 @@ namespace Bsa
Files::IStreamPtr getFile(const char* filePath); Files::IStreamPtr getFile(const char* filePath);
Files::IStreamPtr getFile(const FileStruct* fileStruct); Files::IStreamPtr getFile(const FileStruct* fileStruct);
void addFile(const std::string& filename, std::istream& file) override; void addFile(const std::string& filename, std::istream& file);
}; };
} }

@ -40,7 +40,7 @@ namespace Bsa
Memory buffer is freed once the class instance is destroyed. Memory buffer is freed once the class instance is destroyed.
*/ */
class MemoryInputStream : private std::vector<char>, public virtual Files::MemBuf, public std::istream { class MemoryInputStream : private std::vector<char>, public Files::MemBuf, public std::istream {
public: public:
explicit MemoryInputStream(size_t bufferSize) explicit MemoryInputStream(size_t bufferSize)
: std::vector<char>(bufferSize) : std::vector<char>(bufferSize)

@ -8,7 +8,7 @@ namespace VFS
BsaArchive::BsaArchive(const std::string &filename) BsaArchive::BsaArchive(const std::string &filename)
{ {
mFile = std::make_unique<Bsa::BSAFile>(Bsa::BSAFile()); mFile = std::make_unique<Bsa::BSAFile>();
mFile->open(filename); mFile->open(filename);
const Bsa::BSAFile::FileList &filelist = mFile->getList(); const Bsa::BSAFile::FileList &filelist = mFile->getList();
@ -53,17 +53,30 @@ std::string BsaArchive::getDescription() const
return std::string{"BSA: "} + mFile->getFilename(); 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::string &filename) CompressedBsaArchive::CompressedBsaArchive(const std::string &filename)
: BsaArchive() : Archive()
{ {
mFile = std::make_unique<Bsa::BSAFile>(Bsa::CompressedBSAFile()); mCompressedFile = std::make_unique<Bsa::CompressedBSAFile>();
mFile->open(filename); mCompressedFile->open(filename);
const Bsa::BSAFile::FileList &filelist = mFile->getList(); const Bsa::BSAFile::FileList &filelist = mCompressedFile->getList();
for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it)
{ {
mResources.emplace_back(&*it, mFile.get()); mCompressedResources.emplace_back(&*it, mCompressedFile.get());
mCompressedResources.emplace_back(&*it, static_cast<Bsa::CompressedBSAFile*>(mFile.get()));
} }
} }
@ -78,22 +91,26 @@ void CompressedBsaArchive::listResources(std::map<std::string, File *> &out, cha
} }
} }
// ------------------------------------------------------------------------------ bool CompressedBsaArchive::contains(const std::string& file, char (*normalize_function)(char)) const
BsaArchiveFile::BsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::BSAFile* bsa)
: mInfo(info)
, mFile(bsa)
{ {
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;
} }
Files::IStreamPtr BsaArchiveFile::open() std::string CompressedBsaArchive::getDescription() const
{ {
return mFile->getFile(mInfo); return std::string{"BSA: "} + mCompressedFile->getFilename();
} }
CompressedBsaArchiveFile::CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::CompressedBSAFile* bsa) CompressedBsaArchiveFile::CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct *info, Bsa::CompressedBSAFile* bsa)
: BsaArchiveFile(info, bsa) : mInfo(info)
, mCompressedFile(bsa) , mCompressedFile(bsa)
{ {

@ -19,12 +19,14 @@ namespace VFS
Bsa::BSAFile* mFile; Bsa::BSAFile* mFile;
}; };
class CompressedBsaArchiveFile : public BsaArchiveFile class CompressedBsaArchiveFile : public File
{ {
public: public:
CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa); CompressedBsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::CompressedBSAFile* bsa);
Files::IStreamPtr open() override; Files::IStreamPtr open() override;
const Bsa::BSAFile::FileStruct* mInfo;
Bsa::CompressedBSAFile* mCompressedFile; Bsa::CompressedBSAFile* mCompressedFile;
}; };
@ -44,12 +46,14 @@ namespace VFS
std::vector<BsaArchiveFile> mResources; std::vector<BsaArchiveFile> mResources;
}; };
class CompressedBsaArchive : public BsaArchive class CompressedBsaArchive : public Archive
{ {
public: public:
CompressedBsaArchive(const std::string& filename); CompressedBsaArchive(const std::string& filename);
void listResources(std::map<std::string, File*>& out, char (*normalize_function) (char)) override;
virtual ~CompressedBsaArchive() {} virtual ~CompressedBsaArchive() {}
void listResources(std::map<std::string, File*>& out, char (*normalize_function) (char)) override;
bool contains(const std::string& file, char (*normalize_function) (char)) const override;
std::string getDescription() const override;
private: private:
std::unique_ptr<Bsa::CompressedBSAFile> mCompressedFile; std::unique_ptr<Bsa::CompressedBSAFile> mCompressedFile;

Loading…
Cancel
Save