Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qcborstreamreader.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 "qcborstreamreader.h"
5
6#define CBOR_NO_ENCODER_API
7#include <private/qcborcommon_p.h>
8
9#include <private/qbytearray_p.h>
10#include <private/qnumeric_p.h>
11#include <private/qstringconverter_p.h>
12#include <qiodevice.h>
13#include <qdebug.h>
14#include <qstack.h>
15#include <qvarlengtharray.h>
16
18
19static bool qt_cbor_decoder_can_read(void *token, size_t len);
20static void qt_cbor_decoder_advance(void *token, size_t len);
21static void *qt_cbor_decoder_read(void *token, void *userptr, size_t offset, size_t len);
22static CborError qt_cbor_decoder_transfer_string(void *token, const void **userptr, size_t offset, size_t len);
23
24#define CBOR_PARSER_READER_CONTROL 1
25#define CBOR_PARSER_CAN_READ_BYTES_FUNCTION qt_cbor_decoder_can_read
26#define CBOR_PARSER_ADVANCE_BYTES_FUNCTION qt_cbor_decoder_advance
27#define CBOR_PARSER_TRANSFER_STRING_FUNCTION qt_cbor_decoder_transfer_string
28#define CBOR_PARSER_READ_BYTES_FUNCTION qt_cbor_decoder_read
29
31QT_WARNING_DISABLE_MSVC(4334) // '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
32
33#include <cborparser.c>
34
36
37static CborError _cbor_value_dup_string(const CborValue *, void **, size_t *, CborValue *)
38{
39 Q_UNREACHABLE_RETURN(CborErrorInternalError);
40}
41[[maybe_unused]] static CborError cbor_value_get_half_float_as_float(const CborValue *, float *)
42{
43 Q_UNREACHABLE_RETURN(CborErrorInternalError);
44}
45
46// confirm our constants match TinyCBOR's
47static_assert(int(QCborStreamReader::UnsignedInteger) == CborIntegerType);
48static_assert(int(QCborStreamReader::ByteString) == CborByteStringType);
49static_assert(int(QCborStreamReader::TextString) == CborTextStringType);
50static_assert(int(QCborStreamReader::Array) == CborArrayType);
51static_assert(int(QCborStreamReader::Map) == CborMapType);
52static_assert(int(QCborStreamReader::Tag) == CborTagType);
53static_assert(int(QCborStreamReader::SimpleType) == CborSimpleType);
54static_assert(int(QCborStreamReader::HalfFloat) == CborHalfFloatType);
55static_assert(int(QCborStreamReader::Float) == CborFloatType);
56static_assert(int(QCborStreamReader::Double) == CborDoubleType);
57static_assert(int(QCborStreamReader::Invalid) == CborInvalidType);
58
516{
517public:
518 enum {
519 // 9 bytes is the maximum size for any integer, floating point or
520 // length in CBOR.
523 };
524
528
529 CborParser parser;
530 CborValue currentElement;
532
534 bool corrupt = false;
535
538 {
539 initDecoder();
540 }
541
543 {
545 }
546
548 {
549 }
550
552 {
553 buffer.clear();
554 device = dev;
555 initDecoder();
556 }
557
559 {
561 bufferStart = 0;
562 if (device) {
563 buffer.clear();
564 buffer.reserve(IdealIoBufferSize); // sets the CapacityReserved flag
565 }
566
567 preread();
568 if (CborError err = cbor_parser_init_reader(nullptr, &parser, &currentElement, this))
569 handleError(err);
570 else
572 }
573
574 char *bufferPtr()
575 {
576 Q_ASSERT(buffer.isDetached());
577 return const_cast<char *>(buffer.constData()) + bufferStart;
578 }
579
580 void preread()
581 {
583 // load more, but only if there's more to be read
584 qint64 avail = device->bytesAvailable();
585 Q_ASSERT(avail >= buffer.size());
586 if (avail == buffer.size())
587 return;
588
589 if (bufferStart)
590 device->skip(bufferStart); // skip what we've already parsed
591
592 if (buffer.size() != IdealIoBufferSize)
594
595 bufferStart = 0;
597 if (read < 0)
598 buffer.clear();
599 else if (read != IdealIoBufferSize)
600 buffer.truncate(read);
601 }
602 }
603
604 void handleError(CborError err) noexcept
605 {
606 Q_ASSERT(err);
607
608 // is the error fatal?
609 if (err != CborErrorUnexpectedEOF)
610 corrupt = true;
611
612 lastError = QCborError { QCborError::Code(int(err)) };
613 }
614
616 union {
617 char *ptr;
620 };
621 enum { ByteArray = -1, String = -3 };
623
624 ReadStringChunk(char *ptr, qsizetype maxlen) : ptr(ptr), maxlen_or_type(maxlen) {}
627 bool isString() const { return maxlen_or_type == String; }
628 bool isByteArray() const { return maxlen_or_type == ByteArray; }
629 bool isPlainPointer() const { return maxlen_or_type >= 0; }
630 };
631
635 qsizetype readStringChunk_unicode(ReadStringChunk params, qsizetype utf8len);
637};
638
640{
641 d->handleError(CborError(error.c));
642}
643
644static inline bool qt_cbor_decoder_can_read(void *token, size_t len)
645{
647 auto self = static_cast<QCborStreamReaderPrivate *>(token);
648
649 qint64 avail = self->buffer.size() - self->bufferStart;
650 return len <= quint64(avail);
651}
652
653static void qt_cbor_decoder_advance(void *token, size_t len)
654{
656 auto self = static_cast<QCborStreamReaderPrivate *>(token);
657 Q_ASSERT(len <= size_t(self->buffer.size() - self->bufferStart));
658
659 self->bufferStart += int(len);
660 self->preread();
661}
662
663static void *qt_cbor_decoder_read(void *token, void *userptr, size_t offset, size_t len)
664{
665 Q_ASSERT(len == 1 || len == 2 || len == 4 || len == 8);
666 Q_ASSERT(offset == 0 || offset == 1);
667 auto self = static_cast<const QCborStreamReaderPrivate *>(token);
668
669 // we must have pre-read the data
670 Q_ASSERT(len + offset <= size_t(self->buffer.size() - self->bufferStart));
671 return memcpy(userptr, self->buffer.constData() + self->bufferStart + offset, len);
672}
673
674static CborError qt_cbor_decoder_transfer_string(void *token, const void **userptr, size_t offset, size_t len)
675{
676 auto self = static_cast<QCborStreamReaderPrivate *>(token);
677 Q_ASSERT(offset <= size_t(self->buffer.size()));
678 static_assert(sizeof(size_t) >= sizeof(QByteArray::size_type));
679 static_assert(sizeof(size_t) == sizeof(qsizetype));
680
681 // check that we will have enough data from the QIODevice before we advance
682 // (otherwise, we'd lose the length information)
683 qsizetype total;
684 if (len > size_t(std::numeric_limits<QByteArray::size_type>::max())
685 || qAddOverflow<qsizetype>(offset, len, &total))
686 return CborErrorDataTooLarge;
687
688 // our string transfer is just saving the offset to the userptr
689 *userptr = reinterpret_cast<void *>(offset);
690
691 qint64 avail = (self->device ? self->device->bytesAvailable() : self->buffer.size()) -
692 self->bufferStart;
693 return total > avail ? CborErrorUnexpectedEOF : CborNoError;
694}
695
697{
698 if (currentElement.flags & CborIteratorFlag_IteratingStringChunks)
699 return true;
700
701 CborError err = cbor_value_begin_string_iteration(&currentElement);
702 if (!err)
703 return true;
704 handleError(err);
705 return false;
706}
707
711inline void QCborStreamReader::preparse()
712{
714 type_ = cbor_value_get_type(&d->currentElement);
715
716 if (type_ == CborInvalidType) {
717 // We may have reached the end.
718 if (d->device && d->containerStack.isEmpty()) {
719 d->buffer.clear();
720 if (d->bufferStart)
721 d->device->skip(d->bufferStart);
722 d->bufferStart = 0;
723 }
724 } else {
725 d->lastError = {};
726 // Undo the type mapping that TinyCBOR does (we have an explicit type
727 // for negative integer and we don't have separate types for Boolean,
728 // Null and Undefined).
729 if (type_ == CborBooleanType || type_ == CborNullType || type_ == CborUndefinedType) {
730 type_ = CborSimpleType;
731 value64 = quint8(d->buffer.at(d->bufferStart)) - CborSimpleType;
732 } else {
733 // Using internal TinyCBOR API!
734 value64 = _cbor_value_extract_int64_helper(&d->currentElement);
735
736 if (cbor_value_is_negative_integer(&d->currentElement))
738 }
739 }
740 } else {
741 type_ = Invalid;
742 }
743}
744
755 : d(new QCborStreamReaderPrivate({})), type_(Invalid)
756{
757}
758
766 : QCborStreamReader(QByteArray::fromRawData(data, len))
767{
768}
769
777 : QCborStreamReader(QByteArray::fromRawData(reinterpret_cast<const char *>(data), len))
778{
779}
780
789{
790 preparse();
791}
792
802{
803 preparse();
804}
805
810{
811}
812
818{
819 d->setDevice(device);
820 preparse();
821}
822
829{
830 return d->device;
831}
832
839{
840 addData(data.constData(), data.size());
841}
842
862{
863 if (!d->device) {
864 if (len > 0)
865 d->buffer.append(data, len);
866 reparse();
867 } else {
868 qWarning("QCborStreamReader: addData() with device()");
869 }
870}
871
881{
882 d->lastError = {};
883 d->preread();
884 if (CborError err = cbor_value_reparse(&d->currentElement))
885 d->handleError(err);
886 else
887 preparse();
888}
889
900{
901 setDevice(nullptr);
902}
903
918{
919 if (d->device)
920 d->device->reset();
921 d->lastError = {};
922 d->initDecoder();
923 preparse();
924}
925
933{
934 return d->lastError;
935}
936
946{
947 return (d->device ? d->device->pos() : 0) + d->bufferStart;
948}
949
957{
958 return d->containerStack.size();
959}
960
970{
971 if (d->containerStack.isEmpty())
972 return Invalid;
973 return Type(cbor_value_get_type(&std::as_const(d->containerStack).top()));
974}
975
985bool QCborStreamReader::hasNext() const noexcept
986{
987 return cbor_value_is_valid(&d->currentElement) &&
988 !cbor_value_at_end(&d->currentElement);
989}
990
1007bool QCborStreamReader::next(int maxRecursion)
1008{
1010 return false;
1011
1012 if (!hasNext()) {
1013 d->handleError(CborErrorAdvancePastEOF);
1014 } else if (maxRecursion < 0) {
1015 d->handleError(CborErrorNestingTooDeep);
1016 } else if (isContainer()) {
1017 // iterate over each element
1019 while (lastError() == QCborError::NoError && hasNext())
1020 next(maxRecursion - 1);
1023 } else if (isByteArray()) {
1024 char c;
1026 do {
1027 r = readStringChunk(&c, 1);
1028 } while (r.status == Ok);
1029 } else if (isString()) {
1030 // we need to use actual readString so we get UTF-8 validation
1032 do {
1033 r = readString();
1034 } while (r.status == Ok);
1035 } else {
1036 // fixed types
1037 CborError err = cbor_value_advance_fixed(&d->currentElement);
1038 if (err)
1039 d->handleError(err);
1040 }
1041
1042 preparse();
1043 return d->lastError == QCborError::NoError;
1044}
1045
1065{
1066 return cbor_value_is_length_known(&d->currentElement);
1067}
1068
1079{
1080 CborError err;
1081 switch (type()) {
1082 case String:
1083 case ByteArray:
1084 case Map:
1085 case Array:
1086 if (isLengthKnown())
1087 return value64;
1088 err = CborErrorUnknownLength;
1089 break;
1090
1091 default:
1092 err = CborErrorIllegalType;
1093 break;
1094 }
1095
1096 d->handleError(err);
1097 return quint64(-1);
1098}
1099
1114bool QCborStreamReader::_enterContainer_helper()
1115{
1117 CborError err = cbor_value_enter_container(&d->containerStack.top(), &d->currentElement);
1118 if (!err) {
1119 preparse();
1120 return true;
1121 }
1122 d->handleError(err);
1123 return false;
1124}
1125
1139{
1140 if (d->containerStack.isEmpty()) {
1141 qWarning("QCborStreamReader::leaveContainer: trying to leave top-level element");
1142 return false;
1143 }
1144 if (d->corrupt)
1145 return false;
1146
1147 CborValue container = d->containerStack.pop();
1148 CborError err = cbor_value_leave_container(&container, &d->currentElement);
1149 d->currentElement = container;
1150 if (err) {
1151 d->handleError(err);
1152 return false;
1153 }
1154
1155 preparse();
1156 return true;
1157}
1158
1304QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper()
1305{
1307 auto r = d->readStringChunk(&result.data);
1308 result.status = r.status;
1309 if (r.status == Error) {
1310 result.data.clear();
1311 } else {
1312 Q_ASSERT(r.data == result.data.size());
1313 if (r.status == EndOfString && lastError() == QCborError::NoError)
1314 preparse();
1315 }
1316
1317 return result;
1318}
1319
1336QCborStreamReader::StringResult<QByteArray> QCborStreamReader::_readByteArray_helper()
1337{
1339 auto r = d->readStringChunk(&result.data);
1340 result.status = r.status;
1341 if (r.status == Error) {
1342 result.data.clear();
1343 } else {
1344 Q_ASSERT(r.data == result.data.size());
1345 if (r.status == EndOfString && lastError() == QCborError::NoError)
1346 preparse();
1347 }
1348
1349 return result;
1350}
1351
1365qsizetype QCborStreamReader::_currentStringChunkSize() const
1366{
1367 if (!d->ensureStringIteration())
1368 return -1;
1369
1370 size_t len;
1371 CborError err = cbor_value_get_string_chunk_size(&d->currentElement, &len);
1372 if (err == CborErrorNoMoreStringChunks)
1373 return 0; // not a real error
1374 else if (err)
1375 d->handleError(err);
1376 else if (qsizetype(len) < 0)
1377 d->handleError(CborErrorDataTooLarge);
1378 else
1379 return qsizetype(len);
1380 return -1;
1381}
1382
1413{
1414 auto r = d->readStringChunk({ptr, maxlen});
1415 if (r.status == EndOfString && lastError() == QCborError::NoError)
1416 preparse();
1417 return r;
1418}
1419
1420// used by qcborvalue.cpp
1422{
1424}
1425
1428{
1429 auto status = reader.d->readStringChunk(data).status;
1430 if (status == QCborStreamReader::EndOfString && reader.lastError() == QCborError::NoError)
1431 reader.preparse();
1432 return status;
1433}
1434
1437{
1438 CborError err;
1439 size_t len;
1440 const void *content = nullptr;
1442 result.data = 0;
1444
1445 lastError = {};
1446 if (!ensureStringIteration())
1447 return result;
1448
1449 // Note: in the current implementation, the call into TinyCBOR below only
1450 // succeeds if we *already* have all the data in memory. That's obvious for
1451 // the case of direct memory (no QIODevice), whereas for QIODevices
1452 // qt_cbor_decoder_transfer_string() enforces that
1453 // QIODevice::bytesAvailable() be bigger than the amount we're about to
1454 // read.
1455#if 1
1456 // Using internal TinyCBOR API!
1457 err = _cbor_value_get_string_chunk(&currentElement, &content, &len, &currentElement);
1458#else
1459 // the above is effectively the same as:
1460 if (cbor_value_is_byte_string(&currentElement))
1461 err = cbor_value_get_byte_string_chunk(&currentElement, reinterpret_cast<const uint8_t **>(&content),
1462 &len, &currentElement);
1463 else
1464 err = cbor_value_get_text_string_chunk(&currentElement, reinterpret_cast<const char **>(&content),
1465 &len, &currentElement);
1466#endif
1467
1468 // Range check: using implementation-defined behavior in converting an
1469 // unsigned value out of range of the destination signed type (same as
1470 // "len > size_t(std::numeric_limits<qsizetype>::max())", but generates
1471 // better code with ICC and MSVC).
1472 if (!err && qsizetype(len) < 0)
1473 err = CborErrorDataTooLarge;
1474
1475 if (err) {
1476 if (err == CborErrorNoMoreStringChunks) {
1477 preread();
1478 err = cbor_value_finish_string_iteration(&currentElement);
1480 }
1481 if (err)
1482 handleError(err);
1483 // caller musts call preparse()
1484 return result;
1485 }
1486
1487 qptrdiff offset = qptrdiff(content);
1489 if (device) {
1490 // This first skip can't fail because we've already read this many bytes.
1492 }
1493
1494 if (params.isString()) {
1495 // readString()
1497 } else {
1498 // readByteArray() or readStringChunk()
1500 }
1501
1502 if (result.data < 0)
1503 return result; // error
1504
1505 // adjust the buffers after we're done reading the string
1506 bufferStart += len;
1507 if (device) {
1508 qsizetype remainingInBuffer = buffer.size() - bufferStart;
1509
1510 if (remainingInBuffer <= 0) {
1511 // We've read from the QIODevice more than what was in the buffer.
1512 buffer.truncate(0);
1513 } else {
1514 // There's still data buffered, but we need to move it around.
1515 char *ptr = buffer.data();
1516 memmove(ptr, ptr + bufferStart, remainingInBuffer);
1517 buffer.truncate(remainingInBuffer);
1518 }
1519
1520 bufferStart = 0;
1521 }
1522
1523 preread();
1525 return result;
1526}
1527
1528inline qsizetype
1530{
1531 qint64 actuallyRead;
1532 qsizetype toRead = qsizetype(len);
1533 qsizetype left = 0; // bytes from the chunk not copied to the user buffer, to discard
1534 char *ptr = nullptr;
1535
1536 if (params.isPlainPointer()) {
1537 left = toRead - params.maxlen_or_type;
1538 if (left < 0)
1539 left = 0; // buffer bigger than string
1540 else
1541 toRead = params.maxlen_or_type; // buffer smaller than string
1542 ptr = params.ptr;
1543 } else if (params.isByteArray()) {
1544 // See note above on having ensured there is enough incoming data.
1545 auto oldSize = params.array->size();
1546 auto newSize = oldSize;
1547 if (qAddOverflow<decltype(newSize)>(oldSize, toRead, &newSize)) {
1548 handleError(CborErrorDataTooLarge);
1549 return -1;
1550 }
1551 QT_TRY {
1552 params.array->resize(newSize);
1553 } QT_CATCH (const std::bad_alloc &) {
1554 // the distinction between DataTooLarge and OOM is mostly for
1555 // compatibility with Qt 5; in Qt 6, we could consider everything
1556 // to be OOM.
1557 handleError(newSize > MaxByteArraySize ? CborErrorDataTooLarge: CborErrorOutOfMemory);
1558 return -1;
1559 }
1560
1561 ptr = const_cast<char *>(params.array->constData()) + oldSize;
1562 }
1563
1564 if (device) {
1565 actuallyRead = device->read(ptr, toRead);
1566
1567 if (actuallyRead != toRead) {
1568 actuallyRead = -1;
1569 } else if (left) {
1570 qint64 skipped = device->skip(left);
1571 if (skipped != left)
1572 actuallyRead = -1;
1573 }
1574
1575 if (actuallyRead < 0) {
1576 handleError(CborErrorIO);
1577 return -1;
1578 }
1579 } else {
1580 actuallyRead = toRead;
1581 memcpy(ptr, buffer.constData() + bufferStart, toRead);
1582 }
1583
1584 return actuallyRead;
1585}
1586
1587inline qsizetype
1589{
1590 // See QUtf8::convertToUnicode() a detailed explanation of why this
1591 // conversion uses the same number of words or less.
1592 QChar *begin = nullptr;
1593 if (params.isString()) {
1594 QT_TRY {
1595 params.string->resize(utf8len);
1596 } QT_CATCH (const std::bad_alloc &) {
1597 if (utf8len > MaxStringSize)
1598 handleError(CborErrorDataTooLarge);
1599 else
1600 handleError(CborErrorOutOfMemory);
1601 return -1;
1602 }
1603
1604 begin = const_cast<QChar *>(params.string->constData());
1605 }
1606
1607 QChar *ptr = begin;
1609 if (device == nullptr) {
1610 // Easy case: we can decode straight from the buffer we already have
1611 ptr = QUtf8::convertToUnicode(ptr, { buffer.constData() + bufferStart, utf8len }, &cs);
1612 } else {
1613 // read in chunks, to avoid creating large, intermediate buffers
1614 constexpr qsizetype StringChunkSize = 16384;
1615 qsizetype chunkSize = qMin(StringChunkSize, utf8len);
1616 QVarLengthArray<char> chunk(chunkSize);
1617
1619 while (utf8len > 0 && cs.invalidChars == 0) {
1620 qsizetype toRead = qMin(chunkSize, utf8len);
1621 qint64 actuallyRead = device->read(chunk.data(), toRead);
1622 if (actuallyRead == toRead)
1623 ptr = QUtf8::convertToUnicode(ptr, { chunk.data(), toRead }, &cs);
1624
1625 if (actuallyRead != toRead) {
1626 handleError(CborErrorIO);
1627 return -1;
1628 }
1629 utf8len -= toRead;
1630 }
1631 }
1632
1633 if (cs.invalidChars != 0 || cs.remainingChars != 0) {
1634 handleError(CborErrorInvalidUtf8TextString);
1635 return -1;
1636 }
1637
1638 qsizetype size = ptr - begin;
1639 if (params.isString())
1640 params.string->truncate(size);
1641 return size;
1642}
1643
1645
1646#include "moc_qcborstreamreader.cpp"
IOBluetoothDevice * device
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size_type
Definition qbytearray.h:444
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
Definition qbytearray.h:523
void clear()
Clears the contents of the byte array and makes it null.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QStack< CborValue > containerStack
void handleError(CborError err) noexcept
QCborStreamReaderPrivate(QIODevice *device)
QByteArray::size_type bufferStart
qsizetype readStringChunk_byte(ReadStringChunk params, qsizetype len)
qsizetype readStringChunk_unicode(ReadStringChunk params, qsizetype utf8len)
static QCborStreamReader::StringResultCode appendStringChunk(QCborStreamReader &reader, QByteArray *data)
QCborStreamReader::StringResult< qsizetype > readStringChunk(ReadStringChunk params)
void setDevice(QIODevice *dev)
QCborStreamReaderPrivate(const QByteArray &data)
\inmodule QtCore\reentrant
void setDevice(QIODevice *device)
Sets the source of data to device, resetting the decoder to its initial state.
bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION
Returns true if the length of the current array, map, byte array or string is known (explicit in the ...
QIODevice * device() const
Returns the QIODevice that was set with either setDevice() or the QCborStreamReader constructor.
void clear()
Clears the decoder state and resets the input source data to an empty byte array.
qint64 currentOffset() const
Returns the offset in the input stream of the item currently being decoded.
bool isByteArray() const
Returns true if the type of the current element is a byte array (that is, if type() returns QCborStre...
bool next(int maxRecursion=10000)
Advance the CBOR stream decoding one element.
void addData(const QByteArray &data)
Adds data to the CBOR stream and reparses the current element.
bool isString() const
Returns true if the type of the current element is a text string (that is, if type() returns QCborStr...
void reset()
Resets the source back to the beginning and clears the decoder state.
QCborStreamReader()
Creates a QCborStreamReader object with no source data.
QCborError lastError()
Returns the last error in decoding the stream, if any.
QCborStreamReader::Type parentContainerType() const
Returns either QCborStreamReader::Array or QCborStreamReader::Map, indicating whether the container t...
bool enterContainer()
Enters the array or map that is the current item and prepares for iterating the elements contained in...
void reparse()
Reparses the current element.
quint64 length() const
Returns the length of the string or byte array, or the number of items in an array or the number,...
StringResult< QString > readString()
Decodes one string chunk from the CBOR string and returns it.
bool hasNext() const noexcept Q_DECL_PURE_FUNCTION
Returns true if there are more items to be decoded in the current container or false of we've reached...
StringResultCode
This enum is returned by readString() and readByteArray() and is used to indicate what the status of ...
StringResult< qsizetype > readStringChunk(char *ptr, qsizetype maxlen)
Reads the current string chunk into the buffer pointed to by ptr, whose size is maxlen.
Type
This enumeration contains all possible CBOR types as decoded by QCborStreamReader.
bool isContainer() const
Returns true if the current element is a container (that is, an array or a map), false if it is anyth...
~QCborStreamReader()
Destroys this QCborStreamReader object and frees any associated resources.
bool leaveContainer()
Leaves the array or map whose items were being processed and positions the decoder at the next item a...
int containerDepth() const
Returns the number of containers that this stream has entered with enterContainer() but not yet left.
\inmodule QtCore
Definition qchar.h:48
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
qint64 peek(char *data, qint64 maxlen)
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
qint64 skip(qint64 maxSize)
virtual bool reset()
Seeks to the start of input for random-access devices.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
void clear()
Definition qlist.h:417
\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
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1101
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
T * data() noexcept
QString str
[2]
short next
Definition keywords.cpp:445
Token token
Definition keywords.cpp:444
Combined button and popup list for selecting options.
constexpr qsizetype MaxStringSize
QT_BEGIN_NAMESPACE constexpr qsizetype MaxByteArraySize
QT_WARNING_PUSH static QT_WARNING_POP CborError _cbor_value_dup_string(const CborValue *, void **, size_t *, CborValue *)
static CborError qt_cbor_decoder_transfer_string(void *token, const void **userptr, size_t offset, size_t len)
QCborStreamReader::StringResultCode qt_cbor_append_string_chunk(QCborStreamReader &reader, QByteArray *data)
static QT_BEGIN_NAMESPACE bool qt_cbor_decoder_can_read(void *token, size_t len)
void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error)
static void qt_cbor_decoder_advance(void *token, size_t len)
static void * qt_cbor_decoder_read(void *token, void *userptr, size_t offset, size_t len)
static CborError cbor_value_get_half_float_as_float(const CborValue *, float *)
#define Q_NEVER_INLINE
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_MSVC(number)
#define QT_WARNING_PUSH
DBusConnection const char DBusError * error
#define QT_CATCH(A)
#define QT_TRY
#define qWarning
Definition qlogging.h:162
static ControlElement< T > * ptr(QWidget *widget)
@ Invalid
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
Definition qnumeric.h:113
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLenum GLuint buffer
GLint left
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
void ** params
const GLubyte * c
GLenum array
GLenum GLsizei len
GLuint64EXT * result
[6]
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
ptrdiff_t qptrdiff
Definition qtypes.h:69
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
long long qint64
Definition qtypes.h:55
unsigned char quint8
Definition qtypes.h:41
ReturnedValue read(const char *data)
QObject::connect nullptr
\inmodule QtCore \inheaderfile QtCborCommon \reentrant
Definition qcborcommon.h:63
Code
This enum contains the possible error condition codes.
Definition qcborcommon.h:66
static QChar * convertToUnicode(QChar *buffer, QByteArrayView in) noexcept