diff options
Diffstat (limited to 'tests/auto/qxmlstream/qc14n.h')
-rw-r--r-- | tests/auto/qxmlstream/qc14n.h | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/tests/auto/qxmlstream/qc14n.h b/tests/auto/qxmlstream/qc14n.h new file mode 100644 index 0000000..5c358e3 --- /dev/null +++ b/tests/auto/qxmlstream/qc14n.h @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +QT_FORWARD_DECLARE_CLASS(QIODevice) +QT_FORWARD_DECLARE_CLASS(QString) + +#include <QtCore/QFlags> + +class QC14N +{ +public: + enum Option + { + IgnoreProcessingInstruction, + IgnoreComments + }; + typedef QFlags<Option> Options; + + static bool isEqual(QIODevice *const firstDocument, + QIODevice *const secondDocument, + QString *const message = 0, + const Options options = Options()); + +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, + const Options options) +{ + qDebug() << Q_FUNC_INFO; + Q_ASSERT_X(firstDocument, Q_FUNC_INFO, + "A valid QIODevice pointer must be supplied"); + Q_ASSERT_X(secondDocument, Q_FUNC_INFO, + "A valid QIODevice pointer must be supplied"); + Q_ASSERT_X(firstDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); + Q_ASSERT_X(secondDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); + + Q_ASSERT_X(options == Options(), Q_FUNC_INFO, + "Not yet implemented."); + Q_UNUSED(options); + + 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(); + + } + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "This line should never be reached"); + return false; +} + |