Switch to unified view

a/upmpd/upmpdutils.cxx b/upmpd/upmpdutils.cxx
...
...
178
178
179
    pos = s.find_last_not_of(ws);
179
    pos = s.find_last_not_of(ws);
180
    if (pos != string::npos && pos != s.length()-1)
180
    if (pos != string::npos && pos != s.length()-1)
181
    s.replace(pos+1, string::npos, string());
181
    s.replace(pos+1, string::npos, string());
182
}
182
}
183
void stringToTokens(const string& str, vector<string>& tokens,
184
          const string& delims, bool skipinit)
185
{
186
    string::size_type startPos = 0, pos;
187
188
    // Skip initial delims, return empty if this eats all.
189
    if (skipinit && 
190
  (startPos = str.find_first_not_of(delims, 0)) == string::npos) {
191
  return;
192
    }
193
    while (startPos < str.size()) { 
194
        // Find next delimiter or end of string (end of token)
195
        pos = str.find_first_of(delims, startPos);
196
197
        // Add token to the vector and adjust start
198
  if (pos == string::npos) {
199
      tokens.push_back(str.substr(startPos));
200
      break;
201
  } else if (pos == startPos) {
202
      // Dont' push empty tokens after first
203
      if (tokens.empty())
204
      tokens.push_back(string());
205
      startPos = ++pos;
206
  } else {
207
      tokens.push_back(str.substr(startPos, pos - startPos));
208
      startPos = ++pos;
209
  }
210
    }
211
}
183
212
184
string xmlquote(const string& in)
213
string xmlquote(const string& in)
185
{
214
{
186
    string out;
215
    string out;
187
    for (unsigned int i = 0; i < in.size(); i++) {
216
    for (unsigned int i = 0; i < in.size(); i++) {
...
...
283
    return out;
312
    return out;
284
}
313
}
285
314
286
// Bogus didl fragment maker. We probably don't need a full-blown XML
315
// Bogus didl fragment maker. We probably don't need a full-blown XML
287
// helper here
316
// helper here
288
string didlmake(const MpdStatus& mpds, bool next)
317
string didlmake(const UpSong& song)
289
{
318
{
290
    const unordered_map<string, string>& songmap = 
291
        next? mpds.nextsong : mpds.currentsong;
292
    ostringstream ss;
319
    ostringstream ss;
293
    ss << "<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\" "
320
    ss << "<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\" "
294
        "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" "
321
        "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" "
295
        "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" "
322
        "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" "
296
        "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">"
323
        "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">"
297
       << "<item restricted=\"1\">";
324
       << "<item restricted=\"1\">";
298
325
299
    {   const string& val = mapget(songmap, "dc:title");
326
    {   const string& val = song.title;
300
        ss << "<dc:title>" << xmlquote(val) << "</dc:title>";
327
        ss << "<dc:title>" << xmlquote(val) << "</dc:title>";
301
    }
328
    }
302
    
329
    
303
    // TBD Playlists etc?
330
    // TBD Playlists etc?
304
    ss << "<upnp:class>object.item.audioItem.musicTrack</upnp:class>";
331
    ss << "<upnp:class>object.item.audioItem.musicTrack</upnp:class>";
305
332
306
    {   const string& val = mapget(songmap, "upnp:artist");
333
    {   const string& val = song.artist;
307
        if (!val.empty()) {
334
        if (!val.empty()) {
308
            string a = xmlquote(val);
335
            string a = xmlquote(val);
309
            ss << "<dc:creator>" << a << "</dc:creator>" << 
336
            ss << "<dc:creator>" << a << "</dc:creator>" << 
310
                "<upnp:artist>" << a << "</upnp:artist>";
337
                "<upnp:artist>" << a << "</upnp:artist>";
311
        }
338
        }
312
    }
339
    }
313
340
314
    {   const string& val = mapget(songmap, "upnp:album");
341
    {   const string& val = song.album;
315
        if (!val.empty()) {
342
        if (!val.empty()) {
316
            ss << "<upnp:album>" << xmlquote(val) << "</upnp:album>";
343
            ss << "<upnp:album>" << xmlquote(val) << "</upnp:album>";
317
        }
344
        }
318
    }
345
    }
319
346
320
    {   const string& val = mapget(songmap, "upnp:genre");
347
    {   const string& val = song.genre;
321
        if (!val.empty()) {
348
        if (!val.empty()) {
322
            ss << "<upnp:genre>" << xmlquote(val) << "</upnp:genre>";
349
            ss << "<upnp:genre>" << xmlquote(val) << "</upnp:genre>";
323
        }
350
        }
324
    }
351
    }
325
352
326
    {const string& val = mapget(songmap, "upnp:originalTrackNumber");
353
    {const string& val = song.tracknum;
327
        if (!val.empty()) {
354
        if (!val.empty()) {
328
            ss << "<upnp:originalTrackNumber>" << val << 
355
            ss << "<upnp:originalTrackNumber>" << val << 
329
                "</upnp:originalTrackNumber>";
356
                "</upnp:originalTrackNumber>";
330
        }
357
        }
331
    }
358
    }
...
...
333
    // TBD: the res element normally has size, sampleFrequency,
360
    // TBD: the res element normally has size, sampleFrequency,
334
    // nrAudioChannels and protocolInfo attributes, which are bogus
361
    // nrAudioChannels and protocolInfo attributes, which are bogus
335
    // for the moment. partly because MPD does not supply them.  And
362
    // for the moment. partly because MPD does not supply them.  And
336
    // mostly everything is bogus if next is set...  
363
    // mostly everything is bogus if next is set...  
337
364
338
    ss << "<res " << "duration=\"" << upnpduration(mpds.songlenms) << "\" "
365
    ss << "<res " << "duration=\"" << upnpduration(song.duration_secs * 1000) 
366
       << "\" "
339
    // Bitrate keeps changing for VBRs and forces events. Keeping
367
    // Bitrate keeps changing for VBRs and forces events. Keeping
340
    // it out for now.
368
    // it out for now.
341
    //       << "bitrate=\"" << mpds.kbrate << "\" "
369
    //       << "bitrate=\"" << mpds.kbrate << "\" "
342
       << "sampleFrequency=\"44100\" audioChannels=\"2\" "
370
       << "sampleFrequency=\"44100\" audioChannels=\"2\" "
343
       << "protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\""
371
       << "protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\""
344
       << ">"
372
       << ">"
345
       << xmlquote(mapget(songmap, "uri")) 
373
       << xmlquote(song.uri) 
346
       << "</res>"
374
       << "</res>"
347
       << "</item></DIDL-Lite>";
375
       << "</item></DIDL-Lite>";
348
    return ss.str();
376
    return ss.str();
349
}
377
}
350
378