corelib/include/ebcl/Filesystem.hh
Emmanuel BENOîT 68716e9193 Filesystem - Actual filesystem operations
* Entry type, directory listing
 * Directory creation and deletion
 * File deletion
 * Move
2018-12-23 22:30:11 +01:00

248 lines
8 KiB
C++

/******************************************************************************/
/* FILESYSTEM ABSTRACTION *****************************************************/
/******************************************************************************/
#ifndef _H_EBCL_FILESYSTEM
#define _H_EBCL_FILESYSTEM
#include <ebcl/Strings.hh>
#include <ebcl/Types.hh>
namespace ebcl {
/*= FILESYSTEM PATH ==========================================================*/
// Supported filesystem path separators
enum class E_FSPathSeparator
{
SLASH , BACKSLASH
};
using T_OptPathSeparator = T_Optional< E_FSPathSeparator >;
// The style of a filesystem path.
class T_FSPathStyle
{
private:
bool caseSensitive_;
bool hasDriveLetter_;
T_Flags< E_FSPathSeparator > pathSeparators_;
public:
//----------------------------------------------------------------------
// Constructors and assignment operators
T_FSPathStyle( ) = delete;
// Initialise the filesystem path style, specifying:
// - whether it is case-sensitive,
// - whether is can use a drive letter as its root,
// - which separators it supports
constexpr T_FSPathStyle( bool cs , bool hdl ,
T_Flags< E_FSPathSeparator > ps ) noexcept;
// Default copy/move constructors/assignement operators
constexpr T_FSPathStyle( T_FSPathStyle const& ) noexcept = default;
constexpr T_FSPathStyle& operator =( T_FSPathStyle const& ) noexcept = default;
constexpr T_FSPathStyle( T_FSPathStyle&& ) noexcept = default;
constexpr T_FSPathStyle& operator =( T_FSPathStyle&& ) noexcept = default;
T_FSPathStyle& swap( T_FSPathStyle& other ) noexcept;
//----------------------------------------------------------------------
// Accessors
constexpr bool caseSensitive( ) const noexcept;
constexpr T_FSPathStyle& caseSensitive( bool cs ) noexcept;
constexpr bool hasDriveLetter( ) const noexcept;
constexpr T_FSPathStyle& hasDriveLetter( bool hdl ) noexcept;
constexpr T_Flags< E_FSPathSeparator > pathSeparators( ) const noexcept;
constexpr T_FSPathStyle& pathSeparator( T_Flags< E_FSPathSeparator > ps ) noexcept;
//----------------------------------------------------------------------
// Checks
constexpr bool isSeparator( T_Character chr ) const noexcept;
bool isValidRoot( T_String const& string ) const noexcept;
constexpr bool operator ==( T_FSPathStyle const& other ) const noexcept;
constexpr bool operator !=( T_FSPathStyle const& other ) const noexcept;
//----------------------------------------------------------------------
// Pre-initialised styles
static constexpr T_FSPathStyle Unix( );
static constexpr T_FSPathStyle Windows( );
static constexpr T_FSPathStyle System( );
};
M_DECLARE_SWAP( T_FSPathStyle );
// Representation of a path
class T_FSPath
{
public:
using T_Components = T_AutoArray< T_String , 16 >;
private:
// Path style
T_FSPathStyle style_;
// Root will be '/' on Unix, or a drive letter on Windows. Relative
// paths will have a blank root.
T_String root_;
T_Components components_;
// Is the path valid?
bool valid_;
// String comparison helpers
using F_StrCmp_ = int (*)( T_String const& , T_String const& );
F_StrCmp_ cmpFunction_( ) const noexcept;
public:
//----------------------------------------------------------------------
// Helpers
static bool IsValidComponent( T_String const& string ) noexcept;
//----------------------------------------------------------------------
// Basic constructors and assignment operators
T_FSPath( T_FSPathStyle style = T_FSPathStyle::System( ) ) 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 ,
T_FSPathStyle style = T_FSPathStyle::System( ) ) noexcept;
//----------------------------------------------------------------------
bool isValid( ) const noexcept;
T_FSPathStyle const& style( ) 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( T_OptPathSeparator separator = {} ) const noexcept;
// Compute a hash value for the path
uint32_t computeHash( ) const noexcept;
// Append to a string builder
void appendTo( T_StringBuilder& sb ,
T_OptPathSeparator separator = {} ) 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 ===============================================================*/
// Type of entries
enum class E_FSEntryType {
NONE , // Filesystem entry does not exist
FILE , // Filesystem entry refers to a file
DIRECTORY , // Filesystem entry refers to a directory
OTHER // Filesystem entry exists but refers to something else
// entirely (e.g. symlinks) and is therefore off-limits
};
class Filesystem final
{
Filesystem( ) = delete;
public:
// Return the absolute path to the current working directory
static T_FSPath Cwd( ) noexcept;
// Get the type of an entry
static E_FSEntryType TypeOf( T_FSPath const& path ) noexcept;
// List a directory's contents
static bool List( T_FSPath const& path ,
T_Array< T_String >& output ) noexcept;
// Create a new directory
static bool MkDir( T_FSPath const& path ) noexcept;
// Create a new directory, including parent directories if
// they do not exist
static bool MkDirFull( T_FSPath const& path ) noexcept;
// Delete a directory
static bool RmDir( T_FSPath const& path ) noexcept;
// Delete a file
static bool Rm( T_FSPath const& path ) noexcept;
// Move or rename a file
static bool Move( T_FSPath const& from ,
T_FSPath const& to ) noexcept;
};
} // namespace ebcl
#endif // _H_EBCL_FILESYSTEM
#include <ebcl/inline/Filesystem.hh>