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 <alexander.blasche@qt.io>
This commit is contained in:
Lars Knoll 2020-08-29 20:27:07 +02:00
parent 7d1a74d36d
commit 14dece57e9
3 changed files with 91 additions and 55 deletions

View File

@ -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

View File

@ -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);

View File

@ -2782,7 +2782,7 @@ void tst_QVariant::loadUnknownUserType()
qRegisterMetaType<MyClass>("MyClass");
QTest::ignoreMessage(QtWarningMsg, "QVariant::load: unable to load type "
+ QByteArray::number(qMetaTypeId<MyClass>()) +".");
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);