/**************************************************************************** ** ** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QCBORSTREAM_H #define QCBORSTREAM_H #include #include #include #include #include #include QT_REQUIRE_CONFIG(cborstream); // See qcborcommon.h for why we check #if defined(QT_X11_DEFINES_FOUND) # undef True # undef False #endif QT_BEGIN_NAMESPACE class QIODevice; enum class QCborNegativeInteger : quint64 {}; class QCborStreamWriterPrivate; class Q_CORE_EXPORT QCborStreamWriter { public: explicit QCborStreamWriter(QIODevice *device); explicit QCborStreamWriter(QByteArray *data); ~QCborStreamWriter(); Q_DISABLE_COPY(QCborStreamWriter) void setDevice(QIODevice *device); QIODevice *device() const; void append(quint64 u); void append(qint64 i); void append(QCborNegativeInteger n); void append(const QByteArray &ba) { appendByteString(ba.constData(), ba.size()); } void append(QLatin1String str); void append(QStringView str); void append(QCborTag tag); void append(QCborKnownTags tag) { append(QCborTag(tag)); } void append(QCborSimpleType st); void append(std::nullptr_t) { append(QCborSimpleType::Null); } void append(qfloat16 f); void append(float f); void append(double d); void appendByteString(const char *data, qsizetype len); void appendTextString(const char *utf8, qsizetype len); // convenience void append(bool b) { append(b ? QCborSimpleType::True : QCborSimpleType::False); } void appendNull() { append(QCborSimpleType::Null); } void appendUndefined() { append(QCborSimpleType::Undefined); } #ifndef Q_QDOC // overloads to make normal code not complain void append(int i) { append(qint64(i)); } void append(uint u) { append(quint64(u)); } #endif #ifndef QT_NO_CAST_FROM_ASCII void append(const char *str, qsizetype size = -1) { appendTextString(str, (str && size == -1) ? int(strlen(str)) : size); } #endif void startArray(); void startArray(quint64 count); bool endArray(); void startMap(); void startMap(quint64 count); bool endMap(); // no API for encoding chunked strings private: QScopedPointer d; }; class QCborStreamReaderPrivate; class Q_CORE_EXPORT QCborStreamReader { Q_GADGET public: enum Type : quint8 { UnsignedInteger = 0x00, NegativeInteger = 0x20, ByteString = 0x40, ByteArray = ByteString, TextString = 0x60, String = TextString, Array = 0x80, Map = 0xa0, Tag = 0xc0, SimpleType = 0xe0, HalfFloat = 0xf9, Float16 = HalfFloat, Float = 0xfa, Double = 0xfb, Invalid = 0xff }; Q_ENUM(Type) enum StringResultCode { EndOfString = 0, Ok = 1, Error = -1 }; template struct StringResult { Container data; StringResultCode status = Error; }; Q_ENUM(StringResultCode) QCborStreamReader(); QCborStreamReader(const char *data, qsizetype len); QCborStreamReader(const quint8 *data, qsizetype len); explicit QCborStreamReader(const QByteArray &data); explicit QCborStreamReader(QIODevice *device); ~QCborStreamReader(); Q_DISABLE_COPY(QCborStreamReader) void setDevice(QIODevice *device); QIODevice *device() const; void addData(const QByteArray &data); void addData(const char *data, qsizetype len); void addData(const quint8 *data, qsizetype len) { addData(reinterpret_cast(data), len); } void reparse(); void clear(); void reset(); QCborError lastError(); qint64 currentOffset() const; bool isValid() const { return !isInvalid(); } int containerDepth() const; QCborStreamReader::Type parentContainerType() const; bool hasNext() const noexcept Q_DECL_PURE_FUNCTION; bool next(int maxRecursion = 10000); Type type() const { return QCborStreamReader::Type(type_); } bool isUnsignedInteger() const { return type() == UnsignedInteger; } bool isNegativeInteger() const { return type() == NegativeInteger; } bool isInteger() const { return quint8(type()) <= quint8(NegativeInteger); } bool isByteArray() const { return type() == ByteArray; } bool isString() const { return type() == String; } bool isArray() const { return type() == Array; } bool isMap() const { return type() == Map; } bool isTag() const { return type() == Tag; } bool isSimpleType() const { return type() == SimpleType; } bool isFloat16() const { return type() == Float16; } bool isFloat() const { return type() == Float; } bool isDouble() const { return type() == Double; } bool isInvalid() const { return type() == Invalid; } bool isSimpleType(QCborSimpleType st) const { return isSimpleType() && toSimpleType() == st; } bool isFalse() const { return isSimpleType(QCborSimpleType::False); } bool isTrue() const { return isSimpleType(QCborSimpleType::True); } bool isBool() const { return isFalse() || isTrue(); } bool isNull() const { return isSimpleType(QCborSimpleType::Null); } bool isUndefined() const { return isSimpleType(QCborSimpleType::Undefined); } bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION; quint64 length() const; bool isContainer() const { return isMap() || isArray(); } bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); } bool leaveContainer(); StringResult readString() { Q_ASSERT(isString()); return _readString_helper(); } StringResult readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); } qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); } StringResult readStringChunk(char *ptr, qsizetype maxlen); bool toBool() const { Q_ASSERT(isBool()); return value64 - int(QCborSimpleType::False); } QCborTag toTag() const { Q_ASSERT(isTag()); return QCborTag(value64); } quint64 toUnsignedInteger() const { Q_ASSERT(isUnsignedInteger()); return value64; } QCborNegativeInteger toNegativeInteger() const { Q_ASSERT(isNegativeInteger()); return QCborNegativeInteger(value64 + 1); } QCborSimpleType toSimpleType() const{ Q_ASSERT(isSimpleType()); return QCborSimpleType(value64); } qfloat16 toFloat16() const { Q_ASSERT(isFloat16()); return _toFloatingPoint(); } float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint(); } double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint(); } qint64 toInteger() const { Q_ASSERT(isInteger()); qint64 v = qint64(value64); if (isNegativeInteger()) return -v - 1; return v; } private: void preparse(); bool _enterContainer_helper(); StringResult _readString_helper(); StringResult _readByteArray_helper(); qsizetype _currentStringChunkSize() const; template FP _toFloatingPoint() const noexcept { using UIntFP = typename QIntegerForSizeof::Unsigned; UIntFP u = UIntFP(value64); FP f; memcpy(static_cast(&f), &u, sizeof(f)); return f; } friend QCborStreamReaderPrivate; friend class QCborContainerPrivate; quint64 value64; QScopedPointer d; quint8 type_; quint8 reserved[3] = {}; }; QT_END_NAMESPACE #if defined(QT_X11_DEFINES_FOUND) # define True 1 # define False 0 #endif #endif // QCBORSTREAM_H