aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/InotifyUpdate.cxx12
-rw-r--r--src/Mapper.cxx6
-rw-r--r--src/PlaylistFile.cxx7
-rw-r--r--src/PlaylistSong.cxx15
-rw-r--r--src/UpdateWalk.cxx19
-rw-r--r--src/fs/Path.cxx35
-rw-r--r--src/fs/Path.hxx18
7 files changed, 59 insertions, 53 deletions
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<GIConv>(-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<char *>(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<size_t>(-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
@@ -49,13 +49,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.
*/
@@ -174,6 +167,13 @@ public:
}
/**
+ * 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.
*/
Path &operator=(const Path &other) {
@@ -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