mirror of https://github.com/stella-emu/stella.git
Fully converted FSNodePOSIX to C++17 filesystem API.
This commit is contained in:
parent
aa4f4bbb16
commit
f714933f6f
|
@ -69,12 +69,6 @@ FSNode& FSNode::operator/=(const string& path)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::exists() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->exists() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FSNode::getAllChildren(FSList& fslist, ListMode mode,
|
bool FSNode::getAllChildren(FSList& fslist, ListMode mode,
|
||||||
const NameFilter& filter,
|
const NameFilter& filter,
|
||||||
|
@ -290,64 +284,6 @@ string FSNode::getPathWithExt(const string& ext) const
|
||||||
return (pos != string::npos) ? s.replace(pos, string::npos, ext) : s + ext;
|
return (pos != string::npos) ? s.replace(pos, string::npos, ext) : s + ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::hasParent() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->hasParent() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
FSNode FSNode::getParent() const
|
|
||||||
{
|
|
||||||
if (!_realNode)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
AbstractFSNodePtr node = _realNode->getParent();
|
|
||||||
return node ? FSNode(node) : *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::isDirectory() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->isDirectory() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::isFile() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->isFile() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::isReadable() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->isReadable() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::isWritable() const
|
|
||||||
{
|
|
||||||
return _realNode ? _realNode->isWritable() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::makeDir()
|
|
||||||
{
|
|
||||||
return (_realNode && !_realNode->exists()) ? _realNode->makeDir() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool FSNode::rename(const string& newfile)
|
|
||||||
{
|
|
||||||
return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
size_t FSNode::getSize() const
|
|
||||||
{
|
|
||||||
return (_realNode && _realNode->exists()) ? _realNode->getSize() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
size_t FSNode::read(ByteBuffer& buffer, size_t size) const
|
size_t FSNode::read(ByteBuffer& buffer, size_t size) const
|
||||||
{
|
{
|
||||||
|
@ -395,3 +331,67 @@ size_t FSNode::write(const stringstream& buffer) const
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
size_t FSNode::getSize() const
|
||||||
|
{
|
||||||
|
return (_realNode && _realNode->exists()) ? _realNode->getSize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::hasParent() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->hasParent() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FSNode FSNode::getParent() const
|
||||||
|
{
|
||||||
|
if (!_realNode)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
AbstractFSNodePtr node = _realNode->getParent();
|
||||||
|
return node ? FSNode(node) : *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::exists() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->exists() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::isDirectory() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->isDirectory() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::isFile() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->isFile() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::isReadable() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->isReadable() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::isWritable() const
|
||||||
|
{
|
||||||
|
return _realNode ? _realNode->isWritable() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::makeDir()
|
||||||
|
{
|
||||||
|
return (_realNode && !_realNode->exists()) ? _realNode->makeDir() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool FSNode::rename(const string& newfile)
|
||||||
|
{
|
||||||
|
return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false;
|
||||||
|
}
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
* in a portable fashion. To this end, multiple or single roots have to be
|
* in a portable fashion. To this end, multiple or single roots have to be
|
||||||
* supported (compare Unix with a single root, Windows with multiple roots C:,
|
* supported (compare Unix with a single root, Windows with multiple roots C:,
|
||||||
* D:, ...).
|
* D:, ...).
|
||||||
*
|
|
||||||
* To this end, we abstract away from paths; implementations can be based on
|
|
||||||
* paths (and it's left to them whether / or \ or : is the path separator :-).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class FSNode;
|
class FSNode;
|
||||||
|
@ -52,11 +49,7 @@ class FSList : public vector<FSNode> { };
|
||||||
class FSNode
|
class FSNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef BSPF_WINDOWS
|
static constexpr char PATH_SEPARATOR = fs::path::preferred_separator;
|
||||||
static constexpr char PATH_SEPARATOR = '\\';
|
|
||||||
#else
|
|
||||||
static constexpr char PATH_SEPARATOR = '/';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,7 +35,7 @@ FSNodePOSIX::FSNodePOSIX(const string& path, bool verify)
|
||||||
: _path{path.length() > 0 ? path : "~"} // Default to home directory
|
: _path{path.length() > 0 ? path : "~"} // Default to home directory
|
||||||
{
|
{
|
||||||
// Expand '~' to the HOME environment variable
|
// Expand '~' to the HOME environment variable
|
||||||
if(_path[0] == '~')
|
if (_path[0] == '~')
|
||||||
{
|
{
|
||||||
#if defined(BSPF_WINDOWS)
|
#if defined(BSPF_WINDOWS)
|
||||||
|
|
||||||
|
@ -45,20 +45,21 @@ FSNodePOSIX::FSNodePOSIX(const string& path, bool verify)
|
||||||
if (home != nullptr)
|
if (home != nullptr)
|
||||||
_path.replace(0, 1, home);
|
_path.replace(0, 1, home);
|
||||||
}
|
}
|
||||||
// Get absolute path (only used for relative directories)
|
|
||||||
else if(_path[0] == '.')
|
|
||||||
{
|
|
||||||
std::array<char, MAXPATHLEN> buf;
|
|
||||||
if(realpath(_path.c_str(), buf.data()))
|
|
||||||
_path = buf.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
_fspath = _path;
|
_fspath = _path;
|
||||||
|
|
||||||
|
if (fs::exists(_fspath)) // get absolute path whenever possible
|
||||||
|
_fspath = fs::canonical(_fspath);
|
||||||
|
|
||||||
_path = _fspath.string();
|
_path = _fspath.string();
|
||||||
_displayName = lastPathComponent(_path);
|
_displayName = lastPathComponent(_path);
|
||||||
|
|
||||||
if(verify)
|
if (verify)
|
||||||
setFlags();
|
setFlags();
|
||||||
|
|
||||||
|
// Add a trailing slash, if necessary
|
||||||
|
if (_isDirectory && _path.length() > 0 &&
|
||||||
|
_path[_path.length()-1] != FSNode::PATH_SEPARATOR)
|
||||||
|
_path += FSNode::PATH_SEPARATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -98,11 +99,12 @@ string FSNodePOSIX::getShortPath() const
|
||||||
#endif
|
#endif
|
||||||
const string& home = env_home != nullptr ? env_home : EmptyString;
|
const string& home = env_home != nullptr ? env_home : EmptyString;
|
||||||
|
|
||||||
if(home != EmptyString && BSPF::startsWithIgnoreCase(_path, home))
|
if (home != EmptyString && BSPF::startsWithIgnoreCase(_path, home))
|
||||||
{
|
{
|
||||||
string path = "~";
|
string path = "~";
|
||||||
const char* offset = _path.c_str() + home.size();
|
const char* offset = _path.c_str() + home.size();
|
||||||
if(*offset != '/') path += "/";
|
if(*offset != FSNode::PATH_SEPARATOR)
|
||||||
|
path += FSNode::PATH_SEPARATOR;
|
||||||
path += offset;
|
path += offset;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -177,8 +179,6 @@ size_t FSNodePOSIX::read(ByteBuffer& buffer, size_t size) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error("File open/read error");
|
throw runtime_error("File open/read error");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -196,8 +196,6 @@ size_t FSNodePOSIX::read(stringstream& buffer) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error("File open/read error");
|
throw runtime_error("File open/read error");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -212,8 +210,6 @@ size_t FSNodePOSIX::write(const ByteBuffer& buffer, size_t size) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error("File open/write error");
|
throw runtime_error("File open/write error");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -228,56 +224,51 @@ size_t FSNodePOSIX::write(const stringstream& buffer) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error("File open/write error");
|
throw runtime_error("File open/write error");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FSNodePOSIX::makeDir()
|
bool FSNodePOSIX::makeDir()
|
||||||
{
|
{
|
||||||
if(mkdir(_path.c_str(), 0777) == 0)
|
if (!(exists() && _isDirectory) && fs::create_directory(_fspath))
|
||||||
{
|
{
|
||||||
// Get absolute path
|
_fspath = fs::canonical(_fspath);
|
||||||
std::array<char, MAXPATHLEN> buf;
|
_path = _fspath.string();
|
||||||
if(realpath(_path.c_str(), buf.data()))
|
|
||||||
_path = buf.data();
|
|
||||||
|
|
||||||
_displayName = lastPathComponent(_path);
|
_displayName = lastPathComponent(_path);
|
||||||
|
|
||||||
setFlags();
|
setFlags();
|
||||||
|
|
||||||
// Add a trailing slash, if necessary
|
// Add a trailing slash, if necessary
|
||||||
if (_path.length() > 0 && _path[_path.length()-1] != '/')
|
if (_path.length() > 0 && _path[_path.length()-1] != FSNode::PATH_SEPARATOR)
|
||||||
_path += '/';
|
_path += FSNode::PATH_SEPARATOR;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool FSNodePOSIX::rename(const string& newfile)
|
bool FSNodePOSIX::rename(const string& newfile)
|
||||||
{
|
{
|
||||||
if(std::rename(_path.c_str(), newfile.c_str()) == 0)
|
fs::path newpath = newfile;
|
||||||
|
|
||||||
|
std::error_code ec;
|
||||||
|
fs::rename(_fspath, newpath, ec);
|
||||||
|
if (!ec)
|
||||||
{
|
{
|
||||||
_path = newfile;
|
_fspath = fs::canonical(newpath);
|
||||||
|
_path = _fspath.string();
|
||||||
// Get absolute path
|
|
||||||
std::array<char, MAXPATHLEN> buf;
|
|
||||||
if(realpath(_path.c_str(), buf.data()))
|
|
||||||
_path = buf.data();
|
|
||||||
|
|
||||||
_displayName = lastPathComponent(_path);
|
_displayName = lastPathComponent(_path);
|
||||||
|
|
||||||
setFlags();
|
setFlags();
|
||||||
|
|
||||||
// Add a trailing slash, if necessary
|
// Add a trailing slash, if necessary
|
||||||
if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/')
|
if (_isDirectory && _path.length() > 0 &&
|
||||||
_path += '/';
|
_path[_path.length()-1] != FSNode::PATH_SEPARATOR)
|
||||||
|
_path += FSNode::PATH_SEPARATOR;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -20,24 +20,6 @@
|
||||||
|
|
||||||
#include "FSNode.hxx"
|
#include "FSNode.hxx"
|
||||||
|
|
||||||
#ifdef BSPF_MACOS
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifndef MAXPATHLEN // No MAXPATHLEN, as happens on Hurd
|
|
||||||
#define MAXPATHLEN 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation of the Stella filesystem API for regular files,
|
* Implementation of the Stella filesystem API for regular files,
|
||||||
* based on the std::filesystem API in C++17.
|
* based on the std::filesystem API in C++17.
|
||||||
|
|
Loading…
Reference in New Issue