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