aboutsummaryrefslogtreecommitdiffstats
path: root/src/fs/Traits.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/Traits.hxx')
-rw-r--r--src/fs/Traits.hxx168
1 files changed, 139 insertions, 29 deletions
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx
index 244ab8b5c..88715c3e8 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;
#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 char *pointer;
+ typedef const char *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