Filesystem paths - Path style support
This commit is contained in:
parent
96d81b9cd3
commit
fc3415047f
4 changed files with 114 additions and 82 deletions
|
@ -55,7 +55,9 @@ bool T_FSPath::IsValidComponent(
|
|||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_FSPath::T_FSPath(
|
||||
T_String const& path ) noexcept
|
||||
T_String const& path ,
|
||||
T_FSPathStyle style ) noexcept
|
||||
: style_{ style }
|
||||
{
|
||||
if ( !path ) {
|
||||
valid_ = true;
|
||||
|
@ -71,7 +73,7 @@ T_FSPath::T_FSPath(
|
|||
const auto p{ it.index( ) };
|
||||
it.next( );
|
||||
|
||||
if ( c != '/' && c != '\\' ) {
|
||||
if ( !style_.isSeparator( c ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -97,7 +99,7 @@ T_FSPath::T_FSPath(
|
|||
const auto firstSlashPos{ slashPos[ 0 ] };
|
||||
T_String firstItem{ path.substr( 0 , 1 + firstSlashPos ) };
|
||||
valid_ = true;
|
||||
if ( IsValidRoot( firstItem ) ) {
|
||||
if ( style_.isValidRoot( firstItem ) ) {
|
||||
root_ = std::move( firstItem );
|
||||
}
|
||||
|
||||
|
@ -124,14 +126,22 @@ 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 ] );
|
||||
if ( style_.caseSensitive( ) ) {
|
||||
for ( auto i = 0u ; i < cs ; i ++ ) {
|
||||
h = ( ( h << 27 ) | ( h >> 5 ) ) ^ ComputeHash( components_[ i ] );
|
||||
}
|
||||
} else {
|
||||
for ( auto i = 0u ; i < cs ; i ++ ) {
|
||||
h = ( ( h << 27 ) | ( h >> 5 ) )
|
||||
^ ComputeHash( components_[ i ].toLower( ) );
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void T_FSPath::appendTo(
|
||||
T_StringBuilder& sb ) const noexcept
|
||||
T_StringBuilder& sb ,
|
||||
T_OptPathSeparator separator ) const noexcept
|
||||
{
|
||||
const auto cs{ components_.size( ) };
|
||||
if ( !( root_ || cs ) ) {
|
||||
|
@ -139,11 +149,14 @@ void T_FSPath::appendTo(
|
|||
return;
|
||||
}
|
||||
|
||||
const T_Character sepVal{ separator
|
||||
? ( *separator == E_FSPathSeparator::SLASH ? '/' : '\\' )
|
||||
: ( style_.pathSeparators( ) & E_FSPathSeparator::SLASH ? '/' : '\\' ) };
|
||||
for ( auto i = 0u ; i < cs ; i ++ ) {
|
||||
if ( i == 0 ) {
|
||||
sb << root_;
|
||||
} else {
|
||||
sb << M_PATHSEP_;
|
||||
sb << sepVal;
|
||||
}
|
||||
sb << components_[ i ];
|
||||
}
|
||||
|
@ -151,11 +164,24 @@ void T_FSPath::appendTo(
|
|||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# define M_CMPSTR_(A,B) (A).compareIgnoreCase( B )
|
||||
#else
|
||||
# define M_CMPSTR_(A,B) (A).compare( B )
|
||||
#endif
|
||||
// String comparison functions
|
||||
namespace {
|
||||
int CmpCi_( T_String const& a , T_String const& b )
|
||||
{
|
||||
return a.compareIgnoreCase( b );
|
||||
}
|
||||
int CmpCs_( T_String const& a , T_String const& b )
|
||||
{
|
||||
return a.compare( b );
|
||||
}
|
||||
}
|
||||
|
||||
T_FSPath::F_StrCmp_ T_FSPath::cmpFunction_( ) const noexcept
|
||||
{
|
||||
return style_.caseSensitive( ) ? CmpCs_ : CmpCi_;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int32_t T_FSPath::compareTo(
|
||||
T_FSPath const& other ) const noexcept
|
||||
|
@ -164,13 +190,14 @@ int32_t T_FSPath::compareTo(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t cmp{ M_CMPSTR_( root_ , other.root_ ) };
|
||||
const auto cmpFn{ cmpFunction_( ) };
|
||||
int32_t cmp{ cmpFn( 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 ] );
|
||||
cmp = cmpFn( components_[ i ] , other.components_[ i ] );
|
||||
}
|
||||
if ( cmp == 0 ) {
|
||||
cmp = T_Comparator< uint32_t >::compare( nca , ncb );
|
||||
|
@ -220,7 +247,9 @@ bool T_FSPath::inDirectoryOf(
|
|||
if ( &other == this ) {
|
||||
return false;
|
||||
}
|
||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
||||
|
||||
const auto cmpFn{ cmpFunction_( ) };
|
||||
if ( cmpFn( root_ , other.root_ ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -230,12 +259,12 @@ bool T_FSPath::inDirectoryOf(
|
|||
}
|
||||
|
||||
for ( auto i = 0u ; i < nc - 1 ; i ++ ) {
|
||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
if ( cmpFn( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return M_CMPSTR_( components_[ nc - 1 ] , other.components_[ nc - 1 ] ) != 0;
|
||||
return cmpFn( components_[ nc - 1 ] , other.components_[ nc - 1 ] ) != 0;
|
||||
}
|
||||
|
||||
bool T_FSPath::isParentOf(
|
||||
|
@ -244,7 +273,9 @@ bool T_FSPath::isParentOf(
|
|||
if ( &other == this ) {
|
||||
return false;
|
||||
}
|
||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
||||
|
||||
const auto cmpFn{ cmpFunction_( ) };
|
||||
if ( cmpFn( root_ , other.root_ ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -254,7 +285,7 @@ bool T_FSPath::isParentOf(
|
|||
}
|
||||
|
||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
if ( cmpFn( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +298,9 @@ bool T_FSPath::isAbove(
|
|||
if ( &other == this ) {
|
||||
return false;
|
||||
}
|
||||
if ( M_CMPSTR_( root_ , other.root_ ) != 0 ) {
|
||||
|
||||
const auto cmpFn{ cmpFunction_( ) };
|
||||
if ( cmpFn( root_ , other.root_ ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -277,7 +310,7 @@ bool T_FSPath::isAbove(
|
|||
}
|
||||
|
||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
||||
if ( M_CMPSTR_( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
if ( cmpFn( components_[ i ] , other.components_[ i ] ) != 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -295,18 +328,19 @@ T_FSPath T_FSPath::makeRelative(
|
|||
return *this;
|
||||
}
|
||||
|
||||
const auto cmpFn{ cmpFunction_( ) };
|
||||
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 ) {
|
||||
if ( cmpFn( components_[ i ] , relTo.components_[ i ] ) != 0 ) {
|
||||
break;
|
||||
}
|
||||
nCommon ++;
|
||||
}
|
||||
|
||||
T_FSPath np;
|
||||
T_FSPath np{ relTo.style_ };
|
||||
const T_String parent{ T_String::Pooled( ".." ) };
|
||||
for ( auto i = ncb ; i > nCommon ; i -- ) {
|
||||
np.components_.add( parent );
|
||||
|
@ -341,10 +375,9 @@ T_FSPath T_FSPath::canonical( ) const noexcept
|
|||
return *this;
|
||||
}
|
||||
|
||||
T_FSPath np;
|
||||
T_FSPath np{ style_ };
|
||||
np.root_ = root_;
|
||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
||||
auto const& cmp{ components_[ i ] };
|
||||
for ( auto const& cmp : components_ ) {
|
||||
if ( cmp == ".." ) {
|
||||
if ( np.components_.size( ) ) {
|
||||
np.components_.removeLast( );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue