Cleanup mess in public type ids.

There is no reason to keep two separated core types sets. It
couldn't be fixed before Qt5 because of binary compatibility promise.

This patch merges QMetaType core types with ext core types.

This "simple" operation consists of:
- QDataStream version was incremented, because type ids are
saved in QVariant's data stream.
- QMetaType LastExtCoreType and FirstExtCoreType were replaced by
LastCoreType, FirstCoreType and new QMetaType::HighestInternalId.
- New tests checking QVariant data stream for Qt4 and for Qt5 versions
were added.

Change-Id: I02dd74d29317365c297a789a4eb7c9c5edc3b231
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
This commit is contained in:
Jędrzej Nowacki 2012-01-13 10:41:02 +01:00 committed by Qt by Nokia
parent 4df34f055a
commit aee1f6cc41
136 changed files with 212 additions and 55 deletions

View File

@ -250,7 +250,7 @@ QT_BEGIN_NAMESPACE
return retVal; return retVal;
enum { enum {
DefaultStreamVersion = QDataStream::Qt_4_6 DefaultStreamVersion = QDataStream::Qt_5_0
}; };
// ### 5.0: when streaming invalid QVariants, just the type should // ### 5.0: when streaming invalid QVariants, just the type should

View File

@ -87,7 +87,7 @@ public:
Qt_4_7 = Qt_4_6, Qt_4_7 = Qt_4_6,
Qt_4_8 = Qt_4_7, Qt_4_8 = Qt_4_7,
Qt_4_9 = Qt_4_8, Qt_4_9 = Qt_4_8,
Qt_5_0 = Qt_4_8 Qt_5_0 = 13
#if QT_VERSION >= 0x050100 #if QT_VERSION >= 0x050100
#error Add the datastream version for this Qt version #error Add the datastream version for this Qt version
#endif #endif

View File

@ -228,14 +228,13 @@ template<> struct TypeDefiniton<QRegExp> { static const bool IsAvailable = false
\value User Base value for user types \value User Base value for user types
\omitvalue FirstCoreExtType
\omitvalue FirstGuiType \omitvalue FirstGuiType
\omitvalue FirstWidgetsType \omitvalue FirstWidgetsType
\omitvalue LastCoreExtType
\omitvalue LastCoreType \omitvalue LastCoreType
\omitvalue LastGuiType \omitvalue LastGuiType
\omitvalue LastWidgetsType \omitvalue LastWidgetsType
\omitvalue QReal \omitvalue QReal
\omitvalue HighestInternalId
Additional types can be registered using Q_DECLARE_METATYPE(). Additional types can be registered using Q_DECLARE_METATYPE().
@ -362,10 +361,10 @@ const char *QMetaType::typeName(int type)
// In theory it can be filled during compilation time, but for some reason template code // In theory it can be filled during compilation time, but for some reason template code
// that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably // that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
// it is not worth of it. // it is not worth of it.
static const char *namesCache[QMetaType::LastCoreExtType + 1]; static const char *namesCache[QMetaType::HighestInternalId + 1];
const char *result; const char *result;
if (type <= QMetaType::LastCoreExtType && ((result = namesCache[type]))) if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
return result; return result;
#define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \ #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
@ -388,7 +387,7 @@ const char *QMetaType::typeName(int type)
} }
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER #undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
Q_ASSERT(type <= QMetaType::LastCoreExtType); Q_ASSERT(type <= QMetaType::HighestInternalId);
namesCache[type] = result; namesCache[type] = result;
return result; return result;
} }

View File

@ -65,16 +65,16 @@ QT_BEGIN_NAMESPACE
F(LongLong, 4, qlonglong) \ F(LongLong, 4, qlonglong) \
F(ULongLong, 5, qulonglong) \ F(ULongLong, 5, qulonglong) \
F(Double, 6, double) \ F(Double, 6, double) \
F(Long, 129, long) \ F(Long, 32, long) \
F(Short, 130, short) \ F(Short, 33, short) \
F(Char, 131, char) \ F(Char, 34, char) \
F(ULong, 132, ulong) \ F(ULong, 35, ulong) \
F(UShort, 133, ushort) \ F(UShort, 36, ushort) \
F(UChar, 134, uchar) \ F(UChar, 37, uchar) \
F(Float, 135, float) \ F(Float, 38, float) \
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\ #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
F(VoidStar, 128, void*) \ F(VoidStar, 31, void*) \
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\ #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
F(QChar, 7, QChar) \ F(QChar, 7, QChar) \
@ -98,12 +98,12 @@ QT_BEGIN_NAMESPACE
F(QRegExp, 27, QRegExp) \ F(QRegExp, 27, QRegExp) \
F(QEasingCurve, 29, QEasingCurve) \ F(QEasingCurve, 29, QEasingCurve) \
F(QUuid, 30, QUuid) \ F(QUuid, 30, QUuid) \
F(QModelIndex, 31, QModelIndex) \ F(QVariant, 41, QVariant) \
F(QVariant, 138, QVariant) \ F(QModelIndex, 42, QModelIndex) \
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\ #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
F(QObjectStar, 136, QObject*) \ F(QObjectStar, 39, QObject*) \
F(QWidgetStar, 137, QWidget*) \ F(QWidgetStar, 40, QWidget*) \
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
F(QVariantMap, 8, QVariantMap) \ F(QVariantMap, 8, QVariantMap) \
@ -188,8 +188,7 @@ public:
LastGuiType = QPolygonF, LastGuiType = QPolygonF,
FirstWidgetsType = QIcon, FirstWidgetsType = QIcon,
LastWidgetsType = QSizePolicy, LastWidgetsType = QSizePolicy,
FirstCoreExtType = VoidStar, HighestInternalId = LastWidgetsType,
LastCoreExtType = QVariant,
// This logic must match the one in qglobal.h // This logic must match the one in qglobal.h
#if defined(QT_COORD_TYPE) #if defined(QT_COORD_TYPE)

View File

@ -68,8 +68,6 @@ static inline int moduleForType(const int typeId)
return Gui; return Gui;
if (typeId <= QMetaType::LastWidgetsType) if (typeId <= QMetaType::LastWidgetsType)
return Widgets; return Widgets;
if (typeId <= QMetaType::LastCoreExtType)
return Core;
return Unknown; return Unknown;
} }
} }

View File

@ -1625,7 +1625,7 @@ QVariant::Type QVariant::nameToType(const char *name)
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
enum { MapFromThreeCount = 36 }; enum { MapFromThreeCount = 36 };
static const ushort map_from_three[MapFromThreeCount] = static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
{ {
QVariant::Invalid, QVariant::Invalid,
QVariant::Map, QVariant::Map,
@ -1675,26 +1675,45 @@ void QVariant::load(QDataStream &s)
{ {
clear(); clear();
quint32 u; quint32 typeId;
s >> u; s >> typeId;
if (s.version() < QDataStream::Qt_4_0) { if (s.version() < QDataStream::Qt_4_0) {
if (u >= MapFromThreeCount) if (typeId >= MapFromThreeCount)
return; return;
u = map_from_three[u]; typeId = mapIdFromQt3ToCurrent[typeId];
} else if (s.version() < QDataStream::Qt_5_0) {
if (typeId >= 128 && typeId != QVariant::UserType) {
// 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 == 69 /* QIcon */) {
// In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
typeId = QMetaType::QIcon;
} else if (typeId == 75 /* QSizePolicy */) {
typeId = QMetaType::QSizePolicy;
} else if (typeId >= 70) {
// and as a result this types recieved lower ids too
if (typeId <= 74) { // QImage QPolygon QRegion QBitmap QCursor
typeId -=1;
} else if (typeId <= 86) { // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
typeId -=2;
}
}
} }
qint8 is_null = false; qint8 is_null = false;
if (s.version() >= QDataStream::Qt_4_2) if (s.version() >= QDataStream::Qt_4_2)
s >> is_null; s >> is_null;
if (u == QVariant::UserType) { if (typeId == QVariant::UserType) {
QByteArray name; QByteArray name;
s >> name; s >> name;
u = QMetaType::type(name); typeId = QMetaType::type(name);
if (!u) { if (!typeId) {
s.setStatus(QDataStream::ReadCorruptData); s.setStatus(QDataStream::ReadCorruptData);
return; return;
} }
} }
create(static_cast<int>(u), 0); create(static_cast<int>(typeId), 0);
d.is_null = is_null; d.is_null = is_null;
if (!isValid()) { if (!isValid()) {
@ -1720,12 +1739,12 @@ void QVariant::load(QDataStream &s)
*/ */
void QVariant::save(QDataStream &s) const void QVariant::save(QDataStream &s) const
{ {
quint32 tp = type(); quint32 typeId = type();
if (s.version() < QDataStream::Qt_4_0) { if (s.version() < QDataStream::Qt_4_0) {
int i; int i;
for (i = MapFromThreeCount - 1; i >= 0; i--) { for (i = MapFromThreeCount - 1; i >= 0; i--) {
if (map_from_three[i] == tp) { if (mapIdFromQt3ToCurrent[i] == typeId) {
tp = i; typeId = i;
break; break;
} }
} }
@ -1733,11 +1752,29 @@ void QVariant::save(QDataStream &s) const
s << QVariant(); s << QVariant();
return; return;
} }
} else if (s.version() < QDataStream::Qt_5_0) {
if (typeId >= 128 - 97 && typeId <= LastCoreType) {
// 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::QIcon) {
// In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
typeId = 69;
} else if (typeId == QMetaType::QSizePolicy) {
typeId = 75;
} else if (typeId >= QMetaType::QImage) {
// and as a result this types recieved lower ids too
if (typeId <= QMetaType::QCursor) {
typeId +=1;
} else if (typeId <= QMetaType::QQuaternion) {
typeId +=2;
}
}
} }
s << tp; s << typeId;
if (s.version() >= QDataStream::Qt_4_2) if (s.version() >= QDataStream::Qt_4_2)
s << qint8(d.is_null); s << qint8(d.is_null);
if (tp == QVariant::UserType) { if (typeId == QVariant::UserType) {
s << QMetaType::typeName(userType()); s << QMetaType::typeName(userType());
} }
@ -2411,17 +2448,15 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
*/ */
bool QVariant::canConvert(Type t) const bool QVariant::canConvert(Type t) const
{ {
//we can treat floats as double // TODO Reimplement this function, currently it works but it is a historical mess.
//the reason for not doing it the "proper" way is that QMetaType::Float's value is 135,
//which can't be handled by qCanConvertMatrix
//In addition QVariant::Type doesn't have a Float value, so we're using QMetaType::Float
const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type); const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double; if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;
if (currentType == uint(t)) if (currentType == uint(t))
return true; return true;
if (currentType > QVariant::LastCoreType || t > QVariant::LastCoreType) { // FIXME It should be LastCoreType intead of Uuid
if (currentType > QVariant::Uuid || t > QVariant::Uuid) {
switch (uint(t)) { switch (uint(t)) {
case QVariant::Int: case QVariant::Int:
return currentType == QVariant::KeySequence return currentType == QVariant::KeySequence

View File

@ -255,7 +255,8 @@ static int NColorRoles[] = {
QPalette::ToolTipText + 1, // Qt_4_4 QPalette::ToolTipText + 1, // Qt_4_4
QPalette::ToolTipText + 1, // Qt_4_5 QPalette::ToolTipText + 1, // Qt_4_5
QPalette::ToolTipText + 1, // Qt_4_6 QPalette::ToolTipText + 1, // Qt_4_6
0 // add the correct value for Qt_4_7 here later QPalette::ToolTipText + 1, // Qt_5_0
0 // add the correct value for Qt_5_1 here later
}; };
// Testing get/set functions // Testing get/set functions

View File

@ -2,5 +2,6 @@ CONFIG += testcase
TARGET = tst_qvariant TARGET = tst_qvariant
QT += widgets network testlib QT += widgets network testlib
SOURCES = tst_qvariant.cpp SOURCES = tst_qvariant.cpp
RESOURCES += qvariant.qrc
mac: CONFIG += insignificant_test # QTBUG-QTBUG-22747 mac: CONFIG += insignificant_test # QTBUG-QTBUG-22747

View File

@ -0,0 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>stream/qt4.9/</file>
<file>stream/qt5.0/</file>
</qresource>
</RCC>

Some files were not shown because too many files have changed in this diff Show More