Qt 6.x
The Qt SDK
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
4#include "qcborstreamwriter.h"
5
6#define CBOR_NO_PARSER_API
7#include <private/qcborcommon_p.h>
8
9#include <private/qnumeric_p.h>
10#include <qbuffer.h>
11#include <qdebug.h>
12#include <qstack.h>
13
15
16static CborError qt_cbor_encoder_write_callback(void *token, const void *data, size_t len, CborEncoderAppendType);
17#define CBOR_ENCODER_WRITER_CONTROL 1
18#define CBOR_ENCODER_WRITE_FUNCTION qt_cbor_encoder_write_callback
19#define CBOR_ENCODER_NO_CHECK_USER
20
22QT_WARNING_DISABLE_MSVC(4334) // '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
23
24#include <cborencoder.c>
25
27
28// silence compilers that complain about this being a static function declared
29// but never defined
30[[maybe_unused]] static CborError cbor_encoder_close_container_checked(CborEncoder*, const CborEncoder*)
31{
32 Q_UNREACHABLE_RETURN(CborErrorInternalError);
33}
34
35[[maybe_unused]] static CborError cbor_encode_float_as_half_float(CborEncoder *, float)
36{
37 Q_UNREACHABLE_RETURN(CborErrorInternalError);
38}
39
41
182{
183public:
184 static constexpr quint64 IndefiniteLength = (std::numeric_limits<quint64>::max)();
185
187 CborEncoder encoder;
189 bool deleteDevice = false;
190
192 : device(device)
193 {
194 cbor_encoder_init_writer(&encoder, qt_cbor_encoder_write_callback, this);
195 }
196
198 {
199 if (deleteDevice)
200 delete device;
201 }
202
203 template <typename... Args> void executeAppend(CborError (*f)(CborEncoder *, Args...), Args... args)
204 {
205 f(&encoder, std::forward<Args>(args)...);
206 }
207
208 void createContainer(CborError (*f)(CborEncoder *, CborEncoder *, size_t), quint64 len = IndefiniteLength)
209 {
210 static_assert(size_t(IndefiniteLength) == CborIndefiniteLength);
211 if (sizeof(len) != sizeof(size_t) && len != IndefiniteLength) {
212 if (Q_UNLIKELY(len >= CborIndefiniteLength)) {
213 // TinyCBOR can't do this in 32-bit mode
214 qWarning("QCborStreamWriter: container of size %llu is too big for a 32-bit build; "
215 "will use indeterminate length instead", len);
216 len = CborIndefiniteLength;
217 }
218 }
219
222 }
223
225 {
226 if (containerStack.isEmpty()) {
227 qWarning("QCborStreamWriter: closing map or array that wasn't open");
228 return false;
229 }
230
231 CborEncoder container = containerStack.pop();
232 CborError err = cbor_encoder_close_container(&container, &encoder);
233 encoder = container;
234
235 if (Q_UNLIKELY(err)) {
236 if (err == CborErrorTooFewItems)
237 qWarning("QCborStreamWriter: not enough items added to array or map");
238 else if (err == CborErrorTooManyItems)
239 qWarning("QCborStreamWriter: too many items added to array or map");
240 return false;
241 }
242
243 return true;
244 }
245};
246
247static CborError qt_cbor_encoder_write_callback(void *self, const void *data, size_t len, CborEncoderAppendType)
248{
249 auto that = static_cast<QCborStreamWriterPrivate *>(self);
250 if (!that->device)
251 return CborNoError;
252 qint64 written = that->device->write(static_cast<const char *>(data), len);
253 return (written == qsizetype(len) ? CborNoError : CborErrorIO);
254}
255
275{
276}
277
292{
293 d->deleteDevice = true;
295}
296
305{
306}
307
315{
316 if (d->deleteDevice)
317 delete d->device;
318 d->device = device;
319 d->deleteDevice = false;
320}
321
333{
334 return d->device;
335}
336
349{
350 d->executeAppend(cbor_encode_uint, uint64_t(u));
351}
352
366{
367 d->executeAppend(cbor_encode_int, int64_t(i));
368}
369
390{
391 d->executeAppend(cbor_encode_negative_int, uint64_t(n));
392}
393
435{
436 // We've got Latin-1 but CBOR wants UTF-8, so check if the string is the
437 // common subset (US-ASCII).
438 if (QtPrivate::isAscii(str)) {
439 // it is plain US-ASCII
440 appendTextString(str.latin1(), str.size());
441 } else {
442 // non-ASCII, so we need a pass-through UTF-16
444 }
445}
446
461{
462 QByteArray utf8 = str.toUtf8();
463 appendTextString(utf8.constData(), utf8.size());
464}
465
480{
481 d->executeAppend(cbor_encode_tag, CborTag(tag));
482}
483
516{
517 d->executeAppend(cbor_encode_simple_value, uint8_t(st));
518}
519
520#ifndef QT_BOOTSTRAPPED
534{
535 d->executeAppend(cbor_encode_half_float, static_cast<const void *>(&f));
536}
537#endif // QT_BOOTSTRAPPED
538
552{
553 d->executeAppend(cbor_encode_float, f);
554}
555
577{
578 this->d->executeAppend(cbor_encode_double, d);
579}
580
595{
596 d->executeAppend(cbor_encode_byte_string, reinterpret_cast<const uint8_t *>(data), size_t(len));
597}
598
615{
616 d->executeAppend(cbor_encode_text_string, utf8, size_t(len));
617}
618
705{
706 d->createContainer(cbor_encoder_create_array);
707}
708
736{
737 d->createContainer(cbor_encoder_create_array, count);
738}
739
755{
756 return d->closeContainer();
757}
758
778{
779 d->createContainer(cbor_encoder_create_map);
780}
781
809{
810 d->createContainer(cbor_encoder_create_map, count);
811}
812
828{
829 return d->closeContainer();
830}
831
833
834#undef CBOR_ENCODER_WRITER_CONTROL
835#undef CBOR_ENCODER_WRITE_FUNCTION
836#undef CBOR_ENCODER_NO_CHECK_USER
IOBluetoothDevice * device
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:474
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
void executeAppend(CborError(*f)(CborEncoder *, Args...), Args... args)
QCborStreamWriterPrivate(QIODevice *device)
QStack< CborEncoder > containerStack
static constexpr quint64 IndefiniteLength
void createContainer(CborError(*f)(CborEncoder *, CborEncoder *, size_t), quint64 len=IndefiniteLength)
void setDevice(QIODevice *device)
Replaces the device or byte array that this QCborStreamWriter object is writing to with device.
~QCborStreamWriter()
Destroys this QCborStreamWriter object and frees any resources associated.
bool endMap()
Terminates the map started by either overload of startMap() and returns true if the correct number of...
void startMap()
Starts a CBOR Map with indeterminate length in the CBOR stream.
void appendTextString(const char *utf8, qsizetype len)
Appends len bytes of text starting from utf8 to the stream, creating a CBOR Text String value.
void appendByteString(const char *data, qsizetype len)
Appends len bytes of data starting from data to the stream, creating a CBOR Byte String value.
QCborStreamWriter(QIODevice *device)
Creates a QCborStreamWriter object that will write the stream to device.
void startArray()
Starts a CBOR Array with indeterminate length in the CBOR stream.
void append(quint64 u)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool endArray()
Terminates the array started by either overload of startArray() and returns true if the correct numbe...
QIODevice * device() const
Returns the QIODevice that this QCborStreamWriter object is writing to.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
bool isEmpty() const noexcept
Definition qlist.h:390
\inmodule QtCore
Definition qstack.h:13
T & top()
Returns a reference to the stack's top item.
Definition qstack.h:19
T pop()
Removes the top item from the stack and returns it.
Definition qstack.h:18
void push(const T &t)
Adds element t to the top of the stack.
Definition qstack.h:17
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QByteArray toUtf8() const &
Definition qstring.h:563
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Definition qfloat16.h:46
QString str
[2]
Token token
Definition keywords.cpp:444
Combined button and popup list for selecting options.
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QLatin1StringView s) noexcept
Definition qstring.cpp:860
QCborTag
Definition qcborcommon.h:30
QCborSimpleType
Definition qcborcommon.h:23
QCborNegativeInteger
QT_WARNING_PUSH static QT_WARNING_POP CborError cbor_encoder_close_container_checked(CborEncoder *, const CborEncoder *)
static QT_BEGIN_NAMESPACE CborError qt_cbor_encoder_write_callback(void *token, const void *data, size_t len, CborEncoderAppendType)
static CborError cbor_encode_float_as_half_float(CborEncoder *, float)
#define Q_UNLIKELY(x)
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_MSVC(number)
#define QT_WARNING_PUSH
AudioChannelLayoutTag tag
#define qWarning
Definition qlogging.h:162
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat n
GLenum GLsizei len
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:144
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
long long qint64
Definition qtypes.h:55
QJSValueList args