diff options
author | Liang Qi <liang.qi@qt.io> | 2018-10-25 07:21:05 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-10-25 07:21:53 +0200 |
commit | e28e91ae99b8c3859899e04cc9370534c7c7b86d (patch) | |
tree | cca81b1e745be4f25aab78e8e917c2324594e539 /src/corelib/serialization | |
parent | 5ea233ca6782eb27adf596515cb66ef3dadc1d5e (diff) | |
parent | ebfad73b4e44fe6db8059200da105b4b87888718 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
src/corelib/animation/qpropertyanimation.cpp
src/gui/image/qicon.cpp
tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
Change-Id: I3698172b7b44ebb487cb38f50fd2c4a9f8a35b21
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r-- | src/corelib/serialization/qcborstream.cpp | 309 | ||||
-rw-r--r-- | src/corelib/serialization/qcborvalue.cpp | 31 | ||||
-rw-r--r-- | src/corelib/serialization/qdatastream.cpp | 10 | ||||
-rw-r--r-- | src/corelib/serialization/qjson.cpp | 1 | ||||
-rw-r--r-- | src/corelib/serialization/qjsondocument.cpp | 16 | ||||
-rw-r--r-- | src/corelib/serialization/qjsonparser.cpp | 1 |
6 files changed, 43 insertions, 325 deletions
diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 38b809158a..b7ba85281f 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -213,9 +213,7 @@ QDebug operator<<(QDebug dbg, QCborSimpleType st) For example, the following creates a QCborValue containing a byte array tagged with a tag 2. - \code - QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9)); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 0 \sa QCborKnownTags, QCborStreamWriter::append(QCborTag), QCborStreamReader::isTag(), QCborStreamReader::toTag(), @@ -546,25 +544,7 @@ QString QCborError::toString() const } \enddiv - \code - writer.startMap(4); // 4 elements in the map - - writer.append(QLatin1String("label")); - writer.append(QLatin1String("journald")); - - writer.append(QLatin1String("autoDetect")); - writer.append(false); - - writer.append(QLatin1String("condition")); - writer.append(QLatin1String("libs.journald")); - - writer.append(QLatin1String("output")); - writer.startArray(1); - writer.append(QLatin1String("privateFeature")); - writer.endArray(); - - writer.endMap(); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 1 \section1 CBOR support @@ -747,12 +727,7 @@ static CborError qt_cbor_encoder_write_callback(void *self, const void *data, si The following example writes an empty map to a file: - \code - QFile f("output", QIODevice::WriteOnly); - QCborStreamWriter writer(&f); - writer.startMap(0); - writer.endMap(); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 2 QCborStreamWriter does not take ownership of \a device. @@ -771,15 +746,7 @@ QCborStreamWriter::QCborStreamWriter(QIODevice *device) The following example writes a number to a byte array then returns it. - \code - QByteArray encodedNumber(qint64 value) - { - QByteArray ba; - QCborStreamWriter writer(&ba); - writer.append(value); - return ba; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 3 QCborStreamWriter does not take ownership of \a data. */ @@ -837,11 +804,7 @@ QIODevice *QCborStreamWriter::device() const Unsigned Integer value. In the following example, we write the values 0, 2\sup{32} and \c UINT64_MAX: - \code - writer.append(0U); - writer.append(Q_UINT64_C(4294967296)); - writer.append(std::numeric_limits<quint64>::max()); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 4 \sa QCborStreamReader::isUnsignedInteger(), QCborStreamReader::toUnsignedInteger() */ @@ -858,12 +821,7 @@ void QCborStreamWriter::append(quint64 u) sign of the parameter. In the following example, we write the values 0, -1, 2\sup{32} and \c INT64_MAX: - \code - writer.append(0); - writer.append(-1); - writer.append(Q_INT64_C(4294967296)); - writer.append(std::numeric_limits<qint64>::max()); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 5 \sa QCborStreamReader::isInteger(), QCborStreamReader::toInteger() */ @@ -881,11 +839,7 @@ void QCborStreamWriter::append(qint64 i) equivalent to 2\sup{64} (that is, -18,446,744,073,709,551,616). In the following example, we write the values -1, -2\sup{32} and INT64_MIN: - \code - writer.append(QCborNegativeInteger(1)); - writer.append(QCborNegativeInteger(Q_INT64_C(4294967296))); - writer.append(QCborNegativeInteger(-quint64(std::numeric_limits<qint64>::min()))); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 6 Note how this function can be used to encode numbers that cannot fit a standard computer's 64-bit signed integer like \l qint64. That is, if \a n @@ -911,14 +865,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n) The following example will load and append the contents of a file to the stream: - \code - void writeFile(QCborStreamWriter &writer, const QString &fileName) - { - QFile f(fileName); - if (f.open(QIODevice::ReadOnly)) - writer.append(f.readAll()); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 7 As the example shows, unlike JSON, CBOR requires no escaping for binary content. @@ -936,9 +883,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n) The following example appends a simple string to the stream: - \code - writer.append(QLatin1String("Hello, World")); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 8 \b{Performance note}: CBOR requires that all Text Strings be encoded in UTF-8, so this function will iterate over the characters in the string to @@ -971,12 +916,7 @@ void QCborStreamWriter::append(QLatin1String str) The following example writes an arbitrary QString to the stream: - \code - void writeString(QCborStreamWriter &writer, const QString &str) - { - writer.append(str); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 9 \sa QCborStreamReader::isString(), QCborStreamReader::readString() */ @@ -995,13 +935,7 @@ void QCborStreamWriter::append(QStringView str) In the following example, we append a CBOR Tag 36 (Regular Expression) and a QRegularExpression's pattern to the stream: - \code - void writeRxPattern(QCborStreamWriter &writer, const QRegularExpression &rx) - { - writer.append(QCborTag(36)); - writer.append(rx.pattern()); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 10 \sa QCborStreamReader::isTag(), QCborStreamReader::toTag() */ @@ -1021,13 +955,7 @@ void QCborStreamWriter::append(QCborTag tag) integer representing the current time to the stream, obtained using the \c time() function: - \code - void writeCurrentTime(QCborStreamWriter &writer) - { - writer.append(QCborKnownTags::UnixTime_t); - writer.append(time(nullptr)); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 11 \sa QCborStreamReader::isTag(), QCborStreamReader::toTag() */ @@ -1039,10 +967,7 @@ void QCborStreamWriter::append(QCborTag tag) Type value. In the following example, we write the simple type for Null as well as for type 32, which Qt has no support for. - \code - writer.append(QCborSimpleType::Null); - writer.append(QCborSimpleType(32)); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 12 \note Using Simple Types for which there is no specification can lead to validation errors by the remote receiver. In addition, simple type values 24 @@ -1063,16 +988,7 @@ void QCborStreamWriter::append(QCborSimpleType st) a C++ \tt float to \c qfloat16 if there's no loss of precision and append it, or instead append the \tt float. - \code - void writeFloat(QCborStreamWriter &writer, float f) - { - qfloat16 f16 = f; - if (qIsNaN(f) || f16 == f) - writer.append(f16); - else - writer.append(f); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 13 \sa QCborStreamReader::isFloat16(), QCborStreamReader::toFloat16() */ @@ -1089,16 +1005,7 @@ void QCborStreamWriter::append(qfloat16 f) a C++ \tt double to \tt float if there's no loss of precision and append it, or instead append the \tt double. - \code - void writeFloat(QCborStreamWriter &writer, double d) - { - float f = d; - if (qIsNaN(d) || d == f) - writer.append(f); - else - writer.append(d); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 14 \sa QCborStreamReader::isFloat(), QCborStreamReader::toFloat() */ @@ -1120,25 +1027,7 @@ void QCborStreamWriter::append(float f) which is expected to be taken into account by the system FPU or floating point emulation directly. - \code - void writeDouble(QCborStreamWriter &writer, double d) - { - float f; - if (qIsNaN(d)) { - writer.append(qfloat16(qQNaN())); - } else if (qIsInf(d)) { - writer.append(d < 0 ? -qInf() : qInf()); - } else if ((f = d) == d) { - qfloat16 f16 = f; - if (f16 == f) - writer.append(f16); - else - writer.append(f); - } else { - writer.append(d); - } - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 15 Determining if a double can be converted to an integral with no loss of precision is left as an exercise to the reader. @@ -1216,9 +1105,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) value or a CBOR True value. This function is equivalent to (and implemented as): - \code - writer.append(b ? QCborSimpleType::True : QCborSimpleType::False); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 16 \sa appendNull(), appendUndefined(), QCborStreamReader::isBool(), QCborStreamReader::toBool() @@ -1231,9 +1118,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Null value to the stream. This function is equivalent to (and implemented as): The parameter is ignored. - \code - writer.append(QCborSimpleType::Null); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 17 \sa appendNull(), append(QCborSimpleType), QCborStreamReader::isNull() */ @@ -1244,9 +1129,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Null value to the stream. This function is equivalent to (and implemented as): - \code - writer.append(QCborSimpleType::Null); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 18 \sa append(std::nullptr_t), append(QCborSimpleType), QCborStreamReader::isNull() */ @@ -1257,9 +1140,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Undefined value to the stream. This function is equivalent to (and implemented as): - \code - writer.append(QCborSimpleType::Undefined); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 19 \sa append(QCborSimpleType), QCborStreamReader::isUndefined() */ @@ -1276,15 +1157,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) The following example appends elements from the linked list of strings passed as input: - \code - void appendList(QCborStreamWriter &writer, const QLinkedList<QString> &list) - { - writer.startArray(); - for (const QString &s : list) - writer.append(s); - writer.endArray(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 20 \sa startArray(quint64), endArray(), startMap(), QCborStreamReader::isArray(), QCborStreamReader::isLengthKnown() @@ -1309,15 +1182,7 @@ void QCborStreamWriter::startArray() The following example appends all strings found in the \l QStringList passed as input: - \code - void appendList(QCborStreamWriter &writer, const QStringList &list) - { - writer.startArray(list.size()); - for (const QString &s : list) - writer.append(s); - writer.endArray(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 21 \b{Size limitations}: The parameter to this function is quint64, which would seem to allow up to 2\sup{64}-1 elements in the array. However, both @@ -1365,17 +1230,7 @@ bool QCborStreamWriter::endArray() The following example appends elements from the linked list of int and string pairs passed as input: - \code - void appendMap(QCborStreamWriter &writer, const QLinkedList<QPair<int, QString>> &list) - { - writer.startMap(); - for (const auto pair : list) { - writer.append(pair.first) - writer.append(pair.second); - } - writer.endMap(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 22 \sa startMap(quint64), endMap(), startArray(), QCborStreamReader::isMap(), QCborStreamReader::isLengthKnown() @@ -1400,17 +1255,7 @@ void QCborStreamWriter::startMap() The following example appends all strings found in the \l QMap passed as input: - \code - void appendMap(QCborStreamWriter &writer, const QMap<int, QString> &map) - { - writer.startMap(map.size()); - for (auto it = map.begin(); it != map.end(); ++it) { - writer.append(it.key()); - writer.append(it.value()); - } - writer.endMap(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 23 \b{Size limitations}: The parameter to this function is quint64, which would seem to allow up to 2\sup{64}-1 pairs in the map. However, both @@ -1491,33 +1336,7 @@ bool QCborStreamWriter::endMap() So a processor function typically looks like this: - \code - void handleStream(QCborStreamReader &reader) - { - switch (reader.type()) - case QCborStreamReader::UnsignedInteger: - case QCborStreamReader::NegativeInteger: - case QCborStreamReader::SimpleType: - case QCborStreamReader::Float16: - case QCborStreamReader::Float: - case QCborStreamReader::Double: - handleFixedWidth(reader); - reader.next(); - break; - case QCborStreamReader::ByteArray: - case QCborStreamReader::String: - handleString(reader); - break; - case QCborStreamReader::Array: - case QCborStreamReader::Map: - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError) - handleStream(reader); - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 24 \section1 CBOR support @@ -1733,20 +1552,7 @@ bool QCborStreamWriter::endMap() The following example pre-allocates a QVariantList given the array's size for more efficient decoding: - \code - QVariantList populateFromCbor(QCborStreamReader &reader) - { - QVariantList list; - if (reader.isLengthKnown()) - list.reserve(reader.length()); - - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError && reader.hasNext()) - list.append(readOneElement(reader)); - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 25 \note The code above does not validate that the length is a sensible value. If the input stream reports that the length is 1 billion elements, the above @@ -1770,22 +1576,7 @@ bool QCborStreamWriter::endMap() The following example pre-allocates a QVariantMap given the map's size for more efficient decoding: - \code - QVariantMap populateFromCbor(QCborStreamReader &reader) - { - QVariantMap map; - if (reader.isLengthKnown()) - map.reserve(reader.length()); - - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError && reader.hasNext()) { - QString key = readElementAsString(reader); - map.insert(key, readOneElement(reader)); - } - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 26 The example above uses a function called \c readElementAsString to read the map's keys and obtain a string. That is because CBOR maps may contain any @@ -2718,23 +2509,7 @@ bool QCborStreamReader::leaveContainer() always loop around calling this function, even if isLengthKnown() has is true. The typical use of this function is as follows: - \code - QString decodeString(QCborStreamReader &reader) - { - QString result; - auto r = reader.readString(); - while (r.code == QCborStreamReader::Ok) { - result += r.data; - r = reader.readString(); - } - - if (r.code == QCborStreamReader::Error) { - // handle error condition - result.clear(); - } - return result; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 27 This function does not perform any type conversions, including from integers or from byte arrays. Therefore, it may only be called if isString() returned @@ -2770,23 +2545,7 @@ QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper() always loop around calling this function, even if isLengthKnown() has is true. The typical use of this function is as follows: - \code - QBytearray decodeBytearray(QCborStreamReader &reader) - { - QBytearray result; - auto r = reader.readBytearray(); - while (r.code == QCborStreamReader::Ok) { - result += r.data; - r = reader.readByteArray(); - } - - if (r.code == QCborStreamReader::Error) { - // handle error condition - result.clear(); - } - return result; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 28 This function does not perform any type conversions, including from integers or from strings. Therefore, it may only be called if isByteArray() is true; @@ -2856,15 +2615,7 @@ qsizetype QCborStreamReader::_currentStringChunkSize() const This function is usually used alongside currentStringChunkSize() in a loop. For example: - \code - QCborStreamReader<qsizetype> result; - do { - qsizetype size = reader.currentStringChunkSize(); - qsizetype oldsize = buffer.size(); - buffer.resize(oldsize + size); - result = reader.readStringChunk(buffer.data() + oldsize, size); - } while (result.status() == QCborStreamReader::Ok); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 29 Unlike readByteArray() and readString(), this function is not limited by implementation limits of QByteArray and QString. diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 73ac3125e4..170ad588d1 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -102,9 +102,7 @@ QT_BEGIN_NAMESPACE Qt types compare equal to the tag type of the same contents. In other words, the following expression is true: - \code - QCborValue(uuid) == QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122()); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 0 \section1 Undefined and null values @@ -429,9 +427,7 @@ QT_BEGIN_NAMESPACE This function can be used with simple types not defined in the API. For example, to create a QCborValue with simple type 12, one could write: - \code - QCborValue value(QCborSimpleType(12)); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 1 Simple types should not be used until a specification for them has been published, since other implementations may not support them properly. @@ -702,9 +698,7 @@ QT_BEGIN_NAMESPACE any CBOR simple type, even those for which there is no enumeration in the API. For example, for the simple type of value 12, you could write: - \code - value.isSimpleType(QCborSimpleType(12)); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 2 \sa QCborValue::QCborValue(QCborSimpleType), isSimpleType(), isFalse(), isTrue(), isNull, isUndefined(), toSimpleType() @@ -1163,9 +1157,7 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv \l{Type}{Url} and \l{Type}{Url} and its equivalent tagged representation. So, for example, the following expression is true: - \code - QCborValue(QUrl("https://example.com")) == QCborValue(QCborKnownTags::Url, "https://example.com"); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 3 Do note that Qt types like \l QUrl and \l QDateTime will normalize and otherwise modify their arguments. The expression above is true only because @@ -2081,9 +2073,7 @@ QCborMap QCborValue::toMap(const QCborMap &defaultValue) const This function is equivalent to: - \code - value.toMap().value(key); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 4 \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), QCborMap::find() @@ -2104,9 +2094,7 @@ const QCborValue QCborValue::operator[](const QString &key) const This function is equivalent to: - \code - value.toMap().value(key); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 5 \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), QCborMap::find() @@ -2147,12 +2135,7 @@ const QCborValue QCborValue::operator[](qint64 key) const QCborStreamReader. For example, the following code illustrates how to skip the CBOR signature tag from the beginning of a file: - \code - if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature) - reader.next(); - - QCborValue contents = QCborValue::fromCbor(reader); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 6 The returned value may be partially complete and indistinguishable from a valid QCborValue even if the decoding failed. To determine if there was an diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index eccbc357e1..8566b4fd56 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -170,18 +170,12 @@ QT_BEGIN_NAMESPACE will have appropriate stream operators declared as non-member of the class: - \code - QDataStream &operator<<(QDataStream &, const QXxx &); - QDataStream &operator>>(QDataStream &, QXxx &); - \endcode + \snippet code/src_corelib_serialization_qdatastream.cpp 0 For example, here are the stream operators declared as non-members of the QImage class: - \code - QDataStream & operator<< (QDataStream& stream, const QImage& image); - QDataStream & operator>> (QDataStream& stream, QImage& image); - \endcode + \snippet code/src_corelib_serialization_qdatastream.cpp 1 To see if your favorite Qt class has similar stream operators defined, check the \b {Related Non-Members} section of the diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index b82923fe0c..d74ffb2a20 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -70,6 +70,7 @@ void Data::compact() int size = sizeof(Base) + reserve + base->length*sizeof(offset); int alloc = sizeof(Header) + size; Header *h = (Header *) malloc(alloc); + Q_CHECK_PTR(h); h->tag = QJsonDocument::BinaryFormatTag; h->version = 1; Base *b = h->root(); diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index aaa0f6acaa..179a87c699 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -351,22 +351,10 @@ QByteArray QJsonDocument::toJson() const when converting to a QJsonDocument using toJson(). \value Indented Defines human readable output as follows: - \code - { - "Array": [ - true, - 999, - "string" - ], - "Key": "Value", - "null": null - } - \endcode + \snippet code/src_corelib_serialization_qjsondocument.cpp 0 \value Compact Defines a compact output as follows: - \code - {"Array":[true,999,"string"],"Key":"Value","null":null} - \endcode + \snippet code/src_corelib_serialization_qjsondocument.cpp 1 */ /*! diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp index 39738b90a8..bfba95520e 100644 --- a/src/corelib/serialization/qjsonparser.cpp +++ b/src/corelib/serialization/qjsonparser.cpp @@ -304,6 +304,7 @@ QJsonDocument Parser::parse(QJsonParseError *error) // allocate some space dataLength = qMax(end - json, (ptrdiff_t) 256); data = (char *)malloc(dataLength); + Q_CHECK_PTR(data); // fill in Header data QJsonPrivate::Header *h = (QJsonPrivate::Header *)data; |