diff options
Diffstat (limited to 'tests/auto/corelib/xml/qxmlstream/qc14n.h')
-rw-r--r-- | tests/auto/corelib/xml/qxmlstream/qc14n.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/tests/auto/corelib/xml/qxmlstream/qc14n.h b/tests/auto/corelib/xml/qxmlstream/qc14n.h new file mode 100644 index 0000000000..f7c17b5a7a --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/qc14n.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +QT_FORWARD_DECLARE_CLASS(QIODevice) +QT_FORWARD_DECLARE_CLASS(QString) + +#include <QtCore/QFlags> + +class QC14N +{ +public: + static bool isEqual(QIODevice *const firstDocument, + QIODevice *const secondDocument, + QString *const message = 0); + +private: + static bool isDifferent(const QXmlStreamReader &r1, + const QXmlStreamReader &r2, + QString *const message); + static bool isAttributesEqual(const QXmlStreamReader &r1, + const QXmlStreamReader &r2, + QString *const message); +}; + +#include <QXmlStreamReader> + +/*! \internal + + \a firstDocument and \a secondDocument must be pointers to opened devices. + */ +bool QC14N::isEqual(QIODevice *const firstDocument, + QIODevice *const secondDocument, + QString *const message) +{ + qDebug() << Q_FUNC_INFO; + if (!firstDocument) + qFatal("%s: A valid firstDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!secondDocument) + qFatal("%s: A valid secondDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!firstDocument->isReadable()) + qFatal("%s: The firstDocument device must be readable.", Q_FUNC_INFO); + if (!secondDocument->isReadable()) + qFatal("%s: The secondDocument device must be readable.", Q_FUNC_INFO); + + QXmlStreamReader r1(firstDocument); + QXmlStreamReader r2(secondDocument); + + while(!r1.atEnd()) + { + if(r1.error()) + { + if(message) + *message = r1.errorString(); + + return false; + } + else if(r2.error()) + { + if(message) + *message = r1.errorString(); + + return false; + } + else + { + if(isDifferent(r1, r2, message)) + return true; + } + + r1.readNext(); + r2.readNext(); + } + + if(!r2.atEnd()) + { + if(message) + *message = QLatin1String("Reached the end of the first document, while there was still content left in the second"); + + return false; + } + + /* And they lived happily ever after. */ + return true; +} + +/*! \internal + */ +bool QC14N::isAttributesEqual(const QXmlStreamReader &r1, + const QXmlStreamReader &r2, + QString *const message) +{ + Q_UNUSED(message); + + const QXmlStreamAttributes &attrs1 = r1.attributes(); + const QXmlStreamAttributes &attrs2 = r2.attributes(); + const int len = attrs1.size(); + + if(len != attrs2.size()) + return false; + + for(int i = 0; i < len; ++i) + { + if(!attrs2.contains(attrs1.at(i))) + return false; + } + + return true; +} + +bool QC14N::isDifferent(const QXmlStreamReader &r1, + const QXmlStreamReader &r2, + QString *const message) +{ + // TODO error reporting can be a lot better here. + if(r1.tokenType() != r2.tokenType()) + return false; + + switch(r1.tokenType()) + { + case QXmlStreamReader::NoToken: + /* Fallthrough. */ + case QXmlStreamReader::StartDocument: + /* Fallthrough. */ + case QXmlStreamReader::EndDocument: + /* Fallthrough. */ + case QXmlStreamReader::DTD: + return true; + case QXmlStreamReader::Invalid: + return false; + case QXmlStreamReader::StartElement: + { + return r1.qualifiedName() == r2.qualifiedName() + /* Yes, the namespace test below should be redundant, but with it we + * trap namespace bugs in QXmlStreamReader, if any. */ + && r1.namespaceUri() == r2.namespaceUri() + && isAttributesEqual(r1, r2, message); + + } + case QXmlStreamReader::EndElement: + { + return r1.qualifiedName() == r2.qualifiedName() + && r1.namespaceUri() == r2.namespaceUri() + && r1.name() == r2.name(); + } + case QXmlStreamReader::Characters: + /* Fallthrough. */ + case QXmlStreamReader::Comment: + return r1.text() == r2.text(); + case QXmlStreamReader::EntityReference: + case QXmlStreamReader::ProcessingInstruction: + { + return r1.processingInstructionTarget() == r2.processingInstructionTarget() && + r2.processingInstructionData() == r2.processingInstructionData(); + + } + default: + qFatal("%s: Unknown tokenType: %d", Q_FUNC_INFO, static_cast<int>(r1.tokenType())); + return false; + } +} + |