MythTV master
dsmcccache.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) David C.J. Matthews 2005, 2006
3 * Derived from libdsmcc by Richard Palmer
4 */
5#include <cstring> // For memcmp
6
7#include <QStringList>
8
10
11#include "dsmcccache.h"
12#include "dsmccbiop.h"
13#include "dsmccreceiver.h"
14#include "dsmcc.h"
15
32 // Delete all this when the cache is deleted.
33 : m_dsmcc(dsmcc)
34{
35}
36
38{
39 QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir;
40 QMap<DSMCCCacheReference, DSMCCCacheFile*>::Iterator fil;
41
42 for (dir = m_directories.begin(); dir != m_directories.end(); ++dir)
43 delete *dir;
44
45 for (dir = m_gateways.begin(); dir != m_gateways.end(); ++dir)
46 delete *dir;
47
48 for (fil = m_files.begin(); fil != m_files.end(); ++fil)
49 delete *fil;
50}
51
52// Print out a key for debugging.
54{
55 QString result;
56 for (int i = 0; i < 4 && i < size(); i++)
57 result += QString("%1").arg(static_cast<uint>(at(i)), 2, 16, QChar('0'));
58 return result;
59}
60
61// Ordering function used in QMap
62bool operator < (const DSMCCCacheKey &key1, const DSMCCCacheKey &key2)
63{
64 const char *data1 = key1.data();
65 const char *data2 = key2.data();
66 uint size1 = key1.size();
67 uint size2 = key2.size();
68 uint size = 0;
69 if (size1 < size2)
70 size = size1;
71 else
72 size = size2;
73 int res = memcmp(data1, data2, size);
74 if (res < 0)
75 return true;
76 if (res > 0)
77 return false;
78
79 return size1 < size2;
80}
81
82// Test for equality of the cache references
83// which include the carousel and module ids.
85{
88}
89
91{
92 return p != nullptr && Equal(*p);
93}
94
95
96// Print out a cache reference for debugging.
98{
99 return QString("%1-%2-%3-")
100 .arg(m_nCarouselId).arg(m_nStreamTag)
101 .arg(m_nModuleId) + m_key.toString();
102}
103
104// Operator required for QMap
106 const DSMCCCacheReference &ref2)
107{
108 if (ref1.m_nCarouselId < ref2.m_nCarouselId)
109 return true;
110 if (ref1.m_nCarouselId > ref2.m_nCarouselId)
111 return false;
112 if (ref1.m_nStreamTag < ref2.m_nStreamTag)
113 return true;
114 if (ref1.m_nStreamTag > ref2.m_nStreamTag)
115 return false;
116 if (ref1.m_nModuleId < ref2.m_nModuleId)
117 return true;
118 if (ref1.m_nModuleId > ref2.m_nModuleId)
119 return false;
120 if (ref1.m_key < ref2.m_key)
121 return true;
122
123 return false;
124}
125
126// Create a gateway entry.
128{
129 // Check to see that it isn't already there. It shouldn't be.
130 QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
131 m_gateways.find(ref);
132
133 if (dir != m_gateways.end())
134 {
135 LOG(VB_DSMCC, LOG_ERR, QString("[DSMCCCache] Already seen gateway %1")
136 .arg(ref.toString()));
137 return *dir;
138 }
139
140 LOG(VB_DSMCC, LOG_INFO, QString("[DSMCCCache] New gateway reference %1")
141 .arg(ref.toString()));
142
143 auto *pSrg = new DSMCCCacheDir(ref);
144 m_gateways.insert(ref, pSrg);
145
146 return pSrg;
147}
148
149// Create a directory entry.
151{
152 // Check to see that it isn't already there. It shouldn't be.
153 QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
154 m_directories.find(ref);
155
156 if (dir != m_directories.end())
157 {
158 LOG(VB_DSMCC, LOG_ERR, QString("[DSMCCCache] Already seen directory %1")
159 .arg(ref.toString()));
160 return *dir;
161 }
162
163 LOG(VB_DSMCC, LOG_INFO, QString("[DSMCCCache] New directory reference %1")
164 .arg(ref.toString()));
165
166 auto *pDir = new DSMCCCacheDir(ref);
167 m_directories.insert(ref, pDir);
168
169 return pDir;
170}
171
172// Called when the data for a file module arrives.
174 const QByteArray &data)
175{
176 // Do we have the file already?
177 LOG(VB_DSMCC, LOG_INFO,
178 QString("[DSMCCCache] Adding file data size %1 for reference %2")
179 .arg(data.size()).arg(ref.toString()));
180
181 QMap<DSMCCCacheReference, DSMCCCacheFile*>::Iterator fil =
182 m_files.find(ref);
183
184 DSMCCCacheFile *pFile = nullptr;
185 if (fil == m_files.end())
186 {
187 pFile = new DSMCCCacheFile(ref);
188 m_files.insert(ref, pFile);
189 }
190 else
191 {
192 pFile = *fil;
193 }
194
195 pFile->m_contents = data; // Save the data (this is use-counted by Qt).
196}
197
198// Add a file to the directory.
200{
201 QString name;
202 name = QString::fromStdString(pBB->m_name.m_comps[0].m_id);
203
204 const DSMCCCacheReference *entry =
206
207 pDir->m_files.insert(name, *entry);
208
209 LOG(VB_DSMCC, LOG_INFO,
210 QString("[DSMCCCache] Added file name %1 reference %2 parent %3")
211 .arg(name, entry->toString(), pDir->m_reference.toString()));
212}
213
214// Add a sub-directory to the directory.
216{
217 // Is it already there?
218 QString name;
219 name = QString::fromStdString(pBB->m_name.m_comps[0].m_id);
220 const DSMCCCacheReference *entry =
222
223 pDir->m_subDirectories.insert(name, *entry);
224
225 LOG(VB_DSMCC, LOG_INFO,
226 QString("[DSMCCCache] added subdirectory name %1 reference %2 parent %3")
227 .arg(name, entry->toString(), pDir->m_reference.toString()));
228}
229
230// Find File, Directory or Gateway by reference.
232{
233 // Find a file.
234 QMap<DSMCCCacheReference, DSMCCCacheFile*>::Iterator fil =
235 m_files.find(ref);
236
237 if (fil == m_files.end())
238 return nullptr;
239
240 return *fil;
241}
242
244{
245 // Find a directory.
246 QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
247 m_directories.find(ref);
248
249 if (dir == m_directories.end())
250 return nullptr;
251
252 return *dir;
253}
254
256{
257 // Find a gateway.
258 QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
259 m_gateways.find(ref);
260
261 if (dir == m_gateways.end())
262 return nullptr;
263
264 return *dir;
265}
266
267
268// Return the contents of an object if it exists.
269// Returns zero for success, -1 if we know the object does not
270// currently exist and +1 if the carousel has not so far loaded
271// the object or one of the parent files.
272int DSMCCCache::GetDSMObject(QStringList &objectPath, QByteArray &result)
273{
275 if (dir == nullptr)
276 return 1; // No gateway yet.
277
278 QStringList::Iterator it = objectPath.begin();
279 while (it != objectPath.end())
280 {
281 QString name = *it;
282 ++it;
283 if (it == objectPath.end())
284 { // It's a leaf - look in the file names
285 QMap<QString, DSMCCCacheReference>::Iterator ref =
286 dir->m_files.find(name);
287
288 if (ref == dir->m_files.end())
289 return -1; // Not there.
290
291 DSMCCCacheFile *fil = FindFileData(*ref);
292
293 if (fil == nullptr) // Exists but not yet set.
294 return 1;
295
296 result = fil->m_contents;
297 return 0;
298 }
299
300 // It's a directory
301 QMap<QString, DSMCCCacheReference>::Iterator ref =
302 dir->m_subDirectories.find(name);
303
304 if (ref == dir->m_subDirectories.end())
305 return -1; // Not there
306
307 dir = FindDir(*ref);
308
309 if (dir == nullptr) // Exists but not yet set.
310 return 1;
311 // else search in this directory
312 }
313
314 return -1;
315}
316
317// Set the gateway reference from a DSI message.
319{
320 if (!m_gatewayRef.Equal(ref))
321 {
322 LOG(VB_DSMCC, LOG_INFO, QString("[DSMCCCache] Setting gateway to reference %1")
323 .arg(ref.toString()));
324 m_gatewayRef = ref;
325 }
326}
BiopName m_name
Definition: dsmccbiop.h:154
BiopIor m_ior
Definition: dsmccbiop.h:156
ProfileBody * m_profileBody
Definition: dsmccbiop.h:141
std::string m_id
Definition: dsmccbiop.h:27
BiopNameComp * m_comps
Definition: dsmccbiop.h:40
DSMCCCacheReference m_reference
Definition: dsmcccache.h:72
QMap< QString, DSMCCCacheReference > m_files
Definition: dsmcccache.h:70
QMap< QString, DSMCCCacheReference > m_subDirectories
Definition: dsmcccache.h:69
QByteArray m_contents
Definition: dsmcccache.h:83
QString toString(void) const
Definition: dsmcccache.cpp:53
bool Equal(const DSMCCCacheReference &r) const
Definition: dsmcccache.cpp:84
QString toString(void) const
Definition: dsmcccache.cpp:97
unsigned short m_nStreamTag
Definition: dsmcccache.h:53
unsigned short m_nModuleId
Definition: dsmcccache.h:52
unsigned long m_nCarouselId
Definition: dsmcccache.h:51
DSMCCCacheKey m_key
Definition: dsmcccache.h:54
QMap< DSMCCCacheReference, DSMCCCacheDir * > m_gateways
Definition: dsmcccache.h:120
DSMCCCacheFile * FindFileData(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:231
DSMCCCache(Dsmcc *dsmcc)
Definition: dsmcccache.cpp:31
static void AddDirInfo(DSMCCCacheDir *dir, const BiopBinding *pBB)
Definition: dsmcccache.cpp:215
void SetGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:318
static void AddFileInfo(DSMCCCacheDir *dir, const BiopBinding *pBB)
Definition: dsmcccache.cpp:199
DSMCCCacheDir * Srg(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:127
DSMCCCacheDir * Directory(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:150
DSMCCCacheDir * FindGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:255
DSMCCCacheReference m_gatewayRef
Definition: dsmcccache.h:116
QMap< DSMCCCacheReference, DSMCCCacheFile * > m_files
Definition: dsmcccache.h:121
void CacheFileData(const DSMCCCacheReference &ref, const QByteArray &data)
Definition: dsmcccache.cpp:173
DSMCCCacheDir * FindDir(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:243
QMap< DSMCCCacheReference, DSMCCCacheDir * > m_directories
Definition: dsmcccache.h:119
int GetDSMObject(QStringList &objectPath, QByteArray &result)
Definition: dsmcccache.cpp:272
Definition: dsmcc.h:78
virtual DSMCCCacheReference * GetReference()=0
unsigned int uint
Definition: compat.h:60
bool operator<(const DSMCCCacheKey &key1, const DSMCCCacheKey &key2)
Definition: dsmcccache.cpp:62
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39