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;
enum {
DefaultStreamVersion = QDataStream::Qt_4_6
DefaultStreamVersion = QDataStream::Qt_5_0
};
// ### 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_8 = Qt_4_7,
Qt_4_9 = Qt_4_8,
Qt_5_0 = Qt_4_8
Qt_5_0 = 13
#if QT_VERSION >= 0x050100
#error Add the datastream version for this Qt version
#endif

View File

@ -228,14 +228,13 @@ template<> struct TypeDefiniton<QRegExp> { static const bool IsAvailable = false
\value User Base value for user types
\omitvalue FirstCoreExtType
\omitvalue FirstGuiType
\omitvalue FirstWidgetsType
\omitvalue LastCoreExtType
\omitvalue LastCoreType
\omitvalue LastGuiType
\omitvalue LastWidgetsType
\omitvalue QReal
\omitvalue HighestInternalId
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
// that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
// it is not worth of it.
static const char *namesCache[QMetaType::LastCoreExtType + 1];
static const char *namesCache[QMetaType::HighestInternalId + 1];
const char *result;
if (type <= QMetaType::LastCoreExtType && ((result = namesCache[type])))
if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
return result;
#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
Q_ASSERT(type <= QMetaType::LastCoreExtType);
Q_ASSERT(type <= QMetaType::HighestInternalId);
namesCache[type] = result;
return result;
}

View File

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

View File

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

View File

@ -1625,7 +1625,7 @@ QVariant::Type QVariant::nameToType(const char *name)
#ifndef QT_NO_DATASTREAM
enum { MapFromThreeCount = 36 };
static const ushort map_from_three[MapFromThreeCount] =
static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
{
QVariant::Invalid,
QVariant::Map,
@ -1675,26 +1675,45 @@ void QVariant::load(QDataStream &s)
{
clear();
quint32 u;
s >> u;
quint32 typeId;
s >> typeId;
if (s.version() < QDataStream::Qt_4_0) {
if (u >= MapFromThreeCount)
if (typeId >= MapFromThreeCount)
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;
if (s.version() >= QDataStream::Qt_4_2)
s >> is_null;
if (u == QVariant::UserType) {
if (typeId == QVariant::UserType) {
QByteArray name;
s >> name;
u = QMetaType::type(name);
if (!u) {
typeId = QMetaType::type(name);
if (!typeId) {
s.setStatus(QDataStream::ReadCorruptData);
return;
}
}
create(static_cast<int>(u), 0);
create(static_cast<int>(typeId), 0);
d.is_null = is_null;
if (!isValid()) {
@ -1720,12 +1739,12 @@ void QVariant::load(QDataStream &s)
*/
void QVariant::save(QDataStream &s) const
{
quint32 tp = type();
quint32 typeId = type();
if (s.version() < QDataStream::Qt_4_0) {
int i;
for (i = MapFromThreeCount - 1; i >= 0; i--) {
if (map_from_three[i] == tp) {
tp = i;
if (mapIdFromQt3ToCurrent[i] == typeId) {
typeId = i;
break;
}
}
@ -1733,11 +1752,29 @@ void QVariant::save(QDataStream &s) const
s << QVariant();
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)
s << qint8(d.is_null);
if (tp == QVariant::UserType) {
if (typeId == QVariant::UserType) {
s << QMetaType::typeName(userType());
}
@ -2411,17 +2448,15 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
*/
bool QVariant::canConvert(Type t) const
{
//we can treat floats as double
//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
// TODO Reimplement this function, currently it works but it is a historical mess.
const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;
if (currentType == uint(t))
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)) {
case QVariant::Int:
return currentType == QVariant::KeySequence

View File

@ -255,7 +255,8 @@ static int NColorRoles[] = {
QPalette::ToolTipText + 1, // Qt_4_4
QPalette::ToolTipText + 1, // Qt_4_5
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

View File

@ -2,5 +2,6 @@ CONFIG += testcase
TARGET = tst_qvariant
QT += widgets network testlib
SOURCES = tst_qvariant.cpp
RESOURCES += qvariant.qrc
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