mirror of https://github.com/stella-emu/stella.git
Added getSize() to FSNodeZIP. This allows to detect too large files in ZIP files.
This commit is contained in:
parent
42b6a29274
commit
b5cc7d41c9
|
@ -80,11 +80,12 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
|
|||
bool found = false;
|
||||
while(myZipHandler->hasNext() && !found)
|
||||
{
|
||||
const string& file = myZipHandler->next();
|
||||
if(Bankswitch::isValidRomName(file))
|
||||
const auto [name, size, isFile] = myZipHandler->next();
|
||||
if(Bankswitch::isValidRomName(name))
|
||||
{
|
||||
_virtualPath = file;
|
||||
_isFile = true;
|
||||
_virtualPath = name;
|
||||
_size = size;
|
||||
_isFile = isFile;
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
@ -109,8 +110,9 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FilesystemNodeZIP::FilesystemNodeZIP(
|
||||
const string& zipfile, const string& virtualpath,
|
||||
const AbstractFSNodePtr& realnode, bool isdir)
|
||||
: _isDirectory{isdir},
|
||||
const AbstractFSNodePtr& realnode, size_t size, bool isdir)
|
||||
: _size{size},
|
||||
_isDirectory{isdir},
|
||||
_isFile{!isdir}
|
||||
{
|
||||
setFlags(zipfile, virtualpath, realnode);
|
||||
|
@ -152,8 +154,11 @@ bool FilesystemNodeZIP::exists() const
|
|||
{
|
||||
myZipHandler->open(_zipFile);
|
||||
while(myZipHandler->hasNext())
|
||||
if(BSPF::startsWithIgnoreCase(myZipHandler->next(), _virtualPath))
|
||||
{
|
||||
const auto [name, size, isFile] = myZipHandler->next();
|
||||
if(BSPF::startsWithIgnoreCase(name, _virtualPath))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(const runtime_error&)
|
||||
{
|
||||
|
@ -177,26 +182,26 @@ bool FilesystemNodeZIP::getChildren(AbstractFSList& myList, ListMode mode) const
|
|||
{
|
||||
// Only consider entries that start with '_virtualPath'
|
||||
// Ignore empty filenames and '__MACOSX' virtual directories
|
||||
const string& next = myZipHandler->next();
|
||||
if(BSPF::startsWithIgnoreCase(next, "__MACOSX") || next == EmptyString)
|
||||
const auto [name, size, isFile] = myZipHandler->next();
|
||||
if(BSPF::startsWithIgnoreCase(name, "__MACOSX") || name == EmptyString)
|
||||
continue;
|
||||
if(BSPF::startsWithIgnoreCase(next, _virtualPath))
|
||||
if(BSPF::startsWithIgnoreCase(name, _virtualPath))
|
||||
{
|
||||
// First strip off the leading directory
|
||||
const string& curr = next.substr(_virtualPath == "" ? 0 : _virtualPath.size()+1);
|
||||
const string& curr = name.substr(_virtualPath == "" ? 0 : _virtualPath.size()+1);
|
||||
// Only add sub-directory entries once
|
||||
const auto pos = curr.find_first_of("/\\");
|
||||
if(pos != string::npos)
|
||||
dirs.emplace(curr.substr(0, pos));
|
||||
else
|
||||
myList.emplace_back(new FilesystemNodeZIP(_zipFile, next, _realNode, false));
|
||||
myList.emplace_back(new FilesystemNodeZIP(_zipFile, name, _realNode, size, false));
|
||||
}
|
||||
}
|
||||
for(const auto& dir: dirs)
|
||||
{
|
||||
// Prepend previous path
|
||||
const string& vpath = _virtualPath != "" ? _virtualPath + "/" + dir : dir;
|
||||
myList.emplace_back(new FilesystemNodeZIP(_zipFile, vpath, _realNode, true));
|
||||
myList.emplace_back(new FilesystemNodeZIP(_zipFile, vpath, _realNode, 0, true));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -217,7 +222,10 @@ size_t FilesystemNodeZIP::read(ByteBuffer& image, size_t) const
|
|||
|
||||
bool found = false;
|
||||
while(myZipHandler->hasNext() && !found)
|
||||
found = myZipHandler->next() == _virtualPath;
|
||||
{
|
||||
const auto [name, size, isFile] = myZipHandler->next();
|
||||
found = name == _virtualPath;
|
||||
}
|
||||
|
||||
return found ? myZipHandler->decompress(image) : 0;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ class FilesystemNodeZIP : public AbstractFSNode
|
|||
bool rename(const string& newfile) override { return false; }
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
size_t getSize() const override { return _size; }
|
||||
bool getChildren(AbstractFSList& list, ListMode mode) const override;
|
||||
AbstractFSNodePtr getParent() const override;
|
||||
|
||||
|
@ -69,7 +70,7 @@ class FilesystemNodeZIP : public AbstractFSNode
|
|||
|
||||
private:
|
||||
FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
|
||||
const AbstractFSNodePtr& realnode, bool isdir);
|
||||
const AbstractFSNodePtr& realnode, size_t size, bool isdir);
|
||||
|
||||
void setFlags(const string& zipfile, const string& virtualpath,
|
||||
const AbstractFSNodePtr& realnode);
|
||||
|
@ -78,7 +79,9 @@ class FilesystemNodeZIP : public AbstractFSNode
|
|||
{
|
||||
os << "_zipFile: " << node._zipFile << endl
|
||||
<< "_virtualPath: " << node._virtualPath << endl
|
||||
<< "_name: " << node._name << endl
|
||||
<< "_path: " << node._path << endl
|
||||
<< "_size: " << node._size << endl
|
||||
<< "_shortPath: " << node._shortPath << endl;
|
||||
return os;
|
||||
}
|
||||
|
@ -100,7 +103,8 @@ class FilesystemNodeZIP : public AbstractFSNode
|
|||
string _zipFile, _virtualPath;
|
||||
string _name, _path, _shortPath;
|
||||
zip_error _error{zip_error::NONE};
|
||||
uInt32 _numFiles{0};
|
||||
uInt16 _numFiles{0};
|
||||
size_t _size{0};
|
||||
|
||||
bool _isDirectory{false}, _isFile{false};
|
||||
|
||||
|
|
|
@ -66,8 +66,11 @@ void ZipHandler::open(const string& filename)
|
|||
try
|
||||
{
|
||||
while(hasNext())
|
||||
if(Bankswitch::isValidRomName(next()))
|
||||
{
|
||||
const auto [name, size, isFile] = next();
|
||||
if(Bankswitch::isValidRomName(name))
|
||||
myZip->myRomfiles++;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -93,7 +96,7 @@ bool ZipHandler::hasNext() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& ZipHandler::next()
|
||||
std::tuple<string, size_t, bool> ZipHandler::next()
|
||||
{
|
||||
if(hasNext())
|
||||
{
|
||||
|
@ -103,9 +106,9 @@ const string& ZipHandler::next()
|
|||
else if(header->uncompressedLength == 0)
|
||||
return next();
|
||||
else
|
||||
return header->filename;
|
||||
return {header->filename, header->uncompressedLength, true};
|
||||
}
|
||||
return EmptyString;
|
||||
return {EmptyString, 0, false};
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef ZIP_HANDLER_HXX
|
||||
#define ZIP_HANDLER_HXX
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
/**
|
||||
|
@ -41,7 +43,7 @@ class ZipHandler
|
|||
// The following form an iterator for processing the filenames in the ZIP file
|
||||
void reset(); // Reset iterator to first file
|
||||
bool hasNext() const; // Answer whether there are more files present
|
||||
const string& next(); // Get next file
|
||||
std::tuple<string, size_t, bool> next(); // Get information on next file
|
||||
|
||||
// Decompress the currently selected file and return its length
|
||||
// An exception will be thrown on any errors
|
||||
|
@ -297,8 +299,8 @@ class ZipHandler
|
|||
void addToCache();
|
||||
|
||||
private:
|
||||
static constexpr size_t DECOMPRESS_BUFSIZE = 16_KB;
|
||||
static constexpr uInt32 CACHE_SIZE = 8; // number of open files to cache
|
||||
static constexpr size_t DECOMPRESS_BUFSIZE = 128_KB;
|
||||
static constexpr size_t CACHE_SIZE = 16; // number of open files to cache
|
||||
|
||||
ZipFilePtr myZip;
|
||||
std::array<ZipFilePtr, CACHE_SIZE> myZipCache;
|
||||
|
|
Loading…
Reference in New Issue