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