| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- #pragma once
- #include "Defines.h"
- namespace gameplay
- {
- class Path;
- inline Path operator/(const Path& left, const Path& right);
- inline Path operator+(const Path& left, const Path& right);
- /**
- * Paths are used for file system path manipulations.
- *
- * Paths are all in utf-8 encoding using forward slash as path separator.
- * Paths support implicit casting 'std::string'
- * Paths support explicit cast to a 'const char*' pointer.
- */
- class GP_API Path
- {
- public:
- static constexpr const char* EMPTY_STRING = "";
- static constexpr char DOT_CHAR = '.';
- static constexpr const char* DOT_STRING = ".";
- static constexpr size_t DOT_STRING_LENGTH = 1;
- static constexpr const char* DOTDOT_STRING = "..";
- static constexpr size_t DOTDOT_STRING_LENGTH = 2;
- static constexpr char BACKWARD_SLASH_CHAR = '\\';
- static constexpr char FORWARD_SLASH_CHAR = '/';
- static constexpr const char* FORWARD_SLASH_STRING = "/";
- static constexpr size_t FORWARD_SLASH_STRING_LENGTH = 1;
- static constexpr char COLON_CHAR = ':';
- static constexpr char FIRST_LOWERCASE_LETTER = 'a';
- static constexpr char LAST_LOWERCASE_LETTER = 'z';
- /**
- * Constructor
- */
- Path();
- /**
- * Constructor.
- *
- * Creates a path from a possible non zero-terminated char array containing utf8 string.
- *
- * @param path A pointer to the data
- * @param pathLen the size of the data to be used to create the path object
- */
- Path(const char* path, size_t pathLen);
- /**
- * Constructor.
- *
- * Creates a path from a zero-terminated char array containing utf8 string.
- *
- * @param path A pointer to the char array
- */
- Path(const char* path);
- /**
- *
- * Constructor.
- *
- * Creates a new path from a utf8 std string
- *
- * @param path The source string
- */
- Path(std::string path);
- /**
- * Constructor (Copy).
- */
- Path(const Path& other);
- /**
- * Constructor (Copy).
- */
- Path(Path&& other) noexcept;
- /*
- * Destructor
- */
- ~Path();
- /**
- * Copy operator.
- */
- Path& operator=(const Path& other);
- /**
- * Copy operator.
- */
- Path& operator=(Path&& other) noexcept;
- /**
- * Gets the std string representation of the path
- *
- * @return The std::string representation
- */
- std::string get_string() const;
- /**
- * Implicit conversion operator to the std string
- *
- * @return The std::string representation
- */
- operator std::string() const;
- /**
- * Get the const char pointer to the path data
- *
- * @return The c_str pointer to the start of the path data
- */
- const char* c_str() const;
- /**
- * Explicit conversion operator to the pointer to const char
- *
- * @return The c_str pointer to the start of the path data
- */
- explicit operator const char*() const
- {
- return c_str();
- }
- /**
- * operator==
- */
- bool operator==(const Path& other) const;
- /**
- * operator==
- */
- bool operator==(const std::string& other) const;
- /**
- * operator==
- */
- bool operator==(const char* other) const;
- /**
- * operator!=
- */
- bool operator!=(const Path& other) const;
- /**
- * operator!=
- */
- bool operator!=(const std::string& other) const;
- /**
- * operator!=
- */
- bool operator!=(const char* other) const;
- /**
- * Gets the length of the path.
- *
- * @return The length of the path
- */
- size_t len() const;
- /**
- * Clears the current path
- *
- * @return Reference to the current path
- */
- Path& clear();
- /**
- * Checks if the path is an empty string
- *
- * @return true if the path contains at least one character, false otherwise
- */
- bool is_empty() const;
- /**
- * Gets the filename component of the path, or an empty path object if there is no filename.
- *
- * @return The path object representing the filename
- */
- Path get_filename() const;
- /**
- * Gets the extension of the filename component of the path, including period (.), or an empty path object.
- *
- * @return The path object representing the extension
- */
- Path get_extension() const;
- /**
- * Gets the path to the parent directory, or an empty path object if there is no parent.
- *
- * @return The path object representing the parent directory
- */
- Path get_parent() const;
- /**
- * Gets the filename component of the path stripped of the extension,
- * or an empty path object if there is no filename.
- *
- * @return The path object representing the stem
- */
- Path get_stem() const;
- /**
- * Gets the root name in the path.
- *
- * @return The path object representing the root name
- */
- Path get_root_name() const;
- /**
- * Gets the relative part of the path (the part after optional root name and root directory).
- *
- * @return The path objects representing the relative part of the path
- */
- Path get_relative_part() const;
- /**
- * Gets the root directory if it's present in the path
- *
- * @return The path object representing the root directory
- */
- Path get_root_directory() const;
- /**
- * Checks if the path has a root directory
- *
- * @return true if the path has a root directory, false if otherwise.
- */
- bool has_root_directory() const noexcept;
- /**
- * Gets the root of the path. (root name + root directory, if present)
- *
- * @return The path object representing the root of the path
- */
- Path get_root() const;
- /**
- * Concatenates together two paths without checking for a separator and adding it
- *
- * @return The path object that has the unified data from the both paths
- */
- Path concat(const Path& concatedPart) const;
- /**
- * operator+=
- */
- Path& operator+=(const Path& path);
- /**
- * Joins together two path with checking for a separator and adding it if needed
- *
- * @ return The path object that has the unified data from the both paths
- */
- Path join(const Path& joinedPart) const;
- /**
- * operator/=
- */
- Path& operator/=(const Path& path);
- /**
- * Replaces the extension part of the current path with a new one.
- *
- * @param newExtension The path containing the data for the new extension
- * @return The current path with the extension changed.
- */
- Path& replace_extension(const Path& newExtension);
- /**
- * Gets the absolute path as normalizing the addition of the current path to the root.
- *
- * @return The path representing the constructed absolute path
- */
- Path get_absolute(const Path& root = "") const;
- /**
- * Checks if the current path is an absolute path.
- *
- * @return True if the current path is an absolute path, false otherwise.
- */
- bool is_absolute() const;
- /**
- * Gets the result of the normalization of the current path
- *
- * @return The new path representing the normalized current path
- */
- Path get_normalized() const;
- /**
- * Normalizes current path in place
- *
- * @return The reference to the current object
- */
- Path& normalize();
- /**
- * Gets the current path made relative to base.
- *
- * The function does NOT normalize the paths prior to the operation.
- *
- * @param base The base path.
- * @return An empty path if it's impossible to match roots (different root names, different states of being
- * relative/absolute with a base path, not having a root directory while the base has it), otherwise a non-empty
- * relative path
- */
- Path get_relative(const Path& base) const noexcept;
- /**
- * Checks if the current path is the relative path.
- *
- * @return true if the current path is a relative path, false otherwise.
- */
- bool is_relative() const;
- #if GP_PLATFORM_WINDOWS
- /**
- * Converts a utf-8 file path to Windows system file path.
- * Slashes are replaced with backslashes, long path prefix is appended if required.
- * @param path Input string to convert, in utf-8 encoding.
- * @return The wide string containing Windows system file path or empty string if conversion cannot be performed.
- */
- static std::wstring convert_utf8_to_windows_path(const std::string& path);
- /**
- * Converts Windows system file path to a utf-8 file path.
- * Backslashes are replaced with slashes, long path prefix is removed.
- *
- * @param path The input string to convert, in unicode (Windows native) encoding.
- * @return The utf-8 encoded file path or empty string if conversion cannot be performed.
- */
- static std::string convert_windows_to_utf8_path(const std::wstring& path);
- /**
- * Gets a Windows path string into a canonical form.
- * If it's not possible, original path is returned.
- *
- * @param path The windows system file path, in Unicode (Windows native) encoding.
- * @return The canonical form of the input path.
- */
- static std::wstring get_windows_canonical_path(const std::wstring& path);
- /**
- * Gets the full path and file name of the specified file.
- * If it's not possible, original path is returned.
- *
- * @param path The Windows system file path, in Unicode (Windows native) encoding.
- * @return The full path and file name of the input file.
- */
- static std::wstring get_windows_full_path(const std::wstring& path);
- /**
- * Fixes the windows path prefixes.
- *
- * @param str The windows system fix to be fixed.
- */
- static std::wstring fix_windows_path_prefixes(const std::wstring& str);
- #endif
- private:
- enum class PathTokenType
- {
- SLASH,
- ROOT_NAME,
- DOT,
- DOTDOT,
- NAME
- };
- static const char* _get_token_end(const char* bufferBegin, const char* bufferEnd, PathTokenType& resultType);
- struct PathPartDesc
- {
- const char* data;
- size_t size;
- };
- static Path _concat(const PathPartDesc* pathParts, size_t numParts);
- template <class Pred = std::equal_to<char>>
- static const char* _find_from_end(const char* data, size_t dataSize, char ch)
- {
- if (!data || dataSize == 0)
- {
- return nullptr;
- }
- --data;
- Pred pred;
- while (dataSize > 0)
- {
- if (pred(data[dataSize], ch))
- {
- return data + dataSize;
- }
- --dataSize;
- }
- return nullptr;
- }
- template <class Pred = std::equal_to<char>>
- static const char* _find_from_start(const char* data, size_t dataSize, char ch)
- {
- if (!data || dataSize == 0)
- {
- return nullptr;
- }
- Pred pred;
- for (const char* const dataEnd = data + dataSize; data != dataEnd; ++data)
- {
- if (pred(*data, ch))
- {
- return data;
- }
- }
- return nullptr;
- }
- const char* _get_filename_ptr() const;
- const char* _get_extension_ptr() const;
- const char* _get_root_name_end_ptr() const;
- const char* _get_relative_part_ptr() const;
- const char* _get_root_directory_end_ptr() const;
- void _sanitize_path();
- std::string _pathStr;
- };
- inline Path operator+(const Path& left, const Path& right)
- {
- return left.concat(right);
- }
- inline Path operator/(const Path& left, const Path& right)
- {
- return left.join(right);
- }
- inline Path get_parent_path(std::string path)
- {
- return Path(std::move(path)).get_parent();
- }
- inline Path get_path_extension(std::string path)
- {
- return Path(std::move(path)).get_extension();
- }
- inline Path get_path_stem(std::string path)
- {
- return Path(std::move(path)).get_stem();
- }
- inline Path get_path_relative(std::string path, std::string base)
- {
- return Path(std::move(path)).get_relative(std::move(base));
- }
- inline bool operator==(const std::string& left, const Path& right)
- {
- return right == left;
- }
- inline bool operator==(const char* left, const Path& right)
- {
- return right == left;
- }
- inline bool operator!=(const std::string& left, const Path& right)
- {
- return right != left;
- }
- inline bool operator!=(const char* left, const Path& right)
- {
- return right != left;
- }
- }
|