aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/DecoderThread.cxx2
-rw-r--r--src/DetachedSong.cxx14
-rw-r--r--src/DetachedSong.hxx37
-rw-r--r--src/Mapper.cxx13
-rw-r--r--src/PlaylistSave.cxx3
-rw-r--r--src/PlaylistUpdate.cxx2
-rw-r--r--src/SongUpdate.cxx2
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))