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 50 QT_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 58 QT_BEGIN_NAMESPACE 59 60 class QIODevice; 61 62 class QCborStreamReaderPrivate; 63 class Q_CORE_EXPORT QCborStreamReader 64 { 65 Q_GADGET 66 public: 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); addData(const quint8 * 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 isValid()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 type()127 Type type() const { return QCborStreamReader::Type(type_); } isUnsignedInteger()128 bool isUnsignedInteger() const { return type() == UnsignedInteger; } isNegativeInteger()129 bool isNegativeInteger() const { return type() == NegativeInteger; } isInteger()130 bool isInteger() const { return quint8(type()) <= quint8(NegativeInteger); } isByteArray()131 bool isByteArray() const { return type() == ByteArray; } isString()132 bool isString() const { return type() == String; } isArray()133 bool isArray() const { return type() == Array; } isMap()134 bool isMap() const { return type() == Map; } isTag()135 bool isTag() const { return type() == Tag; } isSimpleType()136 bool isSimpleType() const { return type() == SimpleType; } isFloat16()137 bool isFloat16() const { return type() == Float16; } isFloat()138 bool isFloat() const { return type() == Float; } isDouble()139 bool isDouble() const { return type() == Double; } isInvalid()140 bool isInvalid() const { return type() == Invalid; } 141 isSimpleType(QCborSimpleType st)142 bool isSimpleType(QCborSimpleType st) const { return isSimpleType() && toSimpleType() == st; } isFalse()143 bool isFalse() const { return isSimpleType(QCborSimpleType::False); } isTrue()144 bool isTrue() const { return isSimpleType(QCborSimpleType::True); } isBool()145 bool isBool() const { return isFalse() || isTrue(); } isNull()146 bool isNull() const { return isSimpleType(QCborSimpleType::Null); } isUndefined()147 bool isUndefined() const { return isSimpleType(QCborSimpleType::Undefined); } 148 149 bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION; 150 quint64 length() const; 151 isContainer()152 bool isContainer() const { return isMap() || isArray(); } enterContainer()153 bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); } 154 bool leaveContainer(); 155 readString()156 StringResult<QString> readString() { Q_ASSERT(isString()); return _readString_helper(); } readByteArray()157 StringResult<QByteArray> readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); } currentStringChunkSize()158 qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); } 159 StringResult<qsizetype> readStringChunk(char *ptr, qsizetype maxlen); 160 toBool()161 bool toBool() const { Q_ASSERT(isBool()); return value64 - int(QCborSimpleType::False); } toTag()162 QCborTag toTag() const { Q_ASSERT(isTag()); return QCborTag(value64); } toUnsignedInteger()163 quint64 toUnsignedInteger() const { Q_ASSERT(isUnsignedInteger()); return value64; } toNegativeInteger()164 QCborNegativeInteger toNegativeInteger() const { Q_ASSERT(isNegativeInteger()); return QCborNegativeInteger(value64 + 1); } toSimpleType()165 QCborSimpleType toSimpleType() const{ Q_ASSERT(isSimpleType()); return QCborSimpleType(value64); } toFloat16()166 qfloat16 toFloat16() const { Q_ASSERT(isFloat16()); return _toFloatingPoint<qfloat16>(); } toFloat()167 float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint<float>(); } toDouble()168 double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint<double>(); } 169 toInteger()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 179 private: 180 void preparse(); 181 bool _enterContainer_helper(); 182 StringResult<QString> _readString_helper(); 183 StringResult<QByteArray> _readByteArray_helper(); 184 qsizetype _currentStringChunkSize() const; 185 _toFloatingPoint()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 203 QT_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