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