From b3611524f45c2a478f9decd6d22ecd1dbbbb64b9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 17 Oct 2013 23:23:25 +0200 Subject: fs/Path: move definitions to struct PathTraits --- src/CommandLine.cxx | 3 +- src/ConfigPath.cxx | 3 +- src/DecoderThread.cxx | 3 +- src/Mapper.cxx | 5 +- src/PlaylistFile.cxx | 3 +- src/PlaylistSave.cxx | 3 +- src/PlaylistSong.cxx | 5 +- src/QueueSave.cxx | 4 +- src/SongUpdate.cxx | 3 +- src/UpdateWalk.cxx | 7 ++- src/fs/FileSystem.hxx | 62 +++++++++++---------- src/fs/Path.cxx | 11 +--- src/fs/Path.hxx | 57 ++----------------- src/fs/Traits.hxx | 89 ++++++++++++++++++++++++++++++ src/input/ArchiveInputPlugin.cxx | 4 +- src/input/FileInputPlugin.cxx | 4 +- src/playlist/EmbeddedCuePlaylistPlugin.cxx | 4 +- 17 files changed, 159 insertions(+), 111 deletions(-) create mode 100644 src/fs/Traits.hxx (limited to 'src') diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx index 22f0ccc02..b55f2bec4 100644 --- a/src/CommandLine.cxx +++ b/src/CommandLine.cxx @@ -32,6 +32,7 @@ #include "PlaylistRegistry.hxx" #include "PlaylistPlugin.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/FileSystem.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -136,7 +137,7 @@ static const char *summary = gcc_pure static Path -PathBuildChecked(const Path &a, Path::const_pointer b) +PathBuildChecked(const Path &a, PathTraits::const_pointer b) { if (a.IsNull()) return Path::Null(); diff --git a/src/ConfigPath.cxx b/src/ConfigPath.cxx index 6c3177c17..ae97275b3 100644 --- a/src/ConfigPath.cxx +++ b/src/ConfigPath.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "ConfigPath.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/Domain.hxx" #include "util/Error.hxx" #include "ConfigGlobal.hxx" @@ -119,7 +120,7 @@ ParsePath(const char *path, Error &error) return Path::Null(); return Path::Build(home, path2); - } else if (!Path::IsAbsoluteUTF8(path)) { + } else if (!PathTraits::IsAbsoluteUTF8(path)) { error.Format(path_domain, "not an absolute path: %s", path); return Path::Null(); diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx index a02bd9ee6..3a282451a 100644 --- a/src/DecoderThread.cxx +++ b/src/DecoderThread.cxx @@ -26,6 +26,7 @@ #include "Song.hxx" #include "system/FatalError.hxx" #include "Mapper.hxx" +#include "fs/Traits.hxx" #include "fs/Path.hxx" #include "DecoderAPI.hxx" #include "tag/Tag.hxx" @@ -153,7 +154,7 @@ decoder_file_decode(const struct decoder_plugin *plugin, assert(decoder->stream_tag == NULL); assert(decoder->decoder_tag == NULL); assert(path != NULL); - assert(Path::IsAbsoluteFS(path)); + assert(PathTraits::IsAbsoluteFS(path)); assert(decoder->dc->state == DecoderState::START); FormatDebug(decoder_thread_domain, "probing plugin %s", plugin->name); diff --git a/src/Mapper.cxx b/src/Mapper.cxx index b89f83cd7..8a6bd2201 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -26,6 +26,7 @@ #include "Directory.hxx" #include "Song.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/Charset.hxx" #include "fs/FileSystem.hxx" #include "fs/DirectoryReader.hxx" @@ -147,7 +148,7 @@ map_to_relative_path(const char *path_utf8) return !music_dir_utf8.empty() && memcmp(path_utf8, music_dir_utf8.c_str(), music_dir_utf8_length) == 0 && - Path::IsSeparatorUTF8(path_utf8[music_dir_utf8_length]) + PathTraits::IsSeparatorUTF8(path_utf8[music_dir_utf8_length]) ? path_utf8 + music_dir_utf8_length + 1 : path_utf8; } @@ -231,7 +232,7 @@ map_song_fs(const Song *song) std::string map_fs_to_utf8(const char *path_fs) { - if (Path::IsSeparatorFS(path_fs[0])) { + if (PathTraits::IsSeparatorFS(path_fs[0])) { path_fs = music_dir_fs.RelativeFS(path_fs); if (path_fs == nullptr || *path_fs == 0) return std::string(); diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index ea6b3c914..aad9cee7a 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -33,6 +33,7 @@ #include "Idle.hxx" #include "fs/Limits.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/Charset.hxx" #include "fs/FileSystem.hxx" #include "fs/DirectoryReader.hxx" @@ -248,7 +249,7 @@ LoadPlaylistFile(const char *utf8path, Error &error) if (!uri_has_scheme(s)) { uri_utf8 = map_fs_to_utf8(s); if (uri_utf8.empty()) { - if (Path::IsAbsoluteFS(s)) { + if (PathTraits::IsAbsoluteFS(s)) { uri_utf8 = PathToUTF8(s); if (uri_utf8.empty()) continue; diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 556ef0238..57a0d1351 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -26,6 +26,7 @@ #include "Mapper.hxx" #include "Idle.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/FileSystem.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" @@ -55,7 +56,7 @@ void playlist_print_uri(FILE *file, const char *uri) { Path path = playlist_saveAbsolutePaths && !uri_has_scheme(uri) && - !Path::IsAbsoluteUTF8(uri) + !PathTraits::IsAbsoluteUTF8(uri) ? map_uri_fs(uri) : Path::FromUTF8(uri); diff --git a/src/PlaylistSong.cxx b/src/PlaylistSong.cxx index db6c39b3b..fc1fe884c 100644 --- a/src/PlaylistSong.cxx +++ b/src/PlaylistSong.cxx @@ -25,6 +25,7 @@ #include "ls.hxx" #include "tag/Tag.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "Song.hxx" @@ -98,7 +99,7 @@ playlist_check_load_song(const Song *song, const char *uri, bool secure) if (uri_has_scheme(uri)) { dest = Song::NewRemote(uri); - } else if (Path::IsAbsoluteUTF8(uri) && secure) { + } else if (PathTraits::IsAbsoluteUTF8(uri) && secure) { dest = Song::LoadFile(uri, nullptr); if (dest == nullptr) return nullptr; @@ -147,7 +148,7 @@ playlist_check_translate_song(Song *song, const char *base_uri, functions */ base_uri = nullptr; - if (Path::IsAbsoluteUTF8(uri)) { + if (PathTraits::IsAbsoluteUTF8(uri)) { /* XXX fs_charset vs utf8? */ const char *suffix = map_to_relative_path(uri); assert(suffix != nullptr); diff --git a/src/QueueSave.cxx b/src/QueueSave.cxx index 30c669538..7fe985a69 100644 --- a/src/QueueSave.cxx +++ b/src/QueueSave.cxx @@ -28,7 +28,7 @@ #include "TextFile.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" -#include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "Log.hxx" #include @@ -91,7 +91,7 @@ queue_load_song(TextFile &file, const char *line, queue *queue) if (g_str_has_prefix(line, SONG_BEGIN)) { const char *uri = line + sizeof(SONG_BEGIN) - 1; - if (!uri_has_scheme(uri) && !Path::IsAbsoluteUTF8(uri)) + if (!uri_has_scheme(uri) && !PathTraits::IsAbsoluteUTF8(uri)) return; Error error; diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index 075e94242..1bf70a8c9 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -24,6 +24,7 @@ #include "Directory.hxx" #include "Mapper.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/FileSystem.hxx" #include "InputStream.hxx" #include "DecoderPlugin.hxx" @@ -47,7 +48,7 @@ Song::LoadFile(const char *path_utf8, Directory *parent) Song *song; bool ret; - assert((parent == NULL) == Path::IsAbsoluteUTF8(path_utf8)); + assert((parent == NULL) == PathTraits::IsAbsoluteUTF8(path_utf8)); assert(!uri_has_scheme(path_utf8)); assert(strchr(path_utf8, '\n') == NULL); diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx index bb9b307dc..82a0959b1 100644 --- a/src/UpdateWalk.cxx +++ b/src/UpdateWalk.cxx @@ -35,6 +35,7 @@ #include "ConfigGlobal.hxx" #include "ConfigOption.hxx" #include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "fs/FileSystem.hxx" #include "fs/DirectoryReader.hxx" #include "util/UriUtil.hxx" @@ -295,7 +296,7 @@ skip_symlink(const Directory *directory, const char *utf8_name) const char *target_str = target.c_str(); - if (Path::IsAbsoluteFS(target_str)) { + if (PathTraits::IsAbsoluteFS(target_str)) { /* if the symlink points to an absolute path, see if that path is inside the music directory */ const char *relative = map_to_relative_path(target_str); @@ -306,7 +307,7 @@ skip_symlink(const Directory *directory, const char *utf8_name) const char *p = target_str; while (*p == '.') { - if (p[1] == '.' && Path::IsSeparatorFS(p[2])) { + if (p[1] == '.' && PathTraits::IsSeparatorFS(p[2])) { /* "../" moves to parent directory */ directory = directory->parent; if (directory == NULL) { @@ -316,7 +317,7 @@ skip_symlink(const Directory *directory, const char *utf8_name) return !follow_outside_symlinks; } p += 3; - } else if (Path::IsSeparatorFS(p[1])) + } else if (PathTraits::IsSeparatorFS(p[1])) /* eliminate "./" */ p += 2; else diff --git a/src/fs/FileSystem.hxx b/src/fs/FileSystem.hxx index d247f1a75..faa00751a 100644 --- a/src/fs/FileSystem.hxx +++ b/src/fs/FileSystem.hxx @@ -21,6 +21,7 @@ #define MPD_FS_FILESYSTEM_HXX #include "check.h" +#include "Traits.hxx" #include "system/fd_util.h" #include "Path.hxx" @@ -31,41 +32,42 @@ #include namespace FOpenMode { -/** - * Open mode for reading text files. - */ -constexpr Path::const_pointer ReadText = "r"; - -/** - * Open mode for reading binary files. - */ -constexpr Path::const_pointer ReadBinary = "rb"; - -/** - * Open mode for writing text files. - */ -constexpr Path::const_pointer WriteText = "w"; - -/** - * Open mode for writing binary files. - */ -constexpr Path::const_pointer WriteBinary = "wb"; - -/** - * Open mode for appending text files. - */ -constexpr Path::const_pointer AppendText = "a"; - -/** - * Open mode for appending binary files. - */ -constexpr Path::const_pointer AppendBinary = "ab"; + /** + * Open mode for reading text files. + */ + constexpr PathTraits::const_pointer ReadText = "r"; + + /** + * Open mode for reading binary files. + */ + constexpr PathTraits::const_pointer ReadBinary = "rb"; + + /** + * Open mode for writing text files. + */ + constexpr PathTraits::const_pointer WriteText = "w"; + + /** + * Open mode for writing binary files. + */ + constexpr PathTraits::const_pointer WriteBinary = "wb"; + + /** + * Open mode for appending text files. + */ + constexpr PathTraits::const_pointer AppendText = "a"; + + /** + * Open mode for appending binary files. + */ + constexpr PathTraits::const_pointer AppendBinary = "ab"; } /** * Wrapper for fopen() that uses #Path names. */ -static inline FILE *FOpen(const Path &file, Path::const_pointer mode) +static inline FILE * +FOpen(const Path &file, PathTraits::const_pointer mode) { return fopen(file.c_str(), mode); } diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx index 4a4292d05..ecdf73e49 100644 --- a/src/fs/Path.cxx +++ b/src/fs/Path.cxx @@ -29,11 +29,6 @@ #include #include -#ifdef WIN32 -#include // for GetACP() -#include // for sprintf() -#endif - inline Path::Path(Donate, pointer _value) :value(_value) { g_free(_value); @@ -86,14 +81,14 @@ Path::RelativeFS(const char *other_fs) const other_fs += l; if (*other_fs != 0) { - if (!IsSeparatorFS(*other_fs)) + if (!PathTraits::IsSeparatorFS(*other_fs)) /* mismatch */ return nullptr; /* skip remaining path separators */ do { ++other_fs; - } while (IsSeparatorFS(*other_fs)); + } while (PathTraits::IsSeparatorFS(*other_fs)); } return other_fs; @@ -105,7 +100,7 @@ Path::ChopSeparators() size_t l = length(); const char *p = data(); - while (l >= 2 && IsSeparatorFS(p[l - 1])) { + while (l >= 2 && PathTraits::IsSeparatorFS(p[l - 1])) { --l; #if GCC_CHECK_VERSION(4,7) && !defined(__clang__) diff --git a/src/fs/Path.hxx b/src/fs/Path.hxx index a6e74104e..558e2923f 100644 --- a/src/fs/Path.hxx +++ b/src/fs/Path.hxx @@ -22,6 +22,7 @@ #include "check.h" #include "Compiler.h" +#include "Traits.hxx" #ifdef WIN32 #include @@ -40,20 +41,10 @@ class Error; class Path { typedef std::string string; -public: - typedef string::value_type value_type; - typedef string::pointer pointer; - typedef string::const_pointer const_pointer; - -#ifdef WIN32 - static constexpr value_type SEPARATOR_FS = '\\'; - static constexpr char SEPARATOR_UTF8 = '/'; -#else - static constexpr value_type SEPARATOR_FS = '/'; - static constexpr char SEPARATOR_UTF8 = '/'; -#endif + typedef PathTraits::value_type value_type; + typedef PathTraits::pointer pointer; + typedef PathTraits::const_pointer const_pointer; -private: string value; struct Donate {}; @@ -216,47 +207,9 @@ public: */ void ChopSeparators(); - static constexpr bool IsSeparatorFS(value_type ch) { - return -#ifdef WIN32 - ch == '/' || -#endif - ch == SEPARATOR_FS; - } - - static constexpr bool IsSeparatorUTF8(char ch) { - return -#ifdef WIN32 - ch == '/' || -#endif - ch == SEPARATOR_UTF8; - } - - gcc_pure - static bool IsAbsoluteFS(const_pointer p) { - assert(p != nullptr); - -#ifdef WIN32 - return g_path_is_absolute(p); -#else - return IsSeparatorFS(*p); -#endif - } - - gcc_pure - static bool IsAbsoluteUTF8(const char *p) { - assert(p != nullptr); - -#ifdef WIN32 - return g_path_is_absolute(p); -#else - return IsSeparatorUTF8(*p); -#endif - } - gcc_pure bool IsAbsolute() { - return IsAbsoluteFS(c_str()); + return PathTraits::IsAbsoluteFS(c_str()); } }; diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx new file mode 100644 index 000000000..564f6ca1a --- /dev/null +++ b/src/fs/Traits.hxx @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * 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 +#include +#endif + +#include + +class Error; + +/** + * This class describes the nature of a filesystem path. + */ +struct PathTraits { + 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 = '/'; +#else + static constexpr value_type SEPARATOR_FS = '/'; + static constexpr char SEPARATOR_UTF8 = '/'; +#endif + + static constexpr bool IsSeparatorFS(value_type ch) { + return +#ifdef WIN32 + ch == '/' || +#endif + ch == SEPARATOR_FS; + } + + static constexpr bool IsSeparatorUTF8(char ch) { + return +#ifdef WIN32 + ch == '/' || +#endif + ch == SEPARATOR_UTF8; + } + + gcc_pure + static bool IsAbsoluteFS(const_pointer p) { + assert(p != nullptr); + +#ifdef WIN32 + return g_path_is_absolute(p); +#else + return IsSeparatorFS(*p); +#endif + } + + gcc_pure + static bool IsAbsoluteUTF8(const char *p) { + assert(p != nullptr); + +#ifdef WIN32 + return g_path_is_absolute(p); +#else + return IsSeparatorUTF8(*p); +#endif + } +}; + +#endif diff --git a/src/input/ArchiveInputPlugin.cxx b/src/input/ArchiveInputPlugin.cxx index 39d71f740..38435d563 100644 --- a/src/input/ArchiveInputPlugin.cxx +++ b/src/input/ArchiveInputPlugin.cxx @@ -26,7 +26,7 @@ #include "ArchiveFile.hxx" #include "InputPlugin.hxx" #include "util/Error.hxx" -#include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "Log.hxx" #include @@ -47,7 +47,7 @@ input_archive_open(const char *pathname, const struct archive_plugin *arplug; struct input_stream *is; - if (!Path::IsAbsoluteFS(pathname)) + if (!PathTraits::IsAbsoluteFS(pathname)) return NULL; char *pname = g_strdup(pathname); diff --git a/src/input/FileInputPlugin.cxx b/src/input/FileInputPlugin.cxx index f52b1cd14..22cb8d5e6 100644 --- a/src/input/FileInputPlugin.cxx +++ b/src/input/FileInputPlugin.cxx @@ -24,7 +24,7 @@ #include "InputPlugin.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" -#include "fs/Path.hxx" +#include "fs/Traits.hxx" #include "system/fd_util.h" #include "open.h" @@ -63,7 +63,7 @@ input_file_open(const char *filename, int fd, ret; struct stat st; - if (!Path::IsAbsoluteFS(filename)) + if (!PathTraits::IsAbsoluteFS(filename)) return nullptr; fd = open_cloexec(filename, O_RDONLY|O_BINARY, 0); diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx index 2a06d2236..fe3b4ca12 100644 --- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx +++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx @@ -34,7 +34,7 @@ #include "Song.hxx" #include "TagFile.hxx" #include "cue/CueParser.hxx" -#include "fs/Path.hxx" +#include "fs/Traits.hxx" #include #include @@ -96,7 +96,7 @@ embcue_playlist_open_uri(const char *uri, gcc_unused Mutex &mutex, gcc_unused Cond &cond) { - if (!Path::IsAbsoluteUTF8(uri)) + if (!PathTraits::IsAbsoluteUTF8(uri)) /* only local files supported */ return NULL; -- cgit v1.2.3