diff options
Diffstat (limited to 'src/corelib/serialization/qjsoncbor.cpp')
-rw-r--r-- | src/corelib/serialization/qjsoncbor.cpp | 211 |
1 files changed, 116 insertions, 95 deletions
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp index 2ae02cd239..285ae6a8ec 100644 --- a/src/corelib/serialization/qjsoncbor.cpp +++ b/src/corelib/serialization/qjsoncbor.cpp @@ -54,8 +54,7 @@ QT_BEGIN_NAMESPACE using namespace QtCbor; - -enum class ConversionMode { FromRaw, FromVariantToJson }; +using ConversionMode = QCborContainerPrivate::ConversionMode; static QJsonValue fpToJson(double v) { @@ -450,7 +449,8 @@ QJsonArray QCborArray::toJsonArray() const QJsonArray QJsonPrivate::Variant::toJsonArray(const QVariantList &list) { - const auto cborArray = QCborArray::fromVariantList(list); + const auto cborArray = + QCborContainerPrivate::fromVariantList(list, ConversionMode::FromVariantToJson); return convertToJsonArray(cborArray.d.data(), ConversionMode::FromVariantToJson); } @@ -498,7 +498,8 @@ QJsonObject QCborMap::toJsonObject() const QJsonObject QJsonPrivate::Variant::toJsonObject(const QVariantMap &map) { - const auto cborMap = QCborMap::fromVariantMap(map); + const auto cborMap = + QCborContainerPrivate::fromVariantMap(map, ConversionMode::FromVariantToJson); return convertToJsonObject(cborMap.d.data(), ConversionMode::FromVariantToJson); } @@ -661,77 +662,8 @@ QCborValue QCborValue::fromJsonValue(const QJsonValue &v) return QCborValue(); } -static void appendVariant(QCborContainerPrivate *d, const QVariant &variant) -{ - // Handle strings and byte arrays directly, to avoid creating a temporary - // dummy container to hold their data. - int type = variant.userType(); - if (type == QMetaType::QString) { - d->append(variant.toString()); - } else if (type == QMetaType::QByteArray) { - QByteArray ba = variant.toByteArray(); - d->appendByteData(ba.constData(), ba.size(), QCborValue::ByteArray); - } else { - // For everything else, use the function below. - d->append(QCborValue::fromVariant(variant)); - } -} - -/*! - Converts the QVariant \a variant into QCborValue and returns it. - - QVariants may contain a large list of different meta types, many of which - have no corresponding representation in CBOR. That includes all - user-defined meta types. When preparing transmission using CBOR, it is - suggested to encode carefully each value to prevent loss of representation. - - The following table lists the conversion this function will apply: - - \table - \header \li Qt (C++) type \li CBOR type - \row \li invalid (QVariant()) \li Undefined - \row \li \c bool \li Bool - \row \li \c std::nullptr_t \li Null - \row \li \c short, \c ushort, \c int, \c uint, \l qint64 \li Integer - \row \li \l quint64 \li Integer, but they are cast to \c qint64 first so - values higher than 2\sup{63}-1 (\c INT64_MAX) will - be wrapped to negative - \row \li \c float, \c double \li Double - \row \li \l QByteArray \li ByteArray - \row \li \l QDateTime \li DateTime - \row \li \l QCborSimpleType \li Simple type - \row \li \l QJsonArray \li Array, converted using QCborArray::formJsonArray() - \row \li \l QJsonDocument \li Array or Map - \row \li \l QJsonObject \li Map, converted using QCborMap::fromJsonObject() - \row \li \l QJsonValue \li converted using fromJsonValue() - \row \li \l QRegularExpression \li RegularExpression - \row \li \l QString \li String - \row \li \l QStringList \li Array - \row \li \l QVariantHash \li Map - \row \li \l QVariantList \li Array - \row \li \l QVariantMap \li Map - \row \li \l QUrl \li Url - \row \li \l QUuid \li Uuid - \endtable - - If QVariant::isNull() returns true, a null QCborValue is returned or - inserted into the list or object, regardless of the type carried by - QVariant. Note the behavior change in Qt 6.0 affecting QVariant::isNull() - also affects this function. - - For other types not listed above, a conversion to string will be attempted, - usually but not always by calling QVariant::toString(). If the conversion - fails the value is replaced by an Undefined CBOR value. Note that - QVariant::toString() is also lossy for the majority of types. - - Please note that the conversions via QVariant::toString() are subject to - change at any time. Both QVariant and QCborValue may be extended in the - future to support more types, which will result in a change in how this - function performs conversions. - - \sa toVariant(), fromJsonValue(), QCborArray::toVariantList(), QCborMap::toVariantMap(), QJsonValue::fromVariant() - */ -QCborValue QCborValue::fromVariant(const QVariant &variant) +static QCborValue fromVariantImpl(const QVariant &variant, + ConversionMode mode = ConversionMode::FromRaw) { switch (variant.userType()) { case QMetaType::UnknownType: @@ -744,9 +676,12 @@ QCborValue QCborValue::fromVariant(const QVariant &variant) case QMetaType::UShort: case QMetaType::Int: case QMetaType::LongLong: - case QMetaType::ULongLong: case QMetaType::UInt: return variant.toLongLong(); + case QMetaType::ULongLong: + if (mode != ConversionMode::FromVariantToJson ) + return variant.toLongLong(); + Q_FALLTHROUGH(); case QMetaType::Float: case QMetaType::Double: return variant.toDouble(); @@ -765,9 +700,9 @@ QCborValue QCborValue::fromVariant(const QVariant &variant) case QMetaType::QUuid: return QCborValue(variant.toUuid()); case QMetaType::QVariantList: - return QCborArray::fromVariantList(variant.toList()); + return QCborContainerPrivate::fromVariantList(variant.toList(), mode); case QMetaType::QVariantMap: - return QCborMap::fromVariantMap(variant.toMap()); + return QCborContainerPrivate::fromVariantMap(variant.toMap(), mode); case QMetaType::QVariantHash: return QCborMap::fromVariantHash(variant.toHash()); #ifndef QT_BOOTSTRAPPED @@ -776,7 +711,7 @@ QCborValue QCborValue::fromVariant(const QVariant &variant) return QCborValue(variant.toRegularExpression()); #endif case QMetaType::QJsonValue: - return fromJsonValue(variant.toJsonValue()); + return QCborValue::fromJsonValue(variant.toJsonValue()); case QMetaType::QJsonObject: return QCborMap::fromJsonObject(variant.toJsonObject()); case QMetaType::QJsonArray: @@ -809,6 +744,106 @@ QCborValue QCborValue::fromVariant(const QVariant &variant) return string; } +static void appendVariant(QCborContainerPrivate *d, const QVariant &variant, + ConversionMode mode = ConversionMode::FromRaw) +{ + // Handle strings and byte arrays directly, to avoid creating a temporary + // dummy container to hold their data. + int type = variant.userType(); + if (type == QMetaType::QString) { + d->append(variant.toString()); + } else if (type == QMetaType::QByteArray) { + QByteArray ba = variant.toByteArray(); + d->appendByteData(ba.constData(), ba.size(), QCborValue::ByteArray); + } else { + // For everything else, use the function below. + d->append(fromVariantImpl(variant, mode)); + } +} + +QCborMap QCborContainerPrivate::fromVariantMap(const QVariantMap &map, ConversionMode mode) +{ + QCborMap m; + m.detach(map.size()); + QCborContainerPrivate *d = m.d.data(); + + auto it = map.begin(); + auto end = map.end(); + for ( ; it != end; ++it) { + d->append(it.key()); + appendVariant(d, it.value(), mode); + } + return m; +} + +QCborArray QCborContainerPrivate::fromVariantList(const QVariantList &list, ConversionMode mode) +{ + QCborArray a; + a.detach(list.size()); + for (const QVariant &v : list) + appendVariant(a.d.data(), v, mode); + return a; +} + +/*! + Converts the QVariant \a variant into QCborValue and returns it. + + QVariants may contain a large list of different meta types, many of which + have no corresponding representation in CBOR. That includes all + user-defined meta types. When preparing transmission using CBOR, it is + suggested to encode carefully each value to prevent loss of representation. + + The following table lists the conversion this function will apply: + + \table + \header \li Qt (C++) type \li CBOR type + \row \li invalid (QVariant()) \li Undefined + \row \li \c bool \li Bool + \row \li \c std::nullptr_t \li Null + \row \li \c short, \c ushort, \c int, \c uint, \l qint64 \li Integer + \row \li \l quint64 \li Integer, but they are cast to \c qint64 first so + values higher than 2\sup{63}-1 (\c INT64_MAX) will + be wrapped to negative + \row \li \c float, \c double \li Double + \row \li \l QByteArray \li ByteArray + \row \li \l QDateTime \li DateTime + \row \li \l QCborSimpleType \li Simple type + \row \li \l QJsonArray \li Array, converted using QCborArray::formJsonArray() + \row \li \l QJsonDocument \li Array or Map + \row \li \l QJsonObject \li Map, converted using QCborMap::fromJsonObject() + \row \li \l QJsonValue \li converted using fromJsonValue() + \row \li \l QRegularExpression \li RegularExpression + \row \li \l QString \li String + \row \li \l QStringList \li Array + \row \li \l QVariantHash \li Map + \row \li \l QVariantList \li Array + \row \li \l QVariantMap \li Map + \row \li \l QUrl \li Url + \row \li \l QUuid \li Uuid + \endtable + + If QVariant::isNull() returns true, a null QCborValue is returned or + inserted into the list or object, regardless of the type carried by + QVariant. Note the behavior change in Qt 6.0 affecting QVariant::isNull() + also affects this function. + + For other types not listed above, a conversion to string will be attempted, + usually but not always by calling QVariant::toString(). If the conversion + fails the value is replaced by an Undefined CBOR value. Note that + QVariant::toString() is also lossy for the majority of types. + + Please note that the conversions via QVariant::toString() are subject to + change at any time. Both QVariant and QCborValue may be extended in the + future to support more types, which will result in a change in how this + function performs conversions. + + \sa toVariant(), fromJsonValue(), QCborArray::toVariantList(), QCborMap::toVariantMap(), QJsonValue::fromVariant() + */ +QCborValue QCborValue::fromVariant(const QVariant &variant) +{ + return fromVariantImpl(variant); +} + /*! Recursively converts each \l QCborValue in this array using QCborValue::toVariant() and returns the QVariantList composed of the @@ -854,11 +889,7 @@ QCborArray QCborArray::fromStringList(const QStringList &list) */ QCborArray QCborArray::fromVariantList(const QVariantList &list) { - QCborArray a; - a.detach(list.size()); - for (const QVariant &v : list) - appendVariant(a.d.data(), v); - return a; + return QCborContainerPrivate::fromVariantList(list); } /*! @@ -939,17 +970,7 @@ QVariantHash QCborMap::toVariantHash() const */ QCborMap QCborMap::fromVariantMap(const QVariantMap &map) { - QCborMap m; - m.detach(map.size()); - QCborContainerPrivate *d = m.d.data(); - - auto it = map.begin(); - auto end = map.end(); - for ( ; it != end; ++it) { - d->append(it.key()); - appendVariant(d, it.value()); - } - return m; + return QCborContainerPrivate::fromVariantMap(map); } /*! |