QCborStreamWriter Class
The QCborStreamWriter class is a simple CBOR encoder operating on a one-way stream. More...
| Header: | #include <QCborStreamWriter> |
| qmake: | QT += core |
| Since: | Qt 5.12 |
This class was introduced in Qt 5.12.
Note: All functions in this class are reentrant.
Detailed Description
This class can be used to quickly encode a stream of CBOR content directly to either a QByteArray or QIODevice. CBOR is the Concise Binary Object Representation, a very compact form of binary data encoding that is compatible with JSON. It was created by the IETF Constrained RESTful Environments (CoRE) WG, which has used it in many new RFCs. It is meant to be used alongside the CoAP protocol.
QCborStreamWriter provides a StAX-like API, similar to that of QXmlStreamWriter. It is rather low-level and requires a bit of knowledge of CBOR encoding. For a simpler API, see QCborValue and especially the encoding function QCborValue::toCbor().
The typical use of QCborStreamWriter is to create the object on the target QByteArray or QIODevice, then call one of the append() overloads with the desired type to be encoded. To create arrays and maps, QCborStreamWriter provides startArray() and startMap() overloads, which must be terminated by the corresponding endArray() and endMap() functions.
The following example encodes the equivalent of this JSON content:
{ "label": "journald", "autoDetect": false, "condition": "libs.journald", "output": [ "privateFeature" ] }
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();
CBOR support
QCborStreamWriter supports all CBOR features required to create canonical and strict streams. It implements almost all of the features specified in RFC 7049.
The following table lists the CBOR features that QCborStreamWriter supports.
| Feature | Support |
|---|---|
| Unsigned numbers | Yes (full range) |
| Negative numbers | Yes (full range) |
| Byte strings | Yes |
| Text strings | Yes |
| Chunked strings | No |
| Tags | Yes (arbitrary) |
| Booleans | Yes |
| Null | Yes |
| Undefined | Yes |
| Arbitrary simple values | Yes |
| Half-precision float (16-bit) | Yes |
| Single-precision float (32-bit) | Yes |
| Double-precision float (64-bit) | Yes |
| Infinities and NaN floating point | Yes |
| Determinate-length arrays and maps | Yes |
| Indeterminate-length arrays and maps | Yes |
| Map key types other than strings and integers | Yes (arbitrary) |
Canonical CBOR encoding
Canonical CBOR encoding is defined by Section 3.9 of RFC 7049. Canonical encoding is not a requirement for Qt's CBOR decoding functionality, but it may be required for some protocols. In particular, protocols that require the ability to reproduce the same stream identically may require this.
In order to be considered "canonical", a CBOR stream must meet the following requirements:
- Integers must be as small as possible. QCborStreamWriter always does this (no user action is required and it is not possible to write overlong integers).
- Array, map and string lengths must be as short as possible. As above, QCborStreamWriter automatically does this.
- Arrays, maps and strings must use explicit length. QCborStreamWriter always does this for strings; for arrays and maps, be sure to call startArray() and startMap() overloads with explicit length.
- Keys in every map must be sorted in ascending order. QCborStreamWriter offers no help in this item: the developer must ensure that before calling append() for the map pairs.
- Floating point values should be as small as possible. QCborStreamWriter will not convert floating point values; it is up to the developer to perform this check prior to calling append() (see those functions' examples).
Strict CBOR mode
Strict mode is defined by Section 3.10 of RFC 7049. As for Canonical encoding above, QCborStreamWriter makes it possible to create strict CBOR streams, but does not require them or validate that the output is so.
- Keys in a map must be unique. QCborStreamWriter performs no validation of map keys.
- Tags may be required to be paired only with the correct types, according to their specification. QCborStreamWriter performs no validation of tag usage.
- Text Strings must be properly-encoded UTF-8. QCborStreamWriter always writes proper UTF-8 for strings added with append(), but performs no validation for strings added with appendTextString().
Invalid CBOR stream
It is also possible to misuse QCborStreamWriter and produce invalid CBOR streams that will fail to be decoded by a receiver. The following actions will produce invalid streams:
- Append a tag and not append the corresponding tagged value (QCborStreamWriter produces no diagnostic).
- Append too many or too few items to an array or map with explicit length (endMap() and endArray() will return false and QCborStreamWriter will log with qWarning()).
See also QCborStreamReader, QCborValue, and QXmlStreamWriter.