Fully converted FSNodePOSIX to C++17 filesystem API.

This commit is contained in:
Stephen Anthony 2022-06-26 18:06:40 -02:30
parent aa4f4bbb16
commit f714933f6f
4 changed files with 98 additions and 132 deletions

View File

@ -69,12 +69,6 @@ FSNode& FSNode::operator/=(const string& path)
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FSNode::exists() const
{
return _realNode ? _realNode->exists() : false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FSNode::getAllChildren(FSList& fslist, ListMode mode,
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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
{
@ -395,3 +331,67 @@ size_t FSNode::write(const stringstream& buffer) const
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;
}

View File

@ -28,9 +28,6 @@
* 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:,
* 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;
@ -52,11 +49,7 @@ class FSList : public vector<FSNode> { };
class FSNode
{
public:
#ifdef BSPF_WINDOWS
static constexpr char PATH_SEPARATOR = '\\';
#else
static constexpr char PATH_SEPARATOR = '/';
#endif
static constexpr char PATH_SEPARATOR = fs::path::preferred_separator;
public:
/**

View File

@ -35,7 +35,7 @@ FSNodePOSIX::FSNodePOSIX(const string& path, bool verify)
: _path{path.length() > 0 ? path : "~"} // Default to home directory
{
// Expand '~' to the HOME environment variable
if(_path[0] == '~')
if (_path[0] == '~')
{
#if defined(BSPF_WINDOWS)
@ -45,20 +45,21 @@ FSNodePOSIX::FSNodePOSIX(const string& path, bool verify)
if (home != nullptr)
_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;
if (fs::exists(_fspath)) // get absolute path whenever possible
_fspath = fs::canonical(_fspath);
_path = _fspath.string();
_displayName = lastPathComponent(_path);
if(verify)
if (verify)
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
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 = "~";
const char* offset = _path.c_str() + home.size();
if(*offset != '/') path += "/";
if(*offset != FSNode::PATH_SEPARATOR)
path += FSNode::PATH_SEPARATOR;
path += offset;
return path;
}
@ -177,8 +179,6 @@ size_t FSNodePOSIX::read(ByteBuffer& buffer, size_t size) const
}
else
throw runtime_error("File open/read error");
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -196,8 +196,6 @@ size_t FSNodePOSIX::read(stringstream& buffer) const
}
else
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
throw runtime_error("File open/write error");
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -228,55 +224,50 @@ size_t FSNodePOSIX::write(const stringstream& buffer) const
}
else
throw runtime_error("File open/write error");
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FSNodePOSIX::makeDir()
{
if(mkdir(_path.c_str(), 0777) == 0)
if (!(exists() && _isDirectory) && fs::create_directory(_fspath))
{
// Get absolute path
std::array<char, MAXPATHLEN> buf;
if(realpath(_path.c_str(), buf.data()))
_path = buf.data();
_fspath = fs::canonical(_fspath);
_path = _fspath.string();
_displayName = lastPathComponent(_path);
setFlags();
// Add a trailing slash, if necessary
if (_path.length() > 0 && _path[_path.length()-1] != '/')
_path += '/';
if (_path.length() > 0 && _path[_path.length()-1] != FSNode::PATH_SEPARATOR)
_path += FSNode::PATH_SEPARATOR;
return true;
}
else
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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;
// Get absolute path
std::array<char, MAXPATHLEN> buf;
if(realpath(_path.c_str(), buf.data()))
_path = buf.data();
_fspath = fs::canonical(newpath);
_path = _fspath.string();
_displayName = lastPathComponent(_path);
setFlags();
// Add a trailing slash, if necessary
if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/')
_path += '/';
if (_isDirectory && _path.length() > 0 &&
_path[_path.length()-1] != FSNode::PATH_SEPARATOR)
_path += FSNode::PATH_SEPARATOR;
return true;
}
else
return false;
}

View File

@ -20,24 +20,6 @@
#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,
* based on the std::filesystem API in C++17.