Traits.hxx 6.89 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
	typedef StringPointer<value_type> Pointer;
55 56
	typedef Pointer::pointer_type pointer_type;
	typedef Pointer::const_pointer_type const_pointer_type;
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_type 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
	gcc_pure gcc_nonnull_all
75
	static const_pointer_type FindLastSeparator(const_pointer_type 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
#ifdef WIN32
82
		const_pointer_type pos = p + GetLength(p);
83 84 85 86
		while (p != pos && !IsSeparator(*pos))
			--pos;
		return IsSeparator(*pos) ? pos : nullptr;
#else
87
		return StringFindLast(p, SEPARATOR);
88 89 90
#endif
	}

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

98
	gcc_pure gcc_nonnull_all
99
	static bool IsAbsolute(const_pointer_type 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_type p) {
114
		return StringLength(p);
Max Kellermann's avatar
Max Kellermann committed
115 116 117
	}

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

122 123 124 125 126
	/**
	 * Determine the "base" file name of the given native path.
	 * The return value points inside the given string.
	 */
	gcc_pure gcc_nonnull_all
127
	static const_pointer_type GetBase(const_pointer_type p);
128 129 130 131 132 133 134

	/**
	 * 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
135
	static string GetParent(const_pointer_type p);
136

137 138 139 140 141 142 143
	/**
	 * 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
144 145
	static const_pointer_type Relative(const_pointer_type base,
					   const_pointer_type other);
146

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

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

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

173 174
	static constexpr value_type SEPARATOR = '/';

175
	static constexpr const_pointer_type CURRENT_DIRECTORY = ".";
176

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

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

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

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

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

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

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

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

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

	/**
	 * 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
235
	static string GetParent(const_pointer_type p);
236

237 238 239 240 241 242 243
	/**
	 * 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
244 245
	static const_pointer_type Relative(const_pointer_type base,
					   const_pointer_type other);
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
254 255
	static string Build(const_pointer_type a, size_t a_size,
			    const_pointer_type b, size_t b_size);
256 257

	gcc_pure gcc_nonnull_all
258
	static string Build(const_pointer_type a, const_pointer_type b) {
259 260
		return Build(a, GetLength(a), b, GetLength(b));
	}
261 262 263
};

#endif