From 3c7cf94643bc45237d1e61c4e6015d498e4400b0 Mon Sep 17 00:00:00 2001 From: Denis Krjuchkov Date: Thu, 24 Jan 2013 02:26:38 +0600 Subject: Path: convert fs_charset_to_utf8() to static method Path::ToUTF8() --- src/InotifyUpdate.cxx | 12 ++++++------ src/Mapper.cxx | 6 +++++- src/PlaylistFile.cxx | 7 +++---- src/PlaylistSong.cxx | 15 ++++++--------- src/UpdateWalk.cxx | 19 ++++++++----------- src/fs/Path.cxx | 35 +++++++++++++++++++++-------------- src/fs/Path.hxx | 18 ++++++++++-------- 7 files changed, 59 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/InotifyUpdate.cxx b/src/InotifyUpdate.cxx index ca6db6807..94bff9d4c 100644 --- a/src/InotifyUpdate.cxx +++ b/src/InotifyUpdate.cxx @@ -289,14 +289,14 @@ mpd_inotify_callback(int wd, unsigned mask, (mask & (IN_CREATE|IN_ISDIR)) == (IN_CREATE|IN_ISDIR))) { /* a file was changed, or a directory was moved/deleted: queue a database update */ - char *uri_utf8 = uri_fs != NULL - ? fs_charset_to_utf8(uri_fs) - : g_strdup(""); - if (uri_utf8 != NULL) { - inotify_queue->Enqueue(uri_utf8); - g_free(uri_utf8); + if (uri_fs != nullptr) { + const std::string uri_utf8 = Path::ToUTF8(uri_fs); + if (!uri_utf8.empty()) + inotify_queue->Enqueue(uri_utf8.c_str()); } + else + inotify_queue->Enqueue(""); } g_free(uri_fs); diff --git a/src/Mapper.cxx b/src/Mapper.cxx index 1cb967eb6..fa5af2dba 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -246,7 +246,11 @@ map_fs_to_utf8(const char *path_fs) while (path_fs[0] == G_DIR_SEPARATOR) ++path_fs; - return fs_charset_to_utf8(path_fs); + const std::string path_utf8 = Path::ToUTF8(path_fs); + if (path_utf8.empty()) + return nullptr; + + return g_strdup(path_utf8.c_str()); } const Path & diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index 5e869d9db..daec5ca0a 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -163,13 +163,12 @@ LoadPlaylistFileInfo(PlaylistInfo &info, char *name = g_strndup(name_fs, name_length + 1 - sizeof(PLAYLIST_FILE_SUFFIX)); - char *name_utf8 = fs_charset_to_utf8(name); + std::string name_utf8 = Path::ToUTF8(name); g_free(name); - if (name_utf8 == NULL) + if (name_utf8.empty()) return false; - info.name = name_utf8; - g_free(name_utf8); + info.name = std::move(name_utf8); info.mtime = st.st_mtime; return true; } diff --git a/src/PlaylistSong.cxx b/src/PlaylistSong.cxx index 6c59600f6..4df4d22d4 100644 --- a/src/PlaylistSong.cxx +++ b/src/PlaylistSong.cxx @@ -65,18 +65,15 @@ apply_song_metadata(struct song *dest, const struct song *src) return dest; if (song_in_database(dest)) { - char *path_fs = map_song_fs(dest).Steal(); - if (path_fs == nullptr) + const Path &path_fs = map_song_fs(dest); + if (path_fs.IsNull()) return dest; - char *path_utf8 = fs_charset_to_utf8(path_fs); - if (path_utf8 != NULL) - g_free(path_fs); - else - path_utf8 = path_fs; + std::string path_utf8 = path_fs.ToUTF8(); + if (path_utf8.empty()) + path_utf8 = path_fs.c_str(); - tmp = song_file_new(path_utf8, NULL); - g_free(path_utf8); + tmp = song_file_new(path_utf8.c_str(), NULL); merge_song_metadata(tmp, dest, src); } else { diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx index dcac0f97e..3e0dfe48d 100644 --- a/src/UpdateWalk.cxx +++ b/src/UpdateWalk.cxx @@ -373,28 +373,25 @@ update_directory(Directory *directory, const struct stat *st) struct dirent *ent; while ((ent = readdir(dir))) { - char *utf8; + std::string utf8; struct stat st2; if (skip_path(ent->d_name) || exclude_list.Check(ent->d_name)) continue; - utf8 = fs_charset_to_utf8(ent->d_name); - if (utf8 == NULL) + utf8 = Path::ToUTF8(ent->d_name); + if (utf8.empty()) continue; - if (skip_symlink(directory, utf8)) { - modified |= delete_name_in(directory, utf8); - g_free(utf8); + if (skip_symlink(directory, utf8.c_str())) { + modified |= delete_name_in(directory, utf8.c_str()); continue; } - if (stat_directory_child(directory, utf8, &st2) == 0) - update_directory_child(directory, utf8, &st2); + if (stat_directory_child(directory, utf8.c_str(), &st2) == 0) + update_directory_child(directory, utf8.c_str(), &st2); else - modified |= delete_name_in(directory, utf8); - - g_free(utf8); + modified |= delete_name_in(directory, utf8.c_str()); } closedir(dir); diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx index 294f60781..0590fbd8f 100644 --- a/src/fs/Path.cxx +++ b/src/fs/Path.cxx @@ -48,24 +48,31 @@ static char *fs_charset; -std::string Path::ToUTF8() const +std::string Path::ToUTF8(const_pointer path_fs) { - if (value == nullptr) + if (path_fs == nullptr) return std::string(); - char *path_utf8 = fs_charset_to_utf8(value); - if (path_utf8 == nullptr) + + GIConv conv = g_iconv_open("utf-8", fs_charset); + if (conv == reinterpret_cast(-1)) return std::string(); - std::string result = value; - g_free(path_utf8); - return value; -} -char * -fs_charset_to_utf8(const char *path_fs) -{ - return g_convert(path_fs, -1, - "utf-8", fs_charset, - NULL, NULL, NULL); + // g_iconv() does not need nul-terminator, + // std::string could be created without it too. + char path_utf8[MPD_PATH_MAX_UTF8 - 1]; + char *in = const_cast(path_fs); + char *out = path_utf8; + size_t in_left = strlen(path_fs); + size_t out_left = sizeof(path_utf8); + + size_t ret = g_iconv(conv, &in, &in_left, &out, &out_left); + + g_iconv_close(conv); + + if (ret == static_cast(-1) || in_left > 0) + return std::string(); + + return std::string(path_utf8, sizeof(path_utf8) - out_left); } char * diff --git a/src/fs/Path.hxx b/src/fs/Path.hxx index 0b51983f6..87c3551e9 100644 --- a/src/fs/Path.hxx +++ b/src/fs/Path.hxx @@ -48,13 +48,6 @@ 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. @@ -173,6 +166,13 @@ public: return Path(Donate(), utf8_to_fs_charset(utf8)); } + /** + * Convert the path to UTF-8. + * Returns empty string on error or if #path_fs is null pointer. + */ + gcc_pure + static std::string ToUTF8(const_pointer path_fs); + /** * Copy a #Path object. */ @@ -257,7 +257,9 @@ public: * Returns empty string on error or if this instance is "nulled" * (#IsNull returns true). */ - std::string ToUTF8() const; + std::string ToUTF8() const { + return ToUTF8(value); + } }; #endif -- cgit v1.2.3