Moved prototype FS stuff to ebcl
This commit is contained in:
parent
852573432f
commit
1e55dbb4d9
6 changed files with 18 additions and 685 deletions
2
3rdparty/ebcl
vendored
2
3rdparty/ebcl
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 324774848f5b70f341ad513760d94ebdada446ee
|
Subproject commit 5497856be2761a6f4f1848636304cff134668766
|
2
Makefile
2
Makefile
|
@ -43,8 +43,6 @@ COMMON = \
|
||||||
c-sync.cc \
|
c-sync.cc \
|
||||||
c-syncedit.cc \
|
c-syncedit.cc \
|
||||||
c-syncoverrides.cc \
|
c-syncoverrides.cc \
|
||||||
\
|
|
||||||
p-filesystem.cc \
|
|
||||||
# END COMMON
|
# END COMMON
|
||||||
|
|
||||||
TOOL = \
|
TOOL = \
|
||||||
|
|
|
@ -39,6 +39,7 @@ using std::swap;
|
||||||
#include <ebcl/Arrays.hh>
|
#include <ebcl/Arrays.hh>
|
||||||
#include <ebcl/Strings.hh>
|
#include <ebcl/Strings.hh>
|
||||||
#include <ebcl/HashTables.hh>
|
#include <ebcl/HashTables.hh>
|
||||||
|
#include <ebcl/Filesystem.hh>
|
||||||
|
|
||||||
using ebcl::T_OwnPtr;
|
using ebcl::T_OwnPtr;
|
||||||
using ebcl::NewOwned;
|
using ebcl::NewOwned;
|
||||||
|
@ -62,6 +63,9 @@ using ebcl::T_HashIndex;
|
||||||
using ebcl::T_ObjectTable;
|
using ebcl::T_ObjectTable;
|
||||||
using ebcl::T_KeyValueTable;
|
using ebcl::T_KeyValueTable;
|
||||||
|
|
||||||
|
using ebcl::T_FSPath;
|
||||||
|
using ebcl::Filesystem;
|
||||||
|
|
||||||
// Macros that enable/disable copying/moving
|
// Macros that enable/disable copying/moving
|
||||||
#define NO_COPY( CLS ) \
|
#define NO_COPY( CLS ) \
|
||||||
CLS( CLS const& ) = delete; \
|
CLS( CLS const& ) = delete; \
|
||||||
|
|
13
m-tool.cc
13
m-tool.cc
|
@ -195,6 +195,19 @@ void T_Main::render( )
|
||||||
|
|
||||||
int main( int argc , char** argv )
|
int main( int argc , char** argv )
|
||||||
{
|
{
|
||||||
|
const T_FSPath cwd{ Filesystem::Cwd( ) };
|
||||||
|
T_FSPath pp;
|
||||||
|
if ( argc >= 2 ) {
|
||||||
|
pp = T_String{ argv[ 1 ] };
|
||||||
|
if ( !pp.isValid( ) ) {
|
||||||
|
fprintf( stderr , "Invalid path '%s'\n" , argv[ 1 ] );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pp = T_String{ "." };
|
||||||
|
}
|
||||||
|
const T_FSPath rpp{ ( pp.isRelative( ) ? ( cwd + pp ) : pp ).canonical( ) };
|
||||||
|
|
||||||
T_Main m{ argc < 2 ? "." : argv[ 1 ] };
|
T_Main m{ argc < 2 ? "." : argv[ 1 ] };
|
||||||
m.mainLoop( );
|
m.mainLoop( );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
389
p-filesystem.cc
389
p-filesystem.cc
|
@ -1,389 +0,0 @@
|
||||||
/******************************************************************************/
|
|
||||||
/* FILESYSTEM ABSTRACTION *****************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#include <p-filesystem.hh>
|
|
||||||
using namespace ebcl;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define M_PATHSEP_ '\\'
|
|
||||||
#else
|
|
||||||
# define M_PATHSEP_ '/'
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*= T_FSPath =================================================================*/
|
|
||||||
|
|
||||||
bool T_FSPath::IsValidRoot(
|
|
||||||
T_String const& str ) noexcept
|
|
||||||
{
|
|
||||||
if ( !str ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// TODO: support for network names (\\server\path)
|
|
||||||
if ( str.length( ) == 3 && ( str.endsWith( ":\\" )
|
|
||||||
|| str.endsWith( ":/" ) ) ) {
|
|
||||||
return str[ 0 ].isAlpha( );
|
|
||||||
} else {
|
|
||||||
return ( str == "/" || str == "\\" );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return ( str == "/" || str == "\\" );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool T_FSPath::IsValidComponent(
|
|
||||||
T_String const& str ) noexcept
|
|
||||||
{
|
|
||||||
if ( !str ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_StringIterator it{ str };
|
|
||||||
while ( !it.atEnd( ) ) {
|
|
||||||
const auto c{ it.character( ) };
|
|
||||||
it.next( );
|
|
||||||
if ( c.isControl( ) || c == '\\' || c == '/' || c == '"'
|
|
||||||
|| c == '<' || c == '>' || c == '|' || c == ':'
|
|
||||||
|| c == '*' || c == '?' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
T_FSPath::T_FSPath(
|
|
||||||
T_String const& path ) noexcept
|
|
||||||
{
|
|
||||||
if ( !path ) {
|
|
||||||
valid_ = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find sequences of (back)slashes in the string. For each sequence
|
|
||||||
// we will store the positions of the first and last (back)slash.
|
|
||||||
T_AutoArray< uint32_t , 64 > slashPos;
|
|
||||||
T_StringIterator it{ path };
|
|
||||||
while ( !it.atEnd( ) ) {
|
|
||||||
const auto c{ it.character( ) };
|
|
||||||
const auto p{ it.index( ) };
|
|
||||||
it.next( );
|
|
||||||
|
|
||||||
if ( c != '/' && c != '\\' ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto ps{ slashPos.size( ) };
|
|
||||||
if ( ps == 0 || slashPos[ ps - 1 ] != p - 1 ) {
|
|
||||||
slashPos.add( p );
|
|
||||||
slashPos.add( p );
|
|
||||||
} else {
|
|
||||||
slashPos[ ps - 1 ] ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No (back)slashes, this is a relative path
|
|
||||||
const auto sps{ slashPos.size( ) };
|
|
||||||
if ( sps == 0 ) {
|
|
||||||
components_.add( path );
|
|
||||||
valid_ = IsValidComponent( path );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect the first item, with the first (back)slash included,
|
|
||||||
// check if it's a root
|
|
||||||
const auto firstSlashPos{ slashPos[ 0 ] };
|
|
||||||
T_String firstItem{ path.substr( 0 , 1 + firstSlashPos ) };
|
|
||||||
valid_ = true;
|
|
||||||
if ( IsValidRoot( firstItem ) ) {
|
|
||||||
root_ = std::move( firstItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get and check the components
|
|
||||||
uint32_t pos{ root_ ? 2u : 0u };
|
|
||||||
while ( pos <= sps ) {
|
|
||||||
T_String item{ path.range(
|
|
||||||
pos ? ( 1 + slashPos[ pos - 1 ] ) : 0 ,
|
|
||||||
pos == sps ? path.length( ) : ( slashPos[ pos ] - 1 ) )
|
|
||||||
};
|
|
||||||
assert( item || pos == sps );
|
|
||||||
if ( item ) {
|
|
||||||
valid_ = valid_ && IsValidComponent( item );
|
|
||||||
components_.add( std::move( item ) );
|
|
||||||
}
|
|
||||||
pos += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
uint32_t T_FSPath::computeHash( ) const noexcept
|
|
||||||
{
|
|
||||||
uint32_t h{ ComputeHash( root_ ) };
|
|
||||||
const auto cs{ components_.size( ) };
|
|
||||||
h = ( ( h << 27 ) | ( h >> 5 ) ) ^ cs;
|
|
||||||
for ( auto i = 0u ; i < cs ; i ++ ) {
|
|
||||||
h = ( ( h << 27 ) | ( h >> 5 ) ) ^ ComputeHash( components_[ i ] );
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void T_FSPath::appendTo(
|
|
||||||
T_StringBuilder& sb ) const noexcept
|
|
||||||
{
|
|
||||||
const auto cs{ components_.size( ) };
|
|
||||||
if ( !( root_ || cs ) ) {
|
|
||||||
sb << '.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto i = 0u ; i < cs ; i ++ ) {
|
|
||||||
if ( i == 0 ) {
|
|
||||||
sb << root_;
|
|
||||||
} else {
|
|
||||||
sb << M_PATHSEP_;
|
|
||||||
}
|
|
||||||
sb << components_[ i ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define M_CMPSTR_(A,B) (A).compareIgnoreCase( B )
|
|
||||||
#else
|
|
||||||
# define M_CMPSTR_(A,B) (A).compare( B )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t T_FSPath::compareTo(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
if ( &other == this ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t cmp{ M_CMPSTR_( root_ , other.root_ ) };
|
|
||||||
if ( cmp == 0 ) {
|
|
||||||
const auto nca{ components_.size( ) } ,
|
|
||||||
ncb{ other.components_.size( ) } ,
|
|
||||||
nc{ std::min( nca , ncb ) };
|
|
||||||
for ( auto i = 0u ; i < nc && cmp == 0 ; i ++ ) {
|
|
||||||
cmp = M_CMPSTR_( components_[ i ] , other.components_[ i ] );
|
|
||||||
}
|
|
||||||
if ( cmp == 0 ) {
|
|
||||||
cmp = T_Comparator< uint32_t >::compare( nca , ncb );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
T_FSPath T_FSPath::parent( ) const noexcept
|
|
||||||
{
|
|
||||||
T_FSPath p{ *this };
|
|
||||||
if ( p.components_.size( ) ) {
|
|
||||||
p.components_.removeLast( );
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_FSPath T_FSPath::child(
|
|
||||||
T_String const& name ) const noexcept
|
|
||||||
{
|
|
||||||
T_FSPath c{ *this };
|
|
||||||
c.components_.add( name );
|
|
||||||
c.valid_ = c.valid_ && IsValidComponent( name );
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_FSPath T_FSPath::operator +(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
T_FSPath p{ *this };
|
|
||||||
if ( other.root_ ) {
|
|
||||||
p.valid_ = false;
|
|
||||||
} else {
|
|
||||||
p.valid_ = p.valid_ && other.valid_;
|
|
||||||
}
|
|
||||||
p.components_.addAll( other.components_ );
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
bool T_FSPath::inDirectoryOf(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
if ( &other == this ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto nc{ components_.size( ) };
|
|
||||||
if ( nc != other.components_.size( ) || nc == 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto i = 0u ; i < nc - 1 ; i ++ ) {
|
|
||||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return M_CMPSTR_( components_[ nc - 1 ] , other.components_[ nc - 1 ] ) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool T_FSPath::isParentOf(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
if ( &other == this ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto nc{ components_.size( ) };
|
|
||||||
if ( nc + 1 != other.components_.size( ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
|
||||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool T_FSPath::isAbove(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
if ( &other == this ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto nc{ components_.size( ) };
|
|
||||||
if ( nc >= other.components_.size( ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
|
||||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
T_FSPath T_FSPath::makeRelative(
|
|
||||||
T_FSPath const& relTo ) const noexcept
|
|
||||||
{
|
|
||||||
assert( isValid( ) && relTo.isValid( ) );
|
|
||||||
assert( isCanonical( ) && relTo.isCanonical( ) );
|
|
||||||
if ( relTo.root_ != root_ ) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto nca{ components_.size( ) } ,
|
|
||||||
ncb{ relTo.components_.size( ) } ,
|
|
||||||
nc{ std::min( nca , ncb ) };
|
|
||||||
uint32_t nCommon{ 0u };
|
|
||||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
|
||||||
if ( M_CMPSTR_( components_[ i ] , relTo.components_[ i ] ) != 0 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nCommon ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_FSPath np;
|
|
||||||
const T_String parent{ T_String::Pooled( ".." ) };
|
|
||||||
for ( auto i = ncb ; i > nCommon ; i -- ) {
|
|
||||||
np.components_.add( parent );
|
|
||||||
}
|
|
||||||
for ( auto i = nCommon ; i < nca ; i ++ ) {
|
|
||||||
np.components_.add( components_[ i ] );
|
|
||||||
}
|
|
||||||
return np;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
bool T_FSPath::isCanonical( ) const noexcept
|
|
||||||
{
|
|
||||||
if ( !( valid_ && root_ ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const nc{ components_.size( ) };
|
|
||||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
|
||||||
if ( components_[ i ] == "." || components_[ i ] == ".." ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_FSPath T_FSPath::canonical( ) const noexcept
|
|
||||||
{
|
|
||||||
auto const nc{ components_.size( ) };
|
|
||||||
if ( !( valid_ && nc && root_ ) ) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_FSPath np;
|
|
||||||
np.root_ = root_;
|
|
||||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
|
||||||
auto const& cmp{ components_[ i ] };
|
|
||||||
if ( cmp == ".." ) {
|
|
||||||
if ( np.components_.size( ) ) {
|
|
||||||
np.components_.removeLast( );
|
|
||||||
}
|
|
||||||
} else if ( cmp != "." ) {
|
|
||||||
np.components_.add( cmp );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return np;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*= Filesystem ===============================================================*/
|
|
||||||
|
|
||||||
T_FSPath Filesystem::Cwd( ) noexcept
|
|
||||||
{
|
|
||||||
// TODO windows version
|
|
||||||
|
|
||||||
T_Buffer< char > buffer{ 256 };
|
|
||||||
#if _WIN32
|
|
||||||
auto req{ buffer.bytes( ) };
|
|
||||||
do {
|
|
||||||
if ( req > buffer.bytes( ) ) {
|
|
||||||
buffer.resize( req + 1 );
|
|
||||||
}
|
|
||||||
req = GetCurrentDirectory( buffer.bytes( ) , &buffer[ 0 ] );
|
|
||||||
} while ( req > buffer.bytes( ) );
|
|
||||||
#else
|
|
||||||
while ( getcwd( &buffer[ 0 ] , buffer.bytes( ) ) == nullptr ) {
|
|
||||||
assert( errno == ERANGE );
|
|
||||||
buffer.resize( buffer.size( ) + 256 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
T_FSPath path{ &buffer[ 0 ] };
|
|
||||||
assert( path.isValid( ) );
|
|
||||||
return path;
|
|
||||||
}
|
|
293
p-filesystem.hh
293
p-filesystem.hh
|
@ -1,293 +0,0 @@
|
||||||
/******************************************************************************/
|
|
||||||
/* FILESYSTEM ABSTRACTION *****************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _H_EBCL_FILESYSTEM
|
|
||||||
#define _H_EBCL_FILESYSTEM
|
|
||||||
|
|
||||||
#include <ebcl/Strings.hh>
|
|
||||||
#include <ebcl/Utilities.hh>
|
|
||||||
namespace ebcl {
|
|
||||||
|
|
||||||
|
|
||||||
/*= FILESYSTEM PATH ==========================================================*/
|
|
||||||
|
|
||||||
class T_FSPath
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using T_Components = T_AutoArray< T_String , 16 >;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Root will be '/' on Unix, or a drive letter on Windows. Relative
|
|
||||||
// paths will have a blank root.
|
|
||||||
T_String root_;
|
|
||||||
T_Components components_;
|
|
||||||
bool valid_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Helpers
|
|
||||||
|
|
||||||
static bool IsValidComponent( T_String const& string ) noexcept;
|
|
||||||
static bool IsValidRoot( T_String const& string ) noexcept;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Basic constructors and assignment operators
|
|
||||||
|
|
||||||
T_FSPath( ) noexcept;
|
|
||||||
|
|
||||||
T_FSPath( T_FSPath const& other ) noexcept;
|
|
||||||
T_FSPath& operator =( T_FSPath const& other ) noexcept;
|
|
||||||
|
|
||||||
T_FSPath( T_FSPath&& other ) noexcept;
|
|
||||||
T_FSPath& operator =( T_FSPath&& other ) noexcept;
|
|
||||||
|
|
||||||
T_FSPath& swap( T_FSPath& other ) noexcept;
|
|
||||||
|
|
||||||
// Construct from a string
|
|
||||||
T_FSPath( T_String const& path ) noexcept;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool isValid( ) const noexcept;
|
|
||||||
|
|
||||||
T_String const& root( ) const noexcept;
|
|
||||||
T_Components const& components( ) const noexcept;
|
|
||||||
|
|
||||||
bool isRelative( ) const noexcept;
|
|
||||||
bool isAbsolute( ) const noexcept;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Convert the path into a string
|
|
||||||
T_String toString( ) const noexcept;
|
|
||||||
// Compute a hash value for the path
|
|
||||||
uint32_t computeHash( ) const noexcept;
|
|
||||||
// Append to a string builder
|
|
||||||
void appendTo( T_StringBuilder& sb ) const noexcept;
|
|
||||||
|
|
||||||
// Comparisons. On Windows the comparison will be case-insensitive.
|
|
||||||
int32_t compareTo( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator ==( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator !=( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator <( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator <=( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator >( T_FSPath const& other ) const noexcept;
|
|
||||||
bool operator >=( T_FSPath const& other ) const noexcept;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Returns the parent's path
|
|
||||||
T_FSPath parent( ) const noexcept;
|
|
||||||
|
|
||||||
// Returns the child's path
|
|
||||||
T_FSPath child( T_String const& name ) const noexcept;
|
|
||||||
|
|
||||||
// Appends the specified (relative) path to the current path and return
|
|
||||||
// the result. If the path is absolute, the result will be invalid.
|
|
||||||
T_FSPath operator +( T_FSPath const& other ) const noexcept;
|
|
||||||
|
|
||||||
// Checks if the current path and the specified path have the same
|
|
||||||
// parent and are different.
|
|
||||||
bool inDirectoryOf( T_FSPath const& other ) const noexcept;
|
|
||||||
|
|
||||||
// Checks if the current path is the direct parent of the specified path
|
|
||||||
bool isParentOf( T_FSPath const& other ) const noexcept;
|
|
||||||
// Checks if the current path is the direct child of the specified path
|
|
||||||
bool isChildOf( T_FSPath const& other ) const noexcept;
|
|
||||||
|
|
||||||
// Checks if the current path is a parent of the specified path
|
|
||||||
bool isAbove( T_FSPath const& other ) const noexcept;
|
|
||||||
// Checks if the current path is a child of the specified path
|
|
||||||
bool isUnder( T_FSPath const& other ) const noexcept;
|
|
||||||
|
|
||||||
// Create a relative path based on the current path and a "parent" path.
|
|
||||||
// Both paths must be canonical and valid. If they have different roots,
|
|
||||||
// a copy of the current path will be returned.
|
|
||||||
T_FSPath makeRelative( T_FSPath const& relTo ) const noexcept;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Checks whether the specified path is canonical
|
|
||||||
bool isCanonical( ) const noexcept;
|
|
||||||
// Return a canonical path from the current path
|
|
||||||
T_FSPath canonical( ) const noexcept;
|
|
||||||
};
|
|
||||||
M_DECLARE_SWAP( T_FSPath );
|
|
||||||
M_DECLARE_HASH( T_FSPath );
|
|
||||||
M_LSHIFT_OP( T_StringBuilder , T_FSPath const& );
|
|
||||||
|
|
||||||
|
|
||||||
/*= FILESYSTEM ===============================================================*/
|
|
||||||
|
|
||||||
class Filesystem final
|
|
||||||
{
|
|
||||||
Filesystem( ) = delete;
|
|
||||||
public:
|
|
||||||
// Return the absolute path to the current working directory
|
|
||||||
static T_FSPath Cwd( ) noexcept;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*= T_FSPath =================================================================*/
|
|
||||||
// FIXME: inline stuff should be moved
|
|
||||||
|
|
||||||
inline T_FSPath::T_FSPath( ) noexcept
|
|
||||||
: root_{ } , components_{ } , valid_{ true }
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline T_FSPath::T_FSPath(
|
|
||||||
T_FSPath const& other ) noexcept
|
|
||||||
: root_{ other.root_ } , components_{ other.components_ } ,
|
|
||||||
valid_{ other.valid_ }
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline T_FSPath& T_FSPath::operator =(
|
|
||||||
T_FSPath const& other ) noexcept
|
|
||||||
{
|
|
||||||
root_ = other.root_;
|
|
||||||
components_ = other.components_;
|
|
||||||
valid_ = other.valid_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline T_FSPath::T_FSPath( T_FSPath&& other ) noexcept
|
|
||||||
: T_FSPath{ }
|
|
||||||
{
|
|
||||||
swap( other );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T_FSPath& T_FSPath::operator =(
|
|
||||||
T_FSPath&& other ) noexcept
|
|
||||||
{
|
|
||||||
root_ = T_String{ };
|
|
||||||
components_.free( );
|
|
||||||
valid_ = true;
|
|
||||||
return swap( other );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline T_FSPath& T_FSPath::swap(
|
|
||||||
T_FSPath& other ) noexcept
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap( root_ , other.root_ );
|
|
||||||
swap( components_ , other.components_ );
|
|
||||||
swap( valid_ , other.valid_ );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline M_DEFINE_SWAP( T_FSPath )
|
|
||||||
{
|
|
||||||
lhs.swap( rhs );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline bool T_FSPath::isValid( ) const noexcept
|
|
||||||
{
|
|
||||||
return valid_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T_String const& T_FSPath::root( ) const noexcept
|
|
||||||
{
|
|
||||||
return root_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T_FSPath::T_Components const& T_FSPath::components( ) const noexcept
|
|
||||||
{
|
|
||||||
return components_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::isRelative( ) const noexcept
|
|
||||||
{
|
|
||||||
return !root_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::isAbsolute( ) const noexcept
|
|
||||||
{
|
|
||||||
return bool( root_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline T_String T_FSPath::toString( ) const noexcept
|
|
||||||
{
|
|
||||||
T_StringBuilder sb;
|
|
||||||
appendTo( sb );
|
|
||||||
return T_String{ std::move( sb ) };
|
|
||||||
}
|
|
||||||
|
|
||||||
inline M_DEFINE_HASH( T_FSPath )
|
|
||||||
{
|
|
||||||
return item.computeHash( );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline M_LSHIFT_OP( T_StringBuilder , T_FSPath const& )
|
|
||||||
{
|
|
||||||
value.appendTo( obj );
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator ==(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator !=(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator <(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator <=(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator >(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::operator >=(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return compareTo( other ) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
inline bool T_FSPath::isChildOf(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return other.isParentOf( *this );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool T_FSPath::isUnder(
|
|
||||||
T_FSPath const& other ) const noexcept
|
|
||||||
{
|
|
||||||
return other.isAbove( *this );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ebcl
|
|
||||||
#endif // _H_EBCL_FILESYSTEM
|
|
Loading…
Reference in a new issue