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