1/****************************************************************************
2**
3** Copyright (C) 2018 Intel Corporation.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QCBORSTREAMREADER_H
41#define QCBORSTREAMREADER_H
42
43#include <QtCore/qbytearray.h>
44#include <QtCore/qcborcommon.h>
45#include <QtCore/qfloat16.h>
46#include <QtCore/qscopedpointer.h>
47#include <QtCore/qstring.h>
48#include <QtCore/qstringview.h>
49
50QT_REQUIRE_CONFIG(cborstreamreader);
51
52// See qcborcommon.h for why we check
53#if defined(QT_X11_DEFINES_FOUND)
54# undef True
55# undef False
56#endif
57
58QT_BEGIN_NAMESPACE
59
60class QIODevice;
61
62class QCborStreamReaderPrivate;
63class Q_CORE_EXPORT QCborStreamReader
64{
65 Q_GADGET
66public:
67 enum Type : quint8 {
68 UnsignedInteger = 0x00,
69 NegativeInteger = 0x20,
70 ByteString = 0x40,
71 ByteArray = ByteString,
72 TextString = 0x60,
73 String = TextString,
74 Array = 0x80,
75 Map = 0xa0,
76 Tag = 0xc0,
77 SimpleType = 0xe0,
78 HalfFloat = 0xf9,
79 Float16 = HalfFloat,
80 Float = 0xfa,
81 Double = 0xfb,
82
83 Invalid = 0xff
84 };
85 Q_ENUM(Type)
86
87 enum StringResultCode {
88 EndOfString = 0,
89 Ok = 1,
90 Error = -1
91 };
92 template <typename Container> struct StringResult {
93 Container data;
94 StringResultCode status = Error;
95 };
96 Q_ENUM(StringResultCode)
97
98 QCborStreamReader();
99 QCborStreamReader(const char *data, qsizetype len);
100 QCborStreamReader(const quint8 *data, qsizetype len);
101 explicit QCborStreamReader(const QByteArray &data);
102 explicit QCborStreamReader(QIODevice *device);
103 ~QCborStreamReader();
104 Q_DISABLE_COPY(QCborStreamReader)
105
106 void setDevice(QIODevice *device);
107 QIODevice *device() const;
108 void addData(const QByteArray &data);
109 void addData(const char *data, qsizetype len);
110 void addData(const quint8 *data, qsizetype len)
111 { addData(reinterpret_cast<const char *>(data), len); }
112 void reparse();
113 void clear();
114 void reset();
115
116 QCborError lastError();
117
118 qint64 currentOffset() const;
119
120 bool isValid() const { return !isInvalid(); }
121
122 int containerDepth() const;
123 QCborStreamReader::Type parentContainerType() const;
124 bool hasNext() const noexcept Q_DECL_PURE_FUNCTION;
125 bool next(int maxRecursion = 10000);
126
127 Type type() const { return QCborStreamReader::Type(type_); }
128 bool isUnsignedInteger() const { return type() == UnsignedInteger; }
129 bool isNegativeInteger() const { return type() == NegativeInteger; }
130 bool isInteger() const { return quint8(type()) <= quint8(NegativeInteger); }
131 bool isByteArray() const { return type() == ByteArray; }
132 bool isString() const { return type() == String; }
133 bool isArray() const { return type() == Array; }
134 bool isMap() const { return type() == Map; }
135 bool isTag() const { return type() == Tag; }
136 bool isSimpleType() const { return type() == SimpleType; }
137 bool isFloat16() const { return type() == Float16; }
138 bool isFloat() const { return type() == Float; }
139 bool isDouble() const { return type() == Double; }
140 bool isInvalid() const { return type() == Invalid; }
141
142 bool isSimpleType(QCborSimpleType st) const { return isSimpleType() && toSimpleType() == st; }
143 bool isFalse() const { return isSimpleType(QCborSimpleType::False); }
144 bool isTrue() const { return isSimpleType(QCborSimpleType::True); }
145 bool isBool() const { return isFalse() || isTrue(); }
146 bool isNull() const { return isSimpleType(QCborSimpleType::Null); }
147 bool isUndefined() const { return isSimpleType(QCborSimpleType::Undefined); }
148
149 bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION;
150 quint64 length() const;
151
152 bool isContainer() const { return isMap() || isArray(); }
153 bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); }
154 bool leaveContainer();
155
156 StringResult<QString> readString() { Q_ASSERT(isString()); return _readString_helper(); }
157 StringResult<QByteArray> readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); }
158 qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); }
159 StringResult<qsizetype> readStringChunk(char *ptr, qsizetype maxlen);
160
161 bool toBool() const { Q_ASSERT(isBool()); return value64 - int(QCborSimpleType::False); }
162 QCborTag toTag() const { Q_ASSERT(isTag()); return QCborTag(value64); }
163 quint64 toUnsignedInteger() const { Q_ASSERT(isUnsignedInteger()); return value64; }
164 QCborNegativeInteger toNegativeInteger() const { Q_ASSERT(isNegativeInteger()); return QCborNegativeInteger(value64 + 1); }
165 QCborSimpleType toSimpleType() const{ Q_ASSERT(isSimpleType()); return QCborSimpleType(value64); }
166 qfloat16 toFloat16() const { Q_ASSERT(isFloat16()); return _toFloatingPoint<qfloat16>(); }
167 float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint<float>(); }
168 double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint<double>(); }
169
170 qint64 toInteger() const
171 {
172 Q_ASSERT(isInteger());
173 qint64 v = qint64(value64);
174 if (isNegativeInteger())
175 return -v - 1;
176 return v;
177 }
178
179private:
180 void preparse();
181 bool _enterContainer_helper();
182 StringResult<QString> _readString_helper();
183 StringResult<QByteArray> _readByteArray_helper();
184 qsizetype _currentStringChunkSize() const;
185
186 template <typename FP> FP _toFloatingPoint() const noexcept
187 {
188 using UIntFP = typename QIntegerForSizeof<FP>::Unsigned;
189 UIntFP u = UIntFP(value64);
190 FP f;
191 memcpy(static_cast<void *>(&f), &u, sizeof(f));
192 return f;
193 }
194
195 friend QCborStreamReaderPrivate;
196 friend class QCborContainerPrivate;
197 quint64 value64;
198 QScopedPointer<QCborStreamReaderPrivate> d;
199 quint8 type_;
200 quint8 reserved[3] = {};
201};
202
203QT_END_NAMESPACE
204
205#if defined(QT_X11_DEFINES_FOUND)
206# define True 1
207# define False 0
208#endif
209
210#endif // QCBORSTREAMREADER_H
211