diff options
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 40 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 14 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp | 53 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp | 44 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/typedef.q5 | bin | 0 -> 28 bytes |
7 files changed, 148 insertions, 6 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 9494ff84f9..476234d7c5 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1,6 +1,8 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Copyright (C) 2021 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -179,6 +181,42 @@ Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry) } // namespace +// used by QVariant::save(): returns the name used in the Q_DECLARE_METATYPE +// macro (one of them, indetermine which one) +const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d) +{ + const char *name = nullptr; + QMetaTypeCustomRegistry *r = customTypeRegistry; + if (!r) + return name; + + QByteArrayView officialName(type_d->name); + QReadLocker l(&r->lock); + auto it = r->aliases.constBegin(); + auto end = r->aliases.constEnd(); + for ( ; it != end; ++it) { + if (it.value() != type_d) + continue; + if (it.key() == officialName) + continue; // skip the official name + name = it.key().constData(); + break; + } + +#ifndef QT_NO_DEBUG + QByteArrayList otherNames; + for ( ; it != end; ++it) { + if (it.value() == type_d) + otherNames << it.key(); + } + if (!otherNames.isEmpty()) + qWarning("QMetaType: type %s has more than one typedef alias: %s, %s", + type_d->name, name, otherNames.join(", ").constData()); +#endif + + return name; +} + /*! \macro Q_DECLARE_OPAQUE_POINTER(PointerType) \relates QMetaType diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 16270bc374..2b533608be 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -233,6 +233,7 @@ static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFr case QMetaType::MetaTypeName: \ return QtMetaTypePrivate::getInterfaceFromType<RealName>(); +const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); } //namespace QtMetaTypePrivate QT_END_NAMESPACE diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b34da6ca18..b942ac50c7 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2021 Intel Corporation. ** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** @@ -1314,13 +1314,17 @@ void QVariant::save(QDataStream &s) const } } const char *typeName = nullptr; - if (saveAsUserType) - typeName = d.type().name(); + if (saveAsUserType) { + if (s.version() < QDataStream::Qt_6_0) + typeName = QtMetaTypePrivate::typedefNameForType(d.type().d_ptr); + if (!typeName) + typeName = d.type().name(); + } s << typeId; if (s.version() >= QDataStream::Qt_4_2) s << qint8(d.is_null); if (typeName) - s << d.type().name(); + s << typeName; if (!isValid()) { if (s.version() < QDataStream::Qt_5_0) diff --git a/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt index 136ff4ee19..b29088c712 100644 --- a/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt +++ b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt @@ -6,6 +6,7 @@ # Collect test data list(APPEND test_data "datastream.q42") +list(APPEND test_data "typedef.q5") qt_internal_add_test(tst_qdatastream SOURCES @@ -22,6 +23,7 @@ if(ANDROID OR INTEGRITY) # Resources: set(testdata_resource_files "datastream.q42" + "typedef.q5" ) qt_internal_add_resource(tst_qdatastream "testdata" diff --git a/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp new file mode 100644 index 0000000000..3a10e40576 --- /dev/null +++ b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QDataStream> +#include <QPair> +#include <QFile> +#include <QVariant> +#include <QDebug> + +using CustomPair = QPair<int, int>; +QDataStream &operator<<(QDataStream &ds, CustomPair pd) +{ return ds << pd.first << pd.second; } +QDataStream &operator>>(QDataStream &ds, CustomPair &pd) +{ return ds >> pd.first >> pd.second; } +Q_DECLARE_METATYPE(CustomPair) + + +int main() { + qRegisterMetaTypeStreamOperators<CustomPair>(); + QFile out("typedef.q5"); + out.open(QIODevice::ReadWrite); + QDataStream stream(&out); + stream.setVersion(QDataStream::Qt_5_15); + CustomPair p {42, 100}; + qDebug() << p.first << p.second; + stream << QVariant::fromValue(p); +} diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 8fbe8d745e..511d8f957f 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -221,6 +221,8 @@ private slots: void nestedTransactionsResult_data(); void nestedTransactionsResult(); + void typedefQt5Compat(); + private: void writebool(QDataStream *s); void writeQBitArray(QDataStream *s); @@ -3872,6 +3874,48 @@ void tst_QDataStream::nestedTransactionsResult() QCOMPARE(int(stream.status()), expectedStatus); } +using CustomPair = QPair<int, int>; +QDataStream &operator<<(QDataStream &ds, CustomPair pd) +{ return ds << pd.first << pd.second; } +QDataStream &operator>>(QDataStream &ds, CustomPair &pd) +{ return ds >> pd.first >> pd.second; } + + +void tst_QDataStream::typedefQt5Compat() +{ + qRegisterMetaType<CustomPair>("CustomPair"); + QByteArray qt5Data; + { + // we can read the qt5 version + QFile in(QFINDTESTDATA("typedef.q5")); + QVERIFY(in.open(QIODevice::ReadOnly)); + qt5Data = in.readAll(); + QVERIFY(in.seek(0)); + QDataStream stream(&in); + stream.setVersion(QDataStream::Qt_5_15); + QVariant var; + stream >> var; + QCOMPARE(stream.status(), QDataStream::Ok); + CustomPair p = var.value<CustomPair>(); + QCOMPARE(p.first, 42); + QCOMPARE(p.second, 100); + } + { + // writing in Qt 6 results in the same file + QTemporaryDir dir; + QVERIFY(dir.isValid()); + QFile file(dir.filePath(u"typedef.q6"_qs)); + file.open(QIODevice::WriteOnly); + QDataStream stream(&file); + stream.setVersion(QDataStream::Qt_5_15); + CustomPair p {42, 100}; + stream << QVariant::fromValue(p); + file.close(); + file.open(QIODevice::ReadOnly); + QCOMPARE(file.readAll(), qt5Data); + } +} + QTEST_MAIN(tst_QDataStream) #include "tst_qdatastream.moc" diff --git a/tests/auto/corelib/serialization/qdatastream/typedef.q5 b/tests/auto/corelib/serialization/qdatastream/typedef.q5 Binary files differnew file mode 100644 index 0000000000..c6b5e8a4df --- /dev/null +++ b/tests/auto/corelib/serialization/qdatastream/typedef.q5 |