From efdb41f2a6c194f0ec6371684a8f6b8fcdbe0bcd Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 14 Jan 2014 12:22:37 +0100 Subject: db/upnp/Object: add attribute "name" Call titleToPathElt() only once for each object. --- src/db/upnp/Directory.cxx | 23 ++++++++++++++++++++--- src/db/upnp/Object.hxx | 10 ++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/db/upnp') diff --git a/src/db/upnp/Directory.cxx b/src/db/upnp/Directory.cxx index 3b75eceda..ba759837d 100644 --- a/src/db/upnp/Directory.cxx +++ b/src/db/upnp/Directory.cxx @@ -22,6 +22,7 @@ #include "Util.hxx" #include "Expat.hxx" +#include #include #include @@ -57,6 +58,19 @@ ParseDuration(const std::string &duration) return atoi(v[0].c_str())*3600 + atoi(v[1].c_str())*60 + atoi(v[2].c_str()); } +/** + * Transform titles to turn '/' into '_' to make them acceptable path + * elements. There is a very slight risk of collision in doing + * this. Twonky returns directory names (titles) like 'Artist/Album'. + */ +gcc_pure +static std::string +titleToPathElt(std::string s) +{ + std::replace(s.begin(), s.end(), '/', '_'); + return s; +} + /** * An XML parser which builds directory contents from DIDL lite input. */ @@ -125,7 +139,7 @@ protected: bool checkobjok() { if (m_tobj.m_id.empty() || m_tobj.m_pid.empty() || - m_tobj.m_title.empty() || + m_tobj.name.empty() || (m_tobj.type == UPnPDirObject::Type::ITEM && m_tobj.item_class == UPnPDirObject::ItemClass::UNKNOWN)) return false; @@ -154,8 +168,11 @@ protected: trimstring(str); switch (m_path.back()[0]) { case 'd': - if (!m_path.back().compare("dc:title")) - m_tobj.m_title += str; + if (!m_path.back().compare("dc:title")) { + m_tobj.m_title = str; + m_tobj.name = titleToPathElt(str); + } + break; case 'r': if (!m_path.back().compare("res")) { diff --git a/src/db/upnp/Object.hxx b/src/db/upnp/Object.hxx index d158ab6f7..1346c15d4 100644 --- a/src/db/upnp/Object.hxx +++ b/src/db/upnp/Object.hxx @@ -52,6 +52,12 @@ public: std::string m_id; // ObjectId std::string m_pid; // Parent ObjectId std::string url; + + /** + * A copy of "dc:title" sanitized as a file name. + */ + std::string name; + std::string m_title; // dc:title. Directory name for a container. Type type; ItemClass item_class; @@ -71,8 +77,8 @@ public: * @param[out] value * @return true if found. */ - const char *getprop(const char *name) const { - auto it = m_props.find(name); + 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(); -- cgit v1.2.3