|
a/src/upmpdutils.cxx |
|
b/src/upmpdutils.cxx |
|
... |
|
... |
47 |
#include "libupnpp/soaphelp.hxx" // for xmlQuote
|
47 |
#include "libupnpp/soaphelp.hxx" // for xmlQuote
|
48 |
#include "libupnpp/upnpavutils.hxx" // for upnpduration
|
48 |
#include "libupnpp/upnpavutils.hxx" // for upnpduration
|
49 |
#include "libupnpp/control/cdircontent.hxx"
|
49 |
#include "libupnpp/control/cdircontent.hxx"
|
50 |
|
50 |
|
51 |
#include "mpdcli.hxx" // for UpSong
|
51 |
#include "mpdcli.hxx" // for UpSong
|
|
|
52 |
#include "smallut.h"
|
52 |
|
53 |
|
53 |
using namespace std;
|
54 |
using namespace std;
|
54 |
using namespace UPnPP;
|
55 |
using namespace UPnPP;
|
55 |
using namespace UPnPClient;
|
56 |
using namespace UPnPClient;
|
56 |
|
57 |
|
|
... |
|
... |
202 |
<< "</res>"
|
203 |
<< "</res>"
|
203 |
<< "</item></DIDL-Lite>";
|
204 |
<< "</item></DIDL-Lite>";
|
204 |
return ss.str();
|
205 |
return ss.str();
|
205 |
}
|
206 |
}
|
206 |
|
207 |
|
207 |
bool uMetaToUpSong(const string& metadata, UpSong *ups)
|
208 |
// Extract content format (3rd) field from protocolinfo fragment string
|
|
|
209 |
static string protoInfToFormat(const string& protoinfo)
|
208 |
{
|
210 |
{
|
209 |
if (ups == 0) {
|
211 |
vector<string> toks;
|
|
|
212 |
stringToTokens(protoinfo, toks, ":");
|
|
|
213 |
if (toks.size() != 4) {
|
|
|
214 |
LOGDEB("protoInfToFormat: bad format: [" << protoinfo << "]\n");
|
210 |
return false;
|
215 |
return string();
|
211 |
}
|
216 |
}
|
|
|
217 |
return toks[2];
|
|
|
218 |
}
|
212 |
|
219 |
|
213 |
UPnPDirContent dirc;
|
220 |
// This should be made an UPnPResource method one day
|
214 |
if (!dirc.parse(metadata) || dirc.m_items.size() == 0) {
|
221 |
string resourceContentFormat(const UPnPResource& res)
|
|
|
222 |
{
|
|
|
223 |
map<string, string>::const_iterator it = res.m_props.find("protocolInfo");
|
|
|
224 |
if (it == res.m_props.end()) {
|
|
|
225 |
LOGDEB("resourceContentFormat: no protocolInfo attribute\n");
|
215 |
return false;
|
226 |
return string();
|
|
|
227 |
}
|
|
|
228 |
return protoInfToFormat(it->second);
|
|
|
229 |
}
|
|
|
230 |
|
|
|
231 |
bool protocolInfoToFormats(const string& pinfo, unordered_set<string>& formats)
|
|
|
232 |
{
|
|
|
233 |
vector<string> entries;
|
|
|
234 |
stringToTokens(pinfo, entries, ",");
|
|
|
235 |
for (unsigned int i = 0; i < entries.size(); i++) {
|
|
|
236 |
string format = protoInfToFormat(entries[i]);
|
|
|
237 |
if (!format.empty()) {
|
|
|
238 |
LOGDEB("protocolInfoToFormats: Supported format: " << format << endl);
|
|
|
239 |
formats.insert(stringtolower((const string&)format));
|
216 |
}
|
240 |
}
|
217 |
UPnPDirObject& dobj = *dirc.m_items.begin();
|
241 |
}
|
|
|
242 |
return true;
|
|
|
243 |
}
|
218 |
|
244 |
|
|
|
245 |
bool dirObjToUpSong(const UPnPDirObject& dobj, UpSong *ups)
|
|
|
246 |
{
|
219 |
ups->artist = dobj.f2s("upnp:artist", false);
|
247 |
ups->artist = dobj.getprop("upnp:artist");
|
220 |
ups->album = dobj.f2s("upnp:album", false);
|
248 |
ups->album = dobj.getprop("upnp:album");
|
221 |
ups->title = dobj.m_title;
|
249 |
ups->title = dobj.m_title;
|
222 |
string stmp = dobj.f2s("duration", true);
|
250 |
string stmp;
|
|
|
251 |
dobj.getrprop(0, "duration", stmp);
|
223 |
if (!stmp.empty()) {
|
252 |
if (!stmp.empty()) {
|
224 |
ups->duration_secs = upnpdurationtos(stmp);
|
253 |
ups->duration_secs = upnpdurationtos(stmp);
|
225 |
} else {
|
254 |
} else {
|
226 |
ups->duration_secs = 0;
|
255 |
ups->duration_secs = 0;
|
227 |
}
|
256 |
}
|
228 |
ups->tracknum = dobj.f2s("upnp:originalTrackNumber", false);
|
257 |
ups->tracknum = dobj.getprop("upnp:originalTrackNumber");
|
229 |
return true;
|
258 |
return true;
|
230 |
}
|
259 |
}
|
231 |
|
260 |
|
|
|
261 |
bool uMetaToUpSong(const string& metadata, UpSong *ups)
|
|
|
262 |
{
|
|
|
263 |
if (ups == 0) {
|
|
|
264 |
return false;
|
|
|
265 |
}
|
|
|
266 |
|
|
|
267 |
UPnPDirContent dirc;
|
|
|
268 |
if (!dirc.parse(metadata) || dirc.m_items.size() == 0) {
|
|
|
269 |
return false;
|
|
|
270 |
}
|
|
|
271 |
return dirObjToUpSong(*dirc.m_items.begin(), ups);
|
|
|
272 |
}
|
|
|
273 |
|
232 |
// Substitute regular expression
|
274 |
// Substitute regular expression
|
233 |
// The c++11 regex package does not seem really ready from prime time
|
275 |
// The c++11 regex package does not seem really ready from prime time
|
234 |
// (Tried on gcc + libstdc++ 4.7.2-5 on Debian, with little
|
276 |
// (Tried on gcc + libstdc++ 4.7.2-5 on Debian, with little
|
235 |
// joy). So...:
|
277 |
// joy). So...:
|
236 |
string regsub1(const string& sexp, const string& input, const string& repl)
|
278 |
string regsub1(const string& sexp, const string& input, const string& repl)
|