VFS - Ported from old LW code
This commit is contained in:
parent
68716e9193
commit
bb94169a31
4 changed files with 694 additions and 0 deletions
150
include/ebcl/VFS.hh
Normal file
150
include/ebcl/VFS.hh
Normal file
|
@ -0,0 +1,150 @@
|
|||
/******************************************************************************/
|
||||
/* VIRTUAL FILE SYSTEM ********************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _H_EBCL_VFS
|
||||
#define _H_EBCL_VFS
|
||||
|
||||
#include <ebcl/Sets.hh>
|
||||
#include <ebcl/Strings.hh>
|
||||
#include <ebcl/Streams.hh>
|
||||
#include <ebcl/Files.hh>
|
||||
#include <ebcl/Registration.hh>
|
||||
namespace ebcl {
|
||||
|
||||
|
||||
/*= DRIVERS ==================================================================*/
|
||||
|
||||
class A_VFSDriver
|
||||
{
|
||||
public:
|
||||
virtual ~A_VFSDriver( ) = 0;
|
||||
|
||||
/*
|
||||
* Initialisation and shutdown methods, called by the main VFS code.
|
||||
* These do nothing by default.
|
||||
*/
|
||||
virtual bool init( );
|
||||
virtual void shutdown( );
|
||||
|
||||
/*
|
||||
* Note: the main VFS code will NEVER pass anything but an absolute
|
||||
* path to the methods below.
|
||||
*/
|
||||
|
||||
/* Get the type of an entry in the VFS */
|
||||
virtual E_FSEntryType typeOf( T_FSPath const& path ) = 0;
|
||||
|
||||
/* Checks that a path exists */
|
||||
bool exists( T_FSPath const& path );
|
||||
|
||||
/* List entries matching a VFS path. The method should return true if
|
||||
* the path was found by the driver and was a directory, or false if
|
||||
* it wasn't.
|
||||
*/
|
||||
virtual bool list( T_FSPath const& path ,
|
||||
T_Set< T_FSPath >& values ) = 0;
|
||||
|
||||
/* Try reading from a VFS file. Returns an owning pointer that's either
|
||||
* null if the path in question couldn't be found (or wasn't a file)
|
||||
* or that refers to some unspecified input stream.
|
||||
*/
|
||||
virtual OP_InputStream read( T_FSPath const& path ) = 0;
|
||||
|
||||
/* Try opening a path as an actual file. If the driver doesn't support
|
||||
* this, or if it cannot open the file for whatever reason, this should
|
||||
* return null (which is what the default implementation does).
|
||||
*/
|
||||
virtual OP_File file( T_FSPath const& path );
|
||||
};
|
||||
M_ABSTRACT_POINTERS( VFSDriver );
|
||||
|
||||
|
||||
/*= VFS FILESYSTEM DRIVER ====================================================*/
|
||||
|
||||
/* A driver that allows the VFS to access a part of the actual filesystem. */
|
||||
class T_VFSFilesystemDriver : public A_VFSDriver
|
||||
{
|
||||
private:
|
||||
T_FSPath root_;
|
||||
|
||||
public:
|
||||
T_VFSFilesystemDriver( ) = delete;
|
||||
T_VFSFilesystemDriver( T_VFSFilesystemDriver const& ) = delete;
|
||||
T_VFSFilesystemDriver( T_VFSFilesystemDriver&& ) noexcept = delete;
|
||||
|
||||
explicit T_VFSFilesystemDriver( T_FSPath const& root );
|
||||
|
||||
T_FSPath const& root( ) const;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
bool init( ) override;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
E_FSEntryType typeOf( T_FSPath const& path ) override;
|
||||
bool list( T_FSPath const& path , T_Set< T_FSPath >& values ) override;
|
||||
|
||||
OP_InputStream read( T_FSPath const& path ) override;
|
||||
OP_File file( T_FSPath const& path ) override;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
T_String getFullPath( T_FSPath const& path ) const;
|
||||
T_Buffer< char > getOSPath( T_FSPath const& path ) const;
|
||||
};
|
||||
M_CLASS_POINTERS( VFSFilesystemDriver );
|
||||
|
||||
|
||||
/*= VFS CORE =================================================================*/
|
||||
|
||||
class X_VFSInitialisationFailure : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
X_VFSInitialisationFailure( );
|
||||
};
|
||||
|
||||
class T_VFS : public A_PrivateImplementation
|
||||
{
|
||||
public:
|
||||
// Initialise the VFS, using the specified RW directory
|
||||
T_VFS( T_FSPath const& userDir );
|
||||
|
||||
T_VFS( ) = delete;
|
||||
T_VFS( T_VFS const& ) = delete;
|
||||
T_VFS( T_VFS&& ) = delete;
|
||||
|
||||
// Add a new VFS driver
|
||||
T_RegisteredItem addDriver( OP_VFSDriver&& driver );
|
||||
template<
|
||||
typename DriverType ,
|
||||
typename... ArgTypes
|
||||
>
|
||||
T_RegisteredItem addDriver( ArgTypes&& ... arguments );
|
||||
|
||||
// Read-only access methods.
|
||||
E_FSEntryType typeOf( T_FSPath const& path ) const;
|
||||
bool list( T_FSPath const& path , T_Array< T_FSPath >& output ) const;
|
||||
OP_InputStream read( T_FSPath const& path ) const;
|
||||
OP_File file( T_FSPath const& path ) const;
|
||||
|
||||
// Read/write access for the user directory.
|
||||
OP_File file( T_FSPath const& path , E_FileMode mode ) const;
|
||||
OP_OutputStream write( T_FSPath const& path ) const;
|
||||
bool mkdir( T_FSPath const& path ) const;
|
||||
bool rmdir( T_FSPath const& path ) const;
|
||||
bool rm( T_FSPath const& path ) const;
|
||||
bool move( T_FSPath const& from ,
|
||||
T_FSPath const& to ) const;
|
||||
|
||||
// Path style for the VFS
|
||||
static constexpr T_FSPathStyle Style( ) noexcept;
|
||||
};
|
||||
M_CLASS_POINTERS( VFS );
|
||||
|
||||
|
||||
} // namespace
|
||||
#endif // _H_EBCL_VFS
|
||||
#include <ebcl/inline/VFS.hh>
|
60
include/ebcl/inline/VFS.hh
Normal file
60
include/ebcl/inline/VFS.hh
Normal file
|
@ -0,0 +1,60 @@
|
|||
/******************************************************************************/
|
||||
/* VIRTUAL FILE SYSTEM - INLINE CODE ******************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _H_EBCL_INLINE_VFS
|
||||
#define _H_EBCL_INLINE_VFS
|
||||
#include <ebcl/VFS.hh>
|
||||
namespace ebcl {
|
||||
|
||||
|
||||
/*= A_VFSDriver ==============================================================*/
|
||||
|
||||
inline A_VFSDriver::~A_VFSDriver( )
|
||||
{ }
|
||||
|
||||
inline bool A_VFSDriver::exists( T_FSPath const& path )
|
||||
{
|
||||
const auto et( typeOf( path ) );
|
||||
return et != E_FSEntryType::NONE;
|
||||
}
|
||||
|
||||
|
||||
/*= T_VFSFilesystemDriver ====================================================*/
|
||||
|
||||
inline T_FSPath const& T_VFSFilesystemDriver::root( ) const
|
||||
{
|
||||
return root_;
|
||||
}
|
||||
|
||||
|
||||
/*= X_VFSInitialisationFailure ===============================================*/
|
||||
|
||||
inline X_VFSInitialisationFailure::X_VFSInitialisationFailure( )
|
||||
: std::runtime_error( "unable to initialise VFS" )
|
||||
{ }
|
||||
|
||||
|
||||
/*= T_VFS ====================================================================*/
|
||||
|
||||
template<
|
||||
typename DriverType ,
|
||||
typename... ArgTypes
|
||||
>
|
||||
inline T_RegisteredItem T_VFS::addDriver( ArgTypes&& ... arguments )
|
||||
{
|
||||
return addDriver( NewOwned< DriverType >(
|
||||
std::forward< ArgTypes >( arguments ) ... ) );
|
||||
}
|
||||
|
||||
inline constexpr T_FSPathStyle T_VFS::Style( ) noexcept
|
||||
{
|
||||
return T_FSPathStyle{ true , false ,
|
||||
T_Flags< E_FSPathSeparator >{
|
||||
E_FSPathSeparator::SLASH ,
|
||||
E_FSPathSeparator::BACKSLASH } };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif // _H_EBCL_INLINE_VFS
|
483
src/VFS.cc
Normal file
483
src/VFS.cc
Normal file
|
@ -0,0 +1,483 @@
|
|||
/******************************************************************************/
|
||||
/* VIRTUAL FILE SYSTEM ********************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <ebcl/VFS.hh>
|
||||
using namespace ebcl;
|
||||
|
||||
|
||||
|
||||
/*= A_VFSDriver ==============================================================*/
|
||||
|
||||
bool A_VFSDriver::init( )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void A_VFSDriver::shutdown( )
|
||||
{ }
|
||||
|
||||
OP_File A_VFSDriver::file( T_FSPath const& )
|
||||
{
|
||||
return OP_File( );
|
||||
}
|
||||
|
||||
|
||||
/*= T_VFSFilesystemDriver ====================================================*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# define C_SEPARATOR_ '\\'
|
||||
#else
|
||||
# define C_SEPARATOR_ '/'
|
||||
#endif
|
||||
|
||||
T_VFSFilesystemDriver::T_VFSFilesystemDriver(
|
||||
T_FSPath const& path )
|
||||
{
|
||||
assert( path.style( ) == T_FSPathStyle::System( ) );
|
||||
assert( path.isValid( ) );
|
||||
root_ = path.canonical( );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool T_VFSFilesystemDriver::init( )
|
||||
{
|
||||
const auto type{ Filesystem::TypeOf( root_ ) };
|
||||
return type == E_FSEntryType::DIRECTORY;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
E_FSEntryType T_VFSFilesystemDriver::typeOf(
|
||||
T_FSPath const& path )
|
||||
{
|
||||
return Filesystem::TypeOf( root_ + path );
|
||||
}
|
||||
|
||||
bool T_VFSFilesystemDriver::list(
|
||||
T_FSPath const& path ,
|
||||
T_Set< T_FSPath >& values )
|
||||
{
|
||||
T_Array< T_String > items;
|
||||
if ( ! Filesystem::List( root_ + path , items ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( auto const& item : items ) {
|
||||
if ( item == "." || item == ".." ) {
|
||||
continue;
|
||||
}
|
||||
const T_FSPath iPath{ path + item };
|
||||
if ( !iPath.isValid( ) ) {
|
||||
continue;
|
||||
}
|
||||
values.add( iPath );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
OP_InputStream T_VFSFilesystemDriver::read(
|
||||
T_FSPath const& path )
|
||||
{
|
||||
if ( typeOf( path ) != E_FSEntryType::FILE ) {
|
||||
return OP_InputStream( );
|
||||
} else {
|
||||
auto f( file( path ) );
|
||||
if ( f ) {
|
||||
return NewOwned< T_FileInputStream >( std::move( f ) );
|
||||
} else {
|
||||
return OP_InputStream( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OP_File T_VFSFilesystemDriver::file(
|
||||
T_FSPath const& path )
|
||||
{
|
||||
if ( typeOf( path ) != E_FSEntryType::FILE ) {
|
||||
return OP_File( );
|
||||
}
|
||||
return NewOwned< T_File >( getFullPath( path ) , E_FileMode::READ_ONLY );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_String T_VFSFilesystemDriver::getFullPath(
|
||||
T_FSPath const& path ) const
|
||||
{
|
||||
return ( root_ + path ).toString( );
|
||||
}
|
||||
|
||||
T_Buffer< char > T_VFSFilesystemDriver::getOSPath(
|
||||
T_FSPath const& path ) const
|
||||
{
|
||||
return getFullPath( path ).toOSString( );
|
||||
}
|
||||
|
||||
|
||||
/*= T_VFSUserDirectory_ ======================================================*/
|
||||
|
||||
namespace {
|
||||
|
||||
class T_VFSUserDirectory_ : public T_VFSFilesystemDriver
|
||||
{
|
||||
public:
|
||||
explicit T_VFSUserDirectory_( T_FSPath const& base );
|
||||
|
||||
bool init( ) override;
|
||||
|
||||
OP_File file( T_FSPath const& path ) override;
|
||||
OP_File file( T_FSPath const& path , E_FileMode mode );
|
||||
OP_OutputStream write( T_FSPath const& path );
|
||||
bool mkdir( T_FSPath const& path ) const;
|
||||
bool rmdir( T_FSPath const& path ) const;
|
||||
bool rm( T_FSPath const& path ) const;
|
||||
bool move( T_FSPath const& from , T_FSPath const& to ) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
T_VFSUserDirectory_::T_VFSUserDirectory_(
|
||||
T_FSPath const& base )
|
||||
: T_VFSFilesystemDriver( base )
|
||||
{ }
|
||||
|
||||
bool T_VFSUserDirectory_::init( )
|
||||
{
|
||||
if ( T_VFSFilesystemDriver::init( ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try creating the user directory
|
||||
T_FSPath const& r( root( ) );
|
||||
return Filesystem::MkDirFull( r );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
OP_File T_VFSUserDirectory_::file( T_FSPath const& path )
|
||||
{
|
||||
return T_VFSFilesystemDriver::file( path );
|
||||
}
|
||||
|
||||
OP_File T_VFSUserDirectory_::file( T_FSPath const& path , E_FileMode mode )
|
||||
{
|
||||
if ( mode == E_FileMode::READ_ONLY ) {
|
||||
return file( path );
|
||||
}
|
||||
|
||||
const auto fp( getFullPath( path ) );
|
||||
const auto ft( Filesystem::TypeOf( fp ) );
|
||||
if ( ft != E_FSEntryType::FILE && ft != E_FSEntryType::NONE ) {
|
||||
return OP_File( );
|
||||
}
|
||||
return NewOwned< T_File >( fp , mode );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
OP_OutputStream T_VFSUserDirectory_::write( T_FSPath const& path )
|
||||
{
|
||||
auto f( file( path , E_FileMode::OVERWRITE ) );
|
||||
if ( f ) {
|
||||
return NewOwned< T_FileOutputStream >( std::move( f ) );
|
||||
} else {
|
||||
return OP_OutputStream( );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool T_VFSUserDirectory_::mkdir( T_FSPath const& path ) const
|
||||
{
|
||||
return Filesystem::MkDirFull( root( ) + path );
|
||||
}
|
||||
|
||||
bool T_VFSUserDirectory_::rmdir( T_FSPath const& path ) const
|
||||
{
|
||||
return Filesystem::RmDir( root( ) + path );
|
||||
}
|
||||
|
||||
bool T_VFSUserDirectory_::rm( T_FSPath const& path ) const
|
||||
{
|
||||
return Filesystem::Rm( root( ) + path );
|
||||
}
|
||||
|
||||
bool T_VFSUserDirectory_::move(
|
||||
T_FSPath const& from ,
|
||||
T_FSPath const& to ) const
|
||||
{
|
||||
return Filesystem::Move( root( ) + from , root( ) + to );
|
||||
}
|
||||
|
||||
|
||||
/*= T_VFSPrivate_ ============================================================*/
|
||||
|
||||
namespace {
|
||||
struct T_VFSPrivate_
|
||||
{
|
||||
T_RegisteredItem::SP_Unregister unregisterFunction_{
|
||||
NewShared< T_RegisteredItem::F_Unregister >(
|
||||
[this]( void* data ) {
|
||||
auto const n( drivers_.size( ) );
|
||||
for ( uint32_t i = 0 ; i < n ; i ++ ) {
|
||||
auto& p( drivers_[ i ] );
|
||||
if ( p.get( ) == data ) {
|
||||
p->shutdown( );
|
||||
drivers_.removeSwap( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
) };
|
||||
OP_VFSFilesystemDriver userDir_;
|
||||
T_Array< OP_VFSDriver > drivers_{ 16 };
|
||||
|
||||
static T_String findUserDir( );
|
||||
void initUserDir( T_FSPath const& dir );
|
||||
};
|
||||
} // namespace
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void T_VFSPrivate_::initUserDir( T_FSPath const& dir )
|
||||
{
|
||||
assert( !userDir_ );
|
||||
userDir_ = NewOwned< T_VFSUserDirectory_ >( dir );
|
||||
if ( !userDir_->init( ) ) {
|
||||
throw X_VFSInitialisationFailure( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*= T_VFS ====================================================================*/
|
||||
|
||||
T_VFS::T_VFS( T_FSPath const& userDir )
|
||||
: A_PrivateImplementation( new T_VFSPrivate_( ) )
|
||||
{
|
||||
assert( userDir.style( ) == T_FSPathStyle::System( ) );
|
||||
p< T_VFSPrivate_ >( ).initUserDir( userDir );
|
||||
}
|
||||
|
||||
T_RegisteredItem T_VFS::addDriver( OP_VFSDriver&& driver )
|
||||
{
|
||||
assert( driver );
|
||||
const bool ok( driver->init( ) );
|
||||
if ( ok ) {
|
||||
auto& pi( p< T_VFSPrivate_ >( ) );
|
||||
void* const ptr( driver.get( ) );
|
||||
pi.drivers_.add( std::move( driver ) );
|
||||
return T_RegisteredItem( pi.unregisterFunction_ , ptr );
|
||||
}
|
||||
return T_RegisteredItem( );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
E_FSEntryType T_VFS::typeOf(
|
||||
T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return E_FSEntryType::NONE;
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
auto& pi( p< T_VFSPrivate_ >( ) );
|
||||
E_FSEntryType rv( pi.userDir_->typeOf( np ) );
|
||||
const auto nd( pi.drivers_.size( ) );
|
||||
for ( uint32_t i = nd ; i != 0 && rv == E_FSEntryType::NONE ; i -- ) {
|
||||
rv = pi.drivers_[ i - 1 ]->typeOf( np );
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool T_VFS::list(
|
||||
T_FSPath const& path ,
|
||||
T_Array< T_FSPath >& output ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return false;
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
// Get the result set
|
||||
auto& pi( p< T_VFSPrivate_ >( ) );
|
||||
T_Set< T_FSPath > values{ UseTag< IndexBacked<> >( ) };
|
||||
bool rv{ pi.userDir_->list( np , values ) };
|
||||
const auto nd( pi.drivers_.size( ) );
|
||||
for ( uint32_t i = nd ; i != 0 ; i -- ) {
|
||||
rv = pi.drivers_[ i - 1 ]->list( np , values ) || rv;
|
||||
}
|
||||
|
||||
// Convert to array and sort
|
||||
const auto nr{ values.size( ) };
|
||||
output.clear( );
|
||||
for ( auto i = 0u ; i < nr ; i ++ ) {
|
||||
output.add( values[ i ] );
|
||||
}
|
||||
output.sort( );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
OP_InputStream T_VFS::read( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return {};
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
auto& pi( p< T_VFSPrivate_ >( ) );
|
||||
OP_InputStream rv{ pi.userDir_->read( np ) };
|
||||
const auto nd{ pi.drivers_.size( ) };
|
||||
for ( uint32_t i = nd ; i != 0 && !rv ; i -- ) {
|
||||
rv = pi.drivers_[ i - 1 ]->read( np );
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
OP_File T_VFS::file( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return {};
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
auto& pi{ p< T_VFSPrivate_ >( ) };
|
||||
OP_File rv{ pi.userDir_->file( np ) };
|
||||
const auto nd{ pi.drivers_.size( ) };
|
||||
for ( uint32_t i = nd ; i != 0 && !rv ; i -- ) {
|
||||
rv = pi.drivers_[ i - 1 ]->file( np );
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
OP_File T_VFS::file(
|
||||
T_FSPath const& path ,
|
||||
const E_FileMode mode ) const
|
||||
{
|
||||
if ( mode == E_FileMode::READ_ONLY ) {
|
||||
return file( path );
|
||||
} else {
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return {};
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( ) )
|
||||
->file( np , mode );
|
||||
}
|
||||
}
|
||||
|
||||
OP_OutputStream T_VFS::write( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return {};
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( )
|
||||
)->write( np );
|
||||
}
|
||||
|
||||
bool T_VFS::mkdir( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return false;
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( )
|
||||
)->mkdir( np );
|
||||
}
|
||||
|
||||
bool T_VFS::rmdir( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return false;
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( )
|
||||
)->rmdir( np );
|
||||
}
|
||||
|
||||
bool T_VFS::rm( T_FSPath const& path ) const
|
||||
{
|
||||
assert( path.style( ) == Style( ) );
|
||||
if ( ! path.isValid( ) ) {
|
||||
return false;
|
||||
}
|
||||
const auto np{ path.isAbsolute( )
|
||||
? path.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + path ).canonical( ) };
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( )
|
||||
)->rm( np );
|
||||
}
|
||||
|
||||
bool T_VFS::move( T_FSPath const& from , T_FSPath const& to ) const
|
||||
{
|
||||
assert( from.style( ) == Style( ) );
|
||||
assert( to.style( ) == Style( ) );
|
||||
if ( ! ( from.isValid( ) && to.isValid( ) ) ) {
|
||||
return false;
|
||||
}
|
||||
const auto nFrom{ from.isAbsolute( )
|
||||
? from.canonical( )
|
||||
: ( T_FSPath( "/" , Style( ) ) + from ).canonical( ) };
|
||||
if ( nFrom.components( ).size( ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
T_FSPath nTo;
|
||||
if ( to.isAbsolute( ) ) {
|
||||
nTo = to.canonical( );
|
||||
} else {
|
||||
nTo = ( nFrom + T_FSPath( ".." ) + to ).canonical( );
|
||||
}
|
||||
if ( nTo.components( ).size( ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dynamic_cast< T_VFSUserDirectory_* >(
|
||||
p< T_VFSPrivate_ >( ).userDir_.get( ) )
|
||||
->move( nFrom , nTo );
|
||||
}
|
|
@ -16,4 +16,5 @@ LIB_SOURCES = \
|
|||
src/Strings.cc \
|
||||
src/TemplateInstantiation.cc \
|
||||
src/Utilities.cc \
|
||||
src/VFS.cc \
|
||||
# END
|
||||
|
|
Loading…
Reference in a new issue