Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qjsoncbor.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qcborvalue.h"
5#include "qcborvalue_p.h"
6
7#include "qcborarray.h"
8#include "qcbormap.h"
9
10#include "qjsonarray.h"
11#include "qjsonobject.h"
12#include "qjsondocument.h"
13#include "qjson_p.h"
14
15#include <qmap.h>
16#include <qhash.h>
17
18#include <private/qnumeric_p.h>
19#include <quuid.h>
20
22
23using namespace QtCbor;
24
26
27static QJsonValue fpToJson(double v)
28{
29 return qt_is_finite(v) ? QJsonValue(v) : QJsonValue();
30}
31
33{
34 int simpleType = t - QCborValue::SimpleType;
35 if (unsigned(simpleType) < 0x100)
36 return QString::fromLatin1("simple(%1)").arg(simpleType);
37
38 // if we got here, we got an unknown type
39 qWarning("QCborValue: found unknown type 0x%x", t);
40 return QString();
41
42}
43
45{
46 const ByteData *b = d->byteData(idx);
47 if (!b)
48 return QString();
49
50 QByteArray data = QByteArray::fromRawData(b->byte(), b->len);
51 if (encoding == QCborKnownTags::ExpectedBase16)
52 data = data.toHex();
53 else if (encoding == QCborKnownTags::ExpectedBase64)
54 data = data.toBase64();
55 else
57
58 return QString::fromLatin1(data, data.size());
59}
60
63
65{
66 qint64 tag = d->elements.at(0).value;
67 const Element &e = d->elements.at(1);
68
69 switch (tag) {
72 if (e.type == QCborValue::String)
73 return makeString(d, 1);
74 break;
75
80 return encodeByteArray(d, 1, QCborTag(tag));
81 break;
82
84#ifndef QT_BOOTSTRAPPED
85 if (const ByteData *b = d->byteData(e); e.type == QCborValue::ByteArray && b
86 && b->len == sizeof(QUuid))
87 return QUuid::fromRfc4122(b->asByteArrayView()).toString(QUuid::WithoutBraces);
88#endif
89 break;
90 }
91
92 // don't know what to do, bail out
93 return QString();
94}
95
97{
98 QString s;
99 if (!d || d->elements.size() != 2)
100 return s; // invalid (incomplete?) tag state
101
102 s = maybeEncodeTag(d);
103 if (s.isNull()) {
104 // conversion failed, ignore the tag and convert the tagged value
105 s = makeString(d, 1);
106 }
107 return s;
108}
109
112{
113 const auto &e = d->elements.at(idx);
114
115 switch (e.type) {
117 return QString::number(qint64(e.value));
118
120 return QString::number(e.fpvalue());
121
124 ? d->stringAt(idx)
126
128 return d->stringAt(idx);
129
131 case QCborValue::Map:
132#if defined(QT_JSON_READONLY) || defined(QT_BOOTSTRAPPED)
133 qFatal("Writing JSON is disabled.");
134 return QString();
135#else
136 return d->valueAt(idx).toDiagnosticNotation(QCborValue::Compact);
137#endif
138
140 break;
141
143 return QStringLiteral("false");
144
145 case QCborValue::True:
146 return QStringLiteral("true");
147
148 case QCborValue::Null:
149 return QStringLiteral("null");
150
152 return QStringLiteral("undefined");
153
155 return QString();
156
157 case QCborValue::Tag:
159 case QCborValue::Url:
161 case QCborValue::Uuid:
162 return encodeTag(e.flags & Element::IsContainer ? e.container : nullptr);
163 }
164
165 // maybe it's a simple type
166 return simpleTypeString(e.type);
167}
168
171
173{
174 qint64 tag = d->elements.at(0).value;
175
176 switch (tag) {
178#ifdef QT_BOOTSTRAPPED
179 break;
180#else
181 // use the fully-encoded URL form
182 if (d->elements.at(1).type == QCborValue::String)
183 return QUrl::fromEncoded(d->byteData(1)->asByteArrayView()).toString(QUrl::FullyEncoded);
185#endif
186
192 // use the string conversion
194 if (!s.isNull())
195 return s;
196 }
197 }
198
199 // for all other tags, ignore it and return the converted tagged item
200 return qt_convertToJson(d, 1);
201}
202
203// We need to do this because sub-objects may need conversion.
206{
208 if (d) {
209 for (qsizetype idx = 0; idx < d->elements.size(); ++idx)
211 }
212 return a;
213}
214
215// We need to do this because the keys need to be sorted and converted to strings
216// and sub-objects may need recursive conversion.
219{
221 if (d) {
222 for (qsizetype idx = 0; idx < d->elements.size(); idx += 2)
223 o.insert(makeString(d, idx), qt_convertToJson(d, idx + 1, mode));
224 }
225 return o;
226}
227
229{
230 // encoding the container itself
231 if (idx == -QCborValue::Array)
232 return convertToJsonArray(d, mode);
233 if (idx == -QCborValue::Map)
234 return convertToJsonObject(d, mode);
235 if (idx < 0) {
236 // tag-like type
237 if (!d || d->elements.size() != 2)
238 return QJsonValue::Undefined; // invalid state
240 }
241
242 // an element in the container
243 const auto &e = d->elements.at(idx);
244 switch (e.type) {
246 return QJsonValue(e.value);
249 const auto value = makeString(d, idx, mode);
251 }
252 break;
255 return QJsonValue();
256 break;
259 // make string
260 break;
261
263 case QCborValue::Map:
264 case QCborValue::Tag:
266 case QCborValue::Url:
267 case QCborValue::Uuid:
268 // recurse
269 return qt_convertToJson(e.flags & Element::IsContainer ? e.container : nullptr, -e.type,
270 mode);
271
272 case QCborValue::Null:
275 return QJsonValue();
276
278 return false;
279
280 case QCborValue::True:
281 return true;
282
284 return fpToJson(e.fpvalue());
285 }
286
288}
289
350{
351 if (container)
352 return qt_convertToJson(container, n < 0 ? -type() : n);
353
354 // simple values
355 switch (type()) {
356 case False:
357 return false;
358
359 case Integer:
361
362 case True:
363 return true;
364
365 case Null:
366 case Undefined:
367 case Invalid:
368 return QJsonValue();
369
370 case Double:
371 return fpToJson(fp_helper());
372
373 case SimpleType:
374 break;
375
376 case ByteArray:
377 case String:
378 // empty strings
379 return QJsonValue::String;
380
381 case Array:
382 // empty array
383 return QJsonArray();
384
385 case Map:
386 // empty map
387 return QJsonObject();
388
389 case Tag:
390 case DateTime:
391 case Url:
393 case Uuid:
394 // Reachable, but invalid in Json
396 }
397
399}
400
401#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
402QJsonValue QCborValueRef::toJsonValue() const
403{
404 return qt_convertToJson(d, i);
405}
406#endif
407
423
424#ifndef QT_NO_VARIANT
430#endif // !QT_NO_VARIANT
431
470{
471 return convertToJsonObject(d.data());
472}
473
474#ifndef QT_NO_VARIANT
480
519{
520 switch (type()) {
521 case Integer:
522 return toInteger();
523
524 case Double:
525 return toDouble();
526
527 case SimpleType:
528 break;
529
530 case False:
531 case True:
532 return isTrue();
533
534 case Null:
535 return QVariant::fromValue(nullptr);
536
537 case Undefined:
538 return QVariant();
539
540 case ByteArray:
541 return toByteArray();
542
543 case String:
544 return toString();
545
546 case Array:
547 return toArray().toVariantList();
548
549 case Map:
550 return toMap().toVariantMap();
551
552 case Tag:
553 // ignore tags
554 return taggedValue().toVariant();
555
556 case DateTime:
557 return toDateTime();
558
559#ifndef QT_BOOTSTRAPPED
560 case Url:
561 return toUrl();
562
563# if QT_CONFIG(regularexpression)
565 return toRegularExpression();
566# endif
567
568 case Uuid:
569 return toUuid();
570#endif
571
572 case Invalid:
573 return QVariant();
574
575 default:
576 break;
577 }
578
579 if (isSimpleType())
580 return QVariant::fromValue(toSimpleType());
581
582 Q_UNREACHABLE_RETURN(QVariant());
583}
584#endif // !QT_NO_VARIANT
585
615{
616 switch (v.type()) {
617 case QJsonValue::Bool:
618 return v.toBool();
619 case QJsonValue::Double: {
620 if (v.value.t == Integer)
621 return v.toInteger();
622 return v.toDouble();
623 }
625 return v.toString();
627 return QCborArray::fromJsonArray(v.toArray());
629 return QCborMap::fromJsonObject(v.toObject());
630 case QJsonValue::Null:
631 return nullptr;
633 break;
634 }
635 return QCborValue();
636}
637
638#ifndef QT_NO_VARIANT
640{
641 // Handle strings and byte arrays directly, to avoid creating a temporary
642 // dummy container to hold their data.
643 int type = variant.metaType().id();
644 if (type == QMetaType::QString) {
645 d->append(variant.toString());
646 } else if (type == QMetaType::QByteArray) {
648 d->appendByteData(ba.constData(), ba.size(), QCborValue::ByteArray);
649 } else {
650 // For everything else, use the function below.
652 }
653}
654
708{
709 switch (variant.metaType().id()) {
711 return {};
712 case QMetaType::Nullptr:
713 return nullptr;
714 case QMetaType::Bool:
715 return variant.toBool();
716 case QMetaType::Short:
717 case QMetaType::UShort:
718 case QMetaType::Int:
719 case QMetaType::LongLong:
720 case QMetaType::UInt:
721 return variant.toLongLong();
722 case QMetaType::ULongLong:
723 if (variant.toULongLong() <= static_cast<uint64_t>(std::numeric_limits<qint64>::max()))
724 return variant.toLongLong();
726 case QMetaType::Float:
727 case QMetaType::Double:
728 return variant.toDouble();
729 case QMetaType::QString:
730 return variant.toString();
731 case QMetaType::QStringList:
733 case QMetaType::QByteArray:
734 return variant.toByteArray();
735 case QMetaType::QDateTime:
736 return QCborValue(variant.toDateTime());
737#ifndef QT_BOOTSTRAPPED
738 case QMetaType::QUrl:
739 return QCborValue(variant.toUrl());
740 case QMetaType::QUuid:
741 return QCborValue(variant.toUuid());
742#endif
743 case QMetaType::QVariantList:
745 case QMetaType::QVariantMap:
747 case QMetaType::QVariantHash:
749#ifndef QT_BOOTSTRAPPED
750#if QT_CONFIG(regularexpression)
751 case QMetaType::QRegularExpression:
752 return QCborValue(variant.toRegularExpression());
753#endif
754 case QMetaType::QJsonValue:
755 return fromJsonValue(variant.toJsonValue());
756 case QMetaType::QJsonObject:
758 case QMetaType::QJsonArray:
760 case QMetaType::QJsonDocument: {
762 if (doc.isArray())
763 return QCborArray::fromJsonArray(doc.array());
764 return QCborMap::fromJsonObject(doc.object());
765 }
766 case QMetaType::QCborValue:
767 return qvariant_cast<QCborValue>(variant);
768 case QMetaType::QCborArray:
769 return qvariant_cast<QCborArray>(variant);
770 case QMetaType::QCborMap:
771 return qvariant_cast<QCborMap>(variant);
772 case QMetaType::QCborSimpleType:
773 return qvariant_cast<QCborSimpleType>(variant);
774#endif
775 default:
776 break;
777 }
778
779 if (variant.isNull())
780 return QCborValue(nullptr);
781
782 QString string = variant.toString();
783 if (string.isNull())
784 return QCborValue(); // undefined
785 return string;
786}
787
800{
801 QVariantList retval;
802 retval.reserve(size());
803 for (qsizetype i = 0; i < size(); ++i)
804 retval.append(d->valueAt(i).toVariant());
805 return retval;
806}
807
814{
816 a.detach(list.size());
817 for (const QString &s : list)
818 a.d->append(s);
819 return a;
820}
821
832{
834 a.detach(list.size());
835 for (const QVariant &v : list)
836 appendVariant(a.d.data(), v);
837 return a;
838}
839#endif // !QT_NO_VARIANT
840
858
864{
866 result.d = std::exchange(array.a, {});
867 return result;
868
869}
870
871#ifndef QT_NO_VARIANT
889{
890 QVariantMap retval;
891 for (qsizetype i = 0; i < 2 * size(); i += 2)
892 retval.insert(makeString(d.data(), i), d->valueAt(i + 1).toVariant());
893 return retval;
894}
895
913{
914 QVariantHash retval;
915 retval.reserve(size());
916 for (qsizetype i = 0; i < 2 * size(); i += 2)
917 retval.insert(makeString(d.data(), i), d->valueAt(i + 1).toVariant());
918 return retval;
919}
920
931{
932 QCborMap m;
933 m.detach(map.size());
935
936 auto it = map.begin();
937 auto end = map.end();
938 for ( ; it != end; ++it) {
939 d->append(it.key());
940 appendVariant(d, it.value());
941 }
942 return m;
943}
944
955{
956 QCborMap m;
957 m.detach(hash.size());
959
960 auto it = hash.begin();
961 auto end = hash.end();
962 for ( ; it != end; ++it) {
963 d->append(it.key());
964 appendVariant(d, it.value());
965 }
966 return m;
967}
968#endif // !QT_NO_VARIANT
969
981{
983 result.d = obj.o;
984 return result;
985}
986
992{
994 result.d = std::exchange(obj.o, {});
995 return result;
996}
997
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
@ Base64UrlEncoding
Definition qbytearray.h:74
@ OmitTrailingEquals
Definition qbytearray.h:77
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
\inmodule QtCore\reentrant
Definition qcborarray.h:20
QVariantList toVariantList() const
Recursively converts each \l QCborValue in this array using QCborValue::toVariant() and returns the Q...
static QCborArray fromJsonArray(const QJsonArray &array)
Converts all JSON items found in the array array to CBOR using QCborValue::fromJson(),...
QJsonArray toJsonArray() const
Recursively converts every \l QCborValue element in this array to JSON using QCborValue::toJsonValue(...
static QCborArray fromStringList(const QStringList &list)
Returns a QCborArray containing all the strings found in the list list.
static QCborArray fromVariantList(const QVariantList &list)
Converts all the items in the list to CBOR using QCborValue::fromVariant() and returns the array comp...
\inmodule QtCore\reentrant
Definition qcbormap.h:21
QVariantMap toVariantMap() const
Converts the CBOR values to QVariant using QCborValue::toVariant() and "stringifies" all the CBOR key...
QVariantHash toVariantHash() const
Converts the CBOR values to QVariant using QCborValue::toVariant() and "stringifies" all the CBOR key...
QJsonObject toJsonObject() const
Recursively converts every \l QCborValue value in this map to JSON using QCborValue::toJsonValue() an...
static QCborMap fromJsonObject(const QJsonObject &o)
Converts all JSON items found in the obj object to CBOR using QCborValue::fromJson(),...
static QCborMap fromVariantMap(const QVariantMap &map)
Converts all the items in map to CBOR using QCborValue::fromVariant() and returns the map composed of...
static QCborMap fromVariantHash(const QVariantHash &hash)
Converts all the items in hash to CBOR using QCborValue::fromVariant() and returns the map composed o...
\inmodule QtCore\reentrant
Definition qcborvalue.h:47
static QCborValue fromVariant(const QVariant &variant)
Converts the QVariant variant into QCborValue and returns it.
QVariant toVariant() const
Converts this value to a native Qt type and returns the corresponding QVariant.
QJsonValue toJsonValue() const
Converts this QCborValue object to an equivalent representation in JSON and returns it as a QJsonValu...
Type
This enum represents the QCborValue type.
Definition qcborvalue.h:70
@ RegularExpression
Definition qcborvalue.h:90
Type type() const
Returns the type of this QCborValue.
Definition qcborvalue.h:154
static QCborValue fromJsonValue(const QJsonValue &v)
Converts the JSON value contained in v into its corresponding CBOR value and returns it.
T * data() const noexcept
Returns a pointer to the shared data object.
void reserve(qsizetype size)
Ensures that the QHash's internal hash table has space to store at least size items without having to...
Definition qhash.h:931
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
void append(const QJsonValue &value)
Inserts value at the end of the array.
\inmodule QtCore\reentrant
bool isArray() const
Returns true if the document contains an array.
QJsonArray array() const
Returns the QJsonArray contained in the document.
QJsonObject object() const
Returns the QJsonObject contained in the document.
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
static QJsonValue fromTrustedCbor(const QCborValue &v)
Definition qjson_p.h:200
static QJsonObject toJsonObject(const QVariantMap &map)
static QJsonArray toJsonArray(const QVariantList &list)
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
qsizetype size() const noexcept
Definition qlist.h:397
void reserve(qsizetype size)
Definition qlist.h:753
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
size_type size() const
Definition qmap.h:267
int id(int=0) const
Definition qmetatype.h:475
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
@ FullyEncoded
Definition qurl.h:129
static QUrl fromEncoded(QByteArrayView input, ParsingMode mode=TolerantMode)
Parses input and returns the corresponding QUrl.
Definition qurl.cpp:2988
\inmodule QtCore
Definition quuid.h:31
@ WithoutBraces
Definition quuid.h:54
static QUuid fromRfc4122(QByteArrayView) noexcept
Creates a QUuid object from the binary representation of the UUID, as specified by RFC 4122 section 4...
Definition quuid.cpp:595
\inmodule QtCore
Definition qvariant.h:65
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
QJsonValue toJsonValue() const
double toDouble(bool *ok=nullptr) const
Returns the variant as a double if the variant has userType() \l QMetaType::Double,...
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has userType() \l QMetaType::QVariantList.
QMap< QString, QVariant > toMap() const
Returns the variant as a QVariantMap if the variant has type() \l QMetaType::QVariantMap.
qlonglong toLongLong(bool *ok=nullptr) const
Returns the variant as a long long int if the variant has userType() \l QMetaType::LongLong,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
QJsonArray toJsonArray() const
QHash< QString, QVariant > toHash() const
Returns the variant as a QHash<QString, QVariant> if the variant has type() \l QMetaType::QVariantHas...
bool isNull() const
Returns true if this is a null variant, false otherwise.
QJsonDocument toJsonDocument() const
QJsonObject toJsonObject() const
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
QUuid toUuid() const
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
QMetaType metaType() const
qulonglong toULongLong(bool *ok=nullptr) const
Returns the variant as an unsigned long long int if the variant has type() \l QMetaType::ULongLong,...
QStringList toStringList() const
Returns the variant as a QStringList if the variant has userType() \l QMetaType::QStringList,...
QUrl toUrl() const
Returns the variant as a QUrl if the variant has userType() \l QMetaType::QUrl; otherwise returns an ...
QHash< int, QWidget * > hash
[35multi]
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QCborTag
Definition qcborcommon.h:30
#define Q_FALLTHROUGH()
#define Q_NEVER_INLINE
AudioChannelLayoutTag tag
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
quint32 Tag
static QString simpleTypeString(QCborValue::Type t)
Definition qjsoncbor.cpp:32
static QString makeString(const QCborContainerPrivate *d, qsizetype idx, ConversionMode mode=ConversionMode::FromRaw)
static void appendVariant(QCborContainerPrivate *d, const QVariant &variant)
QJsonValue qt_convertToJson(QCborContainerPrivate *d, qsizetype idx, ConversionMode mode=ConversionMode::FromRaw)
static QString encodeByteArray(const QCborContainerPrivate *d, qsizetype idx, QCborTag encoding)
Definition qjsoncbor.cpp:44
ConversionMode
Definition qjsoncbor.cpp:25
static QJsonArray convertToJsonArray(QCborContainerPrivate *d, ConversionMode mode=ConversionMode::FromRaw)
static QJsonValue convertExtendedTypeToJson(QCborContainerPrivate *d)
static QJsonObject convertToJsonObject(QCborContainerPrivate *d, ConversionMode mode=ConversionMode::FromRaw)
static QJsonValue fpToJson(double v)
Definition qjsoncbor.cpp:27
static QString encodeTag(const QCborContainerPrivate *d)
Definition qjsoncbor.cpp:96
static QString maybeEncodeTag(const QCborContainerPrivate *d)
Definition qjsoncbor.cpp:64
#define qWarning
Definition qlogging.h:166
#define qFatal
Definition qlogging.h:168
@ Invalid
static Q_DECL_CONST_FUNCTION bool qt_is_finite(double d)
Definition qnumeric_p.h:117
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLenum mode
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLfloat n
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
GLenum array
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
#define QStringLiteral(str)
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
QList< std::pair< QString, QString > > Map
static double toDouble(Value v)
QList< int > list
[14]
QByteArray ba
[0]
QVariant variant
[1]
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
value toMap().value(key)
[3]
value isSimpleType(QCborSimpleType(12))
[1]
char * toString(const MyType &t)
[31]
QCborValue::Type type