Traits.hxx 6.03 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2015 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 25 26
 * 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"

#ifdef WIN32
27
#include "util/CharUtil.hxx"
28 29
#endif

Max Kellermann's avatar
Max Kellermann committed
30 31
#include <string>

32
#include <string.h>
33 34 35
#include <assert.h>

/**
36
 * This class describes the nature of a native filesystem path.
37
 */
38
struct PathTraitsFS {
39
	typedef std::string string;
40
	typedef char value_type;
41 42
	typedef value_type *pointer;
	typedef const value_type *const_pointer;
43 44

#ifdef WIN32
45
	static constexpr value_type SEPARATOR = '\\';
46
#else
47
	static constexpr value_type SEPARATOR = '/';
48 49
#endif

50 51
	static constexpr const_pointer CURRENT_DIRECTORY = ".";

52
	static constexpr bool IsSeparator(value_type ch) {
53 54 55 56
		return
#ifdef WIN32
			ch == '/' ||
#endif
57
			ch == SEPARATOR;
58 59
	}

60 61
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
62 63
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
64
		assert(p != nullptr);
65 66
#endif

67 68 69 70 71 72 73 74 75 76
#ifdef WIN32
		const_pointer pos = p + GetLength(p);
		while (p != pos && !IsSeparator(*pos))
			--pos;
		return IsSeparator(*pos) ? pos : nullptr;
#else
		return strrchr(p, SEPARATOR);
#endif
	}

77 78 79 80 81 82 83
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

84
	gcc_pure gcc_nonnull_all
85
	static bool IsAbsolute(const_pointer p) {
86 87
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
88
		assert(p != nullptr);
89 90
#endif

91
#ifdef WIN32
92
		if (IsDrive(p) && IsSeparator(p[2]))
93
			return true;
94
#endif
95
		return IsSeparator(*p);
96
	}
Max Kellermann's avatar
Max Kellermann committed
97

98
	gcc_pure gcc_nonnull_all
99
	static size_t GetLength(const_pointer p) {
100 101 102
		return strlen(p);
	}

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	/**
	 * 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);

118 119 120 121 122 123 124 125 126
	/**
	 * 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);

127 128 129 130 131 132 133
	/**
	 * 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
134 135
	static string Build(const_pointer a, size_t a_size,
			    const_pointer b, size_t b_size);
136 137 138 139 140

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
141 142 143 144 145 146
};

/**
 * This class describes the nature of a MPD internal filesystem path.
 */
struct PathTraitsUTF8 {
147 148
	typedef std::string string;
	typedef char value_type;
149 150
	typedef value_type *pointer;
	typedef const value_type *const_pointer;
151

152 153
	static constexpr value_type SEPARATOR = '/';

154 155
	static constexpr const_pointer CURRENT_DIRECTORY = ".";

156
	static constexpr bool IsSeparator(value_type ch) {
157 158 159
		return ch == SEPARATOR;
	}

160 161
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
162 163
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
164
		assert(p != nullptr);
165 166
#endif

167 168 169
		return strrchr(p, SEPARATOR);
	}

170 171 172 173 174 175 176
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

177
	gcc_pure gcc_nonnull_all
178
	static bool IsAbsolute(const_pointer p) {
179 180
#if !CLANG_CHECK_VERSION(3,6)
		/* disabled on clang due to -Wtautological-pointer-compare */
181
		assert(p != nullptr);
182 183
#endif

184
#ifdef WIN32
185
		if (IsDrive(p) && IsSeparator(p[2]))
186 187 188 189
			return true;
#endif
		return IsSeparator(*p);
	}
190

191 192 193 194 195
	gcc_pure gcc_nonnull_all
	static size_t GetLength(const_pointer p) {
		return strlen(p);
	}

Max Kellermann's avatar
Max Kellermann committed
196 197 198 199 200
	/**
	 * Determine the "base" file name of the given UTF-8 path.
	 * The return value points inside the given string.
	 */
	gcc_pure gcc_nonnull_all
201
	static const_pointer GetBase(const_pointer p);
Max Kellermann's avatar
Max Kellermann committed
202 203 204 205 206 207 208

	/**
	 * 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
209
	static string GetParent(const_pointer p);
210

211 212 213 214 215 216 217 218 219
	/**
	 * 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);

220 221 222 223 224 225 226 227 228
	/**
	 * 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);
229 230 231 232 233

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
234 235 236
};

#endif