From f33f891c54b22233083e82e3743af5ca74a85128 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 18 Jan 2014 15:27:54 +0100 Subject: db/upnp: add UpnpMakeAction() helper function --- src/db/upnp/Action.hxx | 56 +++++++++++++++++++++++++++++++++ src/db/upnp/ContentDirectoryService.cxx | 52 +++++++++++++----------------- 2 files changed, 78 insertions(+), 30 deletions(-) create mode 100644 src/db/upnp/Action.hxx (limited to 'src/db/upnp') diff --git a/src/db/upnp/Action.hxx b/src/db/upnp/Action.hxx new file mode 100644 index 000000000..28c88be92 --- /dev/null +++ b/src/db/upnp/Action.hxx @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_UPNP_ACTION_HXX +#define MPD_UPNP_ACTION_HXX + +#include "Compiler.h" + +#include + +static inline constexpr unsigned +CountNameValuePairs() +{ + return 0; +} + +template +static inline constexpr unsigned +CountNameValuePairs(gcc_unused const char *name, gcc_unused const char *value, + Args... args) +{ + return 1 + CountNameValuePairs(args...); +} + +/** + * A wrapper for UpnpMakeAction() that counts the number of name/value + * pairs and adds the nullptr sentinel. + */ +template +static inline IXML_Document * +MakeActionHelper(const char *action_name, const char *service_type, + Args... args) +{ + const unsigned n = CountNameValuePairs(args...); + return UpnpMakeAction(action_name, service_type, n, + args..., + nullptr, nullptr); +} + +#endif diff --git a/src/db/upnp/ContentDirectoryService.cxx b/src/db/upnp/ContentDirectoryService.cxx index 9349c1163..aea8144bf 100644 --- a/src/db/upnp/ContentDirectoryService.cxx +++ b/src/db/upnp/ContentDirectoryService.cxx @@ -24,12 +24,11 @@ #include "ixmlwrap.hxx" #include "Directory.hxx" #include "Util.hxx" +#include "Action.hxx" #include "util/Error.hxx" #include -#include - ContentDirectoryService::ContentDirectoryService(const UPnPDevice &device, const UPnPService &service) :m_actionURL(caturl(device.URLBase, service.controlURL)), @@ -80,17 +79,15 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl, char ofbuf[100], cntbuf[100]; sprintf(ofbuf, "%d", offset); sprintf(cntbuf, "%d", count); - int argcnt = 6; // Some devices require an empty SortCriteria, else bad params IXML_Document *request = - UpnpMakeAction("Browse", m_serviceType.c_str(), argcnt, - "ObjectID", objectId, - "BrowseFlag", "BrowseDirectChildren", - "Filter", "*", - "SortCriteria", "", - "StartingIndex", ofbuf, - "RequestedCount", cntbuf, - nullptr, nullptr); + MakeActionHelper("Browse", m_serviceType.c_str(), + "ObjectID", objectId, + "BrowseFlag", "BrowseDirectChildren", + "Filter", "*", + "SortCriteria", "", + "StartingIndex", ofbuf, + "RequestedCount", cntbuf); if (request == nullptr) { error.Set(upnp_domain, "UpnpMakeAction() failed"); return false; @@ -165,18 +162,15 @@ ContentDirectoryService::search(UpnpClient_Handle hdl, while (offset < total) { char ofbuf[100]; sprintf(ofbuf, "%d", offset); - // Create request - int argcnt = 6; IXML_Document *request = - UpnpMakeAction("Search", m_serviceType.c_str(), argcnt, - "ContainerID", objectId, - "SearchCriteria", ss, - "Filter", "*", - "SortCriteria", "", - "StartingIndex", ofbuf, - "RequestedCount", "0", // Setting a value here gets twonky into fits - nullptr, nullptr); + MakeActionHelper("Search", m_serviceType.c_str(), + "ContainerID", objectId, + "SearchCriteria", ss, + "Filter", "*", + "SortCriteria", "", + "StartingIndex", ofbuf, + "RequestedCount", "0"); // Setting a value here gets twonky into fits if (request == 0) { error.Set(upnp_domain, "UpnpMakeAction() failed"); return false; @@ -270,16 +264,14 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl, Error &error) { // Create request - int argcnt = 6; IXML_Document *request = - UpnpMakeAction("Browse", m_serviceType.c_str(), argcnt, - "ObjectID", objectId, - "BrowseFlag", "BrowseMetadata", - "Filter", "*", - "SortCriteria", "", - "StartingIndex", "0", - "RequestedCount", "1", - nullptr, nullptr); + MakeActionHelper("Browse", m_serviceType.c_str(), + "ObjectID", objectId, + "BrowseFlag", "BrowseMetadata", + "Filter", "*", + "SortCriteria", "", + "StartingIndex", "0", + "RequestedCount", "1"); if (request == nullptr) { error.Set(upnp_domain, "UpnpMakeAction() failed"); return false; -- cgit v1.2.3