diff options
Diffstat (limited to '')
-rw-r--r-- | src/DecoderThread.cxx | 2 | ||||
-rw-r--r-- | src/DetachedSong.cxx | 14 | ||||
-rw-r--r-- | src/DetachedSong.hxx | 37 | ||||
-rw-r--r-- | src/Mapper.cxx | 13 | ||||
-rw-r--r-- | src/PlaylistSave.cxx | 3 | ||||
-rw-r--r-- | src/PlaylistUpdate.cxx | 2 | ||||
-rw-r--r-- | src/SongUpdate.cxx | 2 |
7 files changed, 62 insertions, 11 deletions
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx index 1df038158..8658c8883 100644 --- a/src/DecoderThread.cxx +++ b/src/DecoderThread.cxx @@ -402,7 +402,7 @@ decoder_run(DecoderControl &dc) const std::string uri = song.IsFile() ? map_song_fs(song).c_str() - : song.GetURI(); + : song.GetRealURI(); if (uri.empty()) { dc.state = DecoderState::ERROR; diff --git a/src/DetachedSong.cxx b/src/DetachedSong.cxx index 4e52afb0c..83106edee 100644 --- a/src/DetachedSong.cxx +++ b/src/DetachedSong.cxx @@ -32,13 +32,23 @@ DetachedSong::DetachedSong(const LightSong &other) bool DetachedSong::IsRemote() const { - return uri_has_scheme(uri.c_str()); + return uri_has_scheme(GetRealURI()); } bool DetachedSong::IsAbsoluteFile() const { - return PathTraitsUTF8::IsAbsolute(uri.c_str()); + return PathTraitsUTF8::IsAbsolute(GetRealURI()); +} + +bool +DetachedSong::IsInDatabase() const +{ + /* here, we use GetURI() and not GetRealURI() because + GetRealURI() is never relative */ + + const char *_uri = GetURI(); + return !uri_has_scheme(_uri) && !PathTraitsUTF8::IsAbsolute(_uri); } double diff --git a/src/DetachedSong.hxx b/src/DetachedSong.hxx index 3b14d5a07..b2f5196ff 100644 --- a/src/DetachedSong.hxx +++ b/src/DetachedSong.hxx @@ -47,6 +47,16 @@ class DetachedSong { */ std::string uri; + /** + * The "real" URI, the one to be used for opening the + * resource. If this attribute is empty, then #uri shall be + * used. + * + * This attribute is used for songs from the database which + * have a relative URI. + */ + std::string real_uri; + Tag tag; time_t mtime; @@ -98,6 +108,29 @@ public: } /** + * Does this object have a "real" URI different from the + * displayed URI? + */ + gcc_pure + bool HasRealURI() const { + return !real_uri.empty(); + } + + /** + * Returns "real" URI (#real_uri) and falls back to just + * GetURI(). + */ + gcc_pure + const char *GetRealURI() const { + return (HasRealURI() ? real_uri : uri).c_str(); + } + + template<typename T> + void SetRealURI(T &&_uri) { + real_uri = std::forward<T>(_uri); + } + + /** * Returns true if both objects refer to the same physical * song. */ @@ -123,9 +156,7 @@ public: bool IsAbsoluteFile() const; gcc_pure - bool IsInDatabase() const { - return IsFile() && !IsAbsoluteFile(); - } + bool IsInDatabase() const; const Tag &GetTag() const { return tag; diff --git a/src/Mapper.cxx b/src/Mapper.cxx index 8fafce12d..c9ef4316b 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -26,6 +26,7 @@ #include "Directory.hxx" #include "Song.hxx" #include "DetachedSong.hxx" +#include "LightSong.hxx" #include "fs/AllocatedPath.hxx" #include "fs/Traits.hxx" #include "fs/Charset.hxx" @@ -220,7 +221,15 @@ map_detached_song_fs(const char *uri_utf8) DetachedSong map_song_detach(const LightSong &song) { - return DetachedSong(song); + DetachedSong detached(song); + + if (detached.IsInDatabase()) { + const auto uri = song.GetURI(); + detached.SetRealURI(PathTraitsUTF8::Build(music_dir_utf8.c_str(), + uri.c_str())); + } + + return detached; } AllocatedPath @@ -235,7 +244,7 @@ AllocatedPath map_song_fs(const DetachedSong &song) { if (song.IsAbsoluteFile()) - return AllocatedPath::FromUTF8(song.GetURI()); + return AllocatedPath::FromUTF8(song.GetRealURI()); else return map_uri_fs(song.GetURI()); } diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 5f5b3e20d..8eeab0f62 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -38,7 +38,8 @@ void playlist_print_song(FILE *file, const DetachedSong &song) { - if (playlist_saveAbsolutePaths && song.IsInDatabase()) { + if (playlist_saveAbsolutePaths && + song.IsInDatabase() && song.IsFile()) { const auto path = map_song_fs(song); if (!path.IsNull()) fprintf(file, "%s\n", path.c_str()); diff --git a/src/PlaylistUpdate.cxx b/src/PlaylistUpdate.cxx index 755589786..800ad49c9 100644 --- a/src/PlaylistUpdate.cxx +++ b/src/PlaylistUpdate.cxx @@ -30,7 +30,7 @@ static bool UpdatePlaylistSong(const Database &db, DetachedSong &song) { - if (!song.IsInDatabase()) + if (!song.IsInDatabase() || !song.IsFile()) /* only update Songs instances that are "detached" from the Database */ return false; diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index ee70085f3..2eb0a0966 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -130,7 +130,7 @@ DetachedSong::Update() { if (IsAbsoluteFile()) { const AllocatedPath path_fs = - AllocatedPath::FromUTF8(uri.c_str()); + AllocatedPath::FromUTF8(GetRealURI()); struct stat st; if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode)) |