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
qcborstreamwriter.cpp
Go to the documentation of this file.
1
// Copyright (C) 2018 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
// Qt-Security score:critical reason:data-parser
4
5
#
include
"qcborstreamwriter.h"
6
7
#
define
CBOR_NO_PARSER_API
8
#
include
<
private
/
qcborcommon_p
.
h
>
9
10
#
include
<
private
/
qnumeric_p
.
h
>
11
#
include
<
private
/
qstringconverter_p
.
h
>
12
#
include
<
qbuffer
.
h
>
13
#
include
<
qdebug
.
h
>
14
#
include
<
qstack
.
h
>
15
#
include
<
qvarlengtharray
.
h
>
16
17
QT_BEGIN_NAMESPACE
18
19
static
CborError
qt_cbor_encoder_write_callback
(
void
*token,
const
void
*data, size_t len,
CborEncoderAppendType
);
20
#
define
CBOR_ENCODER_WRITER_CONTROL
1
21
#
define
CBOR_ENCODER_WRITE_FUNCTION
qt_cbor_encoder_write_callback
22
#
define
CBOR_ENCODER_NO_CHECK_USER
23
24
QT_WARNING_PUSH
25
QT_WARNING_DISABLE_MSVC(4334)
// '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
26
27
#
include
<
cborencoder
.
c
>
28
#
include
<
cborencoder_close_container_checked
.
c
>
29
#
include
<
cborencoder_float
.
c
>
30
31
QT_WARNING_POP
32
33
Q_DECLARE_TYPEINFO(CborEncoder, Q_PRIMITIVE_TYPE);
34
35
/*!
36
\class QCborStreamWriter
37
\inmodule QtCore
38
\ingroup cbor
39
\ingroup qtserialization
40
\reentrant
41
\since 5.12
42
43
\brief The QCborStreamWriter class is a simple CBOR encoder operating on a
44
one-way stream.
45
46
This class can be used to quickly encode a stream of CBOR content directly
47
to either a QByteArray or QIODevice. CBOR is the Concise Binary Object
48
Representation, a very compact form of binary data encoding that is
49
compatible with JSON. It was created by the IETF Constrained RESTful
50
Environments (CoRE) WG, which has used it in many new RFCs. It is meant to
51
be used alongside the \l{RFC 7252}{CoAP protocol}.
52
53
QCborStreamWriter provides a StAX-like API, similar to that of
54
\l{QXmlStreamWriter}. It is rather low-level and requires a bit of knowledge
55
of CBOR encoding. For a simpler API, see \l{QCborValue} and especially the
56
encoding function QCborValue::toCbor().
57
58
The typical use of QCborStreamWriter is to create the object on the target
59
QByteArray or QIODevice, then call one of the append() overloads with the
60
desired type to be encoded. To create arrays and maps, QCborStreamWriter
61
provides startArray() and startMap() overloads, which must be terminated by
62
the corresponding endArray() and endMap() functions.
63
64
The following example encodes the equivalent of this JSON content:
65
66
\div{class="pre"}
67
{
68
"label": "journald",
69
"autoDetect": false,
70
"condition": "libs.journald",
71
"output": [ "privateFeature" ]
72
}
73
\enddiv
74
75
\snippet code/src_corelib_serialization_qcborstream.cpp 1
76
77
\section1 CBOR support
78
79
QCborStreamWriter supports all CBOR features required to create canonical
80
and strict streams. It implements almost all of the features specified in
81
\l {RFC 7049}.
82
83
The following table lists the CBOR features that QCborStreamWriter supports.
84
85
\table
86
\header \li Feature \li Support
87
\row \li Unsigned numbers \li Yes (full range)
88
\row \li Negative numbers \li Yes (full range)
89
\row \li Byte strings \li Yes
90
\row \li Text strings \li Yes
91
\row \li Chunked strings \li No
92
\row \li Tags \li Yes (arbitrary)
93
\row \li Booleans \li Yes
94
\row \li Null \li Yes
95
\row \li Undefined \li Yes
96
\row \li Arbitrary simple values \li Yes
97
\row \li Half-precision float (16-bit) \li Yes
98
\row \li Single-precision float (32-bit) \li Yes
99
\row \li Double-precision float (64-bit) \li Yes
100
\row \li Infinities and NaN floating point \li Yes
101
\row \li Determinate-length arrays and maps \li Yes
102
\row \li Indeterminate-length arrays and maps \li Yes
103
\row \li Map key types other than strings and integers \li Yes (arbitrary)
104
\endtable
105
106
\section2 Canonical CBOR encoding
107
108
Canonical CBOR encoding is defined by
109
\l{RFC 7049, section 3.9}{Section 3.9 of RFC
110
7049}. Canonical encoding is not a requirement for Qt's CBOR decoding
111
functionality, but it may be required for some protocols. In particular,
112
protocols that require the ability to reproduce the same stream identically
113
may require this.
114
115
In order to be considered "canonical", a CBOR stream must meet the
116
following requirements:
117
118
\list
119
\li Integers must be as small as possible. QCborStreamWriter always
120
does this (no user action is required and it is not possible
121
to write overlong integers).
122
\li Array, map and string lengths must be as short as possible. As
123
above, QCborStreamWriter automatically does this.
124
\li Arrays, maps and strings must use explicit length. QCborStreamWriter
125
always does this for strings; for arrays and maps, be sure to call
126
startArray() and startMap() overloads with explicit length.
127
\li Keys in every map must be sorted in ascending order. QCborStreamWriter
128
offers no help in this item: the developer must ensure that before
129
calling append() for the map pairs.
130
\li Floating point values should be as small as possible. QCborStreamWriter
131
will not convert floating point values; it is up to the developer
132
to perform this check prior to calling append() (see those functions'
133
examples).
134
\endlist
135
136
\section2 Strict CBOR mode
137
138
Strict mode is defined by
139
\l{RFC 7049, section 3.10}{Section 3.10 of RFC
140
7049}. As for Canonical encoding above, QCborStreamWriter makes it possible
141
to create strict CBOR streams, but does not require them or validate that
142
the output is so.
143
144
\list
145
\li Keys in a map must be unique. QCborStreamWriter performs no validation
146
of map keys.
147
\li Tags may be required to be paired only with the correct types,
148
according to their specification. QCborStreamWriter performs no
149
validation of tag usage.
150
\li Text Strings must be properly-encoded UTF-8. QCborStreamWriter always
151
writes proper UTF-8 for strings added with append(), but performs no
152
validation for strings added with appendTextString().
153
\endlist
154
155
\section2 Invalid CBOR stream
156
157
It is also possible to misuse QCborStreamWriter and produce invalid CBOR
158
streams that will fail to be decoded by a receiver. The following actions
159
will produce invalid streams:
160
161
\list
162
\li Append a tag and not append the corresponding tagged value
163
(QCborStreamWriter produces no diagnostic).
164
\li Append too many or too few items to an array or map with explicit
165
length (endMap() and endArray() will return false and
166
QCborStreamWriter will log with qWarning()).
167
\endlist
168
169
\sa QCborStreamReader, QCborValue, QXmlStreamWriter
170
{Parsing and displaying CBOR data}, {Serialization Converter},
171
{Saving and Loading a Game}
172
*/
173
174
class
QCborStreamWriterPrivate
175
{
176
public
:
177
static
constexpr
quint64
IndefiniteLength
= (
std
::
numeric_limits
<
quint64
>::
max
)();
178
179
QIODevice *
device
;
180
CborEncoder
encoder
;
181
QStack
<
CborEncoder
>
containerStack
;
182
bool
deleteDevice
=
false
;
183
184
QCborStreamWriterPrivate
(QIODevice *device)
185
:
device
(device)
186
{
187
cbor_encoder_init_writer(&encoder, qt_cbor_encoder_write_callback,
this
);
188
}
189
190
~
QCborStreamWriterPrivate
()
191
{
192
if
(
deleteDevice
)
193
delete
device
;
194
}
195
196
template
<
typename
... Args>
void
executeAppend
(CborError (*f)(CborEncoder *, Args...), Args... args)
197
{
198
f(&encoder,
std
::forward<Args>(args)...);
199
}
200
201
void
createContainer
(CborError (*f)(CborEncoder *, CborEncoder *, size_t), quint64 len = IndefiniteLength)
202
{
203
static_assert
(size_t(IndefiniteLength) == CborIndefiniteLength);
204
if
(
sizeof
(len) !=
sizeof
(size_t) && len != IndefiniteLength) {
205
if
(Q_UNLIKELY(len >= CborIndefiniteLength)) {
206
// TinyCBOR can't do this in 32-bit mode
207
qWarning(
"QCborStreamWriter: container of size %llu is too big for a 32-bit build; "
208
"will use indeterminate length instead"
, len);
209
len = CborIndefiniteLength;
210
}
211
}
212
213
containerStack.push(encoder);
214
f(&containerStack.top(), &encoder, len);
215
}
216
217
bool
closeContainer
()
218
{
219
if
(containerStack.isEmpty()) {
220
qWarning(
"QCborStreamWriter: closing map or array that wasn't open"
);
221
return
false
;
222
}
223
224
CborEncoder container = containerStack.pop();
225
CborError err = cbor_encoder_close_container(&container, &encoder);
226
encoder = container;
227
228
if
(Q_UNLIKELY(err)) {
229
if
(err == CborErrorTooFewItems)
230
qWarning(
"QCborStreamWriter: not enough items added to array or map"
);
231
else
if
(err == CborErrorTooManyItems)
232
qWarning(
"QCborStreamWriter: too many items added to array or map"
);
233
return
false
;
234
}
235
236
return
true
;
237
}
238
};
239
240
static
CborError
qt_cbor_encoder_write_callback
(
void
*self,
const
void
*data, size_t len,
CborEncoderAppendType
)
241
{
242
auto
that =
static_cast
<
QCborStreamWriterPrivate
*>(self);
243
if
(!that->device)
244
return
CborNoError;
245
qint64 written = that
->
device
->write(
static_cast
<
const
char
*>(data), len);
246
return
(written == qsizetype(len) ? CborNoError : CborErrorIO);
247
}
248
249
/*!
250
Creates a QCborStreamWriter object that will write the stream to \a device.
251
The device must be opened before the first append() call is made. This
252
constructor can be used with any class that derives from QIODevice, such as
253
QFile, QProcess or QTcpSocket.
254
255
QCborStreamWriter has no buffering, so every append() call will result in
256
one or more calls to the device's \l {QIODevice::}{write()} method.
257
258
The following example writes an empty map to a file:
259
260
\snippet code/src_corelib_serialization_qcborstream.cpp 2
261
262
QCborStreamWriter does not take ownership of \a device.
263
264
\sa device(), setDevice()
265
*/
266
QCborStreamWriter::QCborStreamWriter(QIODevice *device)
267
: d(
new
QCborStreamWriterPrivate(device))
268
{
269
}
270
271
#
ifndef
QT_BOOTSTRAPPED
272
/*!
273
Creates a QCborStreamWriter object that will append the stream to \a data.
274
All streaming is done immediately to the byte array, without the need for
275
flushing any buffers.
276
277
The following example writes a number to a byte array then returns
278
it.
279
280
\snippet code/src_corelib_serialization_qcborstream.cpp 3
281
282
QCborStreamWriter does not take ownership of \a data.
283
*/
284
QCborStreamWriter::QCborStreamWriter(QByteArray *data)
285
: d(
new
QCborStreamWriterPrivate(
new
QBuffer(data)))
286
{
287
d->deleteDevice =
true
;
288
d->device->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
289
}
290
#
endif
291
292
/*!
293
Destroys this QCborStreamWriter object and frees any resources associated.
294
295
QCborStreamWriter does not perform error checking to see if all required
296
items were written to the stream prior to the object being destroyed. It is
297
the programmer's responsibility to ensure that it was done.
298
*/
299
QCborStreamWriter::~QCborStreamWriter()
300
{
301
}
302
303
/*!
304
Replaces the device or byte array that this QCborStreamWriter object is
305
writing to with \a device.
306
307
\sa device()
308
*/
309
void
QCborStreamWriter::setDevice(QIODevice *device)
310
{
311
if
(d->deleteDevice)
312
delete
d->device;
313
d->device = device;
314
d->deleteDevice =
false
;
315
}
316
317
/*!
318
Returns the QIODevice that this QCborStreamWriter object is writing to. The
319
device must have previously been set with either the constructor or with
320
setDevice().
321
322
If this object was created by writing to a QByteArray, this function will
323
return an internal instance of QBuffer, which is owned by QCborStreamWriter.
324
325
\sa setDevice()
326
*/
327
QIODevice *QCborStreamWriter::device()
const
328
{
329
return
d->device;
330
}
331
332
/*!
333
\overload
334
335
Appends the 64-bit unsigned value \a u to the CBOR stream, creating a CBOR
336
Unsigned Integer value. In the following example, we write the values 0,
337
2\sup{32} and \c UINT64_MAX:
338
339
\snippet code/src_corelib_serialization_qcborstream.cpp 4
340
341
\sa QCborStreamReader::isUnsignedInteger(), QCborStreamReader::toUnsignedInteger()
342
*/
343
void
QCborStreamWriter::append(quint64 u)
344
{
345
d->executeAppend(cbor_encode_uint, uint64_t(u));
346
}
347
348
/*!
349
\overload
350
351
Appends the 64-bit signed value \a i to the CBOR stream. This will create
352
either a CBOR Unsigned Integer or CBOR NegativeInteger value based on the
353
sign of the parameter. In the following example, we write the values 0, -1,
354
2\sup{32} and \c INT64_MAX:
355
356
\snippet code/src_corelib_serialization_qcborstream.cpp 5
357
358
\sa QCborStreamReader::isInteger(), QCborStreamReader::toInteger()
359
*/
360
void
QCborStreamWriter::append(qint64 i)
361
{
362
d->executeAppend(cbor_encode_int, int64_t(i));
363
}
364
365
/*!
366
\overload
367
368
Appends the 64-bit negative value \a n to the CBOR stream.
369
QCborNegativeInteger is a 64-bit enum that holds the absolute value of the
370
negative number we want to write. If n is zero, the value written will be
371
equivalent to 2\sup{64} (that is, -18,446,744,073,709,551,616).
372
373
In the following example, we write the values -1, -2\sup{32} and INT64_MIN:
374
\snippet code/src_corelib_serialization_qcborstream.cpp 6
375
376
Note how this function can be used to encode numbers that cannot fit a
377
standard computer's 64-bit signed integer like \l qint64. That is, if \a n
378
is larger than \c{std::numeric_limits<qint64>::max()} or is 0, this will
379
represent a negative number smaller than
380
\c{std::numeric_limits<qint64>::min()}.
381
382
\sa QCborStreamReader::isNegativeInteger(), QCborStreamReader::toNegativeInteger()
383
*/
384
void
QCborStreamWriter::append(QCborNegativeInteger n)
385
{
386
d->executeAppend(cbor_encode_negative_int, uint64_t(n));
387
}
388
389
/*!
390
\fn void QCborStreamWriter::append(const QByteArray &ba)
391
\fn void QCborStreamWriter::append(QByteArrayView ba)
392
\overload
393
394
Appends the byte array \a ba to the stream, creating a CBOR Byte String
395
value. QCborStreamWriter will attempt to write the entire string in one
396
chunk.
397
398
The following example will load and append the contents of a file to the
399
stream:
400
401
\snippet code/src_corelib_serialization_qcborstream.cpp 7
402
403
As the example shows, unlike JSON, CBOR requires no escaping for binary
404
content.
405
406
\note The overload taking a \l QByteArrayView has been present since Qt
407
6.10.
408
409
\sa appendByteString(), QCborStreamReader::isByteArray(),
410
QCborStreamReader::readByteArray()
411
*/
412
413
/*!
414
\fn void QCborStreamWriter::append(QUtf8StringView str)
415
\since 6.10
416
\overload
417
418
Appends the UTF-8 string viewed by \a str to the stream, creating a CBOR
419
Text String value. QCborStreamWriter will attempt to write the entire string
420
in one chunk.
421
422
\sa appendTextString(), QCborStreamReader::isString(), QCborStreamReader::readString()
423
*/
424
425
/*!
426
\overload
427
428
Appends the Latin-1 string viewed by \a str to the stream, creating a CBOR
429
Text String value. QCborStreamWriter will attempt to write the entire string
430
in one chunk.
431
432
The following example appends a simple Latin-1 string literal to the stream:
433
434
\snippet code/src_corelib_serialization_qcborstream.cpp 8
435
436
\b{Performance note}: CBOR requires that all Text Strings be encoded in
437
UTF-8, so this function will iterate over the characters in the string to
438
determine whether the contents are US-ASCII or not. If the string is found
439
to contain characters outside of US-ASCII, it will allocate memory and
440
convert to UTF-8. If this check is unnecessary, use appendTextString()
441
instead or the overload taking a \l QUtf8StringView.
442
443
\sa QCborStreamReader::isString(), QCborStreamReader::readString()
444
*/
445
void
QCborStreamWriter::append(QLatin1StringView str)
446
{
447
// We've got Latin-1 but CBOR wants UTF-8, so check if the string is the
448
// common subset (US-ASCII).
449
if
(QtPrivate::isAscii(str)) {
450
// it is plain US-ASCII
451
appendTextString(str.latin1(), str.size());
452
}
else
{
453
// non-ASCII, convert:
454
QVarLengthArray<
char
> utf8(str.size() * 2);
// each L1 char gives at most two U8 units
455
const
qsizetype written = QUtf8::convertFromLatin1(utf8.data(), str) - utf8.data();
456
appendTextString(utf8.data(), written);
457
}
458
}
459
460
/*!
461
\overload
462
463
Appends the text string \a str to the stream, creating a CBOR Text String
464
value. QCborStreamWriter will attempt to write the entire string in one
465
chunk.
466
467
The following example writes an arbitrary QString to the stream:
468
469
\snippet code/src_corelib_serialization_qcborstream.cpp 9
470
471
\sa QCborStreamReader::isString(), QCborStreamReader::readString()
472
*/
473
void
QCborStreamWriter::append(QStringView str)
474
{
475
QByteArray utf8 = str.toUtf8();
476
appendTextString(utf8.constData(), utf8.size());
477
}
478
479
/*!
480
\overload
481
482
Appends the CBOR tag \a tag to the stream, creating a CBOR Tag value. All
483
tags must be followed by another type which they provide meaning for.
484
485
In the following example, we append a CBOR Tag 36 (Regular Expression) and a
486
QRegularExpression's pattern to the stream:
487
488
\snippet code/src_corelib_serialization_qcborstream.cpp 10
489
490
\sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
491
*/
492
void
QCborStreamWriter::append(QCborTag tag)
493
{
494
d->executeAppend(cbor_encode_tag, CborTag(tag));
495
}
496
497
/*!
498
\fn void QCborStreamWriter::append(QCborKnownTags tag)
499
\overload
500
501
Appends the CBOR tag \a tag to the stream, creating a CBOR Tag value. All
502
tags must be followed by another type which they provide meaning for.
503
504
In the following example, we append a CBOR Tag 1 (Unix \c time_t) and an
505
integer representing the current time to the stream, obtained using the \c
506
time() function:
507
508
\snippet code/src_corelib_serialization_qcborstream.cpp 11
509
510
\sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
511
*/
512
513
/*!
514
\overload
515
516
Appends the CBOR simple type \a st to the stream, creating a CBOR Simple
517
Type value. In the following example, we write the simple type for Null as
518
well as for type 32, which Qt has no support for.
519
520
\snippet code/src_corelib_serialization_qcborstream.cpp 12
521
522
\note Using Simple Types for which there is no specification can lead to
523
validation errors by the remote receiver. In addition, simple type values 24
524
through 31 (inclusive) are reserved and must not be used.
525
526
\sa QCborStreamReader::isSimpleType(), QCborStreamReader::toSimpleType()
527
*/
528
void
QCborStreamWriter::append(QCborSimpleType st)
529
{
530
d->executeAppend(cbor_encode_simple_value, uint8_t(st));
531
}
532
533
#
ifndef
QT_BOOTSTRAPPED
534
/*!
535
\overload
536
537
Appends the floating point number \a f to the stream, creating a CBOR 16-bit
538
Half-Precision Floating Point value. The following code can be used to convert
539
a C++ \tt float to \c qfloat16 if there's no loss of precision and append it, or
540
instead append the \tt float.
541
542
\snippet code/src_corelib_serialization_qcborstream.cpp 13
543
544
\sa QCborStreamReader::isFloat16(), QCborStreamReader::toFloat16()
545
*/
546
void
QCborStreamWriter::append(qfloat16 f)
547
{
548
d->executeAppend(cbor_encode_half_float,
static_cast
<
const
void
*>(&f));
549
}
550
#
endif
// QT_BOOTSTRAPPED
551
552
/*!
553
\overload
554
555
Appends the floating point number \a f to the stream, creating a CBOR 32-bit
556
Single-Precision Floating Point value. The following code can be used to convert
557
a C++ \tt double to \tt float if there's no loss of precision and append it, or
558
instead append the \tt double.
559
560
\snippet code/src_corelib_serialization_qcborstream.cpp 14
561
562
\sa QCborStreamReader::isFloat(), QCborStreamReader::toFloat()
563
*/
564
void
QCborStreamWriter::append(
float
f)
565
{
566
d->executeAppend(cbor_encode_float, f);
567
}
568
569
/*!
570
\overload
571
572
Appends the floating point number \a d to the stream, creating a CBOR 64-bit
573
Double-Precision Floating Point value. QCborStreamWriter always appends the
574
number as-is, performing no check for whether the number is the canonical
575
form for NaN, an infinite, whether it is denormal or if it could be written
576
with a shorter format.
577
578
The following code performs all those checks, except for the denormal one,
579
which is expected to be taken into account by the system FPU or floating
580
point emulation directly.
581
582
\snippet code/src_corelib_serialization_qcborstream.cpp 15
583
584
Determining if a double can be converted to an integral with no loss of
585
precision is left as an exercise to the reader.
586
587
\sa QCborStreamReader::isDouble(), QCborStreamReader::toDouble()
588
*/
589
void
QCborStreamWriter::append(
double
d)
590
{
591
this
->d->executeAppend(cbor_encode_double, d);
592
}
593
594
/*!
595
Appends \a len bytes of data starting from \a data to the stream, creating a
596
CBOR Byte String value. QCborStreamWriter will attempt to write the entire
597
string in one chunk.
598
599
\sa append(), appendTextString(),
600
QCborStreamReader::isByteArray(), QCborStreamReader::readByteArray()
601
*/
602
void
QCborStreamWriter::appendByteString(
const
char
*data, qsizetype len)
603
{
604
d->executeAppend(cbor_encode_byte_string,
reinterpret_cast
<
const
uint8_t *>(data), size_t(len));
605
}
606
607
/*!
608
Appends \a len bytes of text starting from \a utf8 to the stream, creating a
609
CBOR Text String value. QCborStreamWriter will attempt to write the entire
610
string in one chunk.
611
612
The string pointed to by \a utf8 is expected to be properly encoded UTF-8.
613
QCborStreamWriter performs no validation that this is the case.
614
615
\sa append(QLatin1StringView), append(QStringView),
616
QCborStreamReader::isString(), QCborStreamReader::readString()
617
*/
618
void
QCborStreamWriter::appendTextString(
const
char
*utf8, qsizetype len)
619
{
620
d->executeAppend(cbor_encode_text_string, utf8, size_t(len));
621
}
622
623
/*!
624
\fn void QCborStreamWriter::append(const char *str, qsizetype size)
625
\overload
626
627
Appends \a size bytes of text starting from \a str to the stream, creating a
628
CBOR Text String value. QCborStreamWriter will attempt to write the entire
629
string in one chunk. If \a size is -1, this function will write \c strlen(\a
630
str) bytes.
631
632
The string pointed to by \a str is expected to be properly encoded UTF-8.
633
QCborStreamWriter performs no validation that this is the case.
634
635
\sa append(QLatin1StringView), append(QStringView),
636
QCborStreamReader::isString(), QCborStreamReader::readString()
637
*/
638
639
/*!
640
\fn void QCborStreamWriter::append(bool b)
641
\overload
642
643
Appends the boolean value \a b to the stream, creating either a CBOR False
644
value or a CBOR True value. This function is equivalent to (and implemented
645
as):
646
647
\snippet code/src_corelib_serialization_qcborstream.cpp 16
648
649
\sa appendNull(), appendUndefined(),
650
QCborStreamReader::isBool(), QCborStreamReader::toBool()
651
*/
652
653
/*!
654
\fn void QCborStreamWriter::append(std::nullptr_t)
655
\overload
656
657
Appends a CBOR Null value to the stream. This function is equivalent to (and
658
implemented as): The parameter is ignored.
659
660
\snippet code/src_corelib_serialization_qcborstream.cpp 17
661
662
\sa appendNull(), append(QCborSimpleType), QCborStreamReader::isNull()
663
*/
664
665
/*!
666
\fn void QCborStreamWriter::appendNull()
667
668
Appends a CBOR Null value to the stream. This function is equivalent to (and
669
implemented as):
670
671
\snippet code/src_corelib_serialization_qcborstream.cpp 18
672
673
\sa append(std::nullptr_t), append(QCborSimpleType), QCborStreamReader::isNull()
674
*/
675
676
/*!
677
\fn void QCborStreamWriter::appendUndefined()
678
679
Appends a CBOR Undefined value to the stream. This function is equivalent to (and
680
implemented as):
681
682
\snippet code/src_corelib_serialization_qcborstream.cpp 19
683
684
\sa append(QCborSimpleType), QCborStreamReader::isUndefined()
685
*/
686
687
/*!
688
Starts a CBOR Array with indeterminate length in the CBOR stream. Each
689
startArray() call must be paired with one endArray() call and the current
690
CBOR element extends until the end of the array.
691
692
The array created by this function has no explicit length. Instead, its
693
length is implied by the elements contained in it. Note, however, that use
694
of indeterminate-length arrays is not compliant with canonical CBOR encoding.
695
696
The following example appends elements from the list of strings
697
passed as input:
698
699
\snippet code/src_corelib_serialization_qcborstream.cpp 20
700
701
\sa startArray(quint64), endArray(), startMap(), QCborStreamReader::isArray(),
702
QCborStreamReader::isLengthKnown()
703
*/
704
void
QCborStreamWriter::startArray()
705
{
706
d->createContainer(cbor_encoder_create_array);
707
}
708
709
/*!
710
\overload
711
712
Starts a CBOR Array with explicit length of \a count items in the CBOR
713
stream. Each startArray call must be paired with one endArray() call and the
714
current CBOR element extends until the end of the array.
715
716
The array created by this function has an explicit length and therefore
717
exactly \a count items must be added to the CBOR stream. Adding fewer or
718
more items will result in failure during endArray() and the CBOR stream will
719
be corrupt. However, explicit-length arrays are required by canonical CBOR
720
encoding.
721
722
The following example appends all strings found in the \l QStringList passed as input:
723
724
\snippet code/src_corelib_serialization_qcborstream.cpp 21
725
726
\b{Size limitations}: The parameter to this function is quint64, which would
727
seem to allow up to 2\sup{64}-1 elements in the array. However, both
728
QCborStreamWriter and QCborStreamReader are currently limited to 2\sup{32}-2
729
items on 32-bit systems and 2\sup{64}-2 items on 64-bit ones. Also note that
730
QCborArray is currently limited to 2\sup{27} elements on 32-bit platforms and
731
2\sup{59} elements on 64-bit ones.
732
733
\sa startArray(), endArray(), startMap(), QCborStreamReader::isArray(),
734
QCborStreamReader::isLengthKnown()
735
*/
736
void
QCborStreamWriter::startArray(quint64 count)
737
{
738
d->createContainer(cbor_encoder_create_array, count);
739
}
740
741
/*!
742
Terminates the array started by either overload of startArray() and returns
743
true if the correct number of elements was added to the array. This function
744
must be called for every startArray() used.
745
746
A return of false indicates error in the application and an unrecoverable
747
error in this stream. QCborStreamWriter also writes a warning using
748
qWarning() if that happens.
749
750
Calling this function when the current container is not an array is also an
751
error, though QCborStreamWriter cannot currently detect this condition.
752
753
\sa startArray(), startArray(quint64), endMap()
754
*/
755
bool
QCborStreamWriter::endArray()
756
{
757
return
d->closeContainer();
758
}
759
760
/*!
761
Starts a CBOR Map with indeterminate length in the CBOR stream. Each
762
startMap() call must be paired with one endMap() call and the current CBOR
763
element extends until the end of the map.
764
765
The map created by this function has no explicit length. Instead, its length
766
is implied by the elements contained in it. Note, however, that use of
767
indeterminate-length maps is not compliant with canonical CBOR encoding
768
(canonical encoding also requires keys to be unique and in sorted order).
769
770
The following example appends elements from the list of int and
771
string pairs passed as input:
772
773
\snippet code/src_corelib_serialization_qcborstream.cpp 22
774
775
\sa startMap(quint64), endMap(), startArray(), QCborStreamReader::isMap(),
776
QCborStreamReader::isLengthKnown()
777
*/
778
void
QCborStreamWriter::startMap()
779
{
780
d->createContainer(cbor_encoder_create_map);
781
}
782
783
/*!
784
\overload
785
786
Starts a CBOR Map with explicit length of \a count items in the CBOR
787
stream. Each startMap call must be paired with one endMap() call and the
788
current CBOR element extends until the end of the map.
789
790
The map created by this function has an explicit length and therefore
791
exactly \a count pairs of items must be added to the CBOR stream. Adding
792
fewer or more items will result in failure during endMap() and the CBOR
793
stream will be corrupt. However, explicit-length map are required by
794
canonical CBOR encoding.
795
796
The following example appends all strings found in the \l QMap passed as input:
797
798
\snippet code/src_corelib_serialization_qcborstream.cpp 23
799
800
\b{Size limitations}: The parameter to this function is quint64, which would
801
seem to allow up to 2\sup{64}-1 pairs in the map. However, both
802
QCborStreamWriter and QCborStreamReader are currently limited to 2\sup{31}-1
803
items on 32-bit systems and 2\sup{63}-1 items on 64-bit ones. Also note that
804
QCborMap is currently limited to 2\sup{26} elements on 32-bit platforms and
805
2\sup{58} on 64-bit ones.
806
807
\sa startMap(), endMap(), startArray(), QCborStreamReader::isMap(),
808
QCborStreamReader::isLengthKnown()
809
*/
810
void
QCborStreamWriter::startMap(quint64 count)
811
{
812
d->createContainer(cbor_encoder_create_map, count);
813
}
814
815
/*!
816
Terminates the map started by either overload of startMap() and returns
817
true if the correct number of elements was added to the array. This function
818
must be called for every startMap() used.
819
820
A return of false indicates error in the application and an unrecoverable
821
error in this stream. QCborStreamWriter also writes a warning using
822
qWarning() if that happens.
823
824
Calling this function when the current container is not a map is also an
825
error, though QCborStreamWriter cannot currently detect this condition.
826
827
\sa startMap(), startMap(quint64), endArray()
828
*/
829
bool
QCborStreamWriter::endMap()
830
{
831
return
d->closeContainer();
832
}
833
834
QT_END_NAMESPACE
835
836
#
undef
CBOR_ENCODER_WRITER_CONTROL
837
#
undef
CBOR_ENCODER_WRITE_FUNCTION
838
#
undef
CBOR_ENCODER_NO_CHECK_USER
QCborStreamWriterPrivate
Definition
qcborstreamwriter.cpp:175
QCborStreamWriterPrivate::IndefiniteLength
static constexpr quint64 IndefiniteLength
Definition
qcborstreamwriter.cpp:177
QCborStreamWriterPrivate::encoder
CborEncoder encoder
Definition
qcborstreamwriter.cpp:180
QCborStreamWriterPrivate::~QCborStreamWriterPrivate
~QCborStreamWriterPrivate()
Definition
qcborstreamwriter.cpp:190
QCborStreamWriterPrivate::containerStack
QStack< CborEncoder > containerStack
Definition
qcborstreamwriter.cpp:181
QCborStreamWriterPrivate::executeAppend
void executeAppend(CborError(*f)(CborEncoder *, Args...), Args... args)
Definition
qcborstreamwriter.cpp:196
QCborStreamWriterPrivate::QCborStreamWriterPrivate
QCborStreamWriterPrivate(QIODevice *device)
Definition
qcborstreamwriter.cpp:184
QCborStreamWriterPrivate::closeContainer
bool closeContainer()
Definition
qcborstreamwriter.cpp:217
QCborStreamWriterPrivate::createContainer
void createContainer(CborError(*f)(CborEncoder *, CborEncoder *, size_t), quint64 len=IndefiniteLength)
Definition
qcborstreamwriter.cpp:201
QCborStreamWriterPrivate::deleteDevice
bool deleteDevice
Definition
qcborstreamwriter.cpp:182
QCborStreamWriterPrivate::device
QIODevice * device
Definition
qcborstreamwriter.cpp:179
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qt_cbor_encoder_write_callback
static QT_BEGIN_NAMESPACE CborError qt_cbor_encoder_write_callback(void *token, const void *data, size_t len, CborEncoderAppendType)
Definition
qcborstreamwriter.cpp:240
qtbase
src
corelib
serialization
qcborstreamwriter.cpp
Generated on
for Qt by
1.18.0