From ef93cdf4a8b654342e97e6ab707caaf42cb9c64d Mon Sep 17 00:00:00 2001 From: Denis Krjuchkov Date: Tue, 22 Jan 2013 00:14:37 +0600 Subject: Path: move to fs subdirectory --- src/ConfigFile.cxx | 2 +- src/DatabaseSave.cxx | 2 +- src/DecoderThread.cxx | 2 +- src/ExcludeList.cxx | 2 +- src/InotifyUpdate.cxx | 2 +- src/Main.cxx | 2 +- src/Mapper.cxx | 2 +- src/Path.cxx | 131 -------------------- src/Path.hxx | 264 ---------------------------------------- src/PlaylistFile.cxx | 2 +- src/PlaylistMapper.cxx | 2 +- src/PlaylistSave.cxx | 2 +- src/PlaylistSong.cxx | 2 +- src/SongUpdate.cxx | 2 +- src/StateFile.hxx | 2 +- src/TextFile.hxx | 2 +- src/UpdateArchive.cxx | 2 +- src/UpdateContainer.cxx | 2 +- src/UpdateIO.cxx | 2 +- src/UpdateWalk.cxx | 2 +- src/db/SimpleDatabasePlugin.hxx | 2 +- src/fs/Path.cxx | 131 ++++++++++++++++++++ src/fs/Path.hxx | 264 ++++++++++++++++++++++++++++++++++++++++ 23 files changed, 414 insertions(+), 414 deletions(-) delete mode 100644 src/Path.cxx delete mode 100644 src/Path.hxx create mode 100644 src/fs/Path.cxx create mode 100644 src/fs/Path.hxx (limited to 'src') diff --git a/src/ConfigFile.cxx b/src/ConfigFile.cxx index ce71b21d2..614bb4f91 100644 --- a/src/ConfigFile.cxx +++ b/src/ConfigFile.cxx @@ -26,7 +26,7 @@ extern "C" { #include "tokenizer.h" } -#include "Path.hxx" +#include "fs/Path.hxx" #include "mpd_error.h" #include diff --git a/src/DatabaseSave.cxx b/src/DatabaseSave.cxx index 029189ae5..2c46f4a5b 100644 --- a/src/DatabaseSave.cxx +++ b/src/DatabaseSave.cxx @@ -26,7 +26,7 @@ #include "TextFile.hxx" #include "TagInternal.hxx" #include "tag.h" -#include "Path.hxx" +#include "fs/Path.hxx" #include diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx index 4c493304b..b821c6d7a 100644 --- a/src/DecoderThread.cxx +++ b/src/DecoderThread.cxx @@ -26,7 +26,7 @@ #include "song.h" #include "mpd_error.h" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include "decoder_api.h" #include "tag.h" #include "input_stream.h" diff --git a/src/ExcludeList.cxx b/src/ExcludeList.cxx index 3f929b93c..69a04d5a8 100644 --- a/src/ExcludeList.cxx +++ b/src/ExcludeList.cxx @@ -24,7 +24,7 @@ #include "config.h" #include "ExcludeList.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include #include diff --git a/src/InotifyUpdate.cxx b/src/InotifyUpdate.cxx index a1c3e0393..bd018f5a3 100644 --- a/src/InotifyUpdate.cxx +++ b/src/InotifyUpdate.cxx @@ -23,7 +23,7 @@ #include "InotifyQueue.hxx" #include "Mapper.hxx" #include "Main.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include #include diff --git a/src/Main.cxx b/src/Main.cxx index 6d4fc82d2..44adf2e28 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -47,7 +47,7 @@ #include "InputInit.hxx" #include "event/Loop.hxx" #include "IOThread.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "daemon.h" diff --git a/src/Mapper.cxx b/src/Mapper.cxx index 09fa190f3..5a28874de 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -25,7 +25,7 @@ #include "Mapper.hxx" #include "Directory.hxx" #include "song.h" -#include "Path.hxx" +#include "fs/Path.hxx" #include diff --git a/src/Path.cxx b/src/Path.cxx deleted file mode 100644 index ab8a4e3cc..000000000 --- a/src/Path.cxx +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "Path.hxx" -#include "conf.h" -#include "mpd_error.h" -#include "gcc.h" - -#include - -#include -#include - -#ifdef G_OS_WIN32 -#include // for GetACP() -#include // for sprintf() -#endif - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "path" - -static char *fs_charset; - -char * -fs_charset_to_utf8(const char *path_fs) -{ - return g_convert(path_fs, -1, - "utf-8", fs_charset, - NULL, NULL, NULL); -} - -char * -utf8_to_fs_charset(const char *path_utf8) -{ - gchar *p; - - p = g_convert(path_utf8, -1, - fs_charset, "utf-8", - NULL, NULL, NULL); - if (p == NULL) - /* fall back to UTF-8 */ - p = g_strdup(path_utf8); - - return p; -} - -gcc_pure -static bool -IsSupportedCharset(const char *charset) -{ - /* convert a space to check if the charset is valid */ - char *test = g_convert(" ", 1, charset, "UTF-8", NULL, NULL, NULL); - if (test == NULL) - return false; - - g_free(test); - return true; -} - -static void -path_set_fs_charset(const char *charset) -{ - assert(charset != NULL); - - if (!IsSupportedCharset(charset)) - MPD_ERROR("invalid filesystem charset: %s", charset); - - g_free(fs_charset); - fs_charset = g_strdup(charset); - - g_debug("path_set_fs_charset: fs charset is: %s", fs_charset); -} - -const char *path_get_fs_charset(void) -{ - return fs_charset; -} - -void path_global_init(void) -{ - const char *charset = NULL; - - charset = config_get_string(CONF_FS_CHARSET, NULL); - if (charset == NULL) { -#ifndef G_OS_WIN32 - const gchar **encodings; - g_get_filename_charsets(&encodings); - - if (encodings[0] != NULL && *encodings[0] != '\0') - charset = encodings[0]; -#else /* G_OS_WIN32 */ - /* Glib claims that file system encoding is always utf-8 - * on native Win32 (i.e. not Cygwin). - * However this is true only if helpers are used. - * MPD uses regular functions. - * Those functions use encoding determined by GetACP(). */ - static char win_charset[13]; - sprintf(win_charset, "cp%u", GetACP()); - charset = win_charset; -#endif - } - - if (charset) { - path_set_fs_charset(charset); - } else { - g_message("setting filesystem charset to ISO-8859-1"); - path_set_fs_charset("ISO-8859-1"); - } -} - -void path_global_finish(void) -{ - g_free(fs_charset); -} diff --git a/src/Path.hxx b/src/Path.hxx deleted file mode 100644 index 5c76e4b87..000000000 --- a/src/Path.hxx +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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_PATH_HXX -#define MPD_PATH_HXX - -#include "check.h" -#include "gcc.h" - -#include - -#include - -#include -#include -#include - -#if !defined(MPD_PATH_MAX) -# if defined(MAXPATHLEN) -# define MPD_PATH_MAX MAXPATHLEN -# elif defined(PATH_MAX) -# define MPD_PATH_MAX PATH_MAX -# else -# define MPD_PATH_MAX 256 -# endif -#endif - -void path_global_init(); - -void path_global_finish(); - -/** - * Converts a file name in the filesystem charset to UTF-8. Returns - * NULL on failure. - */ -char * -fs_charset_to_utf8(const char *path_fs); - -/** - * Converts a file name in UTF-8 to the filesystem charset. Returns a - * duplicate of the UTF-8 string on failure. - */ -char * -utf8_to_fs_charset(const char *path_utf8); - -const char *path_get_fs_charset(); - -/** - * A path name in the native file system character set. - */ -class Path { -public: - typedef char value_type; - typedef value_type *pointer; - typedef const value_type *const_pointer; - -private: - pointer value; - - struct Donate {}; - - /** - * Donate the allocated pointer to a new #Path object. - */ - constexpr Path(Donate, pointer _value):value(_value) {} - - /** - * Release memory allocated by the value, but do not clear the - * value pointer. - */ - void Free() { - /* free() can be optimized by gcc, while g_free() can - not: when the compiler knows that the value is - nullptr, it will not emit a free() call in the - inlined destructor; however on Windows, we need to - call g_free(), because the value has been allocated - by GLib, and on Windows, this matters */ -#ifdef WIN32 - g_free(value); -#else - free(value); -#endif - } - -public: - /** - * Copy a #Path object. - */ - Path(const Path &other) - :value(g_strdup(other.value)) {} - - /** - * Move a #Path object. - */ - Path(Path &&other):value(other.value) { - other.value = nullptr; - } - - ~Path() { - Free(); - } - - /** - * Return a "nulled" instance. Its IsNull() method will - * return true. Such an object must not be used. - * - * @see IsNull() - */ - gcc_const - static Path Null() { - return Path(Donate(), nullptr); - } - - /** - * Join two path components with the path separator. - */ - gcc_pure gcc_nonnull_all - static Path Build(const_pointer a, const_pointer b) { - return Path(Donate(), g_build_filename(a, b, nullptr)); - } - - gcc_pure gcc_nonnull_all - static Path Build(const_pointer a, const Path &b) { - return Build(a, b.c_str()); - } - - gcc_pure gcc_nonnull_all - static Path Build(const Path &a, const_pointer b) { - return Build(a.c_str(), b); - } - - gcc_pure - static Path Build(const Path &a, const Path &b) { - return Build(a.c_str(), b.c_str()); - } - - /** - * Convert a C string that is already in the filesystem - * character set to a #Path instance. - */ - gcc_pure - static Path FromFS(const_pointer fs) { - return Path(Donate(), g_strdup(fs)); - } - - /** - * Convert a UTF-8 C string to a #Path instance. - * - * TODO: return a "nulled" instance on error and add checks to - * all callers - */ - gcc_pure - static Path FromUTF8(const char *utf8) { - return Path(Donate(), utf8_to_fs_charset(utf8)); - } - - /** - * Copy a #Path object. - */ - Path &operator=(const Path &other) { - if (this != &other) { - Free(); - value = g_strdup(other.value); - } - - return *this; - } - - /** - * Move a #Path object. - */ - Path &operator=(Path &&other) { - std::swap(value, other.value); - return *this; - } - - /** - * Steal the allocated value. This object has an undefined - * value, and the caller is response for freeing this method's - * return value. - */ - pointer Steal() { - pointer result = value; - value = nullptr; - return result; - } - - /** - * Check if this is a "nulled" instance. A "nulled" instance - * must not be used. - */ - bool IsNull() const { - return value == nullptr; - } - - /** - * Clear this object's value, make it "nulled". - * - * @see IsNull() - */ - void SetNull() { - Free(); - value = nullptr; - } - - gcc_pure - bool empty() const { - assert(value != nullptr); - - return *value == 0; - } - - /** - * @return the length of this string in number of "value_type" - * elements (which may not be the number of characters). - */ - gcc_pure - size_t length() const { - assert(value != nullptr); - - return strlen(value); - } - - /** - * Returns the value as a const C string. The returned - * pointer is invalidated whenever the value of life of this - * instance ends. - */ - gcc_pure - const_pointer c_str() const { - assert(value != nullptr); - - return value; - } - - /** - * Convert the path to UTF-8. The caller is responsible for - * freeing the return value with g_free(). Returns nullptr on - * error. - */ - char *ToUTF8() const { - return value != nullptr - ? fs_charset_to_utf8(value) - : nullptr; - } -}; - -#endif diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index ea81540cf..34f04df77 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -30,7 +30,7 @@ #include "TextFile.hxx" #include "conf.h" #include "Idle.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "uri.h" diff --git a/src/PlaylistMapper.cxx b/src/PlaylistMapper.cxx index e6b8ee439..96106a4cf 100644 --- a/src/PlaylistMapper.cxx +++ b/src/PlaylistMapper.cxx @@ -21,7 +21,7 @@ #include "PlaylistMapper.hxx" #include "PlaylistFile.hxx" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "playlist_list.h" diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 89feebbde..e5b2a8f69 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -24,7 +24,7 @@ #include "song.h" #include "Mapper.hxx" #include "Idle.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "uri.h" diff --git a/src/PlaylistSong.cxx b/src/PlaylistSong.cxx index 0d60c1413..6c59600f6 100644 --- a/src/PlaylistSong.cxx +++ b/src/PlaylistSong.cxx @@ -24,7 +24,7 @@ #include "DatabaseGlue.hxx" #include "ls.hxx" #include "tag.h" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "song.h" diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index ed7293f14..120aaf537 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -26,7 +26,7 @@ extern "C" { #include "Directory.hxx" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include "tag.h" #include "input_stream.h" diff --git a/src/StateFile.hxx b/src/StateFile.hxx index 72d71e105..bb1c382f4 100644 --- a/src/StateFile.hxx +++ b/src/StateFile.hxx @@ -21,7 +21,7 @@ #define MPD_STATE_FILE_HXX #include "event/TimeoutMonitor.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include "gcc.h" #include diff --git a/src/TextFile.hxx b/src/TextFile.hxx index b24889f61..c4822aaf8 100644 --- a/src/TextFile.hxx +++ b/src/TextFile.hxx @@ -21,7 +21,7 @@ #define MPD_TEXT_FILE_HXX #include "gcc.h" -#include "Path.hxx" +#include "fs/Path.hxx" #include diff --git a/src/UpdateArchive.cxx b/src/UpdateArchive.cxx index c45e1b733..0765b1ba7 100644 --- a/src/UpdateArchive.cxx +++ b/src/UpdateArchive.cxx @@ -24,7 +24,7 @@ #include "Directory.hxx" #include "song.h" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "archive_list.h" diff --git a/src/UpdateContainer.cxx b/src/UpdateContainer.cxx index d59fa96c0..f24a1848a 100644 --- a/src/UpdateContainer.cxx +++ b/src/UpdateContainer.cxx @@ -26,7 +26,7 @@ #include "song.h" #include "decoder_plugin.h" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "tag_handler.h" diff --git a/src/UpdateIO.cxx b/src/UpdateIO.cxx index cbf05b6fc..eca5688a1 100644 --- a/src/UpdateIO.cxx +++ b/src/UpdateIO.cxx @@ -21,7 +21,7 @@ #include "UpdateIO.hxx" #include "Directory.hxx" #include "Mapper.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include "glib_compat.h" #include diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx index d0e9281a7..fb6618111 100644 --- a/src/UpdateWalk.cxx +++ b/src/UpdateWalk.cxx @@ -31,7 +31,7 @@ #include "Mapper.hxx" #include "ExcludeList.hxx" #include "conf.h" -#include "Path.hxx" +#include "fs/Path.hxx" extern "C" { #include "uri.h" diff --git a/src/db/SimpleDatabasePlugin.hxx b/src/db/SimpleDatabasePlugin.hxx index 3549aa98c..888f9c33e 100644 --- a/src/db/SimpleDatabasePlugin.hxx +++ b/src/db/SimpleDatabasePlugin.hxx @@ -21,7 +21,7 @@ #define MPD_SIMPLE_DATABASE_PLUGIN_HXX #include "DatabasePlugin.hxx" -#include "Path.hxx" +#include "fs/Path.hxx" #include "gcc.h" #include diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx new file mode 100644 index 000000000..80b41cbaa --- /dev/null +++ b/src/fs/Path.cxx @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#include "config.h" +#include "fs/Path.hxx" +#include "conf.h" +#include "mpd_error.h" +#include "gcc.h" + +#include + +#include +#include + +#ifdef G_OS_WIN32 +#include // for GetACP() +#include // for sprintf() +#endif + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "path" + +static char *fs_charset; + +char * +fs_charset_to_utf8(const char *path_fs) +{ + return g_convert(path_fs, -1, + "utf-8", fs_charset, + NULL, NULL, NULL); +} + +char * +utf8_to_fs_charset(const char *path_utf8) +{ + gchar *p; + + p = g_convert(path_utf8, -1, + fs_charset, "utf-8", + NULL, NULL, NULL); + if (p == NULL) + /* fall back to UTF-8 */ + p = g_strdup(path_utf8); + + return p; +} + +gcc_pure +static bool +IsSupportedCharset(const char *charset) +{ + /* convert a space to check if the charset is valid */ + char *test = g_convert(" ", 1, charset, "UTF-8", NULL, NULL, NULL); + if (test == NULL) + return false; + + g_free(test); + return true; +} + +static void +path_set_fs_charset(const char *charset) +{ + assert(charset != NULL); + + if (!IsSupportedCharset(charset)) + MPD_ERROR("invalid filesystem charset: %s", charset); + + g_free(fs_charset); + fs_charset = g_strdup(charset); + + g_debug("path_set_fs_charset: fs charset is: %s", fs_charset); +} + +const char *path_get_fs_charset(void) +{ + return fs_charset; +} + +void path_global_init(void) +{ + const char *charset = NULL; + + charset = config_get_string(CONF_FS_CHARSET, NULL); + if (charset == NULL) { +#ifndef G_OS_WIN32 + const gchar **encodings; + g_get_filename_charsets(&encodings); + + if (encodings[0] != NULL && *encodings[0] != '\0') + charset = encodings[0]; +#else /* G_OS_WIN32 */ + /* Glib claims that file system encoding is always utf-8 + * on native Win32 (i.e. not Cygwin). + * However this is true only if helpers are used. + * MPD uses regular functions. + * Those functions use encoding determined by GetACP(). */ + static char win_charset[13]; + sprintf(win_charset, "cp%u", GetACP()); + charset = win_charset; +#endif + } + + if (charset) { + path_set_fs_charset(charset); + } else { + g_message("setting filesystem charset to ISO-8859-1"); + path_set_fs_charset("ISO-8859-1"); + } +} + +void path_global_finish(void) +{ + g_free(fs_charset); +} diff --git a/src/fs/Path.hxx b/src/fs/Path.hxx new file mode 100644 index 000000000..24f1d5e19 --- /dev/null +++ b/src/fs/Path.hxx @@ -0,0 +1,264 @@ +/* + * 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_PATH_HXX +#define MPD_FS_PATH_HXX + +#include "check.h" +#include "gcc.h" + +#include + +#include + +#include +#include +#include + +#if !defined(MPD_PATH_MAX) +# if defined(MAXPATHLEN) +# define MPD_PATH_MAX MAXPATHLEN +# elif defined(PATH_MAX) +# define MPD_PATH_MAX PATH_MAX +# else +# define MPD_PATH_MAX 256 +# endif +#endif + +void path_global_init(); + +void path_global_finish(); + +/** + * Converts a file name in the filesystem charset to UTF-8. Returns + * NULL on failure. + */ +char * +fs_charset_to_utf8(const char *path_fs); + +/** + * Converts a file name in UTF-8 to the filesystem charset. Returns a + * duplicate of the UTF-8 string on failure. + */ +char * +utf8_to_fs_charset(const char *path_utf8); + +const char *path_get_fs_charset(); + +/** + * A path name in the native file system character set. + */ +class Path { +public: + typedef char value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + +private: + pointer value; + + struct Donate {}; + + /** + * Donate the allocated pointer to a new #Path object. + */ + constexpr Path(Donate, pointer _value):value(_value) {} + + /** + * Release memory allocated by the value, but do not clear the + * value pointer. + */ + void Free() { + /* free() can be optimized by gcc, while g_free() can + not: when the compiler knows that the value is + nullptr, it will not emit a free() call in the + inlined destructor; however on Windows, we need to + call g_free(), because the value has been allocated + by GLib, and on Windows, this matters */ +#ifdef WIN32 + g_free(value); +#else + free(value); +#endif + } + +public: + /** + * Copy a #Path object. + */ + Path(const Path &other) + :value(g_strdup(other.value)) {} + + /** + * Move a #Path object. + */ + Path(Path &&other):value(other.value) { + other.value = nullptr; + } + + ~Path() { + Free(); + } + + /** + * Return a "nulled" instance. Its IsNull() method will + * return true. Such an object must not be used. + * + * @see IsNull() + */ + gcc_const + static Path Null() { + return Path(Donate(), nullptr); + } + + /** + * Join two path components with the path separator. + */ + gcc_pure gcc_nonnull_all + static Path Build(const_pointer a, const_pointer b) { + return Path(Donate(), g_build_filename(a, b, nullptr)); + } + + gcc_pure gcc_nonnull_all + static Path Build(const_pointer a, const Path &b) { + return Build(a, b.c_str()); + } + + gcc_pure gcc_nonnull_all + static Path Build(const Path &a, const_pointer b) { + return Build(a.c_str(), b); + } + + gcc_pure + static Path Build(const Path &a, const Path &b) { + return Build(a.c_str(), b.c_str()); + } + + /** + * Convert a C string that is already in the filesystem + * character set to a #Path instance. + */ + gcc_pure + static Path FromFS(const_pointer fs) { + return Path(Donate(), g_strdup(fs)); + } + + /** + * Convert a UTF-8 C string to a #Path instance. + * + * TODO: return a "nulled" instance on error and add checks to + * all callers + */ + gcc_pure + static Path FromUTF8(const char *utf8) { + return Path(Donate(), utf8_to_fs_charset(utf8)); + } + + /** + * Copy a #Path object. + */ + Path &operator=(const Path &other) { + if (this != &other) { + Free(); + value = g_strdup(other.value); + } + + return *this; + } + + /** + * Move a #Path object. + */ + Path &operator=(Path &&other) { + std::swap(value, other.value); + return *this; + } + + /** + * Steal the allocated value. This object has an undefined + * value, and the caller is response for freeing this method's + * return value. + */ + pointer Steal() { + pointer result = value; + value = nullptr; + return result; + } + + /** + * Check if this is a "nulled" instance. A "nulled" instance + * must not be used. + */ + bool IsNull() const { + return value == nullptr; + } + + /** + * Clear this object's value, make it "nulled". + * + * @see IsNull() + */ + void SetNull() { + Free(); + value = nullptr; + } + + gcc_pure + bool empty() const { + assert(value != nullptr); + + return *value == 0; + } + + /** + * @return the length of this string in number of "value_type" + * elements (which may not be the number of characters). + */ + gcc_pure + size_t length() const { + assert(value != nullptr); + + return strlen(value); + } + + /** + * Returns the value as a const C string. The returned + * pointer is invalidated whenever the value of life of this + * instance ends. + */ + gcc_pure + const_pointer c_str() const { + assert(value != nullptr); + + return value; + } + + /** + * Convert the path to UTF-8. The caller is responsible for + * freeing the return value with g_free(). Returns nullptr on + * error. + */ + char *ToUTF8() const { + return value != nullptr + ? fs_charset_to_utf8(value) + : nullptr; + } +}; + +#endif -- cgit v1.2.3