#ifndef _LIBRARY_SYSPATH_HPP_ #define _LIBRARY_SYSPATH_HPP_ // ------------------------------------------------------------------------------------------------ #include "Base/Shared.hpp" // ------------------------------------------------------------------------------------------------ #include // ------------------------------------------------------------------------------------------------ namespace SqMod { /* ------------------------------------------------------------------------------------------------ * This class represents filesystem paths in a platform-independent manner. */ class SysPath { public: // -------------------------------------------------------------------------------------------- typedef std::vector< String > StrVec; // Directory list. /* -------------------------------------------------------------------------------------------- * Styles of directories to expect when parsing or to export. */ enum struct Style { Unix = 0, Windows, Native, Guess, Dynamic }; /* -------------------------------------------------------------------------------------------- * Creates an empty relative path. */ SysPath(); /* -------------------------------------------------------------------------------------------- * Creates an empty absolute or relative path. */ SysPath(bool absolute); /* -------------------------------------------------------------------------------------------- * Creates a path in native format from a string. */ SysPath(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path from a string. */ SysPath(CSStr path, Int32 style); /* -------------------------------------------------------------------------------------------- * Creates a path from a string. */ SysPath(CSStr path, Style style); /* -------------------------------------------------------------------------------------------- * Creates a path in native format from a string. */ SysPath(const Buffer & path, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Creates a path from a string. */ SysPath(const Buffer & path, Style style, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Creates a path in native format from a string. */ SysPath(const String & path); /* -------------------------------------------------------------------------------------------- * Creates a path from a string. */ SysPath(const String & path, Style style); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a file name. The parent path is expected to reference * a directory. */ SysPath(const SysPath & parent, CSStr name); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a file name. The parent path is expected to reference * a directory. */ SysPath(const SysPath & parent, const String & name); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a relative path. The parent path is expected * to reference a directory. The relative path is appended to the parent path. */ SysPath(const SysPath & parent, const SysPath & relative); /* -------------------------------------------------------------------------------------------- * Copy constructor. */ SysPath(const SysPath & o); /* -------------------------------------------------------------------------------------------- * Move constructor. */ SysPath(SysPath && o); /* -------------------------------------------------------------------------------------------- * Destructor. */ ~SysPath(); /* -------------------------------------------------------------------------------------------- * Copy assignment operator. */ SysPath & operator = (const SysPath & o); /* -------------------------------------------------------------------------------------------- * Move assignment operator. */ SysPath & operator = (SysPath && o); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path in native format. */ SysPath & operator = (CSStr path); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path in native format. */ SysPath & operator = (const String & path); /* -------------------------------------------------------------------------------------------- * Equality comparison. */ bool operator == (const SysPath & o) const; /* -------------------------------------------------------------------------------------------- * Inequality comparison. */ bool operator != (const SysPath & o) const; /* -------------------------------------------------------------------------------------------- * Implicit conversion to boolean operator. */ operator bool () const; /* -------------------------------------------------------------------------------------------- * Returns the n'th directory in the directory list. If n == depth(), returns the file name. */ const String & operator [] (Uint32 n) const; /* -------------------------------------------------------------------------------------------- * Used by the script engine to compare two instances of this type. */ Int32 Cmp(const SysPath & o) const; /* -------------------------------------------------------------------------------------------- * Used by the script engine to convert an instance of this type to a string. */ Object ToString() const; /* -------------------------------------------------------------------------------------------- * Used by the script engine to retrieve the name from instances of this type. */ static SQInteger Typename(HSQUIRRELVM vm); /* -------------------------------------------------------------------------------------------- * Swaps the path with another one. */ void Swap(SysPath & path); /* -------------------------------------------------------------------------------------------- * Clears all components. */ void Clear(); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path in native format. */ SysPath & Assign(CSStr path); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path. */ SysPath & Assign(CSStr path, Int32 style); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path. */ SysPath & Assign(CSStr path, Style style); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path in native format. */ SysPath & Assign(const Buffer & path, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path. */ SysPath & Assign(const Buffer & path, Style style, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path in native format. */ SysPath & Assign(const String & path); /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path. */ SysPath & Assign(const String & path, Style style); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a file name. The parent path is expected to reference * a directory. */ SysPath & Assign(const SysPath & parent, CSStr name); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a file name. The parent path is expected to reference * a directory. */ SysPath & Assign(const SysPath & parent, const String & name); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a relative path. The parent path is expected * to reference a directory. The relative path is appended to the parent path. */ SysPath & Assign(const SysPath & parent, const SysPath & relative); /* -------------------------------------------------------------------------------------------- * Copy the components from another path. */ SysPath & Assign(const SysPath & path); /* -------------------------------------------------------------------------------------------- * Move the components of another path into this instance. */ SysPath & Assign(SysPath && path); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(CSStr path); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(CSStr path, Int32 style); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(CSStr path, Style style); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(const Buffer & path, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(const Buffer & path, Style style, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(const String & path); /* -------------------------------------------------------------------------------------------- * The resulting path always refers to a directory and the filename part is empty. */ SysPath & AssignDir(const String & path, Style style); /* -------------------------------------------------------------------------------------------- * Returns a string containing the path in native format. */ Buffer ToBuffer() const; /* -------------------------------------------------------------------------------------------- * Returns a string containing the path in the given format. */ Buffer ToBuffer(Style style) const; /* -------------------------------------------------------------------------------------------- * Returns a string containing the path in the given format. */ Object ToStr(Int32 style) const; /* -------------------------------------------------------------------------------------------- * Assigns a string containing a path. */ void FromString(CSStr path); /* -------------------------------------------------------------------------------------------- * See whether the path is absolute. */ bool IsAbsolute() const { return m_Absolute; } /* -------------------------------------------------------------------------------------------- * See whether the path is relative. */ bool IsRelative() const { return !m_Absolute; } /* -------------------------------------------------------------------------------------------- * See whether the path references a directory. */ bool IsDirectory() const { return m_Name.empty(); } /* -------------------------------------------------------------------------------------------- * See whether the path references a file. */ bool IsFile() const { return !m_Name.empty(); } /* -------------------------------------------------------------------------------------------- * See whether the path Does not contain a drive, directories or file name. */ bool Empty() const { return (m_Dirs.empty() && m_Name.empty() && m_Drive == 0); } /* -------------------------------------------------------------------------------------------- * If the path contains a file name, the file name is appended to the directory list and cleared. */ SysPath & MakeDirectory(); /* -------------------------------------------------------------------------------------------- * If the path contains no file name, the last directory becomes the file name. */ SysPath & MakeFile(); /* -------------------------------------------------------------------------------------------- * Makes the path refer to its parent. */ SysPath & MakeParent(); /* -------------------------------------------------------------------------------------------- * Makes the path absolute if it is relative. The current working directory is taken * as base directory. */ SysPath & MakeAbsolute(); /* -------------------------------------------------------------------------------------------- * Makes the path absolute if it is relative. The given path is taken as base. */ SysPath & MakeAbsolute(const SysPath & base); /* -------------------------------------------------------------------------------------------- * Makes the path absolute if it is relative. The given path is taken as base. */ SysPath & MakeAbsolute(SysPath && base); /* -------------------------------------------------------------------------------------------- * Appends the given path. */ SysPath & Append(const SysPath & path); /* -------------------------------------------------------------------------------------------- * Appends the given path. */ SysPath & Append(SysPath && path); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(CSStr path); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(CSStr path, Int32 style); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(CSStr path, Style style); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(const Buffer & path, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(const Buffer & path, Style style, Int32 size = -1); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(const String & path); /* -------------------------------------------------------------------------------------------- * Parse the given string and append the resulted path. */ SysPath & Append(const String & path, Style style); /* -------------------------------------------------------------------------------------------- * Returns the drive letter. */ CharT GetDrive() const { return m_Drive; } /* -------------------------------------------------------------------------------------------- * Modifies the drive letter. */ void SetDrive(CharT drive) { m_Drive = drive; } /* -------------------------------------------------------------------------------------------- * Returns the number of directories in the directory list. */ Uint32 Depth() const { return m_Dirs.size(); } /* -------------------------------------------------------------------------------------------- * Returns the n'th directory in the directory list. If n == depth(), returns the file name. */ const String & Directory(Uint32 n) const; /* -------------------------------------------------------------------------------------------- * Adds a directory to the directory list. */ SysPath & Push(CSStr dir); /* -------------------------------------------------------------------------------------------- * Adds a directory to the directory list. */ SysPath & Push(const String & dir); /* -------------------------------------------------------------------------------------------- * Adds a directory to the directory list. */ SysPath & Push(String && dir); /* -------------------------------------------------------------------------------------------- * Removes the last directory from the directory list. */ SysPath & PopBack(); /* -------------------------------------------------------------------------------------------- * Removes the first directory from the directory list. */ SysPath & PopFront(); /* -------------------------------------------------------------------------------------------- * Set the specified file name. */ SysPath & SetFilename(CSStr name); /* -------------------------------------------------------------------------------------------- * Set the specified file name. */ SysPath & SetFilename(const String & name); /* -------------------------------------------------------------------------------------------- * Set the specified file name. */ SysPath & SetFilename(String && name); /* -------------------------------------------------------------------------------------------- * Retrieves the file name. */ const String & GetFilename() const { return m_Name; } /* -------------------------------------------------------------------------------------------- * Set the specified file name. */ void SqSetFilename(CSStr name) { SetFilename(name); } /* -------------------------------------------------------------------------------------------- * Sets the basename part of the file name and does not change the extension. */ SysPath & SetBasename(CSStr name); /* -------------------------------------------------------------------------------------------- * Sets the basename part of the file name and does not change the extension. */ SysPath & SetBasename(const String & name); /* -------------------------------------------------------------------------------------------- * Sets the basename part of the file name and does not change the extension. */ SysPath & SetBasename(String && name); /* -------------------------------------------------------------------------------------------- * Returns the basename (the file name without extension) of the path. */ String GetBasename() const; /* -------------------------------------------------------------------------------------------- * Sets the basename part of the file name and does not change the extension. */ void SqSetBasename(CSStr name) { SetBasename(name); } /* -------------------------------------------------------------------------------------------- * Sets the file name extension. */ SysPath & SetExtension(CSStr ext); /* -------------------------------------------------------------------------------------------- * Sets the file name extension. */ SysPath & SetExtension(const String & ext); /* -------------------------------------------------------------------------------------------- * Returns the file name extension. */ String GetExtension() const; /* -------------------------------------------------------------------------------------------- * Sets the file name extension. */ void SqSetExtension(CSStr ext) { SetExtension(ext); } /* -------------------------------------------------------------------------------------------- * Returns a pointer to the internal name string where the extension starts. */ CSStr GetExtensionC() const; /* -------------------------------------------------------------------------------------------- * Returns a path referring to the path's directory. */ SysPath Parent() const; /* -------------------------------------------------------------------------------------------- * Resolves the given path against the current one. If the given path is absolute, it replaces * the current one. Otherwise, the relative path is appended to the current path. */ SysPath & Resolve(const SysPath & path); protected: /* -------------------------------------------------------------------------------------------- * Parse a path using the unix standards. */ void ParseUnix(CSStr pos, CSStr end); /* -------------------------------------------------------------------------------------------- * Parse a path using the windows standards. */ void ParseWindows(CSStr pos, CSStr end); /* -------------------------------------------------------------------------------------------- * Parse a path and expect combined windows and unix styles. */ void ParseDynamic(CSStr pos, CSStr end); /* -------------------------------------------------------------------------------------------- * Parse a path and try to detect it's type automatically. */ void ParseGuess(CSStr pos, CSStr end); /* -------------------------------------------------------------------------------------------- * Build a path string using the Unix conventions. */ Buffer BuildUnix() const; /* -------------------------------------------------------------------------------------------- * Build a path string using the Windows conventions. */ Buffer BuildWindows() const; private: // -------------------------------------------------------------------------------------------- StrVec m_Dirs; /* The list of directories that form the path. */ String m_Name; /* The file name if one was specified. */ CharT m_Drive; /* The drive letter if one was specified. */ bool m_Absolute; /* Whether this path is an absolute path. */ public: /* -------------------------------------------------------------------------------------------- * Returns the platform's path name separator, which separates the components (names) in a path. */ static CharT Separator() { #ifdef GMOD_OS_WINDOWS return '\\'; #else return '/'; #endif // GMOD_OS_WINDOWS } /* -------------------------------------------------------------------------------------------- * Returns the platform's path separator, which separates single paths in a list of paths. */ static CharT PathSeparator() { #ifdef GMOD_OS_WINDOWS return ';'; #else return ':'; #endif // GMOD_OS_WINDOWS } /* -------------------------------------------------------------------------------------------- * Creates a path referring to a directory. */ static SysPath ForDirectory(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path referring to a directory. */ static SysPath ForDirectory(CSStr path, Int32 style); /* -------------------------------------------------------------------------------------------- * Creates a path referring to a directory. */ static SysPath ForDirectory(CSStr path, Style style); /* -------------------------------------------------------------------------------------------- * Creates a path referring to a directory. */ static SysPath ForDirectory(const String & path); /* -------------------------------------------------------------------------------------------- * Creates a path referring to a directory. */ static SysPath ForDirectory(const String & path, Style style); /* -------------------------------------------------------------------------------------------- * Expands all environment variables contained in the path. On Unix, a tilde as first character * in the path is replaced with the path to user's home directory. */ static SysPath Expand(CSStr path); /* -------------------------------------------------------------------------------------------- * Expands all environment variables contained in the path. */ static SysPath Expand(const String & path) { return Expand(path.c_str()); } /* -------------------------------------------------------------------------------------------- * Returns the user's home directory. */ static SysPath Home(); /* -------------------------------------------------------------------------------------------- * Returns the user's config directory. */ static SysPath ConfigHome(); /* -------------------------------------------------------------------------------------------- * Returns the user's data directory. */ static SysPath DataHome(); /* -------------------------------------------------------------------------------------------- * Returns the user's temp directory. */ static SysPath TempHome(); /* -------------------------------------------------------------------------------------------- * Returns the user's temp directory. */ static SysPath CacheHome(); /* -------------------------------------------------------------------------------------------- * Returns the current working directory. */ static SysPath Working(); /* -------------------------------------------------------------------------------------------- * Returns the temporary directory. */ static SysPath Temp(); /* -------------------------------------------------------------------------------------------- * Returns the systemwide config directory. */ static SysPath Config(); /* -------------------------------------------------------------------------------------------- * Returns the system directory. */ static SysPath System(); /* -------------------------------------------------------------------------------------------- * Returns the name of the null device. */ static SysPath Null(); /* -------------------------------------------------------------------------------------------- * Creates a path from a parent path and a file name. The parent path is expected to reference * a directory. */ static SysPath With(const SysPath & parent, CSStr name); /* -------------------------------------------------------------------------------------------- * Creates a path in unix format from a string. */ static SysPath MakeUnix(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path in windows format from a string. */ static SysPath MakeWindows(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path in native format from a string. */ static SysPath MakeNative(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path in and guess the format from a string. */ static SysPath MakeGuess(CSStr path); /* -------------------------------------------------------------------------------------------- * Creates a path in dynamic format from a string. */ static SysPath MakeDynamic(CSStr path); }; } // Namespace:: SqMod #endif // _LIBRARY_SYSPATH_HPP_