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#ifndef QCBORSTREAMREADER_H
5#define QCBORSTREAMREADER_H
6
7#include <QtCore/qbytearray.h>
8#include <QtCore/qcborcommon.h>
9#include <QtCore/qfloat16.h>
10#include <QtCore/qscopedpointer.h>
11#include <QtCore/qstring.h>
12#include <QtCore/qstringview.h>
13
14QT_REQUIRE_CONFIG(cborstreamreader);
15
16/* X11 headers use these values too, but as defines */
17#if defined(False) && defined(True)
18# undef True
19# undef False
20#endif
21
22QT_BEGIN_NAMESPACE
23
24class QIODevice;
25
26class QCborStreamReaderPrivate;
27class Q_CORE_EXPORT QCborStreamReader
28{
29 Q_GADGET
30public:
31 enum Type : quint8 {
32 UnsignedInteger = 0x00,
33 NegativeInteger = 0x20,
34 ByteString = 0x40,
35 ByteArray = ByteString,
36 TextString = 0x60,
37 String = TextString,
38 Array = 0x80,
39 Map = 0xa0,
40 Tag = 0xc0,
41 SimpleType = 0xe0,
42 HalfFloat = 0xf9,
43 Float16 = HalfFloat,
44 Float = 0xfa,
45 Double = 0xfb,
46
47 Invalid = 0xff
48 };
49 Q_ENUM(Type)
50
51 enum StringResultCode {
52 EndOfString = 0,
53 Ok = 1,
54 Error = -1
55 };
56 template <typename Container> struct StringResult {
57 Container data;
58 StringResultCode status = Error;
59 };
60 Q_ENUM(StringResultCode)
61
62 QCborStreamReader();
63 QCborStreamReader(const char *data, qsizetype len);
64 QCborStreamReader(const quint8 *data, qsizetype len);
65 explicit QCborStreamReader(const QByteArray &data);
66 explicit QCborStreamReader(QIODevice *device);
67 ~QCborStreamReader();
68 Q_DISABLE_COPY(QCborStreamReader)
69
70 void setDevice(QIODevice *device);
71 QIODevice *device() const;
72 void addData(const QByteArray &data);
73 void addData(const char *data, qsizetype len);
74 void addData(const quint8 *data, qsizetype len)
75 { addData(data: reinterpret_cast<const char *>(data), len); }
76 void reparse();
77 void clear();
78 void reset();
79
80 QCborError lastError();
81
82 qint64 currentOffset() const;
83
84 bool isValid() const { return !isInvalid(); }
85
86 int containerDepth() const;
87 QCborStreamReader::Type parentContainerType() const;
88 bool hasNext() const noexcept Q_DECL_PURE_FUNCTION;
89 bool next(int maxRecursion = 10000);
90
91 Type type() const { return QCborStreamReader::Type(type_); }
92 bool isUnsignedInteger() const { return type() == UnsignedInteger; }
93 bool isNegativeInteger() const { return type() == NegativeInteger; }
94 bool isInteger() const { return quint8(type()) <= quint8(NegativeInteger); }
95 bool isByteArray() const { return type() == ByteArray; }
96 bool isString() const { return type() == String; }
97 bool isArray() const { return type() == Array; }
98 bool isMap() const { return type() == Map; }
99 bool isTag() const { return type() == Tag; }
100 bool isSimpleType() const { return type() == SimpleType; }
101 bool isFloat16() const { return type() == Float16; }
102 bool isFloat() const { return type() == Float; }
103 bool isDouble() const { return type() == Double; }
104 bool isInvalid() const { return type() == Invalid; }
105
106 bool isSimpleType(QCborSimpleType st) const { return isSimpleType() && toSimpleType() == st; }
107 bool isFalse() const { return isSimpleType(st: QCborSimpleType::False); }
108 bool isTrue() const { return isSimpleType(st: QCborSimpleType::True); }
109 bool isBool() const { return isFalse() || isTrue(); }
110 bool isNull() const { return isSimpleType(st: QCborSimpleType::Null); }
111 bool isUndefined() const { return isSimpleType(st: QCborSimpleType::Undefined); }
112
113 bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION;
114 quint64 length() const;
115
116 bool isContainer() const { return isMap() || isArray(); }
117 bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); }
118 bool leaveContainer();
119
120 StringResult<QString> readString() { Q_ASSERT(isString()); return _readString_helper(); }
121 StringResult<QByteArray> readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); }
122 qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); }
123 StringResult<qsizetype> readStringChunk(char *ptr, qsizetype maxlen);
124
125 bool toBool() const { Q_ASSERT(isBool()); return value64 - int(QCborSimpleType::False); }
126 QCborTag toTag() const { Q_ASSERT(isTag()); return QCborTag(value64); }
127 quint64 toUnsignedInteger() const { Q_ASSERT(isUnsignedInteger()); return value64; }
128 QCborNegativeInteger toNegativeInteger() const { Q_ASSERT(isNegativeInteger()); return QCborNegativeInteger(value64 + 1); }
129 QCborSimpleType toSimpleType() const{ Q_ASSERT(isSimpleType()); return QCborSimpleType(value64); }
130 qfloat16 toFloat16() const { Q_ASSERT(isFloat16()); return _toFloatingPoint<qfloat16>(); }
131 float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint<float>(); }
132 double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint<double>(); }
133
134 qint64 toInteger() const
135 {
136 Q_ASSERT(isInteger());
137 qint64 v = qint64(value64);
138 if (isNegativeInteger())
139 return -v - 1;
140 return v;
141 }
142
143private:
144 void preparse();
145 bool _enterContainer_helper();
146 StringResult<QString> _readString_helper();
147 StringResult<QByteArray> _readByteArray_helper();
148 qsizetype _currentStringChunkSize() const;
149
150 template <typename FP> FP _toFloatingPoint() const noexcept
151 {
152 using UIntFP = typename QIntegerForSizeof<FP>::Unsigned;
153 UIntFP u = UIntFP(value64);
154 FP f;
155 memcpy(static_cast<void *>(&f), &u, sizeof(f));
156 return f;
157 }
158
159 friend QCborStreamReaderPrivate;
160 friend class QCborContainerPrivate;
161 quint64 value64;
162 QScopedPointer<QCborStreamReaderPrivate> d;
163 quint8 type_;
164 quint8 reserved[3] = {};
165};
166
167QT_END_NAMESPACE
168
169#if defined(QT_X11_DEFINES_FOUND)
170# define True 1
171# define False 0
172#endif
173
174#endif // QCBORSTREAMREADER_H
175

source code of qtbase/src/corelib/serialization/qcborstreamreader.h