diff options
author | Max Kellermann <max@duempel.org> | 2014-01-15 12:05:44 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-01-15 12:05:44 +0100 |
commit | 9fb82f9687c10ee8430437a97e263c85f968bddb (patch) | |
tree | 16ee0270c77e1a9662ac6ef3ba4e0959d5488f06 | |
parent | df80deb0708f9abe911dc3533c0d3b310f73650c (diff) |
DetachedSong: add method Update()
Don't create an intermediate Song instance when all we want is a
DetachedSong.
-rw-r--r-- | src/DetachedSong.hxx | 7 | ||||
-rw-r--r-- | src/PlaylistEdit.cxx | 8 | ||||
-rw-r--r-- | src/PlaylistSong.cxx | 9 | ||||
-rw-r--r-- | src/SongUpdate.cxx | 37 | ||||
-rw-r--r-- | src/command/OtherCommands.cxx | 9 |
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; } |