Xml: use new comparison helper macros

New comparison macros are used for following classes:
-QXmlStreamAttribute
-QXmlStreamNamespaceDeclaration
-QXmlStreamNotationDeclaration
-QXmlStreamEntityDeclaration

Replace public operators operator==(), operator!=() of
classes to friend methods comparesEqual();

Use QT_CORE_REMOVED_SINCE to get rid of current comparison methods
and replace them with a friend.

Add checkStreamNotationDeclarations()/checkStreamEntityDeclarations()
test-cases to test change.

Task-number: QTBUG-120300
Change-Id: I0b5642b2e23cc21ede7bc4888f0a9bddd6c08d07
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Tatiana Borisova 2024-03-14 17:28:57 +01:00
parent c8fb376de5
commit cd5dd8b95b
5 changed files with 161 additions and 41 deletions

View File

@ -1007,6 +1007,8 @@ int QObject::startTimer(std::chrono::milliseconds time, Qt::TimerType timerType)
#include "qstring.h" // inlined API
#include "qxmlstream.h" // inlined API
// #include "qotherheader.h"
// // implement removed functions from qotherheader.h
// order sections alphabetically to reduce chances of merge conflicts

View File

@ -2331,6 +2331,8 @@ QXmlStreamAttributes QXmlStreamReader::attributes() const
\ingroup xml-tools
\compares equality
An attribute consists of an optionally empty namespaceUri(), a
name(), a value(), and an isDefault() attribute.
@ -2405,14 +2407,14 @@ QXmlStreamAttribute::QXmlStreamAttribute(const QString &qualifiedName, const QSt
value following an ATTLIST declaration in the DTD; otherwise
returns \c false.
*/
/*! \fn bool QXmlStreamAttribute::operator==(const QXmlStreamAttribute &other) const
/*! \fn bool QXmlStreamAttribute::operator==(const QXmlStreamAttribute &lhs, const QXmlStreamAttribute &rhs)
Compares this attribute with \a other and returns \c true if they are
Compares \a lhs attribute with \a rhs and returns \c true if they are
equal; otherwise returns \c false.
*/
/*! \fn bool QXmlStreamAttribute::operator!=(const QXmlStreamAttribute &other) const
/*! \fn bool QXmlStreamAttribute::operator!=(const QXmlStreamAttribute &lhs, const QXmlStreamAttribute &rhs)
Compares this attribute with \a other and returns \c true if they are
Compares \a lhs attribute with \a rhs and returns \c true if they are
not equal; otherwise returns \c false.
*/
@ -2461,6 +2463,8 @@ QXmlStreamAttribute::QXmlStreamAttribute(const QString &qualifiedName, const QSt
\ingroup xml-tools
\compares equality
An notation declaration consists of a name(), a systemId(), and a publicId().
*/
@ -2484,14 +2488,14 @@ Returns the system identifier.
Returns the public identifier.
*/
/*! \fn inline bool QXmlStreamNotationDeclaration::operator==(const QXmlStreamNotationDeclaration &other) const
/*! \fn inline bool QXmlStreamNotationDeclaration::operator==(const QXmlStreamNotationDeclaration &lhs, const QXmlStreamNotationDeclaration &rhs)
Compares this notation declaration with \a other and returns \c true
Compares \a lhs notation declaration with \a rhs and returns \c true
if they are equal; otherwise returns \c false.
*/
/*! \fn inline bool QXmlStreamNotationDeclaration::operator!=(const QXmlStreamNotationDeclaration &other) const
/*! \fn inline bool QXmlStreamNotationDeclaration::operator!=(const QXmlStreamNotationDeclaration &lhs, const QXmlStreamNotationDeclaration &rhs)
Compares this notation declaration with \a other and returns \c true
Compares \a lhs notation declaration with \a rhs and returns \c true
if they are not equal; otherwise returns \c false.
*/
@ -2511,16 +2515,18 @@ Returns the public identifier.
\ingroup xml-tools
\compares equality
An namespace declaration consists of a prefix() and a namespaceUri().
*/
/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator==(const QXmlStreamNamespaceDeclaration &other) const
/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator==(const QXmlStreamNamespaceDeclaration &lhs, const QXmlStreamNamespaceDeclaration &rhs)
Compares this namespace declaration with \a other and returns \c true
Compares \a lhs namespace declaration with \a rhs and returns \c true
if they are equal; otherwise returns \c false.
*/
/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator!=(const QXmlStreamNamespaceDeclaration &other) const
/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator!=(const QXmlStreamNamespaceDeclaration &lhs, const QXmlStreamNamespaceDeclaration &rhs)
Compares this namespace declaration with \a other and returns \c true
Compares \a lhs namespace declaration with \a rhs and returns \c true
if they are not equal; otherwise returns \c false.
*/
@ -2577,6 +2583,7 @@ Returns the namespaceUri.
\ingroup xml-tools
\compares equality
An entity declaration consists of a name(), a notationName(), a
systemId(), a publicId(), and a value().
*/
@ -2609,14 +2616,14 @@ Returns the public identifier.
Returns the entity's value.
*/
/*! \fn bool QXmlStreamEntityDeclaration::operator==(const QXmlStreamEntityDeclaration &other) const
/*! \fn bool QXmlStreamEntityDeclaration::operator==(const QXmlStreamEntityDeclaration &lhs, const QXmlStreamEntityDeclaration &rhs)
Compares this entity declaration with \a other and returns \c true if
Compares \a lhs entity declaration with \a rhs and returns \c true if
they are equal; otherwise returns \c false.
*/
/*! \fn bool QXmlStreamEntityDeclaration::operator!=(const QXmlStreamEntityDeclaration &other) const
/*! \fn bool QXmlStreamEntityDeclaration::operator!=(const QXmlStreamEntityDeclaration &lhs, const QXmlStreamEntityDeclaration &rhs)
Compares this entity declaration with \a other and returns \c true if
Compares \a lhs entity declaration with \a rhs and returns \c true if
they are not equal; otherwise returns \c false.
*/

View File

@ -8,6 +8,7 @@
#if QT_CONFIG(xmlstream)
#include <QtCore/qcompare.h>
#include <QtCore/qlist.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstring.h>
@ -58,13 +59,23 @@ public:
}
inline QStringView value() const { return m_value; }
inline bool isDefault() const { return m_isDefault; }
inline bool operator==(const QXmlStreamAttribute &other) const {
return (value() == other.value()
&& (namespaceUri().isNull() ? (qualifiedName() == other.qualifiedName())
: (namespaceUri() == other.namespaceUri() && name() == other.name())));
}
#if QT_CORE_REMOVED_SINCE(6, 8)
inline bool operator==(const QXmlStreamAttribute &other) const
{ return comparesEqual(*this, other); }
inline bool operator!=(const QXmlStreamAttribute &other) const
{ return !operator==(other); }
#endif
private:
friend bool comparesEqual(const QXmlStreamAttribute &lhs,
const QXmlStreamAttribute &rhs) noexcept
{
return (lhs.value() == rhs.value()
&& (lhs.namespaceUri().isNull() ? (lhs.qualifiedName() == rhs.qualifiedName())
: (lhs.namespaceUri() == rhs.namespaceUri()
&& lhs.name() == rhs.name())));
}
Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamAttribute)
};
Q_DECLARE_TYPEINFO(QXmlStreamAttribute, Q_RELOCATABLE_TYPE);
@ -111,11 +122,19 @@ public:
inline QStringView prefix() const { return m_prefix; }
inline QStringView namespaceUri() const { return m_namespaceUri; }
inline bool operator==(const QXmlStreamNamespaceDeclaration &other) const {
return (prefix() == other.prefix() && namespaceUri() == other.namespaceUri());
}
#if QT_CORE_REMOVED_SINCE(6, 8)
inline bool operator==(const QXmlStreamNamespaceDeclaration &other) const
{ return comparesEqual(*this, other); }
inline bool operator!=(const QXmlStreamNamespaceDeclaration &other) const
{ return !operator==(other); }
#endif
private:
friend bool comparesEqual(const QXmlStreamNamespaceDeclaration &lhs,
const QXmlStreamNamespaceDeclaration &rhs) noexcept
{
return (lhs.prefix() == rhs.prefix() && lhs.namespaceUri() == rhs.namespaceUri());
}
Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamNamespaceDeclaration)
};
Q_DECLARE_TYPEINFO(QXmlStreamNamespaceDeclaration, Q_RELOCATABLE_TYPE);
@ -131,12 +150,20 @@ public:
inline QStringView name() const { return m_name; }
inline QStringView systemId() const { return m_systemId; }
inline QStringView publicId() const { return m_publicId; }
inline bool operator==(const QXmlStreamNotationDeclaration &other) const {
return (name() == other.name() && systemId() == other.systemId()
&& publicId() == other.publicId());
}
#if QT_CORE_REMOVED_SINCE(6, 8)
inline bool operator==(const QXmlStreamNotationDeclaration &other) const
{ return comparesEqual(*this, other); }
inline bool operator!=(const QXmlStreamNotationDeclaration &other) const
{ return !operator==(other); }
#endif
private:
friend bool comparesEqual(const QXmlStreamNotationDeclaration &lhs,
const QXmlStreamNotationDeclaration &rhs) noexcept
{
return (lhs.name() == rhs.name() && lhs.systemId() == rhs.systemId()
&& lhs.publicId() == rhs.publicId());
}
Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamNotationDeclaration)
};
Q_DECLARE_TYPEINFO(QXmlStreamNotationDeclaration, Q_RELOCATABLE_TYPE);
@ -154,15 +181,24 @@ public:
inline QStringView systemId() const { return m_systemId; }
inline QStringView publicId() const { return m_publicId; }
inline QStringView value() const { return m_value; }
inline bool operator==(const QXmlStreamEntityDeclaration &other) const {
return (name() == other.name()
&& notationName() == other.notationName()
&& systemId() == other.systemId()
&& publicId() == other.publicId()
&& value() == other.value());
}
#if QT_CORE_REMOVED_SINCE(6, 8)
inline bool operator==(const QXmlStreamEntityDeclaration &other) const
{ return comparesEqual(*this, other); }
inline bool operator!=(const QXmlStreamEntityDeclaration &other) const
{ return !operator==(other); }
#endif
private:
friend bool comparesEqual(const QXmlStreamEntityDeclaration &lhs,
const QXmlStreamEntityDeclaration &rhs) noexcept
{
return (lhs.name() == rhs.name()
&& lhs.notationName() == rhs.notationName()
&& lhs.systemId() == rhs.systemId()
&& lhs.publicId() == rhs.publicId()
&& lhs.value() == rhs.value());
}
Q_DECLARE_EQUALITY_COMPARABLE(QXmlStreamEntityDeclaration)
};
Q_DECLARE_TYPEINFO(QXmlStreamEntityDeclaration, Q_RELOCATABLE_TYPE);

View File

@ -26,6 +26,7 @@ qt_internal_add_test(tst_qxmlstream
LIBRARIES
Qt::Network
Qt::CorePrivate
Qt::TestPrivate
TESTDATA
${test_data}
${tokenError}

View File

@ -8,6 +8,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTest>
#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QUrl>
#include <QXmlStreamReader>
#include <QBuffer>
@ -542,6 +543,7 @@ public:
private slots:
void initTestCase();
void cleanupTestCase();
void compareCompiles();
void runTestSuite();
void reportFailures() const;
void reportFailures_data();
@ -593,6 +595,8 @@ private slots:
void tokenErrorHandling_data() const;
void tokenErrorHandling() const;
void checkStreamNotationDeclarations() const;
void checkStreamEntityDeclarations() const;
private:
static QByteArray readFile(const QString &filename);
@ -636,6 +640,14 @@ void tst_QXmlStream::cleanupTestCase()
{
}
void tst_QXmlStream::compareCompiles()
{
QTestPrivate::testEqualityOperatorsCompile<QXmlStreamAttribute>();
QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNamespaceDeclaration>();
QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNotationDeclaration>();
QTestPrivate::testEqualityOperatorsCompile<QXmlStreamEntityDeclaration>();
}
void tst_QXmlStream::runTestSuite()
{
QFile file(m_tempDir.filePath(catalogFile));
@ -886,12 +898,17 @@ void tst_QXmlStream::addExtraNamespaceDeclarations()
}
{
QXmlStreamReader xml(data);
xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared", "blabla"));
xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared_too", "foofoo"));
QXmlStreamNamespaceDeclaration undeclared("undeclared", "blabla");
QXmlStreamNamespaceDeclaration undeclared_too("undeclared_too", "blabla");
xml.addExtraNamespaceDeclaration(undeclared);
xml.addExtraNamespaceDeclaration(undeclared_too);
while (!xml.atEnd()) {
xml.readNext();
}
QVERIFY2(!xml.hasError(), xml.errorString().toLatin1().constData());
QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, false);
undeclared = undeclared_too;
QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, true);
}
}
@ -1346,6 +1363,15 @@ void tst_QXmlStream::hasAttribute() const
reader.readNext();
QVERIFY(!reader.hasError());
QXmlStreamAttribute attrValue1(QLatin1String("http://example.com/"), QString::fromLatin1("attr1"));
QXmlStreamAttribute attrValue2 = atts.at(0);
QT_TEST_EQUALITY_OPS(atts.at(0), QXmlStreamAttribute(), false);
QT_TEST_EQUALITY_OPS(atts.at(0), attrValue1, false);
QT_TEST_EQUALITY_OPS(atts.at(0), attrValue2, true);
QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, false);
attrValue1 = attrValue2;
QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, true);
}
void tst_QXmlStream::writeWithUtf8Codec() const
@ -1927,4 +1953,52 @@ void tst_QXmlStream::tokenErrorHandling() const
QVERIFY(reader.errorString().contains(errorKeyWord));
}
void tst_QXmlStream::checkStreamNotationDeclarations() const
{
QString fileName("12.xml");
const QDir dir(QFINDTESTDATA("data"));
QFile file(dir.absoluteFilePath(fileName));
if (!file.exists())
QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
file.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&file);
while (!reader.atEnd())
reader.readNext();
QVERIFY(!reader.hasError());
QXmlStreamNotationDeclaration notation1, notation2, notation3;
QT_TEST_EQUALITY_OPS(notation1, notation2, true);
const auto notationDeclarations = reader.notationDeclarations();
if (notationDeclarations.count() >= 2) {
notation1 = notationDeclarations.at(0);
notation2 = notationDeclarations.at(1);
notation3 = notationDeclarations.at(1);
}
QT_TEST_EQUALITY_OPS(notation1, notation2, false);
QT_TEST_EQUALITY_OPS(notation3, notation2, true);
}
void tst_QXmlStream::checkStreamEntityDeclarations() const
{
QString fileName("5.xml");
const QDir dir(QFINDTESTDATA("data"));
QFile file(dir.absoluteFilePath(fileName));
if (!file.exists())
QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
file.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&file);
while (!reader.atEnd())
reader.readNext();
QVERIFY(!reader.hasError());
QXmlStreamEntityDeclaration entity;
QT_TEST_EQUALITY_OPS(entity, QXmlStreamEntityDeclaration(), true);
const auto entityDeclarations = reader.entityDeclarations();
if (entityDeclarations.count() >= 2) {
entity = entityDeclarations.at(1);
QT_TEST_EQUALITY_OPS(entityDeclarations.at(0), entityDeclarations.at(1), false);
QT_TEST_EQUALITY_OPS(entity, entityDeclarations.at(1), true);
}
}
#include "tst_qxmlstream.moc"