stella/src/common/FSNodeZIP.hxx

114 lines
3.9 KiB
C++

//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#if defined(ZIP_SUPPORT)
#ifndef FS_NODE_ZIP_HXX
#define FS_NODE_ZIP_HXX
#include "ZipHandler.hxx"
#include "FSNode.hxx"
/*
* Implementation of the Stella file system API based on ZIP archives.
* ZIP archives are treated as directories if the contain more than one ROM
* file, as a file if they contain a single ROM file, and as neither if the
* archive is empty. Hence, if a ZIP archive isn't a directory *or* a file,
* it is invalid.
*
* Parts of this class are documented in the base interface class, AbstractFSNode.
*/
class FilesystemNodeZIP : public AbstractFSNode
{
public:
/**
* Creates a FilesystemNodeZIP for a given path.
*
* @param path String with the path the new node should point to.
*/
explicit FilesystemNodeZIP(const string& path);
bool exists() const override;
const string& getName() const override { return _name; }
void setName(const string& name) override { _name = name; }
const string& getPath() const override { return _path; }
string getShortPath() const override { return _shortPath; }
bool hasParent() const override { return true; }
bool isDirectory() const override { return _isDirectory; }
bool isFile() const override { return _isFile; }
bool isReadable() const override { return _realNode && _realNode->isReadable(); }
bool isWritable() const override { return false; }
//////////////////////////////////////////////////////////
// For now, ZIP files cannot be modified in any way
bool makeDir() override { return false; }
bool rename(const string& newfile) override { return false; }
//////////////////////////////////////////////////////////
bool getChildren(AbstractFSList& list, ListMode mode) const override;
AbstractFSNodePtr getParent() const override;
size_t read(ByteBuffer& image) const override;
size_t read(stringstream& image) const override;
size_t write(const ByteBuffer& buffer, size_t size) const override;
size_t write(const stringstream& buffer) const override;
private:
FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
const AbstractFSNodePtr& realnode, bool isdir);
void setFlags(const string& zipfile, const string& virtualpath,
const AbstractFSNodePtr& realnode);
friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node)
{
os << "_zipFile: " << node._zipFile << endl
<< "_virtualPath: " << node._virtualPath << endl
<< "_path: " << node._path << endl
<< "_shortPath: " << node._shortPath << endl;
return os;
}
private:
/* Error types */
enum class zip_error
{
NONE,
NOT_A_FILE,
NOT_READABLE,
NO_ROMS
};
// Since a ZIP file is itself an abstraction, it still needs access to
// an actual concrete filesystem node
AbstractFSNodePtr _realNode;
string _zipFile, _virtualPath;
string _name, _path, _shortPath;
zip_error _error{zip_error::NONE};
uInt32 _numFiles{0};
bool _isDirectory{false}, _isFile{false};
// ZipHandler static reference variable responsible for accessing ZIP files
static unique_ptr<ZipHandler> myZipHandler;
};
#endif
#endif // ZIP_SUPPORT