aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-01-15 12:05:44 +0100
committerMax Kellermann <max@duempel.org>2014-01-15 12:05:44 +0100
commit9fb82f9687c10ee8430437a97e263c85f968bddb (patch)
tree16ee0270c77e1a9662ac6ef3ba4e0959d5488f06
parentdf80deb0708f9abe911dc3533c0d3b310f73650c (diff)
downloadmpd-9fb82f9687c10ee8430437a97e263c85f968bddb.tar.gz
mpd-9fb82f9687c10ee8430437a97e263c85f968bddb.tar.xz
mpd-9fb82f9687c10ee8430437a97e263c85f968bddb.zip
DetachedSong: add method Update()
Don't create an intermediate Song instance when all we want is a DetachedSong.
-rw-r--r--src/DetachedSong.hxx7
-rw-r--r--src/PlaylistEdit.cxx8
-rw-r--r--src/PlaylistSong.cxx9
-rw-r--r--src/SongUpdate.cxx37
-rw-r--r--src/command/OtherCommands.cxx9
5 files changed, 55 insertions, 15 deletions
diff --git a/src/DetachedSong.hxx b/src/DetachedSong.hxx
index 2059d2367..a99cbb4c8 100644
--- a/src/DetachedSong.hxx
+++ b/src/DetachedSong.hxx
@@ -179,6 +179,13 @@ public:
gcc_pure
double GetDuration() const;
+
+ /**
+ * Update the #tag and #mtime.
+ *
+ * @return true on success
+ */
+ bool Update();
};
#endif
diff --git a/src/PlaylistEdit.cxx b/src/PlaylistEdit.cxx
index 24184d0e4..3f9015765 100644
--- a/src/PlaylistEdit.cxx
+++ b/src/PlaylistEdit.cxx
@@ -61,13 +61,11 @@ PlaylistResult
playlist::AppendFile(PlayerControl &pc,
const char *path_utf8, unsigned *added_id)
{
- Song *song = Song::LoadFile(path_utf8, nullptr);
- if (song == nullptr)
+ DetachedSong song(path_utf8);
+ if (!song.Update())
return PlaylistResult::NO_SUCH_SONG;
- const auto result = AppendSong(pc, DetachedSong(*song), added_id);
- song->Free();
- return result;
+ return AppendSong(pc, std::move(song), added_id);
}
PlaylistResult
diff --git a/src/PlaylistSong.cxx b/src/PlaylistSong.cxx
index 4cd076eeb..4fbfb65a4 100644
--- a/src/PlaylistSong.cxx
+++ b/src/PlaylistSong.cxx
@@ -100,12 +100,11 @@ playlist_check_load_song(const DetachedSong *song, const char *uri, bool secure)
if (uri_has_scheme(uri)) {
dest = new DetachedSong(uri);
} else if (PathTraitsUTF8::IsAbsolute(uri) && secure) {
- Song *tmp = Song::LoadFile(uri, nullptr);
- if (tmp == nullptr)
+ dest = new DetachedSong(uri);
+ if (!dest->Update()) {
+ delete dest;
return nullptr;
-
- dest = new DetachedSong(*tmp);
- delete tmp;
+ }
} else {
const Database *db = GetDatabase();
if (db == nullptr)
diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx
index 70a05bf2a..669d0568d 100644
--- a/src/SongUpdate.cxx
+++ b/src/SongUpdate.cxx
@@ -19,6 +19,7 @@
#include "config.h" /* must be first for large file support */
#include "Song.hxx"
+#include "DetachedSong.hxx"
#include "util/UriUtil.hxx"
#include "Directory.hxx"
#include "Mapper.hxx"
@@ -126,3 +127,39 @@ Song::UpdateFileInArchive()
tag = tag_builder.CommitNew();
return true;
}
+
+bool
+DetachedSong::Update()
+{
+ if (IsAbsoluteFile()) {
+ const AllocatedPath path_fs =
+ AllocatedPath::FromUTF8(uri.c_str());
+
+ struct stat st;
+ if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode))
+ return false;
+
+ TagBuilder tag_builder;
+ if (!tag_file_scan(path_fs, full_tag_handler, &tag_builder))
+ return false;
+
+ if (tag_builder.IsEmpty())
+ tag_scan_fallback(path_fs, &full_tag_handler,
+ &tag_builder);
+
+ mtime = st.st_mtime;
+ tag_builder.Commit(tag);
+ return true;
+ } else if (IsRemote()) {
+ TagBuilder tag_builder;
+ if (!tag_stream_scan(uri.c_str(), full_tag_handler,
+ &tag_builder))
+ return false;
+
+ mtime = 0;
+ tag_builder.Commit(tag);
+ return true;
+ } else
+ // TODO: implement
+ return false;
+}
diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx
index 7d7853d0f..0daf62c5a 100644
--- a/src/command/OtherCommands.cxx
+++ b/src/command/OtherCommands.cxx
@@ -23,7 +23,7 @@
#include "CommandError.hxx"
#include "UpdateGlue.hxx"
#include "Directory.hxx"
-#include "Song.hxx"
+#include "DetachedSong.hxx"
#include "SongPrint.hxx"
#include "TagPrint.hxx"
#include "TagStream.hxx"
@@ -140,15 +140,14 @@ handle_lsinfo(Client &client, int argc, char *argv[])
if (!client_allow_file(client, path_fs, error))
return print_error(client, error);
- Song *song = Song::LoadFile(path_utf8, nullptr);
- if (song == nullptr) {
+ DetachedSong song(path_utf8);
+ if (!song.Update()) {
command_error(client, ACK_ERROR_NO_EXIST,
"No such file");
return CommandResult::ERROR;
}
- song_print_info(client, *song);
- song->Free();
+ song_print_info(client, song);
return CommandResult::OK;
}