From 45ed28a9d3790707b18798454d976f3a818a7740 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 3 Apr 2020 20:58:30 +0200 Subject: [PATCH] Remove QRegExp from QVariant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an operator QVariant() to QRegExp to keep things at source compatible as possible. Add a hack to QVariant::load/save() to recognize the old typeid for QRegExp and stream them correctly as long as the streaming operators for QRegExp are registered. Also move the datastream test for QRegExp to tst_qregexp, and adjust it to the qvariant changes. Change-Id: I120b38a7541b43ec07a21b17f7f35c55f071eb75 Reviewed-by: Fabian Kosmale Reviewed-by: MÃ¥rten Nordheim --- src/corelib/kernel/qmetatype.cpp | 2 - src/corelib/kernel/qmetatype.h | 3 +- src/corelib/kernel/qmetatype_p.h | 3 - src/corelib/kernel/qvariant.cpp | 58 +++--- src/corelib/kernel/qvariant.h | 10 - src/corelib/text/qregexp.cpp | 12 ++ src/corelib/text/qregexp.h | 7 +- .../corelib/kernel/qmetatype/tst_qmetatype.h | 10 - .../corelib/kernel/qmetatype/typeFlags.bin | Bin 158 -> 106 bytes .../corelib/kernel/qvariant/tst_qvariant.cpp | 13 -- .../qdatastream/tst_qdatastream.cpp | 70 ------- .../qregexp/data/qdatastream_4.9.bin} | Bin .../qregexp/data/qdatastream_5.0.bin} | Bin tests/auto/corelib/text/qregexp/qregexp.pro | 1 + tests/auto/corelib/text/qregexp/qregexp.qrc | 6 + .../auto/corelib/text/qregexp/tst_qregexp.cpp | 177 ++++++++++++++++++ 16 files changed, 223 insertions(+), 149 deletions(-) rename tests/auto/corelib/{kernel/qvariant/stream/qt4.9/qregexp.bin => text/qregexp/data/qdatastream_4.9.bin} (100%) rename tests/auto/corelib/{kernel/qvariant/stream/qt5.0/qregexp.bin => text/qregexp/data/qdatastream_5.0.bin} (100%) create mode 100644 tests/auto/corelib/text/qregexp/qregexp.qrc diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index c34e442cdb..dfb6842d13 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -53,7 +53,6 @@ #include "quuid.h" #include "qvariant.h" #include "qdatastream.h" -#include "qregexp.h" #include "qmetatypeswitcher_p.h" #if QT_CONFIG(regularexpression) @@ -352,7 +351,6 @@ Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry) \value QRect QRect \value QPoint QPoint \value QUrl QUrl - \value QRegExp QRegExp \value QRegularExpression QRegularExpression \value QDateTime QDateTime \value QPointF QPointF diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index eb81ac4c28..96133c13c5 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -137,7 +137,6 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId(); F(QLineF, 24, QLineF) \ F(QPoint, 25, QPoint) \ F(QPointF, 26, QPointF) \ - F(QRegExp, 27, QRegExp) \ QT_FOR_EACH_STATIC_EASINGCURVE(F) \ F(QUuid, 30, QUuid) \ F(QVariant, 41, QVariant) \ @@ -474,7 +473,7 @@ public: QChar = 7, QString = 10, QStringList = 11, QByteArray = 12, QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17, QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22, - QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27, + QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42, QPersistentModelIndex = 50, QRegularExpression = 44, QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48, diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index e4e2aa9e43..8e08d84ffd 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -164,9 +164,6 @@ template<> struct TypeDefinition { static const bool IsAvailable = false template<> struct TypeDefinition { static const bool IsAvailable = false; }; template<> struct TypeDefinition { static const bool IsAvailable = false; }; #endif -#ifdef QT_NO_REGEXP -template<> struct TypeDefinition { static const bool IsAvailable = false; }; -#endif #if !QT_CONFIG(regularexpression) template<> struct TypeDefinition { static const bool IsAvailable = false; }; #endif diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index c5cf6b9464..25b101d5e3 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -57,7 +57,6 @@ #include "qstringlist.h" #include "qurl.h" #include "qlocale.h" -#include "qregexp.h" #include "quuid.h" #if QT_CONFIG(itemmodel) #include "qabstractitemmodel.h" @@ -1681,7 +1680,6 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names \value Quaternion a QQuaternion \value Rect a QRect \value RectF a QRectF - \value RegExp a QRegExp \value RegularExpression a QRegularExpression \value Region a QRegion \value Size a QSize @@ -2076,12 +2074,6 @@ QVariant::QVariant(const char *val) Constructs a new variant with a locale value, \a l. */ -/*! - \fn QVariant::QVariant(const QRegExp ®Exp) - - Constructs a new variant with the regexp value \a regExp. -*/ - /*! \fn QVariant::QVariant(const QRegularExpression &re) @@ -2216,11 +2208,6 @@ QVariant::QVariant(const QUrl &u) QVariant::QVariant(const QLocale &l) : d(Locale) { v_construct(&d, l); } -#ifndef QT_NO_REGEXP -QVariant::QVariant(const QRegExp ®Exp) - : d(RegExp) -{ v_construct(&d, regExp); } -#endif // QT_NO_REGEXP #if QT_CONFIG(regularexpression) QVariant::QVariant(const QRegularExpression &re) : d(RegularExpression) @@ -2262,7 +2249,7 @@ QVariant::QVariant(const QPersistentModelIndex &modelIndex) Note that return values in the ranges QVariant::Char through QVariant::RegExp and QVariant::Font through QVariant::Transform correspond to the values in the ranges QMetaType::QChar through - QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion. + QMetaType::QRegularExpression and QMetaType::QFont through QMetaType::QQuaternion. Pay particular attention when working with char and QChar variants. Note that there is no QVariant constructor specifically @@ -2493,7 +2480,10 @@ void QVariant::load(QDataStream &s) qint8 is_null = false; if (s.version() >= QDataStream::Qt_4_2) s >> is_null; - if (typeId == QVariant::UserType) { + if (typeId == 27) { + // used to be QRegExp in Qt 4/5 + typeId = QMetaType::type("QRegExp"); + } else if (typeId == QVariant::UserType) { QByteArray name; s >> name; typeId = QMetaType::type(name.constData()); @@ -2532,9 +2522,11 @@ void QVariant::load(QDataStream &s) void QVariant::save(QDataStream &s) const { quint32 typeId = d.type().id(); - if (typeId >= QMetaType::User) + bool saveAsUserType = false; + if (typeId >= QMetaType::User) { typeId = QMetaType::User; - bool fakeUserType = false; + saveAsUserType = true; + } if (s.version() < QDataStream::Qt_4_0) { int i; for (i = 0; i <= MapFromThreeCount - 1; ++i) { @@ -2550,6 +2542,7 @@ void QVariant::save(QDataStream &s) const } else if (s.version() < QDataStream::Qt_5_0) { if (typeId == QMetaType::User) { typeId = 127; // QVariant::UserType had this value in Qt4 + saveAsUserType = true; } else 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. @@ -2566,15 +2559,22 @@ void QVariant::save(QDataStream &s) const } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) { // These existed in Qt 4 only as a custom type typeId = 127; - fakeUserType = true; + saveAsUserType = true; + } + } + const char *typeName = nullptr; + if (saveAsUserType) { + typeName = QMetaType::typeName(d.type().id()); + 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); - if (d.type().id() >= int(QVariant::UserType) || fakeUserType) { + if (typeName) s << QMetaType::typeName(userType()); - } if (!isValid()) { if (s.version() < QDataStream::Qt_5_0) @@ -2938,22 +2938,6 @@ QLocale QVariant::toLocale() const return qVariantToHelper(d, handlerManager); } -/*! - \fn QRegExp QVariant::toRegExp() const - \since 4.1 - - Returns the variant as a QRegExp if the variant has userType() - \l QMetaType::QRegExp; otherwise returns an empty QRegExp. - - \sa canConvert(int targetTypeId), convert() -*/ -#ifndef QT_NO_REGEXP -QRegExp QVariant::toRegExp() const -{ - return qVariantToHelper(d, handlerManager); -} -#endif - #if QT_CONFIG(regularexpression) /*! \fn QRegularExpression QVariant::toRegularExpression() const @@ -3356,7 +3340,7 @@ static const quint32 qCanConvertMatrix[QMetaType::LastCoreType + 1] = /*QPointF*/ 1 << QMetaType::QPoint, -/*QRegExp*/ 0, +/*unused, was: QRegExp*/ 0, /*QHash*/ 0, diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index c519411fc1..d8ac0324ac 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -81,9 +81,6 @@ class QSize; class QSizeF; class QRect; class QRectF; -#ifndef QT_NO_REGEXP -class QRegExp; -#endif // QT_NO_REGEXP #if QT_CONFIG(regularexpression) class QRegularExpression; #endif // QT_CONFIG(regularexpression) @@ -160,7 +157,6 @@ class Q_CORE_EXPORT QVariant LineF = QMetaType::QLineF, Point = QMetaType::QPoint, PointF = QMetaType::QPointF, - RegExp = QMetaType::QRegExp, #if QT_CONFIG(regularexpression) RegularExpression = QMetaType::QRegularExpression, #endif @@ -252,9 +248,6 @@ class Q_CORE_EXPORT QVariant QVariant(const QRectF &rect); #endif QVariant(const QLocale &locale); -#ifndef QT_NO_REGEXP - QVariant(const QRegExp ®Exp); -#endif // QT_NO_REGEXP #if QT_CONFIG(regularexpression) QVariant(const QRegularExpression &re); #endif // QT_CONFIG(regularexpression) @@ -329,9 +322,6 @@ class Q_CORE_EXPORT QVariant QRectF toRectF() const; #endif QLocale toLocale() const; -#ifndef QT_NO_REGEXP - QRegExp toRegExp() const; -#endif // QT_NO_REGEXP #if QT_CONFIG(regularexpression) QRegularExpression toRegularExpression() const; #endif // QT_CONFIG(regularexpression) diff --git a/src/corelib/text/qregexp.cpp b/src/corelib/text/qregexp.cpp index 85086c7a40..9ae96a805e 100644 --- a/src/corelib/text/qregexp.cpp +++ b/src/corelib/text/qregexp.cpp @@ -4388,6 +4388,18 @@ bool QRegExp::exactMatch(const QString &str) const } } +/*! + Returns the regexp as a QVariant +*/ +QRegExp::operator QVariant() const +{ +QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED + QVariant v; + v.setValue(*this); + return v; +QT_WARNING_POP +} + // ### Qt 5: make non-const /*! Attempts to find a match in \a str from position \a offset (0 by diff --git a/src/corelib/text/qregexp.h b/src/corelib/text/qregexp.h index cf4aa0d32d..0c117fd17f 100644 --- a/src/corelib/text/qregexp.h +++ b/src/corelib/text/qregexp.h @@ -45,6 +45,7 @@ #ifndef QT_NO_REGEXP #include +#include QT_BEGIN_NAMESPACE @@ -93,6 +94,8 @@ public: bool exactMatch(const QString &str) const; + operator QVariant() const; + int indexIn(const QString &str, int offset = 0, CaretMode caretMode = CaretAtZero) const; int lastIndexIn(const QString &str, int offset = -1, CaretMode caretMode = CaretAtZero) const; int matchedLength() const; @@ -130,8 +133,6 @@ private: QRegExpPrivate *priv; }; -Q_DECLARE_TYPEINFO(QRegExp, Q_MOVABLE_TYPE); - #ifndef QT_NO_DATASTREAM Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegExp ®Exp); Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegExp ®Exp); @@ -143,6 +144,8 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QRegExp &); QT_END_NAMESPACE +Q_DECLARE_METATYPE(QRegExp) + #endif // QT_NO_REGEXP #endif // QREGEXP_H diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 22bcb69ac9..bf01fdcfcd 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -223,16 +223,6 @@ template<> struct TestValueFactory { template<> struct TestValueFactory { static std::nullptr_t *create() { return new std::nullptr_t; } }; -template<> struct TestValueFactory { - static QRegExp *create() - { -#ifndef QT_NO_REGEXP - return new QRegExp("A*"); -#else - return 0; -#endif - } -}; template<> struct TestValueFactory { static QRegularExpression *create() { diff --git a/tests/auto/corelib/kernel/qmetatype/typeFlags.bin b/tests/auto/corelib/kernel/qmetatype/typeFlags.bin index 0aa282efc970f2595898688030bc04831e56daae..35d922a85c0e83f2831791b14b90e675fada5674 100644 GIT binary patch delta 33 ocmbQom^HyOjR8&c2 zRa8|iSy$+Wo3z|^$6fc__rOC%sgcK?c*=}93zn={vti4QJqM1QICJ63jXMvXym<5B E4=P{|$N&HU diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 86465d25fb..c1c475b9c6 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -171,7 +171,6 @@ private slots: void toLocale(); - void toRegExp(); void toRegularExpression(); void url(); @@ -1219,14 +1218,6 @@ void tst_QVariant::toLocale() loc = variant.toLocale(); } -void tst_QVariant::toRegExp() -{ - QVariant variant; - QRegExp rx = variant.toRegExp(); - variant = QRegExp("foo"); - rx = variant.toRegExp(); -} - void tst_QVariant::toRegularExpression() { QVariant variant; @@ -1320,8 +1311,6 @@ void tst_QVariant::writeToReadFromDataStream_data() QTest::newRow( "uint_valid" ) << QVariant( (uint)123 ) << false; QTest::newRow( "qchar" ) << QVariant(QChar('a')) << false; QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << true; - QTest::newRow( "regexp" ) << QVariant(QRegExp("foo", Qt::CaseInsensitive)) << false; - QTest::newRow( "regexp_empty" ) << QVariant(QRegExp()) << false; QTest::newRow( "regularexpression" ) << QVariant(QRegularExpression("abc.*def")) << false; QTest::newRow( "regularexpression_empty" ) << QVariant(QRegularExpression()) << false; @@ -1768,7 +1757,6 @@ void tst_QVariant::typeName_data() QTest::newRow("38") << int(QVariant::LineF) << QByteArray("QLineF"); QTest::newRow("39") << int(QVariant::RectF) << QByteArray("QRectF"); QTest::newRow("40") << int(QVariant::PointF) << QByteArray("QPointF"); - QTest::newRow("41") << int(QVariant::RegExp) << QByteArray("QRegExp"); QTest::newRow("44") << int(QVariant::Transform) << QByteArray("QTransform"); QTest::newRow("45") << int(QVariant::Hash) << QByteArray("QVariantHash"); QTest::newRow("46") << int(QVariant::Matrix4x4) << QByteArray("QMatrix4x4"); @@ -3902,7 +3890,6 @@ void tst_QVariant::implicitConstruction() F(LineF) \ F(Point) \ F(PointF) \ - F(RegExp) \ F(EasingCurve) \ F(Uuid) \ F(ModelIndex) \ diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 419a8138a1..0687ce0ead 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -111,9 +111,6 @@ private slots: void stream_QString_data(); void stream_QString(); - void stream_QRegExp_data(); - void stream_QRegExp(); - #if QT_CONFIG(regularexpression) void stream_QRegularExpression_data(); void stream_QRegularExpression(); @@ -232,7 +229,6 @@ private: void writeQRegion(QDataStream *s); void writeQSize(QDataStream *s); void writeQString(QDataStream* dev); - void writeQRegExp(QDataStream* dev); #if QT_CONFIG(regularexpression) void writeQRegularExpression(QDataStream *dev); #endif @@ -266,7 +262,6 @@ private: void readQRegion(QDataStream *s); void readQSize(QDataStream *s); void readQString(QDataStream *s); - void readQRegExp(QDataStream *s); #if QT_CONFIG(regularexpression) void readQRegularExpression(QDataStream *s); #endif @@ -519,71 +514,6 @@ void tst_QDataStream::readQString(QDataStream *s) // ************************************ -static QRegExp QRegExpData(int index) -{ - switch (index) { - case 0: return QRegExp(); - case 1: return QRegExp(""); - case 2: return QRegExp("A", Qt::CaseInsensitive); - case 3: return QRegExp("ABCDE FGHI", Qt::CaseSensitive, QRegExp::Wildcard); - case 4: return QRegExp("This is a long string", Qt::CaseInsensitive, QRegExp::FixedString); - case 5: return QRegExp("And again a string with a \nCRLF", Qt::CaseInsensitive, QRegExp::RegExp); - case 6: - { - QRegExp rx("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/"); - rx.setMinimal(true); - return rx; - } - } - return QRegExp("foo"); -} -#define MAX_QREGEXP_DATA 7 - -void tst_QDataStream::stream_QRegExp_data() -{ - stream_data(MAX_QREGEXP_DATA); -} - -void tst_QDataStream::stream_QRegExp() -{ - STREAM_IMPL(QRegExp); -} - -void tst_QDataStream::writeQRegExp(QDataStream* s) -{ - QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag()))); - *s << test; - *s << QString("Her er det noe tekst"); - *s << test; - *s << QString("nonempty"); - *s << test; - *s << QVariant(test); -} - -void tst_QDataStream::readQRegExp(QDataStream *s) -{ - QRegExp R; - QString S; - QVariant V; - QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag()))); - - *s >> R; - QCOMPARE(R, test); - *s >> S; - QCOMPARE(S, QString("Her er det noe tekst")); - *s >> R; - QCOMPARE(R, test); - *s >> S; - QCOMPARE(S, QString("nonempty")); - *s >> R; - QCOMPARE(R, test); - *s >> V; - QCOMPARE(V.type(), QVariant::RegExp); - QCOMPARE(V.toRegExp(), test); -} - -// ************************************ - #if QT_CONFIG(regularexpression) static QRegularExpression QRegularExpressionData(int index) { diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.bin b/tests/auto/corelib/text/qregexp/data/qdatastream_4.9.bin similarity index 100% rename from tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.bin rename to tests/auto/corelib/text/qregexp/data/qdatastream_4.9.bin diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.bin b/tests/auto/corelib/text/qregexp/data/qdatastream_5.0.bin similarity index 100% rename from tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.bin rename to tests/auto/corelib/text/qregexp/data/qdatastream_5.0.bin diff --git a/tests/auto/corelib/text/qregexp/qregexp.pro b/tests/auto/corelib/text/qregexp/qregexp.pro index 5f6ff0a71c..748e6a248c 100644 --- a/tests/auto/corelib/text/qregexp/qregexp.pro +++ b/tests/auto/corelib/text/qregexp/qregexp.pro @@ -2,3 +2,4 @@ CONFIG += testcase TARGET = tst_qregexp QT = core testlib SOURCES = tst_qregexp.cpp +RESOURCES += qregexp.qrc diff --git a/tests/auto/corelib/text/qregexp/qregexp.qrc b/tests/auto/corelib/text/qregexp/qregexp.qrc new file mode 100644 index 0000000000..8fd168793f --- /dev/null +++ b/tests/auto/corelib/text/qregexp/qregexp.qrc @@ -0,0 +1,6 @@ + + + data/qdatastream_4.9.bin + data/qdatastream_5.0.bin + + diff --git a/tests/auto/corelib/text/qregexp/tst_qregexp.cpp b/tests/auto/corelib/text/qregexp/tst_qregexp.cpp index b043d023ea..29ddf3673f 100644 --- a/tests/auto/corelib/text/qregexp/tst_qregexp.cpp +++ b/tests/auto/corelib/text/qregexp/tst_qregexp.cpp @@ -1,3 +1,4 @@ + /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. @@ -83,6 +84,15 @@ private slots: void filterList(); void replaceInList(); + + void datastream_data(); + void datastream(); + + void datastream2(); + +private: + void readQRegExp(QDataStream *s); + void writeQRegExp(QDataStream* dev); }; // Testing get/set functions @@ -1545,5 +1555,172 @@ void tst_QRegExp::replaceInList() QCOMPARE( list5, list6 ); } +static QRegExp QRegExpData(int index) +{ + switch (index) { + case 0: return QRegExp(); + case 1: return QRegExp(""); + case 2: return QRegExp("A", Qt::CaseInsensitive); + case 3: return QRegExp("ABCDE FGHI", Qt::CaseSensitive, QRegExp::Wildcard); + case 4: return QRegExp("This is a long string", Qt::CaseInsensitive, QRegExp::FixedString); + case 5: return QRegExp("And again a string with a \nCRLF", Qt::CaseInsensitive, QRegExp::RegExp); + case 6: + { + QRegExp rx("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/"); + rx.setMinimal(true); + return rx; + } + } + return QRegExp("foo"); +} +#define MAX_QREGEXP_DATA 7 + +void tst_QRegExp::datastream_data() +{ + QTest::addColumn("device"); + QTest::addColumn("byteOrder"); + + const char * const devices[] = { + "file", + "bytearray", + "buffer", + 0 + }; + for (int d=0; devices[d] != 0; d++) { + QString device = devices[d]; + for (int b=0; b<2; b++) { + QString byte_order = b == 0 ? "BigEndian" : "LittleEndian"; + + QString tag = device + QLatin1Char('_') + byte_order; + for (int e = 0; e < MAX_QREGEXP_DATA; e++) { + QTest::newRow(qPrintable(tag + QLatin1Char('_') + QString::number(e))) << device << byte_order; + } + } + } +} + +static int dataIndex(const QString &tag) +{ + int pos = tag.lastIndexOf(QLatin1Char('_')); + if (pos >= 0) { + int ret = 0; + QString count = tag.mid(pos + 1); + bool ok; + ret = count.toInt(&ok); + if (ok) + return ret; + } + return -1; +} + +void tst_QRegExp::datastream() +{ + QFETCH(QString, device); \ + + qRegisterMetaTypeStreamOperators("QRegExp"); + + if (device == "bytearray") { \ + QByteArray ba; \ + QDataStream sout(&ba, QIODevice::WriteOnly); \ + writeQRegExp(&sout); \ + QDataStream sin(&ba, QIODevice::ReadOnly); \ + readQRegExp(&sin); \ + } else if (device == "file") { \ + QString fileName = "qdatastream.out"; \ + QFile fOut(fileName); \ + QVERIFY(fOut.open(QIODevice::WriteOnly)); \ + QDataStream sout(&fOut); \ + writeQRegExp(&sout); \ + fOut.close(); \ + QFile fIn(fileName); \ + QVERIFY(fIn.open(QIODevice::ReadOnly)); \ + QDataStream sin(&fIn); \ + readQRegExp(&sin); \ + fIn.close(); \ + } else if (device == "buffer") { \ + QByteArray ba(10000, '\0'); \ + QBuffer bOut(&ba); \ + bOut.open(QIODevice::WriteOnly); \ + QDataStream sout(&bOut); \ + writeQRegExp(&sout); \ + bOut.close(); \ + QBuffer bIn(&ba); \ + bIn.open(QIODevice::ReadOnly); \ + QDataStream sin(&bIn); \ + readQRegExp(&sin); \ + bIn.close(); \ + } +} + +static void saveQVariantFromDataStream(const QString &fileName, QDataStream::Version version) +{ + + QFile file(fileName); + QVERIFY(file.open(QIODevice::ReadOnly)); + QDataStream dataFileStream(&file); + + QString typeName; + dataFileStream >> typeName; + QByteArray data = file.readAll(); + const int id = QMetaType::type(typeName.toLatin1()); + + QBuffer buffer; + buffer.open(QIODevice::ReadWrite); + QDataStream stream(&buffer); + stream.setVersion(version); + + QVariant constructedVariant(static_cast(id)); + QCOMPARE(constructedVariant.userType(), id); + stream << constructedVariant; + + // We are testing QVariant there is no point in testing full array. + QCOMPARE(buffer.data().left(5), data.left(5)); + + buffer.seek(0); + QVariant recunstructedVariant; + stream >> recunstructedVariant; + QCOMPARE(recunstructedVariant.userType(), constructedVariant.userType()); +} + +void tst_QRegExp::datastream2() +{ + saveQVariantFromDataStream(QLatin1String(":/data/qdatastream_4.9.bin"), QDataStream::Qt_4_9); + saveQVariantFromDataStream(QLatin1String(":/data/qdatastream_5.0.bin"), QDataStream::Qt_5_0); +} + +void tst_QRegExp::writeQRegExp(QDataStream* s) +{ + QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag()))); + *s << test; + *s << QString("Her er det noe tekst"); + *s << test; + *s << QString("nonempty"); + *s << test; + *s << QVariant(test); +} + +void tst_QRegExp::readQRegExp(QDataStream *s) +{ + QRegExp R; + QString S; + QVariant V; + QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag()))); + + *s >> R; + QCOMPARE(R, test); + *s >> S; + QCOMPARE(S, QString("Her er det noe tekst")); + *s >> R; + QCOMPARE(R, test); + *s >> S; + QCOMPARE(S, QString("nonempty")); + *s >> R; + QCOMPARE(R, test); + *s >> V; + QCOMPARE(V.userType(), qMetaTypeId()); + QCOMPARE(qvariant_cast(V), test); +} + + QTEST_APPLESS_MAIN(tst_QRegExp) #include "tst_qregexp.moc"