diff options
Diffstat (limited to '')
-rw-r--r-- | src/fs/Traits.hxx | 172 |
1 files changed, 141 insertions, 31 deletions
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx index 244ab8b5c..77317e1ee 100644 --- a/src/fs/Traits.hxx +++ b/src/fs/Traits.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,67 +24,153 @@ #include "Compiler.h" #ifdef WIN32 -#include <glib.h> +#include "util/CharUtil.hxx" #endif #include <string> +#include <string.h> #include <assert.h> -class Error; - /** - * This class describes the nature of a filesystem path. + * This class describes the nature of a native filesystem path. */ -struct PathTraits { +struct PathTraitsFS { + typedef std::string string; typedef char value_type; - typedef char *pointer; - typedef const char *const_pointer; + typedef value_type *pointer; + typedef const value_type *const_pointer; #ifdef WIN32 - static constexpr value_type SEPARATOR_FS = '\\'; - static constexpr char SEPARATOR_UTF8 = '/'; + static constexpr value_type SEPARATOR = '\\'; #else - static constexpr value_type SEPARATOR_FS = '/'; - static constexpr char SEPARATOR_UTF8 = '/'; + static constexpr value_type SEPARATOR = '/'; #endif - static constexpr bool IsSeparatorFS(value_type ch) { + static constexpr bool IsSeparator(value_type ch) { return #ifdef WIN32 ch == '/' || #endif - ch == SEPARATOR_FS; + ch == SEPARATOR; } - static constexpr bool IsSeparatorUTF8(char ch) { - return + gcc_pure gcc_nonnull_all + static const_pointer FindLastSeparator(const_pointer p) { + assert(p != nullptr); #ifdef WIN32 - ch == '/' || + const_pointer pos = p + GetLength(p); + while (p != pos && !IsSeparator(*pos)) + --pos; + return IsSeparator(*pos) ? pos : nullptr; +#else + return strrchr(p, SEPARATOR); #endif - ch == SEPARATOR_UTF8; } - gcc_pure - static bool IsAbsoluteFS(const_pointer p) { - assert(p != nullptr); +#ifdef WIN32 + gcc_pure gcc_nonnull_all + static constexpr bool IsDrive(const_pointer p) { + return IsAlphaASCII(p[0]) && p[1] == ':'; + } +#endif + gcc_pure gcc_nonnull_all + static bool IsAbsolute(const_pointer p) { + assert(p != nullptr); #ifdef WIN32 - return g_path_is_absolute(p); -#else - return IsSeparatorFS(*p); + if (IsDrive(p) && IsSeparator(p[2])) + return true; #endif + return IsSeparator(*p); } - gcc_pure - static bool IsAbsoluteUTF8(const char *p) { + gcc_pure gcc_nonnull_all + static size_t GetLength(const_pointer p) { + return strlen(p); + } + + /** + * Determine the "base" file name of the given native path. + * The return value points inside the given string. + */ + gcc_pure gcc_nonnull_all + static const_pointer GetBase(const_pointer p); + + /** + * Determine the "parent" file name of the given native path. + * As a special case, returns the string "." if there is no + * separator in the given input string. + */ + gcc_pure gcc_nonnull_all + static string GetParent(const_pointer p); + + /** + * Determine the relative part of the given path to this + * object, not including the directory separator. Returns an + * empty string if the given path equals this object or + * nullptr on mismatch. + */ + gcc_pure gcc_nonnull_all + static const_pointer Relative(const_pointer base, const_pointer other); + + /** + * Constructs the path from the given components. + * If either of the components is empty string, + * remaining component is returned unchanged. + * If both components are empty strings, empty string is returned. + */ + gcc_pure gcc_nonnull_all + static string Build(const_pointer a, size_t a_size, + const_pointer b, size_t b_size); + + gcc_pure gcc_nonnull_all + static string Build(const_pointer a, const_pointer b) { + return Build(a, GetLength(a), b, GetLength(b)); + } +}; + +/** + * This class describes the nature of a MPD internal filesystem path. + */ +struct PathTraitsUTF8 { + typedef std::string string; + typedef char value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + + static constexpr value_type SEPARATOR = '/'; + + static constexpr bool IsSeparator(value_type ch) { + return ch == SEPARATOR; + } + + gcc_pure gcc_nonnull_all + static const_pointer FindLastSeparator(const_pointer p) { assert(p != nullptr); + return strrchr(p, SEPARATOR); + } #ifdef WIN32 - return g_path_is_absolute(p); -#else - return IsSeparatorUTF8(*p); + gcc_pure gcc_nonnull_all + static constexpr bool IsDrive(const_pointer p) { + return IsAlphaASCII(p[0]) && p[1] == ':'; + } #endif + + gcc_pure gcc_nonnull_all + static bool IsAbsolute(const_pointer p) { + assert(p != nullptr); +#ifdef WIN32 + if (IsDrive(p) && IsSeparator(p[2])) + return true; +#endif + return IsSeparator(*p); + } + + gcc_pure gcc_nonnull_all + static size_t GetLength(const_pointer p) { + return strlen(p); } /** @@ -92,7 +178,7 @@ struct PathTraits { * The return value points inside the given string. */ gcc_pure gcc_nonnull_all - static const char *GetBaseUTF8(const char *p); + static const_pointer GetBase(const_pointer p); /** * Determine the "parent" file name of the given UTF-8 path. @@ -100,7 +186,31 @@ struct PathTraits { * separator in the given input string. */ gcc_pure gcc_nonnull_all - static std::string GetParentUTF8(const char *p); + static string GetParent(const_pointer p); + + /** + * Determine the relative part of the given path to this + * object, not including the directory separator. Returns an + * empty string if the given path equals this object or + * nullptr on mismatch. + */ + gcc_pure gcc_nonnull_all + static const_pointer Relative(const_pointer base, const_pointer other); + + /** + * Constructs the path from the given components. + * If either of the components is empty string, + * remaining component is returned unchanged. + * If both components are empty strings, empty string is returned. + */ + gcc_pure gcc_nonnull_all + static string Build(const_pointer a, size_t a_size, + const_pointer b, size_t b_size); + + gcc_pure gcc_nonnull_all + static string Build(const_pointer a, const_pointer b) { + return Build(a, GetLength(a), b, GetLength(b)); + } }; #endif |