MythTV  master
mythbinaryplist.cpp
Go to the documentation of this file.
1 /* Class PList
2 *
3 * Copyright (C) Mark Kendall 2012
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19 
29 // TODO
30 // parse uid (and use QPair to differentiate?)
31 
32 // Qt
33 #include <QDateTime>
34 #include <QTextStream>
35 #include <QBuffer>
36 
37 // MythTV
38 #include "mythlogging.h"
39 #include "mythbinaryplist.h"
40 
41 // Std
42 #include <cmath>
43 
44 #define LOC QString("PList: ")
45 
46 #define MAGIC QByteArray("bplist")
47 #define VERSION QByteArray("00")
48 #define MAGIC_SIZE 6
49 #define VERSION_SIZE 2
50 #define TRAILER_SIZE 26
51 #define MIN_SIZE (MAGIC_SIZE + VERSION_SIZE + TRAILER_SIZE)
52 #define TRAILER_OFFSIZE_INDEX 0
53 #define TRAILER_PARMSIZE_INDEX 1
54 #define TRAILER_NUMOBJ_INDEX 2
55 #define TRAILER_ROOTOBJ_INDEX 10
56 #define TRAILER_OFFTAB_INDEX 18
57 
58 enum
59 {
60  BPLIST_NULL = 0x00,
61  BPLIST_FALSE = 0x08,
62  BPLIST_TRUE = 0x09,
63  BPLIST_FILL = 0x0F,
64  BPLIST_UINT = 0x10,
65  BPLIST_REAL = 0x20,
66  BPLIST_DATE = 0x30,
67  BPLIST_DATA = 0x40,
68  BPLIST_STRING = 0x50,
70  BPLIST_UID = 0x70,
71  BPLIST_ARRAY = 0xA0,
72  BPLIST_SET = 0xC0,
73  BPLIST_DICT = 0xD0,
74 };
75 
76 static void convert_float(uint8_t *p, uint8_t s)
77 {
78 #if defined(HAVE_BIGENDIAN) && !defined (__VFP_FP__)
79  return;
80 #else
81  for (uint8_t i = 0; i < (s / 2); i++)
82  {
83  uint8_t t = p[i];
84  uint8_t j = ((s - 1) + 0) - i;
85  p[i] = p[j];
86  p[j] = t;
87  }
88 #endif
89 }
90 
91 static uint8_t* convert_int(uint8_t *p, uint8_t s)
92 {
93 #if defined(HAVE_BIGENDIAN)
94  return p;
95 #else
96  for (uint8_t i = 0; i < (s / 2); i++)
97  {
98  uint8_t t = p[i];
99  uint8_t j = ((s - 1) + 0) - i;
100  p[i] = p[j];
101  p[j] = t;
102  }
103 #endif
104  return p;
105 }
106 
107 MythBinaryPList::MythBinaryPList(const QByteArray& Data)
108 {
109  ParseBinaryPList(Data);
110 }
111 
112 QVariant MythBinaryPList::GetValue(const QString& Key)
113 {
114  if (m_result.type() != QVariant::Map)
115  return QVariant();
116 
117  QVariantMap map = m_result.toMap();
118  for (auto it = map.cbegin(); it != map.cend(); ++it)
119  if (Key == it.key())
120  return it.value();
121  return QVariant();
122 }
123 
125 {
126  QByteArray res;
127  QBuffer buf(&res);
128  buf.open(QBuffer::WriteOnly);
129  if (!ToXML(&buf))
130  return QString("");
131  return QString(res.data());
132 }
133 
135 {
136  QXmlStreamWriter xml(Device);
137  xml.setAutoFormatting(true);
138  xml.setAutoFormattingIndent(4);
139  xml.writeStartDocument();
140  xml.writeDTD(R"(<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">)");
141  xml.writeStartElement("plist");
142  xml.writeAttribute("version", "1.0");
143  bool success = ToXML(m_result, xml);
144  xml.writeEndElement();
145  xml.writeEndDocument();
146  if (!success)
147  LOG(VB_GENERAL, LOG_WARNING, LOC + "Invalid result.");
148  return success;
149 }
150 
151 bool MythBinaryPList::ToXML(const QVariant& Data, QXmlStreamWriter& Xml)
152 {
153  switch (Data.type())
154  {
155  case QVariant::Map:
156  DictToXML(Data, Xml);
157  break;
158  case QVariant::List:
159  ArrayToXML(Data, Xml);
160  break;
161  case QVariant::Double:
162  Xml.writeTextElement("real", QString("%1").arg(Data.toDouble(), 0, 'f', 6));
163  break;
164  case QVariant::ByteArray:
165  Xml.writeTextElement("data", Data.toByteArray().toBase64().data());
166  break;
167  case QVariant::ULongLong:
168  Xml.writeTextElement("integer", QString("%1").arg(Data.toULongLong()));
169  break;
170  case QVariant::String:
171  Xml.writeTextElement("string", Data.toString());
172  break;
173  case QVariant::DateTime:
174  Xml.writeTextElement("date", Data.toDateTime().toString(Qt::ISODate));
175  break;
176  case QVariant::Bool:
177  {
178  bool val = Data.toBool();
179  Xml.writeEmptyElement(val ? "true" : "false");
180  }
181  break;
182  default:
183  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unknown type.");
184  return false;
185  }
186  return true;
187 }
188 
189 void MythBinaryPList::DictToXML(const QVariant& Data, QXmlStreamWriter& Xml)
190 {
191  Xml.writeStartElement("dict");
192  QVariantMap map = Data.toMap();
193  for (auto it = map.cbegin(); it != map.cend(); ++it)
194  {
195  Xml.writeStartElement("key");
196  Xml.writeCharacters(it.key());
197  Xml.writeEndElement();
198  ToXML(it.value(), Xml);
199  }
200  Xml.writeEndElement();
201 }
202 
203 void MythBinaryPList::ArrayToXML(const QVariant& Data, QXmlStreamWriter& Xml)
204 {
205  Xml.writeStartElement("array");
206  auto list = Data.value<QSequentialIterable>();
207  for (const auto & item : qAsConst(list))
208  ToXML(item, Xml);
209  Xml.writeEndElement();
210 }
211 
212 void MythBinaryPList::ParseBinaryPList(const QByteArray& Data)
213 {
214  // reset
215  m_result = QVariant();
216 
217  // check minimum size
218  auto size = static_cast<quint32>(Data.size());
219  if (size < MIN_SIZE)
220  return;
221 
222  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Binary: size %1, startswith '%2'")
223  .arg(size).arg(Data.left(8).data()));
224 
225  // check plist type & version
226  if ((!Data.startsWith(MAGIC)) || (Data.mid(MAGIC_SIZE, VERSION_SIZE) != VERSION))
227  {
228  LOG(VB_GENERAL, LOG_ERR, LOC + "Unrecognised start sequence. Corrupt?");
229  return;
230  }
231 
232  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Parsing binary plist (%1 bytes)").arg(size));
233 
234  m_data = reinterpret_cast<uint8_t*>(const_cast<char*>(Data.data()));
235  uint8_t* trailer = m_data + size - TRAILER_SIZE;
236  m_offsetSize = *(trailer + TRAILER_OFFSIZE_INDEX);
237  m_parmSize = *(trailer + TRAILER_PARMSIZE_INDEX);
238  m_numObjs = *(reinterpret_cast<uint64_t*>(convert_int(trailer + TRAILER_NUMOBJ_INDEX, 8)));
239  m_rootObj = *(reinterpret_cast<uint64_t*>(convert_int(trailer + TRAILER_ROOTOBJ_INDEX, 8)));
240  uint64_t offset_tindex = *(reinterpret_cast<uint64_t*>(convert_int(trailer + TRAILER_OFFTAB_INDEX, 8)));
241  m_offsetTable = m_data + offset_tindex;
242 
243  LOG(VB_GENERAL, LOG_DEBUG, LOC +
244  QString("numObjs: %1 parmSize: %2 offsetSize: %3 rootObj: %4"
245  "offset_tindex: %5").arg(m_numObjs).arg(m_parmSize)
246  .arg(m_offsetSize).arg(m_rootObj).arg(offset_tindex));
247 
248  // something wrong?
249  if (!m_numObjs || !m_parmSize || !m_offsetSize)
250  {
251  LOG(VB_GENERAL, LOG_ERR, LOC + "Error parsing binary plist. Corrupt?");
252  return;
253  }
254 
255  // parse
257  LOG(VB_GENERAL, LOG_INFO, LOC + "Parse complete.");
258 }
259 
260 QVariant MythBinaryPList::ParseBinaryNode(uint64_t Num)
261 {
262  uint8_t* data = GetBinaryObject(Num);
263  if (!data)
264  return QVariant();
265 
266  quint16 type = (*data) & 0xf0;
267  uint64_t size = (*data) & 0x0f;
268 
269  switch (type)
270  {
271  case BPLIST_SET:
272  case BPLIST_ARRAY: return ParseBinaryArray(data);
273  case BPLIST_DICT: return ParseBinaryDict(data);
274  case BPLIST_STRING: return ParseBinaryString(data);
275  case BPLIST_UINT: return ParseBinaryUInt(&data);
276  case BPLIST_REAL: return ParseBinaryReal(data);
277  case BPLIST_DATE: return ParseBinaryDate(data);
278  case BPLIST_DATA: return ParseBinaryData(data);
279  case BPLIST_UNICODE: return ParseBinaryUnicode(data);
280  case BPLIST_NULL:
281  {
282  switch (size)
283  {
284  case BPLIST_TRUE: return QVariant(true);
285  case BPLIST_FALSE: return QVariant(false);
286  case BPLIST_NULL:
287  default: return QVariant();
288  }
289  }
290  case BPLIST_UID: // FIXME
291  default: break;
292  }
293 
294  return QVariant();
295 }
296 
297 uint64_t MythBinaryPList::GetBinaryUInt(uint8_t *Data, uint64_t Size)
298 {
299  if (Size == 1) return static_cast<uint64_t>(*Data);
300  if (Size == 2) return static_cast<uint64_t>(*(reinterpret_cast<quint16*>(convert_int(Data, 2))));
301  if (Size == 4) return static_cast<uint64_t>(*(reinterpret_cast<quint32*>(convert_int(Data, 4))));
302  if (Size == 8) return (*(reinterpret_cast<uint64_t*>(convert_int(Data, 8))));
303  if (Size == 3)
304  {
305 #if defined(HAVE_BIGENDIAN)
306  return static_cast<uint64_t>(((*Data) << 16) + (*(Data + 1) << 8) + (*(Data + 2)));
307 #else
308  return static_cast<uint64_t>((*Data) + (*(Data + 1) << 8) + ((*(Data + 2)) << 16));
309 #endif
310  }
311 
312  return 0;
313 }
314 
315 uint8_t* MythBinaryPList::GetBinaryObject(uint64_t Num)
316 {
317  if (Num > m_numObjs)
318  return nullptr;
319 
320  uint8_t* p = m_offsetTable + (Num * m_offsetSize);
321  uint64_t offset = GetBinaryUInt(p, m_offsetSize);
322  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("GetBinaryObject num %1, offsize %2 offset %3")
323  .arg(Num).arg(m_offsetSize).arg(offset));
324  return m_data + offset;
325 }
326 
327 QVariantMap MythBinaryPList::ParseBinaryDict(uint8_t *Data)
328 {
329  QVariantMap result;
330  if (((*Data) & 0xf0) != BPLIST_DICT)
331  return result;
332 
333  uint64_t count = GetBinaryCount(&Data);
334  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Dict: Size %1").arg(count));
335  if (!count)
336  return result;
337 
338  uint64_t off = m_parmSize * count;
339  for (uint64_t i = 0; i < count; i++, Data += m_parmSize)
340  {
341  uint64_t keyobj = GetBinaryUInt(Data, m_parmSize);
342  uint64_t valobj = GetBinaryUInt(Data + off, m_parmSize);
343  QVariant key = ParseBinaryNode(keyobj);
344  QVariant val = ParseBinaryNode(valobj);
345  if (!key.canConvert<QString>())
346  {
347  LOG(VB_GENERAL, LOG_ERR, LOC + "Invalid dictionary key type.");
348  return result;
349  }
350  result.insert(key.toString(), val);
351  }
352  return result;
353 }
354 
355 QList<QVariant> MythBinaryPList::ParseBinaryArray(uint8_t* Data)
356 {
357  QList<QVariant> result;
358  if (((*Data) & 0xf0) != BPLIST_ARRAY)
359  return result;
360 
361  uint64_t count = GetBinaryCount(&Data);
362  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Array: Size %1").arg(count));
363  if (!count)
364  return result;
365 
366  for (uint64_t i = 0; i < count; i++, Data += m_parmSize)
367  {
368  uint64_t obj = GetBinaryUInt(Data, m_parmSize);
369  QVariant val = ParseBinaryNode(obj);
370  result.push_back(val);
371  }
372  return result;
373 }
374 
375 QVariant MythBinaryPList::ParseBinaryUInt(uint8_t** Data)
376 {
377  uint64_t result = 0;
378  if (((**Data) & 0xf0) != BPLIST_UINT)
379  return QVariant(static_cast<quint64>(result));
380 
381  uint64_t size = 1 << ((**Data) & 0x0f);
382  (*Data)++;
383  result = GetBinaryUInt(*Data, size);
384  (*Data) += size;
385 
386  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("UInt: %1").arg(result));
387  return QVariant(static_cast<quint64>(result));
388 }
389 
390 QVariant MythBinaryPList::ParseBinaryString(uint8_t* Data)
391 {
392  QString result;
393  if (((*Data) & 0xf0) != BPLIST_STRING)
394  return result;
395 
396  uint64_t count = GetBinaryCount(&Data);
397  if (!count)
398  return result;
399 
400  result = QString::fromLatin1(reinterpret_cast<const char*>(Data), static_cast<int>(count));
401  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("ASCII String: %1").arg(result));
402  return QVariant(result);
403 }
404 
405 QVariant MythBinaryPList::ParseBinaryReal(uint8_t* Data)
406 {
407  double result = 0.0;
408  if (((*Data) & 0xf0) != BPLIST_REAL)
409  return result;
410 
411  uint64_t count = GetBinaryCount(&Data);
412  if (!count)
413  return result;
414 
415  count = 1ULL << count;
416  if (count == sizeof(float))
417  {
418  convert_float(Data, static_cast<uint8_t>(count));
419  float temp = NAN;
420  std::copy(Data, Data + sizeof(float), reinterpret_cast<uint8_t*>(&temp));
421  result = static_cast<double>(temp);
422  }
423  else if (count == sizeof(double))
424  {
425  convert_float(Data, static_cast<uint8_t>(count));
426  std::copy(Data, Data + sizeof(double), reinterpret_cast<uint8_t*>(&result));
427  }
428 
429  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Real: %1").arg(result, 0, 'f', 6));
430  return QVariant(result);
431 }
432 
433 QVariant MythBinaryPList::ParseBinaryDate(uint8_t* Data)
434 {
435  QDateTime result;
436  if (((*Data) & 0xf0) != BPLIST_DATE)
437  return result;
438 
439  uint64_t count = GetBinaryCount(&Data);
440  if (count != 3)
441  return result;
442 
443  convert_float(Data, 8);
444  auto temp = static_cast<double>(NAN);
445  std::copy(Data, Data + sizeof(double), reinterpret_cast<uint8_t*>(&temp));
446  auto msec = static_cast<uint64_t>(temp * 1000.0);
447  result = QDateTime::fromMSecsSinceEpoch(static_cast<qint64>(msec), Qt::UTC);
448  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Date: %1").arg(result.toString(Qt::ISODate)));
449  return QVariant(result);
450 }
451 
452 QVariant MythBinaryPList::ParseBinaryData(uint8_t* Data)
453 {
454  QByteArray result;
455  if (((*Data) & 0xf0) != BPLIST_DATA)
456  return result;
457 
458  uint64_t count = GetBinaryCount(&Data);
459  if (!count)
460  return result;
461 
462  result = QByteArray(reinterpret_cast<const char*>(Data), static_cast<int>(count));
463  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Data: Size %1 (count %2)")
464  .arg(result.size()).arg(count));
465  return QVariant(result);
466 }
467 
468 QVariant MythBinaryPList::ParseBinaryUnicode(uint8_t* Data)
469 {
470  QString result;
471  if (((*Data) & 0xf0) != BPLIST_UNICODE)
472  return result;
473 
474  uint64_t count = GetBinaryCount(&Data);
475  if (!count)
476  return result;
477 
478  // source is big endian (and no BOM?)
479  QByteArray tmp;
480  for (uint64_t i = 0; i < count; i++, Data += 2)
481  {
482  quint16 twobyte = *(reinterpret_cast<quint16*>(convert_int(Data, 2)));
483  tmp.append(static_cast<char>(twobyte & 0xff));
484  tmp.append(static_cast<char>((twobyte >> 8) & 0xff));
485  }
486  result = QString::fromUtf16(reinterpret_cast<const quint16*>(tmp.data()), static_cast<int>(count));
487  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Unicode: %1").arg(result));
488  return QVariant(result);
489 }
490 
491 uint64_t MythBinaryPList::GetBinaryCount(uint8_t** Data)
492 {
493  uint64_t count = (**Data) & 0x0f;
494  (*Data)++;
495  if (count == 0x0f)
496  {
497  QVariant newcount = ParseBinaryUInt(Data);
498  if (!newcount.canConvert<uint64_t>())
499  return 0;
500  count = newcount.toULongLong();
501  }
502  return count;
503 }
MythBinaryPList::MythBinaryPList
MythBinaryPList(const QByteArray &Data)
Definition: mythbinaryplist.cpp:107
MythBinaryPList::ParseBinaryData
static QVariant ParseBinaryData(uint8_t *Data)
Definition: mythbinaryplist.cpp:452
MythBinaryPList::ParseBinaryDict
QVariantMap ParseBinaryDict(uint8_t *Data)
Definition: mythbinaryplist.cpp:327
MythBinaryPList::m_rootObj
uint64_t m_rootObj
Definition: mythbinaryplist.h:40
copy
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
Definition: mythmiscutil.cpp:311
MythBinaryPList::m_data
uint8_t * m_data
Definition: mythbinaryplist.h:38
MythBinaryPList::m_offsetSize
uint8_t m_offsetSize
Definition: mythbinaryplist.h:42
BPLIST_DATA
@ BPLIST_DATA
Definition: mythbinaryplist.cpp:67
MythBinaryPList::ArrayToXML
void ArrayToXML(const QVariant &Data, QXmlStreamWriter &Xml)
Definition: mythbinaryplist.cpp:203
TRAILER_ROOTOBJ_INDEX
#define TRAILER_ROOTOBJ_INDEX
Definition: mythbinaryplist.cpp:55
MythBinaryPList::ParseBinaryNode
QVariant ParseBinaryNode(uint64_t Num)
Definition: mythbinaryplist.cpp:260
TRAILER_PARMSIZE_INDEX
#define TRAILER_PARMSIZE_INDEX
Definition: mythbinaryplist.cpp:53
arg
arg(title).arg(filename).arg(doDelete))
BPLIST_TRUE
@ BPLIST_TRUE
Definition: mythbinaryplist.cpp:62
BPLIST_FILL
@ BPLIST_FILL
Definition: mythbinaryplist.cpp:63
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
TRAILER_OFFSIZE_INDEX
#define TRAILER_OFFSIZE_INDEX
Definition: mythbinaryplist.cpp:52
MythBinaryPList::m_offsetTable
uint8_t * m_offsetTable
Definition: mythbinaryplist.h:39
Device
A device containing images (ie. USB stick, CD, storage group etc)
Definition: imagemanager.cpp:33
MythBinaryPList::GetValue
QVariant GetValue(const QString &Key)
Definition: mythbinaryplist.cpp:112
MIN_SIZE
#define MIN_SIZE
Definition: mythbinaryplist.cpp:51
MythBinaryPList::ParseBinaryUnicode
static QVariant ParseBinaryUnicode(uint8_t *Data)
Definition: mythbinaryplist.cpp:468
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
convert_int
static uint8_t * convert_int(uint8_t *p, uint8_t s)
Definition: mythbinaryplist.cpp:91
MythBinaryPList::ParseBinaryPList
void ParseBinaryPList(const QByteArray &Data)
Definition: mythbinaryplist.cpp:212
mythlogging.h
convert_float
static void convert_float(uint8_t *p, uint8_t s)
Definition: mythbinaryplist.cpp:76
MythBinaryPList::ParseBinaryArray
QList< QVariant > ParseBinaryArray(uint8_t *Data)
Definition: mythbinaryplist.cpp:355
MythBinaryPList::ToXML
bool ToXML(QIODevice *Device)
Definition: mythbinaryplist.cpp:134
hardwareprofile.config.p
p
Definition: config.py:33
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MythBinaryPList::m_parmSize
uint8_t m_parmSize
Definition: mythbinaryplist.h:43
MythBinaryPList::GetBinaryObject
uint8_t * GetBinaryObject(uint64_t Num)
Definition: mythbinaryplist.cpp:315
MythBinaryPList::m_result
QVariant m_result
Definition: mythbinaryplist.h:37
MythBinaryPList::m_numObjs
uint64_t m_numObjs
Definition: mythbinaryplist.h:41
MythBinaryPList::ParseBinaryReal
static QVariant ParseBinaryReal(uint8_t *Data)
Definition: mythbinaryplist.cpp:405
BPLIST_DATE
@ BPLIST_DATE
Definition: mythbinaryplist.cpp:66
BPLIST_FALSE
@ BPLIST_FALSE
Definition: mythbinaryplist.cpp:61
BPLIST_UINT
@ BPLIST_UINT
Definition: mythbinaryplist.cpp:64
MAGIC_SIZE
#define MAGIC_SIZE
Definition: mythbinaryplist.cpp:48
BPLIST_REAL
@ BPLIST_REAL
Definition: mythbinaryplist.cpp:65
LOC
#define LOC
Definition: mythbinaryplist.cpp:44
BPLIST_UID
@ BPLIST_UID
Definition: mythbinaryplist.cpp:70
BPLIST_SET
@ BPLIST_SET
Definition: mythbinaryplist.cpp:72
BPLIST_UNICODE
@ BPLIST_UNICODE
Definition: mythbinaryplist.cpp:69
MythBinaryPList::ParseBinaryDate
static QVariant ParseBinaryDate(uint8_t *Data)
Definition: mythbinaryplist.cpp:433
BPLIST_NULL
@ BPLIST_NULL
Definition: mythbinaryplist.cpp:60
TRAILER_SIZE
#define TRAILER_SIZE
Definition: mythbinaryplist.cpp:50
MythBinaryPList::ToString
QString ToString()
Definition: mythbinaryplist.cpp:124
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
BPLIST_STRING
@ BPLIST_STRING
Definition: mythbinaryplist.cpp:68
MAGIC
#define MAGIC
Definition: mythbinaryplist.cpp:46
TRAILER_OFFTAB_INDEX
#define TRAILER_OFFTAB_INDEX
Definition: mythbinaryplist.cpp:56
TRAILER_NUMOBJ_INDEX
#define TRAILER_NUMOBJ_INDEX
Definition: mythbinaryplist.cpp:54
MythBinaryPList::ParseBinaryUInt
static QVariant ParseBinaryUInt(uint8_t **Data)
Definition: mythbinaryplist.cpp:375
MythBinaryPList::ParseBinaryString
static QVariant ParseBinaryString(uint8_t *Data)
Definition: mythbinaryplist.cpp:390
MythBinaryPList::DictToXML
void DictToXML(const QVariant &Data, QXmlStreamWriter &Xml)
Definition: mythbinaryplist.cpp:189
MythBinaryPList::GetBinaryUInt
static uint64_t GetBinaryUInt(uint8_t *Data, uint64_t Size)
Definition: mythbinaryplist.cpp:297
VERSION_SIZE
#define VERSION_SIZE
Definition: mythbinaryplist.cpp:49
MythBinaryPList::GetBinaryCount
static uint64_t GetBinaryCount(uint8_t **Data)
Definition: mythbinaryplist.cpp:491
BPLIST_DICT
@ BPLIST_DICT
Definition: mythbinaryplist.cpp:73
VERSION
#define VERSION
Definition: mythbinaryplist.cpp:47
BPLIST_ARRAY
@ BPLIST_ARRAY
Definition: mythbinaryplist.cpp:71
mythbinaryplist.h