Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qjsonwriter.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// Copyright (C) 2016 Intel Corporation.
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:critical reason:data-parser
5
6
#
include
<
cmath
>
7
#
include
<
qlocale
.
h
>
8
#
include
"qjsonwriter_p.h"
9
#
include
"qjson_p.h"
10
#
include
"private/qstringconverter_p.h"
11
#
include
<
private
/
qnumeric_p
.
h
>
12
#
include
<
private
/
qcborvalue_p
.
h
>
13
14
QT_BEGIN_NAMESPACE
15
16
using
namespace
QJsonPrivate;
17
18
static
void
objectContentToJson
(
const
QCborContainerPrivate
*o, QByteArray &json,
int
indent,
bool
compact);
19
static
void
arrayContentToJson
(
const
QCborContainerPrivate
*a, QByteArray &json,
int
indent,
bool
compact);
20
21
static
inline
uchar
hexdig
(uint u)
22
{
23
return
(u < 0xa ?
'0'
+ u :
'a'
+ u - 0xa);
24
}
25
26
static
QByteArray
escapedString
(QStringView s)
27
{
28
// give it a minimum size to ensure the resize() below always adds enough space
29
QByteArray ba(qMax(s.size(), 16), Qt::Uninitialized);
30
31
auto
ba_const_start = [&]() {
return
reinterpret_cast
<
const
uchar *>(ba.constData()); };
32
uchar *cursor =
reinterpret_cast
<uchar *>(
const_cast
<
char
*>(ba.constData()));
33
const
uchar *ba_end = cursor + ba.size();
34
const
char16_t
*src = s.utf16();
35
const
char16_t
*
const
end = s.utf16() + s.size();
36
37
while
(src != end) {
38
if
(cursor >= ba_end - 6) {
39
// ensure we have enough space
40
qptrdiff pos = cursor - ba_const_start();
41
ba.resize(ba.size()*2);
42
cursor =
reinterpret_cast
<uchar *>(ba.data()) + pos;
43
ba_end = ba_const_start() + ba.size();
44
}
45
46
char16_t
u = *src++;
47
if
(u < 0x80) {
48
if
(u < 0x20 || u == 0x22 || u == 0x5c) {
49
*cursor++ =
'\\'
;
50
switch
(u) {
51
case
0x22:
52
*cursor++ =
'"'
;
53
break
;
54
case
0x5c:
55
*cursor++ =
'\\'
;
56
break
;
57
case
0x8:
58
*cursor++ =
'b'
;
59
break
;
60
case
0xc:
61
*cursor++ =
'f'
;
62
break
;
63
case
0xa:
64
*cursor++ =
'n'
;
65
break
;
66
case
0xd:
67
*cursor++ =
'r'
;
68
break
;
69
case
0x9:
70
*cursor++ =
't'
;
71
break
;
72
default
:
73
*cursor++ =
'u'
;
74
*cursor++ =
'0'
;
75
*cursor++ =
'0'
;
76
*cursor++ = hexdig(u>>4);
77
*cursor++ = hexdig(u & 0xf);
78
}
79
}
else
{
80
*cursor++ = (uchar)u;
81
}
82
}
else
if
(QUtf8Functions::toUtf8<QUtf8BaseTraits>(u, cursor, src, end) < 0) {
83
// failed to get valid utf8 use JSON escape sequence
84
*cursor++ =
'\\'
;
85
*cursor++ =
'u'
;
86
*cursor++ = hexdig(u>>12 & 0x0f);
87
*cursor++ = hexdig(u>>8 & 0x0f);
88
*cursor++ = hexdig(u>>4 & 0x0f);
89
*cursor++ = hexdig(u & 0x0f);
90
}
91
}
92
93
ba.resize(cursor - ba_const_start());
94
return
ba;
95
}
96
97
static
void
valueContentToJson
(
const
QCborValue &v, QByteArray &json,
int
indent,
bool
compact)
98
{
99
QCborValue::Type type = v.type();
100
switch
(type) {
101
case
QCborValue::True:
102
json +=
"true"
;
103
break
;
104
case
QCborValue::False:
105
json +=
"false"
;
106
break
;
107
case
QCborValue::Integer:
108
json += QByteArray::number(v.toInteger());
109
break
;
110
case
QCborValue::Double: {
111
const
double
d = v.toDouble();
112
if
(qt_is_finite(d))
113
json += QByteArray::number(d,
'g'
, QLocale::FloatingPointShortest);
114
else
115
json +=
"null"
;
// +INF || -INF || NaN (see RFC4627#section2.4)
116
break
;
117
}
118
case
QCborValue::String:
119
json +=
'"'
;
120
json += escapedString(v.toString());
121
json +=
'"'
;
122
break
;
123
case
QCborValue::Array:
124
json += compact ?
"["
:
"[\n"
;
125
arrayContentToJson(
126
QJsonPrivate
::
Value
::
container
(
v
)
, json, indent + (compact ? 0 : 1), compact);
127
json += QByteArray(4*indent,
' '
);
128
json +=
']'
;
129
break
;
130
case
QCborValue::Map:
131
json += compact ?
"{"
:
"{\n"
;
132
objectContentToJson(
133
QJsonPrivate
::
Value
::
container
(
v
)
, json, indent + (compact ? 0 : 1), compact);
134
json += QByteArray(4*indent,
' '
);
135
json +=
'}'
;
136
break
;
137
case
QCborValue::Null:
138
default
:
139
json +=
"null"
;
140
}
141
}
142
143
static
void
arrayContentToJson
(
const
QCborContainerPrivate
*a, QByteArray &json,
int
indent,
bool
compact)
144
{
145
if
(!a || a->elements.empty())
146
return
;
147
148
QByteArray indentString(4*indent,
' '
);
149
150
qsizetype i = 0;
151
while
(
true
) {
152
json += indentString;
153
valueContentToJson(a->valueAt(i), json, indent, compact);
154
155
if
(++i == a->elements.size()) {
156
if
(!compact)
157
json +=
'\n'
;
158
break
;
159
}
160
161
json += compact ?
","
:
",\n"
;
162
}
163
}
164
165
166
static
void
objectContentToJson
(
const
QCborContainerPrivate
*o, QByteArray &json,
int
indent,
bool
compact)
167
{
168
if
(!o || o->elements.empty())
169
return
;
170
171
QByteArray indentString(4*indent,
' '
);
172
173
qsizetype i = 0;
174
while
(
true
) {
175
QCborValue
e = o->valueAt(i);
176
json += indentString;
177
json +=
'"'
;
178
json += escapedString(o->valueAt(i).toString());
179
json += compact ?
"\":"
:
"\": "
;
180
valueContentToJson(o->valueAt(i + 1), json, indent, compact);
181
182
if
((i += 2) == o->elements.size()) {
183
if
(!compact)
184
json +=
'\n'
;
185
break
;
186
}
187
188
json += compact ?
","
:
",\n"
;
189
}
190
}
191
192
void
Writer::objectToJson(
const
QCborContainerPrivate *o, QByteArray &json,
int
indent,
bool
compact)
193
{
194
json.reserve(json.size() + (o ? (
int
)o->elements.size() : 16));
195
json += compact ?
"{"
:
"{\n"
;
196
objectContentToJson(o, json, indent + (compact ? 0 : 1), compact);
197
json += QByteArray(4*indent,
' '
);
198
json += compact ?
"}"
:
"}\n"
;
199
}
200
201
void
Writer::arrayToJson(
const
QCborContainerPrivate *a, QByteArray &json,
int
indent,
bool
compact)
202
{
203
json.reserve(json.size() + (a ? (
int
)a->elements.size() : 16));
204
json += compact ?
"["
:
"[\n"
;
205
arrayContentToJson(a, json, indent + (compact ? 0 : 1), compact);
206
json += QByteArray(4*indent,
' '
);
207
json += compact ?
"]"
:
"]\n"
;
208
}
209
210
void
Writer::valueToJson(
const
QCborValue &v, QByteArray &json,
int
indent,
bool
compact)
211
{
212
const
QCborContainerPrivate *container = QJsonPrivate::Value::container(v);
213
json.reserve(json.size() + (container ? container->elements.size() : 16));
214
valueContentToJson(v, json, indent, compact);
215
216
if
(!compact && (v.isMap() || v.isArray())) {
217
json.append(
'\n'
);
218
}
219
}
220
221
QT_END_NAMESPACE
QCborContainerPrivate
Definition
qcborvalue_p.h:101
QCborValue
\inmodule QtCore\reentrant
Definition
qcborvalue.h:48
QJsonPrivate::Value
Definition
qjson_p.h:173
QJsonPrivate::Value::container
static const QCborContainerPrivate * container(QJsonValueConstRef r) noexcept
Definition
qjson_p.h:177
QJsonPrivate
Definition
qcborarray.h:17
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
arrayContentToJson
static void arrayContentToJson(const QCborContainerPrivate *a, QByteArray &json, int indent, bool compact)
Definition
qjsonwriter.cpp:143
escapedString
static QByteArray escapedString(QStringView s)
Definition
qjsonwriter.cpp:26
objectContentToJson
static void objectContentToJson(const QCborContainerPrivate *o, QByteArray &json, int indent, bool compact)
Definition
qjsonwriter.cpp:166
valueContentToJson
static void valueContentToJson(const QCborValue &v, QByteArray &json, int indent, bool compact)
Definition
qjsonwriter.cpp:97
hexdig
static uchar hexdig(uint u)
Definition
qjsonwriter.cpp:21
qtbase
src
corelib
serialization
qjsonwriter.cpp
Generated on
for Qt by
1.18.0