diff options
-rw-r--r-- | src/db/UpnpDatabasePlugin.cxx | 39 | ||||
-rw-r--r-- | src/db/upnp/Directory.cxx | 39 | ||||
-rw-r--r-- | src/db/upnp/Object.hxx | 29 |
3 files changed, 25 insertions, 82 deletions
diff --git a/src/db/UpnpDatabasePlugin.cxx b/src/db/UpnpDatabasePlugin.cxx index da8aba22c..257797d1a 100644 --- a/src/db/UpnpDatabasePlugin.cxx +++ b/src/db/UpnpDatabasePlugin.cxx @@ -210,21 +210,7 @@ upnpItemToSong(const UPnPDirObject &dirent, const char *uri) uri = dirent.url.c_str(); Song *s = Song::NewFile(uri, nullptr); - - TagBuilder tag; - - if (dirent.duration > 0) - tag.SetTime(dirent.duration); - - tag.AddItem(TAG_TITLE, dirent.m_title.c_str()); - - for (auto i = upnp_tags; i->name != nullptr; ++i) { - const char *value = dirent.getprop(i->name); - if (value != nullptr) - tag.AddItem(i->type, value); - } - - s->tag = tag.CommitNew(); + s->tag = new Tag(dirent.tag); return s; } @@ -268,27 +254,6 @@ UpnpDatabase::GetSong(const char *uri, Error &error) const } /** - * Retrieve the value for an MPD tag from an object entry. - */ -gcc_pure -static const char * -getTagValue(const UPnPDirObject &dirent, TagType tag) -{ - if (tag == TAG_TITLE) { - if (!dirent.m_title.empty()) - return dirent.m_title.c_str(); - - return nullptr; - } - - const char *name = tag_table_lookup(upnp_tags, tag); - if (name == nullptr) - return nullptr; - - return dirent.getprop(name); -} - -/** * Double-quote a string, adding internal backslash escaping. */ static void @@ -801,7 +766,7 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection, dirent.item_class != UPnPDirObject::ItemClass::MUSIC) continue; - const char *value = getTagValue(dirent, tag); + const char *value = dirent.tag.GetValue(tag); if (value != nullptr) { #if defined(__clang__) || GCC_CHECK_VERSION(4,8) values.emplace(value); diff --git a/src/db/upnp/Directory.cxx b/src/db/upnp/Directory.cxx index 35d556c28..3b6428389 100644 --- a/src/db/upnp/Directory.cxx +++ b/src/db/upnp/Directory.cxx @@ -21,6 +21,9 @@ #include "Directory.hxx" #include "Util.hxx" #include "Expat.hxx" +#include "Tags.hxx" +#include "tag/TagBuilder.hxx" +#include "tag/TagTable.hxx" #include <algorithm> #include <string> @@ -28,14 +31,6 @@ #include <string.h> -static const char *const upnptags[] = { - "upnp:artist", - "upnp:album", - "upnp:genre", - "upnp:originalTrackNumber", - nullptr, -}; - gcc_pure static UPnPDirObject::ItemClass ParseItemClass(const char *name) @@ -77,6 +72,7 @@ titleToPathElt(std::string &&s) class UPnPDirParser final : public CommonExpatParser { std::vector<std::string> m_path; UPnPDirObject m_tobj; + TagBuilder tag; public: UPnPDirParser(UPnPDirContent& dir) @@ -130,7 +126,7 @@ protected: const char *duration = GetAttribute(attrs, "duration"); if (duration != nullptr) - m_tobj.duration = ParseDuration(duration); + tag.SetTime(ParseDuration(duration)); } break; @@ -150,8 +146,10 @@ protected: virtual void EndElement(const XML_Char *name) { if ((!strcmp(name, "container") || !strcmp(name, "item")) && - checkobjok()) + checkobjok()) { + tag.Commit(m_tobj.tag); m_dir.objects.push_back(std::move(m_tobj)); + } m_path.pop_back(); } @@ -160,14 +158,19 @@ protected: { std::string str(s, len); trimstring(str); - switch (m_path.back()[0]) { - case 'd': - if (!m_path.back().compare("dc:title")) { - m_tobj.m_title = str; + + TagType type = tag_table_lookup(upnp_tags, + m_path.back().c_str()); + if (type != TAG_NUM_OF_ITEM_TYPES) { + tag.AddItem(type, str.c_str()); + + if (type == TAG_TITLE) m_tobj.name = titleToPathElt(std::move(str)); - } - break; + return; + } + + switch (m_path.back()[0]) { case 'r': if (!m_path.back().compare("res")) { m_tobj.url = str; @@ -178,10 +181,6 @@ protected: m_tobj.item_class = ParseItemClass(str.c_str()); break; } - - for (auto i = upnptags; *i != nullptr; ++i) - if (!m_path.back().compare(*i)) - m_tobj.m_props[*i] += str; break; } } diff --git a/src/db/upnp/Object.hxx b/src/db/upnp/Object.hxx index 1d32d0401..39b8f94f9 100644 --- a/src/db/upnp/Object.hxx +++ b/src/db/upnp/Object.hxx @@ -20,8 +20,9 @@ #ifndef MPD_UPNP_OBJECT_HXX #define MPD_UPNP_OBJECT_HXX +#include "tag/Tag.hxx" + #include <string> -#include <map> /** * UpnP Media Server directory entry, converted from XML data. @@ -61,43 +62,21 @@ public: std::string m_title; // dc:title. Directory name for a container. Type type; ItemClass item_class; - // Properties as gathered from the XML document (url, artist, etc.) - // The map keys are the XML tag or attribute names. - std::map<std::string, std::string> m_props; - /** - * Song duration in seconds. 0 if unknown. - */ - int duration; + Tag tag; UPnPDirObject() = default; UPnPDirObject(UPnPDirObject &&) = default; UPnPDirObject &operator=(UPnPDirObject &&) = default; - /** Get named property - * @param property name (e.g. upnp:artist, upnp:album, - * upnp:originalTrackNumber, upnp:genre). Use m_title instead - * for dc:title. - * @param[out] value - * @return true if found. - */ - const char *getprop(const char *_name) const { - auto it = m_props.find(_name); - if (it == m_props.end()) - return nullptr; - return it->second.c_str(); - } - void clear() { m_id.clear(); m_pid.clear(); url.clear(); - m_title.clear(); type = Type::UNKNOWN; item_class = ItemClass::UNKNOWN; - m_props.clear(); - duration = -1; + tag.Clear(); } }; |