diff options
author | Max Kellermann <max@musicpd.org> | 2018-01-02 13:21:40 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-01-02 14:16:57 +0100 |
commit | 0a4b866d8a191949a2b85a121418457d713342cf (patch) | |
tree | 89f51b8f153d77d6c4020141b4ff26a0863491c4 /src | |
parent | 8c7d7dfa5bf37ff80bbe7fb1cf9d7221f9211e1d (diff) |
db/upnp: use SplitString() instead of stringToTokens()
Diffstat (limited to 'src')
-rw-r--r-- | src/db/plugins/upnp/UpnpDatabasePlugin.cxx | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/src/db/plugins/upnp/UpnpDatabasePlugin.cxx b/src/db/plugins/upnp/UpnpDatabasePlugin.cxx index f25b27f10..f0b0789a7 100644 --- a/src/db/plugins/upnp/UpnpDatabasePlugin.cxx +++ b/src/db/plugins/upnp/UpnpDatabasePlugin.cxx @@ -24,7 +24,6 @@ #include "lib/upnp/ClientInit.hxx" #include "lib/upnp/Discovery.hxx" #include "lib/upnp/ContentDirectoryService.hxx" -#include "lib/upnp/Util.hxx" #include "db/Interface.hxx" #include "db/DatabasePlugin.hxx" #include "db/Selection.hxx" @@ -39,9 +38,9 @@ #include "fs/Traits.hxx" #include "Log.hxx" #include "SongFilter.hxx" +#include "util/SplitString.hxx" #include <string> -#include <vector> #include <set> #include <assert.h> @@ -105,7 +104,7 @@ public: private: void VisitServer(const ContentDirectoryService &server, - const std::list<std::string> &vpath, + std::forward_list<std::string> &&vpath, const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, @@ -125,7 +124,7 @@ private: const DatabaseSelection &selection) const; UPnPDirObject Namei(const ContentDirectoryService &server, - const std::list<std::string> &vpath) const; + std::forward_list<std::string> &&vpath) const; /** * Take server and objid, return metadata. @@ -186,20 +185,28 @@ UpnpDatabase::ReturnSong(const LightSong *_song) const const LightSong * UpnpDatabase::GetSong(const char *uri) const { - auto vpath = stringToTokens(uri, '/'); - if (vpath.size() < 2) + auto vpath = SplitString(uri, '/'); + if (vpath.empty()) throw DatabaseError(DatabaseErrorCode::NOT_FOUND, "No such song"); auto server = discovery->GetServer(vpath.front().c_str()); - vpath.pop_front(); + if (vpath.empty()) + throw DatabaseError(DatabaseErrorCode::NOT_FOUND, + "No such song"); + UPnPDirObject dirent; if (vpath.front() != rootid) { - dirent = Namei(server, vpath); + dirent = Namei(server, std::move(vpath)); } else { - dirent = ReadNode(server, vpath.back().c_str()); + vpath.pop_front(); + if (vpath.empty()) + throw DatabaseError(DatabaseErrorCode::NOT_FOUND, + "No such song"); + + dirent = ReadNode(server, vpath.front().c_str()); } return new UpnpSong(std::move(dirent), uri); @@ -410,7 +417,7 @@ UpnpDatabase::BuildPath(const ContentDirectoryService &server, // Take server and internal title pathname and return objid and metadata. UPnPDirObject UpnpDatabase::Namei(const ContentDirectoryService &server, - const std::list<std::string> &vpath) const + std::forward_list<std::string> &&vpath) const { if (vpath.empty()) // looking for root info @@ -419,16 +426,17 @@ UpnpDatabase::Namei(const ContentDirectoryService &server, std::string objid(rootid); // Walk the path elements, read each directory and try to find the next one - for (auto i = vpath.begin(), last = std::prev(vpath.end());; ++i) { + while (true) { auto dirbuf = server.readDir(handle, objid.c_str()); // Look for the name in the sub-container list - UPnPDirObject *child = dirbuf.FindObject(i->c_str()); + UPnPDirObject *child = dirbuf.FindObject(vpath.front().c_str()); if (child == nullptr) throw DatabaseError(DatabaseErrorCode::NOT_FOUND, "No such object"); - if (i == last) + vpath.pop_front(); + if (vpath.empty()) return std::move(*child); if (child->type != UPnPDirObject::Type::CONTAINER) @@ -497,7 +505,7 @@ VisitObject(const UPnPDirObject &object, const char *uri, // really just one path parameter. void UpnpDatabase::VisitServer(const ContentDirectoryService &server, - const std::list<std::string> &vpath, + std::forward_list<std::string> &&vpath, const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, @@ -512,20 +520,18 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server, because the path is not valid for traversal. Besides, it's just faster to access the target node directly */ if (!vpath.empty() && vpath.front() == rootid) { - switch (vpath.size()) { - case 1: + vpath.pop_front(); + if (vpath.empty()) return; - case 2: - break; - - default: + const std::string objid(std::move(vpath.front())); + vpath.pop_front(); + if (!vpath.empty()) throw DatabaseError(DatabaseErrorCode::NOT_FOUND, "Not found"); - } if (visit_song) { - auto dirent = ReadNode(server, vpath.back().c_str()); + auto dirent = ReadNode(server, objid.c_str()); if (dirent.type != UPnPDirObject::Type::ITEM || dirent.item_class != UPnPDirObject::ItemClass::MUSIC) @@ -542,7 +548,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server, } // Translate the target path into an object id and the associated metadata. - const auto tdirent = Namei(server, vpath); + const auto tdirent = Namei(server, std::move(vpath)); /* If recursive is set, this is a search... No use sending it if the filter is empty. In this case, we implement limited @@ -584,7 +590,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection, VisitSong visit_song, VisitPlaylist visit_playlist) const { - auto vpath = stringToTokens(selection.uri, '/'); + auto vpath = SplitString(selection.uri.c_str(), '/'); if (vpath.empty()) { for (const auto &server : discovery->GetDirectories()) { if (visit_directory) { @@ -594,7 +600,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection, } if (selection.recursive) - VisitServer(server, vpath, selection, + VisitServer(server, std::move(vpath), selection, visit_directory, visit_song, visit_playlist); } @@ -607,7 +613,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection, vpath.pop_front(); auto server = discovery->GetServer(servername.c_str()); - VisitServer(server, vpath, selection, + VisitServer(server, std::move(vpath), selection, visit_directory, visit_song, visit_playlist); } |