Traits.hxx 6.66 KB
Newer Older
1
/*
2
 * Copyright 2003-2016 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef MPD_FS_TRAITS_HXX
#define MPD_FS_TRAITS_HXX

#include "check.h"
#include "Compiler.h"
25
#include "util/StringPointer.hxx"
26
#include "util/StringAPI.hxx"
27 28

#ifdef WIN32
29
#include "util/CharUtil.hxx"
30
#include <tchar.h>
31 32
#endif

Max Kellermann's avatar
Max Kellermann committed
33 34
#include <string>

35 36
#include <assert.h>

37 38 39
#ifdef WIN32
#define PATH_LITERAL(s) _T(s)
#else
40
#define PATH_LITERAL(s) (s)
41
#endif
42

43
/**
44
 * This class describes the nature of a native filesystem path.
45
 */
46
struct PathTraitsFS {
47 48 49
#ifdef WIN32
	typedef std::wstring string;
#else
50
	typedef std::string string;
51
#endif
52 53
	typedef string::traits_type char_traits;
	typedef char_traits::char_type value_type;
54 55 56
	typedef StringPointer<value_type> Pointer;
	typedef Pointer::pointer pointer;
	typedef Pointer::const_pointer const_pointer;
57 58

#ifdef WIN32
59
	static constexpr value_type SEPARATOR = '\\';
60
#else
61
	static constexpr value_type SEPARATOR = '/';
62 63
#endif

64
	static constexpr const_pointer CURRENT_DIRECTORY = PATH_LITERAL(".");
65

66
	static constexpr bool IsSeparator(value_type ch) {
67 68 69 70
		return
#ifdef WIN32
			ch == '/' ||
#endif
71
			ch == SEPARATOR;
72 73
	}

74 75
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
76 77
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
78
		assert(p != nullptr);
79 80
#endif

81 82 83 84 85 86
#ifdef WIN32
		const_pointer pos = p + GetLength(p);
		while (p != pos && !IsSeparator(*pos))
			--pos;
		return IsSeparator(*pos) ? pos : nullptr;
#else
87
		return StringFindLast(p, SEPARATOR);
88 89 90
#endif
	}

91 92 93 94 95 96 97
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

98
	gcc_pure gcc_nonnull_all
99
	static bool IsAbsolute(const_pointer p) {
100 101
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
102
		assert(p != nullptr);
103 104
#endif

105
#ifdef WIN32
106
		if (IsDrive(p) && IsSeparator(p[2]))
107
			return true;
108
#endif
109
		return IsSeparator(*p);
110
	}
Max Kellermann's avatar
Max Kellermann committed
111

112
	gcc_pure gcc_nonnull_all
113
	static size_t GetLength(const_pointer p) {
114
		return StringLength(p);
Max Kellermann's avatar
Max Kellermann committed
115 116 117 118
	}

	gcc_pure gcc_nonnull_all
	static const_pointer Find(const_pointer p, value_type ch) {
119
		return StringFind(p, ch);
Max Kellermann's avatar
Max Kellermann committed
120 121
	}

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
	/**
	 * 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);

137 138 139 140 141 142 143 144 145
	/**
	 * 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);

146 147 148 149 150 151 152
	/**
	 * 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
153 154
	static string Build(const_pointer a, size_t a_size,
			    const_pointer b, size_t b_size);
155 156 157 158 159

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
160 161 162 163 164 165
};

/**
 * This class describes the nature of a MPD internal filesystem path.
 */
struct PathTraitsUTF8 {
166
	typedef std::string string;
167 168
	typedef string::traits_type char_traits;
	typedef char_traits::char_type value_type;
169 170
	typedef value_type *pointer;
	typedef const value_type *const_pointer;
171

172 173
	static constexpr value_type SEPARATOR = '/';

174 175
	static constexpr const_pointer CURRENT_DIRECTORY = ".";

176
	static constexpr bool IsSeparator(value_type ch) {
177 178 179
		return ch == SEPARATOR;
	}

180 181
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
182 183
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
184
		assert(p != nullptr);
185 186
#endif

187 188 189
		return strrchr(p, SEPARATOR);
	}

190 191 192 193 194 195 196
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

197
	gcc_pure gcc_nonnull_all
198
	static bool IsAbsolute(const_pointer p) {
199 200
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
201
		assert(p != nullptr);
202 203
#endif

204
#ifdef WIN32
205
		if (IsDrive(p) && IsSeparator(p[2]))
206 207 208 209
			return true;
#endif
		return IsSeparator(*p);
	}
210

211 212
	gcc_pure gcc_nonnull_all
	static size_t GetLength(const_pointer p) {
213
		return StringLength(p);
Max Kellermann's avatar
Max Kellermann committed
214 215 216 217
	}

	gcc_pure gcc_nonnull_all
	static const_pointer Find(const_pointer p, value_type ch) {
218
		return StringFind(p, ch);
Max Kellermann's avatar
Max Kellermann committed
219 220
	}

Max Kellermann's avatar
Max Kellermann committed
221 222 223 224 225
	/**
	 * Determine the "base" file name of the given UTF-8 path.
	 * The return value points inside the given string.
	 */
	gcc_pure gcc_nonnull_all
226
	static const_pointer GetBase(const_pointer p);
Max Kellermann's avatar
Max Kellermann committed
227 228 229 230 231 232 233

	/**
	 * Determine the "parent" file name of the given UTF-8 path.
	 * As a special case, returns the string "." if there is no
	 * separator in the given input string.
	 */
	gcc_pure gcc_nonnull_all
234
	static string GetParent(const_pointer p);
235

236 237 238 239 240 241 242 243 244
	/**
	 * 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);

245 246 247 248 249 250 251 252 253
	/**
	 * 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);
254 255 256 257 258

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
259 260 261
};

#endif