From f5b411380649c8fc42204ad7eed1dda1fce34ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 26 Dec 2017 13:18:01 +0100 Subject: [PATCH] Filesystem abstraction prototype - Paths "finished" Untested and I might have forgotten some useful shit, but ah well. --- p-filesystem.cc | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ p-filesystem.hh | 14 +++++ 2 files changed, 158 insertions(+) diff --git a/p-filesystem.cc b/p-filesystem.cc index 690a717..5fc8f39 100644 --- a/p-filesystem.cc +++ b/p-filesystem.cc @@ -180,3 +180,147 @@ int32_t T_FSPath::compareTo( } 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; +} + +/*----------------------------------------------------------------------------*/ + +bool T_FSPath::isCanonical( ) const noexcept +{ + if ( !valid_ ) { + return false; + } + + auto const nc{ components_.size( ) }; + for ( auto i = 0u ; i < nc ; i ++ ) { + if ( components_[ i ] == "." || components_[ i ] == ".." ) { + return false; + } + } + return nc > 0; +} + +T_FSPath T_FSPath::canonical( ) const noexcept +{ + auto const nc{ components_.size( ) }; + if ( !( valid_ && nc ) ) { + 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; +} diff --git a/p-filesystem.hh b/p-filesystem.hh index 9b9f133..83e35c4 100644 --- a/p-filesystem.hh +++ b/p-filesystem.hh @@ -268,6 +268,20 @@ inline bool T_FSPath::operator >=( 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