|
a/dirbrowser/rreaper.h |
|
b/dirbrowser/rreaper.h |
|
... |
|
... |
17 |
|
17 |
|
18 |
#ifndef _RREAPER_H_INCLUDED_
|
18 |
#ifndef _RREAPER_H_INCLUDED_
|
19 |
#define _RREAPER_H_INCLUDED_
|
19 |
#define _RREAPER_H_INCLUDED_
|
20 |
|
20 |
|
21 |
#include <string>
|
21 |
#include <string>
|
22 |
#include <list>
|
|
|
23 |
#include <queue>
|
|
|
24 |
#include <iostream>
|
|
|
25 |
#include "libupnpp/config.h"
|
|
|
26 |
|
22 |
|
27 |
#include <QDebug>
|
|
|
28 |
#include <QThread>
|
23 |
#include <QThread>
|
29 |
|
24 |
|
30 |
#include <upnp/upnp.h>
|
25 |
#include <libupnpp/config.h>
|
|
|
26 |
#include <libupnpp/control/cdirectory.hxx>
|
31 |
|
27 |
|
32 |
#include "libupnpp/control/cdirectory.hxx"
|
28 |
struct CtDesc;
|
33 |
|
|
|
34 |
class RecursiveReaper : public QThread {
|
29 |
class RecursiveReaper : public QThread {
|
35 |
Q_OBJECT;
|
30 |
Q_OBJECT;
|
36 |
|
31 |
|
37 |
public:
|
32 |
public:
|
38 |
RecursiveReaper(UPnPClient::CDSH server, std::string objid,
|
33 |
RecursiveReaper(UPnPClient::CDSH server, std::string objid,
|
39 |
QObject *parent = 0)
|
34 |
QObject *parent = 0);
|
40 |
: QThread(parent), m_serv(server), m_cancel(false)
|
35 |
virtual ~RecursiveReaper();
|
41 |
{
|
|
|
42 |
m_ctobjids.push(objid);
|
|
|
43 |
m_allctobjids.insert(objid);
|
|
|
44 |
}
|
|
|
45 |
|
36 |
|
46 |
~RecursiveReaper()
|
|
|
47 |
{
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
virtual void run() {
|
37 |
virtual void run();
|
51 |
qDebug() << "RecursiveReaper::run";
|
|
|
52 |
m_status = UPNP_E_SUCCESS;
|
|
|
53 |
while (!m_ctobjids.empty()) {
|
|
|
54 |
if (m_cancel) {
|
|
|
55 |
qDebug() << "RecursiveReaper:: cancelled";
|
|
|
56 |
break;
|
|
|
57 |
}
|
|
|
58 |
// We don't stop on a container scan error, minimserver for one
|
|
|
59 |
// sometimes has dialog hiccups with libupnp, this is not fatal.
|
|
|
60 |
scanContainer(m_ctobjids.front());
|
|
|
61 |
m_ctobjids.pop();
|
|
|
62 |
}
|
|
|
63 |
emit done(m_status);
|
|
|
64 |
qDebug() << "RecursiveReaper::done";
|
|
|
65 |
}
|
|
|
66 |
|
|
|
67 |
void setCancel() {
|
38 |
void setCancel();
|
68 |
m_cancel = true;
|
39 |
static std::string ttpathPrintable(const std::string in);
|
69 |
}
|
|
|
70 |
|
40 |
|
71 |
signals:
|
41 |
signals:
|
72 |
void sliceAvailable(UPnPClient::UPnPDirContent*);
|
42 |
void sliceAvailable(UPnPClient::UPnPDirContent*);
|
73 |
void done(int);
|
43 |
void done(int);
|
74 |
|
44 |
|
75 |
private:
|
45 |
private:
|
76 |
|
46 |
bool scanContainer(const CtDesc* ctdesc);
|
77 |
virtual bool scanContainer(const std::string& objid) {
|
47 |
class Internal;
|
78 |
//qDebug() << "RecursiveReaper::scanCT: objid:" << objid.c_str();
|
48 |
Internal *m;
|
79 |
|
|
|
80 |
int offset = 0;
|
|
|
81 |
int toread = 20; // read small count the first time
|
|
|
82 |
int total = 1000;// Updated on first read.
|
|
|
83 |
int count;
|
|
|
84 |
|
|
|
85 |
while (offset < total) {
|
|
|
86 |
if (m_cancel) {
|
|
|
87 |
qDebug() << "RecursiveReaper:: cancelled";
|
|
|
88 |
break;
|
|
|
89 |
}
|
|
|
90 |
UPnPClient::UPnPDirContent& slice =
|
|
|
91 |
*(new UPnPClient::UPnPDirContent());
|
|
|
92 |
|
|
|
93 |
unsigned int lastctidx = slice.m_containers.size();
|
|
|
94 |
|
|
|
95 |
// Read entries
|
|
|
96 |
m_status = m_serv->readDirSlice(objid, offset, toread,
|
|
|
97 |
slice, &count, &total);
|
|
|
98 |
if (m_status != UPNP_E_SUCCESS) {
|
|
|
99 |
return false;
|
|
|
100 |
}
|
|
|
101 |
offset += count;
|
|
|
102 |
|
|
|
103 |
// Put containers aside for later exploration
|
|
|
104 |
for (std::vector<UPnPClient::UPnPDirObject>::iterator it =
|
|
|
105 |
slice.m_containers.begin() + lastctidx;
|
|
|
106 |
it != slice.m_containers.end(); it++) {
|
|
|
107 |
if (it->m_title.empty())
|
|
|
108 |
continue;
|
|
|
109 |
if (m_serv->getKind() ==
|
|
|
110 |
UPnPClient::ContentDirectory::CDSKIND_MINIM &&
|
|
|
111 |
it->m_title.size() >= 2 && it->m_title[0] == '>' &&
|
|
|
112 |
it->m_title[1] == '>') {
|
|
|
113 |
continue;
|
|
|
114 |
}
|
|
|
115 |
if (m_allctobjids.find(it->m_id) != m_allctobjids.end()) {
|
|
|
116 |
qDebug() << "scanContainer: loop detected";
|
|
|
117 |
continue;
|
|
|
118 |
}
|
|
|
119 |
//qDebug()<< "scanContainer: pushing objid " << it->m_id.c_str()
|
|
|
120 |
// << " title " << it->m_title.c_str();
|
|
|
121 |
m_allctobjids.insert(it->m_id);
|
|
|
122 |
m_ctobjids.push(it->m_id);
|
|
|
123 |
}
|
|
|
124 |
slice.m_containers.clear();
|
|
|
125 |
|
|
|
126 |
// Make items available
|
|
|
127 |
if (!slice.m_items.empty()) {
|
|
|
128 |
qDebug() << "RecursiveReaper::scanCT got " <<
|
|
|
129 |
slice.m_items.size() << " items";
|
|
|
130 |
emit sliceAvailable(&slice);
|
|
|
131 |
}
|
|
|
132 |
toread = m_serv->goodSliceSize();
|
|
|
133 |
}
|
|
|
134 |
|
|
|
135 |
return true;
|
|
|
136 |
}
|
|
|
137 |
|
|
|
138 |
UPnPClient::CDSH m_serv;
|
|
|
139 |
std::queue<std::string> m_ctobjids;
|
|
|
140 |
STD_UNORDERED_SET<std::string> m_allctobjids;
|
|
|
141 |
int m_status;
|
|
|
142 |
bool m_cancel;
|
|
|
143 |
};
|
49 |
};
|
144 |
|
50 |
|
145 |
#endif /* _RREAPER_H_INCLUDED_ */
|
51 |
#endif /* _RREAPER_H_INCLUDED_ */
|