aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db/upnp/Directory.cxx54
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 &current = 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;
}
}