Parent: [7c3c3d] (diff)

Child: [0cbbaf] (diff)

Download this file

ohpool.cpp    115 lines (104 with data), 4.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* Copyright (C) 2015 J.F.Dockes
* 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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "ohpool.h"
#include <string>
#include <vector>
#include <QDebug>
#include "libupnpp/control/ohplaylist.hxx"
#include "libupnpp/control/ohradio.hxx"
using namespace std;
template <class T>
bool ohupdmetapool(const vector<int>& nids, int curid,
STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>& metapool,
T srv)
{
// Clean up metapool entries not in ids. We build a set with
// the new ids list first. For small lists it does not matter,
// for big ones, this will prevent what would otherwise be a
// linear search the repeated search to make this
// quadratic. We're sort of O(n * log(n)) instead.
if (!metapool.empty() && !nids.empty()){
STD_UNORDERED_SET<int> tmpset(nids.begin(), nids.end());
for (STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>::iterator it
= metapool.begin(); it != metapool.end(); ) {
if (tmpset.find(it->first) == tmpset.end()) {
it = metapool.erase(it);
} else {
it++;
}
}
}
// Find ids for which we have no metadata. Always re-read current title
vector<int> unids; // unknown
for (vector<int>::const_iterator it = nids.begin();
it != nids.end(); it++) {
if (metapool.find(*it) == metapool.end() || curid == *it)
unids.push_back(*it);
}
if (!unids.empty()) {
//qDebug() << "OHPL::onIdArrayChanged: need metadata for: "
// << ivtos(unids).c_str();
}
// Fetch needed metadata, 10 entries at a time
const unsigned int batchsize(10);
for (unsigned int i = 0; i < unids.size();) {
unsigned int j = 0;
vector<int> metaslice;
for (; j < batchsize && (i+j) < unids.size(); j++) {
metaslice.push_back(unids[i+j]);
}
//qDebug() << "OHPL::onIdArrayChanged: Requesting metadata for "
//<< vtos(metaslice).c_str();
vector<UPnPClient::OHPlaylist::TrackListEntry> entries;
int ret;
if ((ret = srv->readList(metaslice, &entries))) {
qDebug() << "OHPL: readList failed: " << ret;
return false;
}
for (vector<UPnPClient::OHPlaylist::TrackListEntry>::iterator
it = entries.begin(); it != entries.end(); it++) {
// Kazoo for example does not set a resource (uri)
// inside the dirent. Set it from the uri field in
// this case.
if (it->dirent.m_resources.empty()) {
UPnPClient::UPnPResource res;
res.m_uri = it->url;
it->dirent.m_resources.push_back(res);
}
metapool[it->id] = it->dirent;
}
i += j;
}
#if 0
qDebug() << "Metadata Pool now: ";
for (STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>::const_iterator it
= metapool.begin(); it != metapool.end(); it++) {
qDebug() << "Id " << it->first << "->\n" << it->second.dump().c_str();
}
#endif
return true;
}
template bool
ohupdmetapool<UPnPClient::OHPLH>
(const vector<int>&, int,
STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>& ,
UPnPClient::OHPLH);
template bool
ohupdmetapool<UPnPClient::OHRDH>
(const vector<int>&, int,
STD_UNORDERED_MAP<int, UPnPClient::UPnPDirObject>& ,
UPnPClient::OHRDH);