diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/upnp/Directory.cxx | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/src/db/upnp/Directory.cxx b/src/db/upnp/Directory.cxx index 1108d9878..9d3e0daeb 100644 --- a/src/db/upnp/Directory.cxx +++ b/src/db/upnp/Directory.cxx @@ -28,17 +28,26 @@ #include <algorithm> #include <string> -#include <vector> #include <string.h> +gcc_pure gcc_nonnull_all +static bool +CompareStringLiteral(const char *literal, const char *value, size_t length) +{ + return length == strlen(literal) && + memcmp(literal, value, length) == 0; +} + gcc_pure static UPnPDirObject::ItemClass -ParseItemClass(const char *name) +ParseItemClass(const char *name, size_t length) { - if (strcmp(name, "object.item.audioItem.musicTrack") == 0) + if (CompareStringLiteral("object.item.audioItem.musicTrack", + name, length)) return UPnPDirObject::ItemClass::MUSIC; - else if (strcmp(name, "object.item.playlistItem") == 0) + else if (CompareStringLiteral("object.item.playlistItem", + name, length)) return UPnPDirObject::ItemClass::PLAYLIST; else return UPnPDirObject::ItemClass::UNKNOWN; @@ -88,7 +97,11 @@ titleToPathElt(std::string &&s) class UPnPDirParser final : public CommonExpatParser { UPnPDirContent &m_dir; - std::vector<std::string> m_path; + enum { + NONE, + RES, + CLASS, + } state; /** * If not equal to #TAG_NUM_OF_ITEM_TYPES, then we're @@ -108,6 +121,7 @@ class UPnPDirParser final : public CommonExpatParser { public: UPnPDirParser(UPnPDirContent& dir) :m_dir(dir), + state(NONE), tag_type(TAG_NUM_OF_ITEM_TYPES) { } @@ -115,8 +129,6 @@ public: protected: virtual void StartElement(const XML_Char *name, const XML_Char **attrs) { - m_path.push_back(name); - if (m_tobj.type != UPnPDirObject::Type::UNKNOWN && tag_type == TAG_NUM_OF_ITEM_TYPES) { tag_type = tag_table_lookup(upnp_tags, name); @@ -167,9 +179,15 @@ protected: GetAttribute(attrs, "duration"); if (duration != nullptr) tag.SetTime(ParseDuration(duration)); + + state = RES; } break; + + case 'u': + if (strcmp(name, "upnp:class") == 0) + state = CLASS; } } @@ -204,7 +222,7 @@ protected: m_dir.objects.push_back(std::move(m_tobj)); } - m_path.pop_back(); + state = NONE; } virtual void CharacterData(const XML_Char *s, int len) @@ -216,20 +234,16 @@ protected: return; } - const auto ¤t = m_path.back(); - std::string str = trimstring(s, len); + switch (state) { + case NONE: + break; - switch (current[0]) { - case 'r': - if (!current.compare("res")) { - m_tobj.url = std::move(str); - } + case RES: + m_tobj.url.assign(s, len); break; - case 'u': - if (current == "upnp:class") { - m_tobj.item_class = ParseItemClass(str.c_str()); - break; - } + + case CLASS: + m_tobj.item_class = ParseItemClass(s, len); break; } } |