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 {
33  // Delete all this when the cache is deleted.
34  m_dsmcc = dsmcc;
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.
53 QString DSMCCCacheKey::toString() const
54 {
55  QString result;
56  for (int i = 0; i < 4 && i < size(); i++)
57  result += QString("%1").arg(at(i), 2, 16, QChar('0'));
58  return result;
59 }
60 
61 // Ordering function used in QMap
62 bool 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 {
86  return m_nCarouselId == r.m_nCarouselId && m_nModuleId == r.m_nModuleId &&
87  m_nStreamTag == r.m_nStreamTag && m_key == r.m_key;
88 }
89 
91 {
92  return p != nullptr && Equal(*p);
93 }
94 
95 
96 // Print out a cache reference for debugging.
97 QString DSMCCCacheReference::toString(void) const
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::fromLatin1(pBB->m_name.m_comps[0].m_id
203  /*, pBB->m_name.m_comps[0].m_id_len*/);
204 
205  const DSMCCCacheReference *entry =
207 
208  pDir->m_files.insert(name, *entry);
209 
210  LOG(VB_DSMCC, LOG_INFO,
211  QString("[DSMCCCache] Added file name %1 reference %2 parent %3")
212  .arg(name, entry->toString(), pDir->m_reference.toString()));
213 }
214 
215 // Add a sub-directory to the directory.
217 {
218  // Is it already there?
219  QString name;
220  name = QString::fromLatin1(pBB->m_name.m_comps[0].m_id
221  /*, pBB->m_name.m_comps[0].m_id_len*/);
222  const DSMCCCacheReference *entry =
224 
225  pDir->m_subDirectories.insert(name, *entry);
226 
227  LOG(VB_DSMCC, LOG_INFO,
228  QString("[DSMCCCache] added subdirectory name %1 reference %2 parent %3")
229  .arg(name, entry->toString(), pDir->m_reference.toString()));
230 }
231 
232 // Find File, Directory or Gateway by reference.
234 {
235  // Find a file.
236  QMap<DSMCCCacheReference, DSMCCCacheFile*>::Iterator fil =
237  m_files.find(ref);
238 
239  if (fil == m_files.end())
240  return nullptr;
241 
242  return *fil;
243 }
244 
246 {
247  // Find a directory.
248  QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
249  m_directories.find(ref);
250 
251  if (dir == m_directories.end())
252  return nullptr;
253 
254  return *dir;
255 }
256 
258 {
259  // Find a gateway.
260  QMap<DSMCCCacheReference, DSMCCCacheDir*>::Iterator dir =
261  m_gateways.find(ref);
262 
263  if (dir == m_gateways.end())
264  return nullptr;
265 
266  return *dir;
267 }
268 
269 
270 // Return the contents of an object if it exists.
271 // Returns zero for success, -1 if we know the object does not
272 // currently exist and +1 if the carousel has not so far loaded
273 // the object or one of the parent files.
274 int DSMCCCache::GetDSMObject(QStringList &objectPath, QByteArray &result)
275 {
277  if (dir == nullptr)
278  return 1; // No gateway yet.
279 
280  QStringList::Iterator it = objectPath.begin();
281  while (it != objectPath.end())
282  {
283  QString name = *it;
284  ++it;
285  if (it == objectPath.end())
286  { // It's a leaf - look in the file names
287  QMap<QString, DSMCCCacheReference>::Iterator ref =
288  dir->m_files.find(name);
289 
290  if (ref == dir->m_files.end())
291  return -1; // Not there.
292 
293  DSMCCCacheFile *fil = FindFileData(*ref);
294 
295  if (fil == nullptr) // Exists but not yet set.
296  return 1;
297 
298  result = fil->m_contents;
299  return 0;
300  }
301 
302  // It's a directory
303  QMap<QString, DSMCCCacheReference>::Iterator ref =
304  dir->m_subDirectories.find(name);
305 
306  if (ref == dir->m_subDirectories.end())
307  return -1; // Not there
308 
309  dir = FindDir(*ref);
310 
311  if (dir == nullptr) // Exists but not yet set.
312  return 1;
313  // else search in this directory
314  }
315 
316  return -1;
317 }
318 
319 // Set the gateway reference from a DSI message.
321 {
322  if (!m_gatewayRef.Equal(ref))
323  {
324  LOG(VB_DSMCC, LOG_INFO, QString("[DSMCCCache] Setting gateway to reference %1")
325  .arg(ref.toString()));
326  m_gatewayRef = ref;
327  }
328 }
DSMCCCache::GetDSMObject
int GetDSMObject(QStringList &objectPath, QByteArray &result)
Definition: dsmcccache.cpp:274
DSMCCCacheReference::toString
QString toString(void) const
Definition: dsmcccache.cpp:97
BiopIor::m_profileBody
ProfileBody * m_profileBody
Definition: dsmccbiop.h:146
DSMCCCacheFile::m_contents
QByteArray m_contents
Definition: dsmcccache.h:83
dsmcccache.h
DSMCCCache::SetGateway
void SetGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:320
DSMCCCache::m_gatewayRef
DSMCCCacheReference m_gatewayRef
Definition: dsmcccache.h:116
DSMCCCache::m_dsmcc
Dsmcc * m_dsmcc
Definition: dsmcccache.h:124
DSMCCCache::FindGateway
DSMCCCacheDir * FindGateway(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:257
DSMCCCacheReference::m_nCarouselId
unsigned long m_nCarouselId
Definition: dsmcccache.h:51
DSMCCCache::AddFileInfo
static void AddFileInfo(DSMCCCacheDir *dir, const BiopBinding *pBB)
Definition: dsmcccache.cpp:199
DSMCCCache::AddDirInfo
static void AddDirInfo(DSMCCCacheDir *dir, const BiopBinding *pBB)
Definition: dsmcccache.cpp:216
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DSMCCCache::FindDir
DSMCCCacheDir * FindDir(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:245
DSMCCCacheReference::m_key
DSMCCCacheKey m_key
Definition: dsmcccache.h:54
DSMCCCache::m_files
QMap< DSMCCCacheReference, DSMCCCacheFile * > m_files
Definition: dsmcccache.h:121
DSMCCCache::Directory
DSMCCCacheDir * Directory(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:150
DSMCCCache::FindFileData
DSMCCCacheFile * FindFileData(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:233
DSMCCCacheReference::m_nStreamTag
unsigned short m_nStreamTag
Definition: dsmcccache.h:53
mythlogging.h
DSMCCCacheDir::m_reference
DSMCCCacheReference m_reference
Definition: dsmcccache.h:72
DSMCCCacheFile
Definition: dsmcccache.h:76
DSMCCCacheDir
Definition: dsmcccache.h:62
hardwareprofile.config.p
p
Definition: config.py:33
ProfileBody::GetReference
virtual DSMCCCacheReference * GetReference()=0
BiopBinding
Definition: dsmccbiop.h:151
dsmccreceiver.h
dsmccbiop.h
DSMCCCache::Srg
DSMCCCacheDir * Srg(const DSMCCCacheReference &ref)
Definition: dsmcccache.cpp:127
uint
unsigned int uint
Definition: compat.h:81
DSMCCCache::~DSMCCCache
~DSMCCCache()
Definition: dsmcccache.cpp:37
operator<
bool operator<(const DSMCCCacheKey &key1, const DSMCCCacheKey &key2)
Definition: dsmcccache.cpp:62
BiopNameComp::m_id
char * m_id
Definition: dsmccbiop.h:29
Dsmcc
Definition: dsmcc.h:77
BiopBinding::m_name
BiopName m_name
Definition: dsmccbiop.h:159
DSMCCCacheKey
Definition: dsmcccache.h:21
DSMCCCacheDir::m_subDirectories
QMap< QString, DSMCCCacheReference > m_subDirectories
Definition: dsmcccache.h:69
DSMCCCacheReference::m_nModuleId
unsigned short m_nModuleId
Definition: dsmcccache.h:52
BiopName::m_comps
BiopNameComp * m_comps
Definition: dsmccbiop.h:42
BiopBinding::m_ior
BiopIor m_ior
Definition: dsmccbiop.h:161
DSMCCCache::CacheFileData
void CacheFileData(const DSMCCCacheReference &ref, const QByteArray &data)
Definition: dsmcccache.cpp:173
DSMCCCacheReference::Equal
bool Equal(const DSMCCCacheReference &r) const
Definition: dsmcccache.cpp:84
DSMCCCache::DSMCCCache
DSMCCCache(Dsmcc *dsmcc)
Definition: dsmcccache.cpp:31
dsmcc.h
DSMCCCache::m_gateways
QMap< DSMCCCacheReference, DSMCCCacheDir * > m_gateways
Definition: dsmcccache.h:120
DSMCCCacheKey::toString
QString toString(void) const
Definition: dsmcccache.cpp:53
DSMCCCache::m_directories
QMap< DSMCCCacheReference, DSMCCCacheDir * > m_directories
Definition: dsmcccache.h:119
DSMCCCacheReference
Definition: dsmcccache.h:33
DSMCCCacheDir::m_files
QMap< QString, DSMCCCacheReference > m_files
Definition: dsmcccache.h:70