Traits.hxx 5.5 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 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 41 42 43 44
	typedef char value_type;
	typedef char *pointer;
	typedef const char *const_pointer;

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

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

58 59 60 61 62 63 64 65 66 67 68 69 70
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
		assert(p != nullptr);
#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
	}

71 72 73 74 75 76 77
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

78
	gcc_pure gcc_nonnull_all
79
	static bool IsAbsolute(const_pointer p) {
80 81
		assert(p != nullptr);
#ifdef WIN32
82
		if (IsDrive(p) && IsSeparator(p[2]))
83
			return true;
84
#endif
85
		return IsSeparator(*p);
86
	}
Max Kellermann's avatar
Max Kellermann committed
87

88
	gcc_pure gcc_nonnull_all
89
	static size_t GetLength(const_pointer p) {
90 91 92
		return strlen(p);
	}

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
	/**
	 * 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);

108 109 110 111 112 113 114 115 116
	/**
	 * 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);

117 118 119 120 121 122 123
	/**
	 * 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
124 125
	static string Build(const_pointer a, size_t a_size,
			    const_pointer b, size_t b_size);
126 127 128 129 130

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
131 132 133 134 135 136
};

/**
 * This class describes the nature of a MPD internal filesystem path.
 */
struct PathTraitsUTF8 {
137 138 139 140
	typedef std::string string;
	typedef char value_type;
	typedef char *pointer;
	typedef const char *const_pointer;
141

142 143 144
	static constexpr value_type SEPARATOR = '/';

	static constexpr bool IsSeparator(value_type ch) {
145 146 147
		return ch == SEPARATOR;
	}

148 149 150 151 152 153
	gcc_pure gcc_nonnull_all
	static const_pointer FindLastSeparator(const_pointer p) {
		assert(p != nullptr);
		return strrchr(p, SEPARATOR);
	}

154 155 156 157 158 159 160
#ifdef WIN32
	gcc_pure gcc_nonnull_all
	static constexpr bool IsDrive(const_pointer p) {
		return IsAlphaASCII(p[0]) && p[1] == ':';
	}
#endif

161
	gcc_pure gcc_nonnull_all
162
	static bool IsAbsolute(const_pointer p) {
163 164
		assert(p != nullptr);
#ifdef WIN32
165
		if (IsDrive(p) && IsSeparator(p[2]))
166 167 168 169
			return true;
#endif
		return IsSeparator(*p);
	}
170

171 172 173 174 175
	gcc_pure gcc_nonnull_all
	static size_t GetLength(const_pointer p) {
		return strlen(p);
	}

Max Kellermann's avatar
Max Kellermann committed
176 177 178 179 180
	/**
	 * Determine the "base" file name of the given UTF-8 path.
	 * The return value points inside the given string.
	 */
	gcc_pure gcc_nonnull_all
181
	static const_pointer GetBase(const_pointer p);
Max Kellermann's avatar
Max Kellermann committed
182 183 184 185 186 187 188

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

191 192 193 194 195 196 197 198 199
	/**
	 * 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);

200 201 202 203 204 205 206 207 208
	/**
	 * 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);
209 210 211 212 213

	gcc_pure gcc_nonnull_all
	static string Build(const_pointer a, const_pointer b) {
		return Build(a, GetLength(a), b, GetLength(b));
	}
214 215 216
};

#endif