diff options
Diffstat (limited to 'src/corelib/serialization/qcborvalue.h')
-rw-r--r-- | src/corelib/serialization/qcborvalue.h | 335 |
1 files changed, 230 insertions, 105 deletions
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 6a1558e2b5..93adbec344 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -1,48 +1,13 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2022 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCBORVALUE_H #define QCBORVALUE_H #include <QtCore/qbytearray.h> -#include <QtCore/qdatetime.h> #include <QtCore/qcborcommon.h> +#include <QtCore/qcompare.h> +#include <QtCore/qdatetime.h> #if QT_CONFIG(regularexpression) # include <QtCore/qregularexpression.h> #endif @@ -58,10 +23,6 @@ # undef False #endif -#if 0 && __has_include(<compare>) -# include <compare> -#endif - QT_BEGIN_NAMESPACE class QCborArray; @@ -146,11 +107,9 @@ public: QCborValue(QCborSimpleType st) : t(type_helper(st)) {} QCborValue(const QByteArray &ba); -#if QT_STRINGVIEW_LEVEL < 2 QCborValue(const QString &s); -#endif QCborValue(QStringView s); - QCborValue(QLatin1String s); + QCborValue(QLatin1StringView s); #ifndef QT_NO_CAST_FROM_ASCII QT_ASCII_CAST_WARN QCborValue(const char *s) : QCborValue(QString::fromUtf8(s)) {} #endif @@ -166,23 +125,23 @@ public: explicit QCborValue(const QDateTime &dt); #ifndef QT_BOOTSTRAPPED explicit QCborValue(const QUrl &url); -#endif -#if QT_CONFIG(regularexpression) +# if QT_CONFIG(regularexpression) explicit QCborValue(const QRegularExpression &rx); -#endif +# endif explicit QCborValue(const QUuid &uuid); +#endif ~QCborValue() { if (container) dispose(); } // make sure const char* doesn't go call the bool constructor QCborValue(const void *) = delete; - QCborValue(const QCborValue &other); + QCborValue(const QCborValue &other) noexcept; QCborValue(QCborValue &&other) noexcept - : n(other.n), container(qExchange(other.container, nullptr)), t(qExchange(other.t, Undefined)) + : n(other.n), container(std::exchange(other.container, nullptr)), t(std::exchange(other.t, Undefined)) { } - QCborValue &operator=(const QCborValue &other); + QCborValue &operator=(const QCborValue &other) noexcept; QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QCborValue) void swap(QCborValue &other) noexcept @@ -238,11 +197,13 @@ public: QByteArray toByteArray(const QByteArray &defaultValue = {}) const; QString toString(const QString &defaultValue = {}) const; QDateTime toDateTime(const QDateTime &defaultValue = {}) const; +#ifndef QT_BOOTSTRAPPED QUrl toUrl(const QUrl &defaultValue = {}) const; -#if QT_CONFIG(regularexpression) +# if QT_CONFIG(regularexpression) QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const; -#endif +# endif QUuid toUuid(const QUuid &defaultValue = {}) const; +#endif // only forward-declared, need split functions QCborArray toArray() const; @@ -251,26 +212,18 @@ public: QCborMap toMap(const QCborMap &defaultValue) const; const QCborValue operator[](const QString &key) const; - const QCborValue operator[](QLatin1String key) const; + const QCborValue operator[](QLatin1StringView key) const; const QCborValue operator[](qint64 key) const; QCborValueRef operator[](qint64 key); - QCborValueRef operator[](QLatin1String key); + QCborValueRef operator[](QLatin1StringView key); QCborValueRef operator[](const QString & key); int compare(const QCborValue &other) const; -#if 0 && __has_include(<compare>) - std::strong_ordering operator<=>(const QCborValue &other) const - { - int c = compare(other); - if (c > 0) return std::partial_ordering::greater; - if (c == 0) return std::partial_ordering::equivalent; - return std::partial_ordering::less; - } -#else +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const QCborValue &other) const noexcept { return compare(other) == 0; } bool operator!=(const QCborValue &other) const noexcept - { return !(*this == other); } + { return !operator==(other); } bool operator<(const QCborValue &other) const { return compare(other) < 0; } #endif @@ -296,6 +249,19 @@ public: QString toDiagnosticNotation(DiagnosticNotationOptions opts = Compact) const; private: + friend Q_CORE_EXPORT Q_DECL_PURE_FUNCTION + bool comparesEqual(const QCborValue &lhs, const QCborValue &rhs) noexcept; + friend Qt::strong_ordering compareThreeWay(const QCborValue &lhs, + const QCborValue &rhs) noexcept + { + int c = lhs.compare(rhs); + return Qt::compareThreeWay(c, 0); + } + + Q_DECLARE_STRONGLY_ORDERED(QCborValue) + friend class QCborArray; + friend class QCborMap; + friend class QCborValueConstRef; friend class QCborValueRef; friend class QCborContainerPrivate; friend class QJsonPrivate::Value; @@ -330,11 +296,160 @@ private: }; Q_DECLARE_SHARED(QCborValue) -class Q_CORE_EXPORT QCborValueRef +class QCborValueConstRef { public: + QCborValueConstRef(const QCborValueConstRef &) = default; + QCborValueConstRef &operator=(const QCborValueConstRef &) = delete; operator QCborValue() const { return concrete(); } + QCborValue::Type type() const { return concreteType(*this); } + bool isInteger() const { return type() == QCborValue::Integer; } + bool isByteArray() const { return type() == QCborValue::ByteArray; } + bool isString() const { return type() == QCborValue::String; } + bool isArray() const { return type() == QCborValue::Array; } + bool isMap() const { return type() == QCborValue::Map; } + bool isTag() const { return concrete().isTag(); } + bool isFalse() const { return type() == QCborValue::False; } + bool isTrue() const { return type() == QCborValue::True; } + bool isBool() const { return isFalse() || isTrue(); } + bool isNull() const { return type() == QCborValue::Null; } + bool isUndefined() const { return type() == QCborValue::Undefined; } + bool isDouble() const { return type() == QCborValue::Double; } + bool isDateTime() const { return type() == QCborValue::DateTime; } + bool isUrl() const { return type() == QCborValue::Url; } + bool isRegularExpression() const { return type() == QCborValue::RegularExpression; } + bool isUuid() const { return type() == QCborValue::Uuid; } + bool isInvalid() const { return type() == QCborValue::Invalid; } + bool isContainer() const { return isMap() || isArray(); } + bool isSimpleType() const { return concrete().isSimpleType(); } + bool isSimpleType(QCborSimpleType st) const { return concrete().isSimpleType(st); } + + QCborSimpleType toSimpleType(QCborSimpleType defaultValue = QCborSimpleType::Undefined) const + { + return concrete().toSimpleType(defaultValue); + } + + QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const + { return concrete().tag(defaultValue); } + QCborValue taggedValue(const QCborValue &defaultValue = QCborValue()) const + { return concrete().taggedValue(defaultValue); } + + qint64 toInteger(qint64 defaultValue = 0) const + { return concrete().toInteger(defaultValue); } + bool toBool(bool defaultValue = false) const + { return concrete().toBool(defaultValue); } + double toDouble(double defaultValue = 0) const + { return concrete().toDouble(defaultValue); } + + QByteArray toByteArray(const QByteArray &defaultValue = {}) const + { return concrete().toByteArray(defaultValue); } + QString toString(const QString &defaultValue = {}) const + { return concrete().toString(defaultValue); } + QDateTime toDateTime(const QDateTime &defaultValue = {}) const + { return concrete().toDateTime(defaultValue); } +#ifndef QT_BOOTSTRAPPED + QUrl toUrl(const QUrl &defaultValue = {}) const + { return concrete().toUrl(defaultValue); } +# if QT_CONFIG(regularexpression) + QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const + { return concrete().toRegularExpression(defaultValue); } +# endif + QUuid toUuid(const QUuid &defaultValue = {}) const + { return concrete().toUuid(defaultValue); } +#endif + + // only forward-declared, need split functions. Implemented in qcbor{array,map}.h + inline QCborArray toArray() const; + inline QCborArray toArray(const QCborArray &a) const; + inline QCborMap toMap() const; + inline QCborMap toMap(const QCborMap &m) const; + + Q_CORE_EXPORT const QCborValue operator[](const QString &key) const; + Q_CORE_EXPORT const QCborValue operator[](QLatin1StringView key) const; + Q_CORE_EXPORT const QCborValue operator[](qint64 key) const; + + int compare(const QCborValue &other) const + { return concrete().compare(other); } + + QVariant toVariant() const { return concrete().toVariant(); } + inline QJsonValue toJsonValue() const; // in qjsonvalue.h + +#if QT_CONFIG(cborstreamwriter) + QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const + { return concrete().toCbor(opt); } + void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const + { return concrete().toCbor(writer, opt); } +#endif + + QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) const + { return concrete().toDiagnosticNotation(opt); } + +protected: + friend class QCborValue; + friend class QCborArray; + friend class QCborMap; + friend class QCborContainerPrivate; + + QCborValue concrete() const noexcept { return concrete(*this); } + static Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool + comparesEqual_helper(QCborValueConstRef lhs, QCborValueConstRef rhs) noexcept; + static Q_CORE_EXPORT Q_DECL_PURE_FUNCTION Qt::strong_ordering + compareThreeWay_helper(QCborValueConstRef lhs, QCborValueConstRef rhs) noexcept; + friend bool comparesEqual(const QCborValueConstRef &lhs, + const QCborValueConstRef &rhs) noexcept + { + return comparesEqual_helper(lhs, rhs); + } + friend Qt::strong_ordering compareThreeWay(const QCborValueConstRef &lhs, + const QCborValueConstRef &rhs) noexcept + { + return compareThreeWay_helper(lhs, rhs); + } + Q_DECLARE_STRONGLY_ORDERED(QCborValueConstRef) + + static Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool + comparesEqual_helper(QCborValueConstRef lhs, const QCborValue &rhs) noexcept; + static Q_CORE_EXPORT Q_DECL_PURE_FUNCTION Qt::strong_ordering + compareThreeWay_helper(QCborValueConstRef lhs, const QCborValue &rhs) noexcept; + friend bool comparesEqual(const QCborValueConstRef &lhs, + const QCborValue &rhs) noexcept + { + return comparesEqual_helper(lhs, rhs); + } + friend Qt::strong_ordering compareThreeWay(const QCborValueConstRef &lhs, + const QCborValue &rhs) noexcept + { + return compareThreeWay_helper(lhs, rhs); + } + Q_DECLARE_STRONGLY_ORDERED(QCborValueConstRef, QCborValue) + + static Q_CORE_EXPORT QCborValue concrete(QCborValueConstRef that) noexcept; + static Q_CORE_EXPORT QCborValue::Type concreteType(QCborValueConstRef that) noexcept Q_DECL_PURE_FUNCTION; + static Q_CORE_EXPORT bool + concreteBoolean(QCborValueConstRef that, bool defaultValue) noexcept Q_DECL_PURE_FUNCTION; + static Q_CORE_EXPORT double + concreteDouble(QCborValueConstRef that, double defaultValue) noexcept Q_DECL_PURE_FUNCTION; + static Q_CORE_EXPORT qint64 + concreteIntegral(QCborValueConstRef that, qint64 defaultValue) noexcept Q_DECL_PURE_FUNCTION; + static Q_CORE_EXPORT QByteArray + concreteByteArray(QCborValueConstRef that, const QByteArray &defaultValue); + static Q_CORE_EXPORT QString + concreteString(QCborValueConstRef that, const QString &defaultValue); + + constexpr QCborValueConstRef() : d(nullptr), i(0) {} // this will actually be invalid + constexpr QCborValueConstRef(QCborContainerPrivate *dd, qsizetype ii) + : d(dd), i(ii) + {} + QCborContainerPrivate *d; + qsizetype i; +}; + +QT_WARNING_PUSH +QT6_ONLY(QT_WARNING_DISABLE_MSVC(4275)) // non dll-interface class 'QJsonValueConstRef' used as base for dll-interface class 'QJsonValueRef' +class QT6_ONLY(Q_CORE_EXPORT) QCborValueRef : public QCborValueConstRef +{ +public: QCborValueRef(const QCborValueRef &) noexcept = default; QCborValueRef(QCborValueRef &&) noexcept = default; QCborValueRef &operator=(const QCborValue &other) @@ -344,6 +459,15 @@ public: QCborValueRef &operator=(const QCborValueRef &other) { assign(*this, other); return *this; } + QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](qint64 key); + QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](QLatin1StringView key); + QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](const QString & key); + +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) + // retained for binary compatibility (due to the Q_CORE_EXPORT) because at + // least one compiler emits and exports all inlines in an exported class + + operator QCborValue() const { return concrete(); } QCborValue::Type type() const { return concreteType(); } bool isInteger() const { return type() == QCborValue::Integer; } bool isByteArray() const { return type() == QCborValue::ByteArray; } @@ -371,6 +495,10 @@ public: { return type() == QCborValue::type_helper(st); } + QCborSimpleType toSimpleType(QCborSimpleType defaultValue = QCborSimpleType::Undefined) const + { + return isSimpleType() ? QCborSimpleType(type() & 0xff) : defaultValue; + } QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const { return concrete().tag(defaultValue); } @@ -378,28 +506,28 @@ public: { return concrete().taggedValue(defaultValue); } qint64 toInteger(qint64 defaultValue = 0) const - { return concrete().toInteger(defaultValue); } + { return concreteIntegral(*this, defaultValue); } bool toBool(bool defaultValue = false) const - { return concrete().toBool(defaultValue); } + { return concreteBoolean(*this, defaultValue); } double toDouble(double defaultValue = 0) const - { return concrete().toDouble(defaultValue); } + { return concreteDouble(*this, defaultValue); } QByteArray toByteArray(const QByteArray &defaultValue = {}) const - { return concrete().toByteArray(defaultValue); } + { return concreteByteArray(*this, defaultValue); } QString toString(const QString &defaultValue = {}) const - { return concrete().toString(defaultValue); } + { return concreteString(*this, defaultValue); } QDateTime toDateTime(const QDateTime &defaultValue = {}) const { return concrete().toDateTime(defaultValue); } #ifndef QT_BOOTSTRAPPED QUrl toUrl(const QUrl &defaultValue = {}) const { return concrete().toUrl(defaultValue); } -#endif -#if QT_CONFIG(regularexpression) +# if QT_CONFIG(regularexpression) QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const { return concrete().toRegularExpression(defaultValue); } -#endif +# endif QUuid toUuid(const QUuid &defaultValue = {}) const { return concrete().toUuid(defaultValue); } +#endif // only forward-declared, need split functions. Implemented in qcbor{array,map}.h QCborArray toArray() const; @@ -408,27 +536,16 @@ public: QCborMap toMap(const QCborMap &m) const; const QCborValue operator[](const QString &key) const; - const QCborValue operator[](QLatin1String key) const; + const QCborValue operator[](QLatin1StringView key) const; const QCborValue operator[](qint64 key) const; - QCborValueRef operator[](qint64 key); - QCborValueRef operator[](QLatin1String key); - QCborValueRef operator[](const QString & key); int compare(const QCborValue &other) const { return concrete().compare(other); } -#if 0 && __has_include(<compare>) - std::strong_ordering operator<=>(const QCborValue &other) const - { - int c = compare(other); - if (c > 0) return std::strong_ordering::greater; - if (c == 0) return std::strong_ordering::equivalent; - return std::strong_ordering::less; - } -#else +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const QCborValue &other) const { return compare(other) == 0; } bool operator!=(const QCborValue &other) const - { return !(*this == other); } + { return !operator==(other); } bool operator<(const QCborValue &other) const { return compare(other) < 0; } #endif @@ -437,25 +554,17 @@ public: QJsonValue toJsonValue() const; #if QT_CONFIG(cborstreamwriter) + using QCborValueConstRef::toCbor; QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) - { return concrete().toCbor(opt); } + { return std::as_const(*this).toCbor(opt); } void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation); #endif + using QCborValueConstRef::toDiagnosticNotation; QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) - { return concrete().toDiagnosticNotation(opt); } + { return std::as_const(*this).toDiagnosticNotation(opt); } private: - friend class QCborValue; - friend class QCborArray; - friend class QCborMap; - friend class QCborContainerPrivate; - friend class QCborValueRefPtr; - - // static so we can pass this by value - static void assign(QCborValueRef that, const QCborValue &other); - static void assign(QCborValueRef that, QCborValue &&other); - static void assign(QCborValueRef that, const QCborValueRef other); static QCborValue concrete(QCborValueRef that) noexcept; QCborValue concrete() const noexcept { return concrete(*this); } @@ -463,14 +572,30 @@ private: QCborValue::Type concreteType() const noexcept { return concreteType(*this); } // this will actually be invalid... - constexpr QCborValueRef() : d(nullptr), i(0) {} + constexpr QCborValueRef() : QCborValueConstRef(nullptr, 0) {} QCborValueRef(QCborContainerPrivate *dd, qsizetype ii) - : d(dd), i(ii) + : QCborValueConstRef(dd, ii) {} - QCborContainerPrivate *d; - qsizetype i; +#else +private: + using QCborValueConstRef::QCborValueConstRef; +#endif // < Qt 7 + + friend class QCborValue; + friend class QCborArray; + friend class QCborMap; + friend class QCborContainerPrivate; + friend class QCborValueConstRef; + + // static so we can pass this by value + QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, const QCborValue &other); + QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, QCborValue &&other); + QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, const QCborValueRef other); }; +QT_WARNING_POP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCborValue::EncodingOptions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCborValue::DiagnosticNotationOptions) Q_CORE_EXPORT size_t qHash(const QCborValue &value, size_t seed = 0); |