diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-12-22 22:45:46 -0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2018-05-27 22:41:49 +0000 |
commit | 81cc806e2629598a5b746a4e5a2ddb2771b4a4ff (patch) | |
tree | e7c235f8dc546e5a5456978e73b8abd7b3ef38af /src/corelib/serialization/qcborstream.h | |
parent | e3cb38b06a55ee394e5a07304f776776a4b2f263 (diff) |
Long live QCborStreamReader!
This is the counterpart of the previous commit.
[ChangeLog][QtCore] Added QCborStreamReader and QCborStreamWriter,
classes for low-level reading and writing of CBOR streams.
Change-Id: Ia0aac2f09e9245339951ffff13c72e4bffdf4a56
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib/serialization/qcborstream.h')
-rw-r--r-- | src/corelib/serialization/qcborstream.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h index 9affe7019c..3f0ce81915 100644 --- a/src/corelib/serialization/qcborstream.h +++ b/src/corelib/serialization/qcborstream.h @@ -110,6 +110,146 @@ private: QScopedPointer<QCborStreamWriterPrivate> 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 <typename Container> 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<const char *>(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 Q_DECL_NOTHROW 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 Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION; + quint64 length() const; + + bool isContainer() const { return isMap() || isArray(); } + bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); } + bool leaveContainer(); + + StringResult<QString> readString() { Q_ASSERT(isString()); return _readString_helper(); } + StringResult<QByteArray> readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); } + qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); } + StringResult<qsizetype> 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<qfloat16>(); } + float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint<float>(); } + double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint<double>(); } + + qint64 toInteger() const + { + Q_ASSERT(isInteger()); + qint64 v = qint64(value64); + if (isNegativeInteger()) + return -v - 1; + return v; + } + +private: + void preparse(); + bool _enterContainer_helper(); + StringResult<QString> _readString_helper(); + StringResult<QByteArray> _readByteArray_helper(); + qsizetype _currentStringChunkSize() const; + + template <typename FP> FP _toFloatingPoint() const Q_DECL_NOTHROW + { + using UInt = typename QIntegerForSizeof<FP>::Unsigned; + UInt u = UInt(value64); + FP f; + memcpy(static_cast<void *>(&f), &u, sizeof(f)); + return f; + } + + friend QCborStreamReaderPrivate; + quint64 value64; + QScopedPointer<QCborStreamReaderPrivate> d; + quint8 type_; + quint8 reserved[3] = {}; +}; + QT_END_NAMESPACE #endif // QCBORSTREAM_H |