From 14dece57e9d63fe4a1be5e8a1fc1816c4a9b7fe6 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 29 Aug 2020 20:27:07 +0200 Subject: [PATCH] Remap QMetaType ids to create more space for builtin types We were starting to run out of space for builtin core types. Remap the type id's to create lots of additional space. We now reserve the first 64k id's for Qt, and have 16k id's for Qt Core. That should hopfully be enough for a while ;-) Fixes: QTBUG-85914 Change-Id: I0dab6bf23652e46a9557d9b38af7990b68c572b6 Reviewed-by: Alex Blasche --- src/corelib/kernel/qmetatype.h | 64 +++++++-------- src/corelib/kernel/qvariant.cpp | 80 ++++++++++++++----- .../corelib/kernel/qvariant/tst_qvariant.cpp | 2 +- 3 files changed, 91 insertions(+), 55 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index d71f956b156..feabede0dd4 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -166,39 +166,39 @@ inline constexpr int qMetaTypeId(); #if QT_CONFIG(shortcut) #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\ - F(QKeySequence, 75, QKeySequence) + F(QKeySequence, 0x100b, QKeySequence) #else #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) #endif #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\ - F(QFont, 64, QFont) \ - F(QPixmap, 65, QPixmap) \ - F(QBrush, 66, QBrush) \ - F(QColor, 67, QColor) \ - F(QPalette, 68, QPalette) \ - F(QIcon, 69, QIcon) \ - F(QImage, 70, QImage) \ - F(QPolygon, 71, QPolygon) \ - F(QRegion, 72, QRegion) \ - F(QBitmap, 73, QBitmap) \ - F(QCursor, 74, QCursor) \ + F(QFont, 0x1000, QFont) \ + F(QPixmap, 0x1001, QPixmap) \ + F(QBrush, 0x1002, QBrush) \ + F(QColor, 0x1003, QColor) \ + F(QPalette, 0x1004, QPalette) \ + F(QIcon, 0x1005, QIcon) \ + F(QImage, 0x1006, QImage) \ + F(QPolygon, 0x1007, QPolygon) \ + F(QRegion, 0x1008, QRegion) \ + F(QBitmap, 0x1009, QBitmap) \ + F(QCursor, 0x100a, QCursor) \ QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) \ - F(QPen, 76, QPen) \ - F(QTextLength, 77, QTextLength) \ - F(QTextFormat, 78, QTextFormat) \ - F(QTransform, 80, QTransform) \ - F(QMatrix4x4, 81, QMatrix4x4) \ - F(QVector2D, 82, QVector2D) \ - F(QVector3D, 83, QVector3D) \ - F(QVector4D, 84, QVector4D) \ - F(QQuaternion, 85, QQuaternion) \ - F(QPolygonF, 86, QPolygonF) \ - F(QColorSpace, 87, QColorSpace) \ + F(QPen, 0x100c, QPen) \ + F(QTextLength, 0x100d, QTextLength) \ + F(QTextFormat, 0x100e, QTextFormat) \ + F(QTransform, 0x1010, QTransform) \ + F(QMatrix4x4, 0x1011, QMatrix4x4) \ + F(QVector2D, 0x1012, QVector2D) \ + F(QVector3D, 0x1013, QVector3D) \ + F(QVector4D, 0x1014, QVector4D) \ + F(QQuaternion, 0x1015, QQuaternion) \ + F(QPolygonF, 0x1016, QPolygonF) \ + F(QColorSpace, 0x1017, QColorSpace) \ #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\ - F(QSizePolicy, 121, QSizePolicy) \ + F(QSizePolicy, 0x2000, QSizePolicy) \ // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType") #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\ @@ -306,7 +306,7 @@ public: QReal = sizeof(qreal) == sizeof(double) ? Double : Float, UnknownType = 0, - User = 1024 + User = 65536 }; #else // If we are using QDoc it fakes the Type enum looks like this. @@ -330,17 +330,17 @@ public: Char16 = 56, Char32 = 57, // Gui types - QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68, - QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73, - QCursor = 74, QKeySequence = 75, QPen = 76, QTextLength = 77, QTextFormat = 78, - QTransform = 80, QMatrix4x4 = 81, QVector2D = 82, - QVector3D = 83, QVector4D = 84, QQuaternion = 85, QPolygonF = 86, QColorSpace = 87, + QFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004, + QIcon = 0x1005, QImage = 0x1006, QPolygon = 0x1007, QRegion = 0x1008, QBitmap = 0x1009, + QCursor = 0x100a, QKeySequence = 0x100b, QPen = 0x100c, QTextLength = 0x100d, QTextFormat = 0x100e, + QTransform = 0x1010, QMatrix4x4 = 0x1011, QVector2D = 0x1012, + QVector3D = 0x1013, QVector4D = 0x1014, QQuaternion = 0x1015, QPolygonF = 0x1016, QColorSpace = 0x1017, // Widget types - QSizePolicy = 121, + QSizePolicy = 0x2000, LastCoreType = Char32, LastGuiType = QColorSpace, - User = 1024 + User = 65536 }; #endif diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 39a97741e16..bfeee901da2 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1138,6 +1138,18 @@ static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] = #endif }; +// enum values needed to map Qt5 based type id's to Qt6 based ones +enum Qt5Types { + Qt5UserType = 1024, + Qt5LastCoreType = QMetaType::QCborMap, + Qt5FirstGuiType = 64, + Qt5LastGuiType = 87, + Qt5SizePolicy = 121, + Qt5RegExp = 27, + Qt5KeySequence = 75, + Qt5QQuaternion = 85 +}; + /*! Internal function for loading a variant from stream \a s. Use the stream operators instead. @@ -1151,32 +1163,43 @@ void QVariant::load(QDataStream &s) quint32 typeId; s >> typeId; if (s.version() < QDataStream::Qt_4_0) { + // map to Qt 5 ids if (typeId >= MapFromThreeCount) return; typeId = mapIdFromQt3ToCurrent[typeId]; } else if (s.version() < QDataStream::Qt_5_0) { + // map to Qt 5 type ids if (typeId == 127 /* QVariant::UserType */) { - typeId = QMetaType::User; - } else if (typeId >= 128 && typeId != QVariant::UserType) { + typeId = Qt5UserType; + } else if (typeId >= 128 && typeId != Qt5UserType) { // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes // by moving all ids down by 97. typeId -= 97; } else if (typeId == 75 /* QSizePolicy */) { - typeId = QMetaType::QSizePolicy; + typeId = Qt5SizePolicy; } else if (typeId > 75 && typeId <= 86) { // and as a result these types received lower ids too // QKeySequence QPen QTextLength QTextFormat QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion typeId -=1; } } + if (s.version() < QDataStream::Qt_6_0) { + // map from Qt 5 to Qt 6 values + if (typeId == Qt5UserType) { + typeId = QMetaType::User; + } else if (typeId >= Qt5FirstGuiType && typeId <= Qt5LastGuiType) { + typeId += QMetaType::FirstGuiType - Qt5FirstGuiType; + } else if (typeId == Qt5SizePolicy) { + typeId = QMetaType::QSizePolicy; + } else if (typeId == Qt5RegExp) { + typeId = QMetaType::fromName("QRegExp").id(); + } + } qint8 is_null = false; if (s.version() >= QDataStream::Qt_4_2) s >> is_null; - if (typeId == 27) { - // used to be QRegExp in Qt 4/5 - typeId = QMetaType::fromName("QRegExp").id(); - } else if (typeId == QVariant::UserType) { + if (typeId == QVariant::UserType) { QByteArray name; s >> name; typeId = QMetaType::fromName(name).id(); @@ -1221,6 +1244,28 @@ void QVariant::save(QDataStream &s) const typeId = QMetaType::User; saveAsUserType = true; } + if (s.version() < QDataStream::Qt_6_0) { + // map to Qt 5 values + if (typeId == QMetaType::User) { + typeId = Qt5UserType; + } else if (typeId > Qt5LastCoreType && typeId <= QMetaType::LastCoreType) { + // the type didn't exist in Qt 5 + typeId = Qt5UserType; + saveAsUserType = true; + } else if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType) { + typeId -= QMetaType::FirstGuiType - Qt5FirstGuiType; + if (typeId > Qt5LastGuiType) { + typeId = Qt5UserType; + saveAsUserType = true; + } + } else if (typeId == QMetaType::QSizePolicy) { + typeId = Qt5SizePolicy; + } else if (saveAsUserType) { + if (!strcmp(d.type().name(), "QRegExp")) { + typeId = 27; // QRegExp in Qt 4/5 + } + } + } if (s.version() < QDataStream::Qt_4_0) { int i; for (i = 0; i <= MapFromThreeCount - 1; ++i) { @@ -1234,36 +1279,27 @@ void QVariant::save(QDataStream &s) const return; } } else if (s.version() < QDataStream::Qt_5_0) { - if (typeId == QMetaType::User) { + if (typeId == Qt5UserType) { typeId = 127; // QVariant::UserType had this value in Qt4 saveAsUserType = true; - } else if (typeId >= 128 - 97 && typeId <= LastCoreType) { + } else if (typeId >= 128 - 97 && typeId <= Qt5LastCoreType) { // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes // by moving all ids down by 97. typeId += 97; - } else if (typeId == QMetaType::QSizePolicy) { + } else if (typeId == Qt5SizePolicy) { typeId = 75; -#if QT_CONFIG(shortcut) - } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) { -#else - } else if (typeId >= QMetaType::QPen && typeId <= QMetaType::QQuaternion) { -#endif + } else if (typeId >= Qt5KeySequence && typeId <= Qt5QQuaternion) { // and as a result these types received lower ids too typeId +=1; - } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) { + } else if (typeId > Qt5QQuaternion || typeId == QMetaType::QUuid) { // These existed in Qt 4 only as a custom type typeId = 127; saveAsUserType = true; } } const char *typeName = nullptr; - if (saveAsUserType) { + if (saveAsUserType) typeName = d.type().name(); - if (!strcmp(typeName, "QRegExp")) { - typeId = 27; // QRegExp in Qt 4/5 - typeName = nullptr; - } - } s << typeId; if (s.version() >= QDataStream::Qt_4_2) s << qint8(d.is_null); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index b0e622e4407..a6c0ecb0123 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -2782,7 +2782,7 @@ void tst_QVariant::loadUnknownUserType() qRegisterMetaType("MyClass"); QTest::ignoreMessage(QtWarningMsg, "QVariant::load: unable to load type " + QByteArray::number(qMetaTypeId()) +"."); - char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0}; + char data[] = {0, QMetaType::User >> 16, char(QMetaType::User >> 8) , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0}; QByteArray ba(data, sizeof(data)); QDataStream ds(&ba, QIODevice::ReadOnly);