summaryrefslogtreecommitdiffstats
path: root/src/corelib/xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/xml')
-rw-r--r--src/corelib/xml/.gitignore1
-rwxr-xr-xsrc/corelib/xml/make-parser.sh53
-rw-r--r--src/corelib/xml/qxmlstream.cpp3954
-rw-r--r--src/corelib/xml/qxmlstream.g1847
-rw-r--r--src/corelib/xml/qxmlstream.h491
-rw-r--r--src/corelib/xml/qxmlstream_p.h1965
-rw-r--r--src/corelib/xml/qxmlutils.cpp390
-rw-r--r--src/corelib/xml/qxmlutils_p.h92
-rw-r--r--src/corelib/xml/xml.pri10
9 files changed, 8803 insertions, 0 deletions
diff --git a/src/corelib/xml/.gitignore b/src/corelib/xml/.gitignore
new file mode 100644
index 0000000000..89f9ac04aa
--- /dev/null
+++ b/src/corelib/xml/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/src/corelib/xml/make-parser.sh b/src/corelib/xml/make-parser.sh
new file mode 100755
index 0000000000..7bfb1bceab
--- /dev/null
+++ b/src/corelib/xml/make-parser.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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 Technology Preview License Agreement accompanying
+## this package.
+##
+## 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+me=$(dirname $0)
+mkdir -p $me/out
+(cd $me/out && ../../../../util/qlalr/qlalr --qt --no-debug --no-lines ../qxmlstream.g)
+
+for f in $me/out/*.h; do
+ n=$(basename $f)
+ cp $f $n
+done
+
+git diff .
+
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
new file mode 100644
index 0000000000..2ef03863b7
--- /dev/null
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -0,0 +1,3954 @@
+/****************************************************************************
+**
+** 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 QtCore module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtCore/qxmlstream.h"
+
+#if defined(QT_BUILD_XML_LIB) && defined(Q_OS_MAC64)
+// No need to define this in the 64-bit Mac libraries.
+// Since Qt 4.4 and previous weren't supported in 64-bit, there are
+// no QXmlStream* symbols to keep compatibility with
+# define QT_NO_XMLSTREAM
+#endif
+
+#ifndef QT_NO_XMLSTREAM
+
+#include "qxmlutils_p.h"
+#include <qdebug.h>
+#include <qfile.h>
+#include <stdio.h>
+#include <qtextcodec.h>
+#include <qstack.h>
+#include <qbuffer.h>
+#ifndef QT_BOOTSTRAPPED
+#include <qcoreapplication.h>
+#else
+// This specialization of Q_DECLARE_TR_FUNCTIONS is not in qcoreapplication.h,
+// because that header depends on QObject being available, which is not the
+// case for most bootstrapped applications.
+#define Q_DECLARE_TR_FUNCTIONS(context) \
+public: \
+ static inline QString tr(const char *sourceText, const char *comment = 0) \
+ { Q_UNUSED(comment); return QString::fromLatin1(sourceText); } \
+ static inline QString trUtf8(const char *sourceText, const char *comment = 0) \
+ { Q_UNUSED(comment); return QString::fromLatin1(sourceText); } \
+ static inline QString tr(const char *sourceText, const char*, int) \
+ { return QString::fromLatin1(sourceText); } \
+ static inline QString trUtf8(const char *sourceText, const char*, int) \
+ { return QString::fromLatin1(sourceText); } \
+private:
+#endif
+QT_BEGIN_NAMESPACE
+
+#include "qxmlstream_p.h"
+
+/*!
+ \enum QXmlStreamReader::TokenType
+
+ This enum specifies the type of token the reader just read.
+
+ \value NoToken The reader has not yet read anything.
+
+ \value Invalid An error has occurred, reported in error() and
+ errorString().
+
+ \value StartDocument The reader reports the XML version number in
+ documentVersion(), and the encoding as specified in the XML
+ document in documentEncoding(). If the document is declared
+ standalone, isStandaloneDocument() returns true; otherwise it
+ returns false.
+
+ \value EndDocument The reader reports the end of the document.
+
+ \value StartElement The reader reports the start of an element
+ with namespaceUri() and name(). Empty elements are also reported
+ as StartElement, followed directly by EndElement. The convenience
+ function readElementText() can be called to concatenate all
+ content until the corresponding EndElement. Attributes are
+ reported in attributes(), namespace declarations in
+ namespaceDeclarations().
+
+ \value EndElement The reader reports the end of an element with
+ namespaceUri() and name().
+
+ \value Characters The reader reports characters in text(). If the
+ characters are all white-space, isWhitespace() returns true. If
+ the characters stem from a CDATA section, isCDATA() returns true.
+
+ \value Comment The reader reports a comment in text().
+
+ \value DTD The reader reports a DTD in text(), notation
+ declarations in notationDeclarations(), and entity declarations in
+ entityDeclarations(). Details of the DTD declaration are reported
+ in in dtdName(), dtdPublicId(), and dtdSystemId().
+
+ \value EntityReference The reader reports an entity reference that
+ could not be resolved. The name of the reference is reported in
+ name(), the replacement text in text().
+
+ \value ProcessingInstruction The reader reports a processing
+ instruction in processingInstructionTarget() and
+ processingInstructionData().
+*/
+
+/*!
+ \enum QXmlStreamReader::ReadElementTextBehaviour
+
+ This enum specifies the different behaviours of readElementText().
+
+ \value ErrorOnUnexpectedElement Raise an UnexpectedElementError and return
+ what was read so far when a child element is encountered.
+
+ \value IncludeChildElements Recursively include the text from child elements.
+
+ \value SkipChildElements Skip child elements.
+
+ \since 4.6
+*/
+
+/*!
+ \enum QXmlStreamReader::Error
+
+ This enum specifies different error cases
+
+ \value NoError No error has occurred.
+
+ \value CustomError A custom error has been raised with
+ raiseError()
+
+ \value NotWellFormedError The parser internally raised an error
+ due to the read XML not being well-formed.
+
+ \value PrematureEndOfDocumentError The input stream ended before a
+ well-formed XML document was parsed. Recovery from this error is
+ possible if more XML arrives in the stream, either by calling
+ addData() or by waiting for it to arrive on the device().
+
+ \value UnexpectedElementError The parser encountered an element
+ that was different to those it expected.
+
+*/
+
+/*!
+ \class QXmlStreamEntityResolver
+ \reentrant
+ \since 4.4
+
+ \brief The QXmlStreamEntityResolver class provides an entity
+ resolver for a QXmlStreamReader.
+
+ \ingroup xml-tools
+ */
+
+/*!
+ Destroys the entity resolver.
+ */
+QXmlStreamEntityResolver::~QXmlStreamEntityResolver()
+{
+}
+
+/*! \internal
+
+This function is a stub for later functionality.
+*/
+QString QXmlStreamEntityResolver::resolveEntity(const QString& /*publicId*/, const QString& /*systemId*/)
+{
+ return QString();
+}
+
+
+/*!
+ Resolves the undeclared entity \a name and returns its replacement
+ text. If the entity is also unknown to the entity resolver, it
+ returns an empty string.
+
+ The default implementation always returns an empty string.
+*/
+
+QString QXmlStreamEntityResolver::resolveUndeclaredEntity(const QString &/*name*/)
+{
+ return QString();
+}
+
+#ifndef QT_NO_XMLSTREAMREADER
+
+QString QXmlStreamReaderPrivate::resolveUndeclaredEntity(const QString &name)
+{
+ if (entityResolver)
+ return entityResolver->resolveUndeclaredEntity(name);
+ return QString();
+}
+
+
+
+/*!
+ \since 4.4
+
+ Makes \a resolver the new entityResolver().
+
+ The stream reader does \e not take ownership of the resolver. It's
+ the callers responsibility to ensure that the resolver is valid
+ during the entire life-time of the stream reader object, or until
+ another resolver or 0 is set.
+
+ \sa entityResolver()
+ */
+void QXmlStreamReader::setEntityResolver(QXmlStreamEntityResolver *resolver)
+{
+ Q_D(QXmlStreamReader);
+ d->entityResolver = resolver;
+}
+
+/*!
+ \since 4.4
+
+ Returns the entity resolver, or 0 if there is no entity resolver.
+
+ \sa setEntityResolver()
+ */
+QXmlStreamEntityResolver *QXmlStreamReader::entityResolver() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->entityResolver;
+}
+
+
+
+/*!
+ \class QXmlStreamReader
+ \reentrant
+ \since 4.3
+
+ \brief The QXmlStreamReader class provides a fast parser for reading
+ well-formed XML via a simple streaming API.
+
+
+ \ingroup xml-tools
+
+ QXmlStreamReader is a faster and more convenient replacement for
+ Qt's own SAX parser (see QXmlSimpleReader). In some cases it might
+ also be a faster and more convenient alternative for use in
+ applications that would otherwise use a DOM tree (see QDomDocument).
+ QXmlStreamReader reads data either from a QIODevice (see
+ setDevice()), or from a raw QByteArray (see addData()).
+
+ Qt provides QXmlStreamWriter for writing XML.
+
+ The basic concept of a stream reader is to report an XML document as
+ a stream of tokens, similar to SAX. The main difference between
+ QXmlStreamReader and SAX is \e how these XML tokens are reported.
+ With SAX, the application must provide handlers (callback functions)
+ that receive so-called XML \e events from the parser at the parser's
+ convenience. With QXmlStreamReader, the application code itself
+ drives the loop and pulls \e tokens from the reader, one after
+ another, as it needs them. This is done by calling readNext(), where
+ the reader reads from the input stream until it completes the next
+ token, at which point it returns the tokenType(). A set of
+ convenient functions including isStartElement() and text() can then
+ be used to examine the token to obtain information about what has
+ been read. The big advantage of this \e pulling approach is the
+ possibility to build recursive descent parsers with it, meaning you
+ can split your XML parsing code easily into different methods or
+ classes. This makes it easy to keep track of the application's own
+ state when parsing XML.
+
+ A typical loop with QXmlStreamReader looks like this:
+
+ \snippet doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp 0
+
+
+ QXmlStreamReader is a well-formed XML 1.0 parser that does \e not
+ include external parsed entities. As long as no error occurs, the
+ application code can thus be assured that the data provided by the
+ stream reader satisfies the W3C's criteria for well-formed XML. For
+ example, you can be certain that all tags are indeed nested and
+ closed properly, that references to internal entities have been
+ replaced with the correct replacement text, and that attributes have
+ been normalized or added according to the internal subset of the
+ DTD.
+
+ If an error occurs while parsing, atEnd() and hasError() return
+ true, and error() returns the error that occurred. The functions
+ errorString(), lineNumber(), columnNumber(), and characterOffset()
+ are for constructing an appropriate error or warning message. To
+ simplify application code, QXmlStreamReader contains a raiseError()
+ mechanism that lets you raise custom errors that trigger the same
+ error handling described.
+
+ The \l{QXmlStream Bookmarks Example} illustrates how to use the
+ recursive descent technique to read an XML bookmark file (XBEL) with
+ a stream reader.
+
+ \section1 Namespaces
+
+ QXmlStream understands and resolves XML namespaces. E.g. in case of
+ a StartElement, namespaceUri() returns the namespace the element is
+ in, and name() returns the element's \e local name. The combination
+ of namespaceUri and name uniquely identifies an element. If a
+ namespace prefix was not declared in the XML entities parsed by the
+ reader, the namespaceUri is empty.
+
+ If you parse XML data that does not utilize namespaces according to
+ the XML specification or doesn't use namespaces at all, you can use
+ the element's qualifiedName() instead. A qualified name is the
+ element's prefix() followed by colon followed by the element's local
+ name() - exactly like the element appears in the raw XML data. Since
+ the mapping namespaceUri to prefix is neither unique nor universal,
+ qualifiedName() should be avoided for namespace-compliant XML data.
+
+ In order to parse standalone documents that do use undeclared
+ namespace prefixes, you can turn off namespace processing completely
+ with the \l namespaceProcessing property.
+
+ \section1 Incremental parsing
+
+ QXmlStreamReader is an incremental parser. It can handle the case
+ where the document can't be parsed all at once because it arrives in
+ chunks (e.g. from multiple files, or over a network connection).
+ When the reader runs out of data before the complete document has
+ been parsed, it reports a PrematureEndOfDocumentError. When more
+ data arrives, either because of a call to addData() or because more
+ data is available through the network device(), the reader recovers
+ from the PrematureEndOfDocumentError error and continues parsing the
+ new data with the next call to readNext().
+
+ For example, if your application reads data from the network using a
+ \l{QNetworkAccessManager} {network access manager}, you would issue
+ a \l{QNetworkRequest} {network request} to the manager and receive a
+ \l{QNetworkReply} {network reply} in return. Since a QNetworkReply
+ is a QIODevice, you connect its \l{QNetworkReply::readyRead()}
+ {readyRead()} signal to a custom slot, e.g. \c{slotReadyRead()} in
+ the code snippet shown in the discussion for QNetworkAccessManager.
+ In this slot, you read all available data with
+ \l{QNetworkReply::readAll()} {readAll()} and pass it to the XML
+ stream reader using addData(). Then you call your custom parsing
+ function that reads the XML events from the reader.
+
+ \section1 Performance and memory consumption
+
+ QXmlStreamReader is memory-conservative by design, since it doesn't
+ store the entire XML document tree in memory, but only the current
+ token at the time it is reported. In addition, QXmlStreamReader
+ avoids the many small string allocations that it normally takes to
+ map an XML document to a convenient and Qt-ish API. It does this by
+ reporting all string data as QStringRef rather than real QString
+ objects. QStringRef is a thin wrapper around QString substrings that
+ provides a subset of the QString API without the memory allocation
+ and reference-counting overhead. Calling
+ \l{QStringRef::toString()}{toString()} on any of those objects
+ returns an equivalent real QString object.
+
+*/
+
+
+/*!
+ Constructs a stream reader.
+
+ \sa setDevice(), addData()
+ */
+QXmlStreamReader::QXmlStreamReader()
+ : d_ptr(new QXmlStreamReaderPrivate(this))
+{
+}
+
+/*! Creates a new stream reader that reads from \a device.
+
+\sa setDevice(), clear()
+ */
+QXmlStreamReader::QXmlStreamReader(QIODevice *device)
+ : d_ptr(new QXmlStreamReaderPrivate(this))
+{
+ setDevice(device);
+}
+
+/*!
+ Creates a new stream reader that reads from \a data.
+
+ \sa addData(), clear(), setDevice()
+ */
+QXmlStreamReader::QXmlStreamReader(const QByteArray &data)
+ : d_ptr(new QXmlStreamReaderPrivate(this))
+{
+ Q_D(QXmlStreamReader);
+ d->dataBuffer = data;
+}
+
+/*!
+ Creates a new stream reader that reads from \a data.
+
+ \sa addData(), clear(), setDevice()
+ */
+QXmlStreamReader::QXmlStreamReader(const QString &data)
+ : d_ptr(new QXmlStreamReaderPrivate(this))
+{
+ Q_D(QXmlStreamReader);
+#ifdef QT_NO_TEXTCODEC
+ d->dataBuffer = data.toLatin1();
+#else
+ d->dataBuffer = d->codec->fromUnicode(data);
+ d->decoder = d->codec->makeDecoder();
+#endif
+ d->lockEncoding = true;
+
+}
+
+/*!
+ Creates a new stream reader that reads from \a data.
+
+ \sa addData(), clear(), setDevice()
+ */
+QXmlStreamReader::QXmlStreamReader(const char *data)
+ : d_ptr(new QXmlStreamReaderPrivate(this))
+{
+ Q_D(QXmlStreamReader);
+ d->dataBuffer = QByteArray(data);
+}
+
+/*!
+ Destructs the reader.
+ */
+QXmlStreamReader::~QXmlStreamReader()
+{
+ Q_D(QXmlStreamReader);
+ if (d->deleteDevice)
+ delete d->device;
+}
+
+/*! \fn bool QXmlStreamReader::hasError() const
+ Returns \c true if an error has occurred, otherwise \c false.
+
+ \sa errorString(), error()
+ */
+
+/*!
+ Sets the current device to \a device. Setting the device resets
+ the stream to its initial state.
+
+ \sa device(), clear()
+*/
+void QXmlStreamReader::setDevice(QIODevice *device)
+{
+ Q_D(QXmlStreamReader);
+ if (d->deleteDevice) {
+ delete d->device;
+ d->deleteDevice = false;
+ }
+ d->device = device;
+ d->init();
+
+}
+
+/*!
+ Returns the current device associated with the QXmlStreamReader,
+ or 0 if no device has been assigned.
+
+ \sa setDevice()
+*/
+QIODevice *QXmlStreamReader::device() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->device;
+}
+
+
+/*!
+ Adds more \a data for the reader to read. This function does
+ nothing if the reader has a device().
+
+ \sa readNext(), clear()
+ */
+void QXmlStreamReader::addData(const QByteArray &data)
+{
+ Q_D(QXmlStreamReader);
+ if (d->device) {
+ qWarning("QXmlStreamReader: addData() with device()");
+ return;
+ }
+ d->dataBuffer += data;
+}
+
+/*!
+ Adds more \a data for the reader to read. This function does
+ nothing if the reader has a device().
+
+ \sa readNext(), clear()
+ */
+void QXmlStreamReader::addData(const QString &data)
+{
+ Q_D(QXmlStreamReader);
+ d->lockEncoding = true;
+#ifdef QT_NO_TEXTCODEC
+ addData(data.toLatin1());
+#else
+ addData(d->codec->fromUnicode(data));
+#endif
+}
+
+/*!
+ Adds more \a data for the reader to read. This function does
+ nothing if the reader has a device().
+
+ \sa readNext(), clear()
+ */
+void QXmlStreamReader::addData(const char *data)
+{
+ addData(QByteArray(data));
+}
+
+/*!
+ Removes any device() or data from the reader and resets its
+ internal state to the initial state.
+
+ \sa addData()
+ */
+void QXmlStreamReader::clear()
+{
+ Q_D(QXmlStreamReader);
+ d->init();
+ if (d->device) {
+ if (d->deleteDevice)
+ delete d->device;
+ d->device = 0;
+ }
+}
+
+/*!
+ Returns true if the reader has read until the end of the XML
+ document, or if an error() has occurred and reading has been
+ aborted. Otherwise, it returns false.
+
+ When atEnd() and hasError() return true and error() returns
+ PrematureEndOfDocumentError, it means the XML has been well-formed
+ so far, but a complete XML document has not been parsed. The next
+ chunk of XML can be added with addData(), if the XML is being read
+ from a QByteArray, or by waiting for more data to arrive if the
+ XML is being read from a QIODevice. Either way, atEnd() will
+ return false once more data is available.
+
+ \sa hasError(), error(), device(), QIODevice::atEnd()
+ */
+bool QXmlStreamReader::atEnd() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->atEnd
+ && ((d->type == QXmlStreamReader::Invalid && d->error == PrematureEndOfDocumentError)
+ || (d->type == QXmlStreamReader::EndDocument))) {
+ if (d->device)
+ return d->device->atEnd();
+ else
+ return !d->dataBuffer.size();
+ }
+ return (d->atEnd || d->type == QXmlStreamReader::Invalid);
+}
+
+
+/*!
+ Reads the next token and returns its type.
+
+ With one exception, once an error() is reported by readNext(),
+ further reading of the XML stream is not possible. Then atEnd()
+ returns true, hasError() returns true, and this function returns
+ QXmlStreamReader::Invalid.
+
+ The exception is when error() returns PrematureEndOfDocumentError.
+ This error is reported when the end of an otherwise well-formed
+ chunk of XML is reached, but the chunk doesn't represent a complete
+ XML document. In that case, parsing \e can be resumed by calling
+ addData() to add the next chunk of XML, when the stream is being
+ read from a QByteArray, or by waiting for more data to arrive when
+ the stream is being read from a device().
+
+ \sa tokenType(), tokenString()
+ */
+QXmlStreamReader::TokenType QXmlStreamReader::readNext()
+{
+ Q_D(QXmlStreamReader);
+ if (d->type != Invalid) {
+ if (!d->hasCheckedStartDocument)
+ if (!d->checkStartDocument())
+ return d->type; // synthetic StartDocument or error
+ d->parse();
+ if (d->atEnd && d->type != EndDocument && d->type != Invalid)
+ d->raiseError(PrematureEndOfDocumentError);
+ else if (!d->atEnd && d->type == EndDocument)
+ d->raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+ } else if (d->error == PrematureEndOfDocumentError) {
+ // resume error
+ d->type = NoToken;
+ d->atEnd = false;
+ d->token = -1;
+ return readNext();
+ }
+ return d->type;
+}
+
+
+/*!
+ Returns the type of the current token.
+
+ The current token can also be queried with the convenience functions
+ isStartDocument(), isEndDocument(), isStartElement(),
+ isEndElement(), isCharacters(), isComment(), isDTD(),
+ isEntityReference(), and isProcessingInstruction().
+
+ \sa tokenString()
+ */
+QXmlStreamReader::TokenType QXmlStreamReader::tokenType() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->type;
+}
+
+/*!
+ Reads until the next start element within the current element. Returns true
+ when a start element was reached. When the end element was reached, or when
+ an error occurred, false is returned.
+
+ The current element is the element matching the most recently parsed start
+ element of which a matching end element has not yet been reached. When the
+ parser has reached the end element, the current element becomes the parent
+ element.
+
+ This is a convenience function for when you're only concerned with parsing
+ XML elements. The \l{QXmlStream Bookmarks Example} makes extensive use of
+ this function.
+
+ \since 4.6
+ \sa readNext()
+ */
+bool QXmlStreamReader::readNextStartElement()
+{
+ while (readNext() != Invalid) {
+ if (isEndElement())
+ return false;
+ else if (isStartElement())
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Reads until the end of the current element, skipping any child nodes.
+ This function is useful for skipping unknown elements.
+
+ The current element is the element matching the most recently parsed start
+ element of which a matching end element has not yet been reached. When the
+ parser has reached the end element, the current element becomes the parent
+ element.
+
+ \since 4.6
+ */
+void QXmlStreamReader::skipCurrentElement()
+{
+ int depth = 1;
+ while (depth && readNext() != Invalid) {
+ if (isEndElement())
+ --depth;
+ else if (isStartElement())
+ ++depth;
+ }
+}
+
+/*
+ * Use the following Perl script to generate the error string index list:
+===== PERL SCRIPT ====
+print "static const char QXmlStreamReader_tokenTypeString_string[] =\n";
+$counter = 0;
+$i = 0;
+while (<STDIN>) {
+ chomp;
+ print " \"$_\\0\"\n";
+ $sizes[$i++] = $counter;
+ $counter += length 1 + $_;
+}
+print " \"\\0\";\n\nstatic const short QXmlStreamReader_tokenTypeString_indices[] = {\n ";
+for ($j = 0; $j < $i; ++$j) {
+ printf "$sizes[$j], ";
+}
+print "0\n};\n";
+===== PERL SCRIPT ====
+
+ * The input data is as follows (copied from qxmlstream.h):
+NoToken
+Invalid
+StartDocument
+EndDocument
+StartElement
+EndElement
+Characters
+Comment
+DTD
+EntityReference
+ProcessingInstruction
+*/
+static const char QXmlStreamReader_tokenTypeString_string[] =
+ "NoToken\0"
+ "Invalid\0"
+ "StartDocument\0"
+ "EndDocument\0"
+ "StartElement\0"
+ "EndElement\0"
+ "Characters\0"
+ "Comment\0"
+ "DTD\0"
+ "EntityReference\0"
+ "ProcessingInstruction\0";
+
+static const short QXmlStreamReader_tokenTypeString_indices[] = {
+ 0, 8, 16, 30, 42, 55, 66, 77, 85, 89, 105, 0
+};
+
+
+/*!
+ \property QXmlStreamReader::namespaceProcessing
+ the namespace-processing flag of the stream reader
+
+ This property controls whether or not the stream reader processes
+ namespaces. If enabled, the reader processes namespaces, otherwise
+ it does not.
+
+ By default, namespace-processing is enabled.
+*/
+
+
+void QXmlStreamReader::setNamespaceProcessing(bool enable)
+{
+ Q_D(QXmlStreamReader);
+ d->namespaceProcessing = enable;
+}
+
+bool QXmlStreamReader::namespaceProcessing() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->namespaceProcessing;
+}
+
+/*! Returns the reader's current token as string.
+
+\sa tokenType()
+*/
+QString QXmlStreamReader::tokenString() const
+{
+ Q_D(const QXmlStreamReader);
+ return QLatin1String(QXmlStreamReader_tokenTypeString_string +
+ QXmlStreamReader_tokenTypeString_indices[d->type]);
+}
+
+#endif // QT_NO_XMLSTREAMREADER
+
+QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
+{
+ tagStack.reserve(16);
+ tagStackStringStorage.reserve(32);
+ tagStackStringStorageSize = 0;
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix = addToStringStorage(QLatin1String("xml"));
+ namespaceDeclaration.namespaceUri = addToStringStorage(QLatin1String("http://www.w3.org/XML/1998/namespace"));
+}
+
+#ifndef QT_NO_XMLSTREAMREADER
+
+QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q)
+ :q_ptr(q)
+{
+ device = 0;
+ deleteDevice = false;
+#ifndef QT_NO_TEXTCODEC
+ decoder = 0;
+#endif
+ stack_size = 64;
+ sym_stack = 0;
+ state_stack = 0;
+ reallocateStack();
+ entityResolver = 0;
+ init();
+ entityHash.insert(QLatin1String("lt"), Entity::createLiteral(QLatin1String("<")));
+ entityHash.insert(QLatin1String("gt"), Entity::createLiteral(QLatin1String(">")));
+ entityHash.insert(QLatin1String("amp"), Entity::createLiteral(QLatin1String("&")));
+ entityHash.insert(QLatin1String("apos"), Entity::createLiteral(QLatin1String("'")));
+ entityHash.insert(QLatin1String("quot"), Entity::createLiteral(QLatin1String("\"")));
+}
+
+void QXmlStreamReaderPrivate::init()
+{
+ tos = 0;
+ scanDtd = false;
+ token = -1;
+ token_char = 0;
+ isEmptyElement = false;
+ isWhitespace = true;
+ isCDATA = false;
+ standalone = false;
+ tos = 0;
+ resumeReduction = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ putStack.clear();
+ putStack.reserve(32);
+ textBuffer.clear();
+ textBuffer.reserve(256);
+ tagStack.clear();
+ tagsDone = false;
+ attributes.clear();
+ attributes.reserve(16);
+ lineNumber = lastLineStart = characterOffset = 0;
+ readBufferPos = 0;
+ nbytesread = 0;
+#ifndef QT_NO_TEXTCODEC
+ codec = QTextCodec::codecForMib(106); // utf8
+ delete decoder;
+ decoder = 0;
+#endif
+ attributeStack.clear();
+ attributeStack.reserve(16);
+ entityParser = 0;
+ hasCheckedStartDocument = false;
+ normalizeLiterals = false;
+ hasSeenTag = false;
+ atEnd = false;
+ inParseEntity = false;
+ referenceToUnparsedEntityDetected = false;
+ referenceToParameterEntityDetected = false;
+ hasExternalDtdSubset = false;
+ lockEncoding = false;
+ namespaceProcessing = true;
+ rawReadBuffer.clear();
+ dataBuffer.clear();
+ readBuffer.clear();
+
+ type = QXmlStreamReader::NoToken;
+ error = QXmlStreamReader::NoError;
+}
+
+/*
+ Well-formed requires that we verify entity values. We do this with a
+ standard parser.
+ */
+void QXmlStreamReaderPrivate::parseEntity(const QString &value)
+{
+ Q_Q(QXmlStreamReader);
+
+ if (value.isEmpty())
+ return;
+
+
+ if (!entityParser)
+ entityParser = new QXmlStreamReaderPrivate(q);
+ else
+ entityParser->init();
+ entityParser->inParseEntity = true;
+ entityParser->readBuffer = value;
+ entityParser->injectToken(PARSE_ENTITY);
+ while (!entityParser->atEnd && entityParser->type != QXmlStreamReader::Invalid)
+ entityParser->parse();
+ if (entityParser->type == QXmlStreamReader::Invalid || entityParser->tagStack.size())
+ raiseWellFormedError(QXmlStream::tr("Invalid entity value."));
+
+}
+
+inline void QXmlStreamReaderPrivate::reallocateStack()
+{
+ stack_size <<= 1;
+ sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
+ Q_CHECK_PTR(sym_stack);
+ state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
+ Q_CHECK_PTR(sym_stack);
+}
+
+
+QXmlStreamReaderPrivate::~QXmlStreamReaderPrivate()
+{
+#ifndef QT_NO_TEXTCODEC
+ delete decoder;
+#endif
+ qFree(sym_stack);
+ qFree(state_stack);
+ delete entityParser;
+}
+
+
+inline uint QXmlStreamReaderPrivate::filterCarriageReturn()
+{
+ uint peekc = peekChar();
+ if (peekc == '\n') {
+ if (putStack.size())
+ putStack.pop();
+ else
+ ++readBufferPos;
+ return peekc;
+ }
+ if (peekc == 0) {
+ putChar('\r');
+ return 0;
+ }
+ return '\n';
+}
+
+/*!
+ \internal
+ If the end of the file is encountered, 0 is returned.
+ */
+inline uint QXmlStreamReaderPrivate::getChar()
+{
+ uint c;
+ if (putStack.size()) {
+ c = atEnd ? 0 : putStack.pop();
+ } else {
+ if (readBufferPos < readBuffer.size())
+ c = readBuffer.at(readBufferPos++).unicode();
+ else
+ c = getChar_helper();
+ }
+
+ return c;
+}
+
+inline uint QXmlStreamReaderPrivate::peekChar()
+{
+ uint c;
+ if (putStack.size()) {
+ c = putStack.top();
+ } else if (readBufferPos < readBuffer.size()) {
+ c = readBuffer.at(readBufferPos).unicode();
+ } else {
+ if ((c = getChar_helper()))
+ --readBufferPos;
+ }
+
+ return c;
+}
+
+/*!
+ \internal
+
+ Scans characters until \a str is encountered, and validates the characters
+ as according to the Char[2] production and do the line-ending normalization.
+ If any character is invalid, false is returned, otherwise true upon success.
+
+ If \a tokenToInject is not less than zero, injectToken() is called with
+ \a tokenToInject when \a str is found.
+
+ If any error occurred, false is returned, otherwise true.
+ */
+bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+{
+ int pos = textBuffer.size();
+ int oldLineNumber = lineNumber;
+
+ while (uint c = getChar()) {
+ /* First, we do the validation & normalization. */
+ switch (c) {
+ case '\r':
+ if ((c = filterCarriageReturn()) == 0)
+ break;
+ // fall through
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ // fall through
+ case '\t':
+ textBuffer += QChar(c);
+ continue;
+ default:
+ if(c < 0x20 || (c > 0xFFFD && c < 0x10000) || c > 0x10FFFF ) {
+ raiseWellFormedError(QXmlStream::tr("Invalid XML character."));
+ lineNumber = oldLineNumber;
+ return false;
+ }
+ textBuffer += QChar(c);
+ }
+
+
+ /* Second, attempt to lookup str. */
+ if (c == uint(*str)) {
+ if (!*(str + 1)) {
+ if (tokenToInject >= 0)
+ injectToken(tokenToInject);
+ return true;
+ } else {
+ if (scanString(str + 1, tokenToInject, false))
+ return true;
+ }
+ }
+ }
+ putString(textBuffer, pos);
+ textBuffer.resize(pos);
+ lineNumber = oldLineNumber;
+ return false;
+}
+
+bool QXmlStreamReaderPrivate::scanString(const char *str, short tokenToInject, bool requireSpace)
+{
+ int n = 0;
+ while (str[n]) {
+ ushort c = getChar();
+ if (c != ushort(str[n])) {
+ if (c)
+ putChar(c);
+ while (n--) {
+ putChar(ushort(str[n]));
+ }
+ return false;
+ }
+ ++n;
+ }
+ for (int i = 0; i < n; ++i)
+ textBuffer += QChar(ushort(str[i]));
+ if (requireSpace) {
+ int s = fastScanSpace();
+ if (!s || atEnd) {
+ int pos = textBuffer.size() - n - s;
+ putString(textBuffer, pos);
+ textBuffer.resize(pos);
+ return false;
+ }
+ }
+ if (tokenToInject >= 0)
+ injectToken(tokenToInject);
+ return true;
+}
+
+bool QXmlStreamReaderPrivate::scanAfterLangleBang()
+{
+ switch (peekChar()) {
+ case '[':
+ return scanString(spell[CDATA_START], CDATA_START, false);
+ case 'D':
+ return scanString(spell[DOCTYPE], DOCTYPE);
+ case 'A':
+ return scanString(spell[ATTLIST], ATTLIST);
+ case 'N':
+ return scanString(spell[NOTATION], NOTATION);
+ case 'E':
+ if (scanString(spell[ELEMENT], ELEMENT))
+ return true;
+ return scanString(spell[ENTITY], ENTITY);
+
+ default:
+ ;
+ };
+ return false;
+}
+
+bool QXmlStreamReaderPrivate::scanPublicOrSystem()
+{
+ switch (peekChar()) {
+ case 'S':
+ return scanString(spell[SYSTEM], SYSTEM);
+ case 'P':
+ return scanString(spell[PUBLIC], PUBLIC);
+ default:
+ ;
+ }
+ return false;
+}
+
+bool QXmlStreamReaderPrivate::scanNData()
+{
+ if (fastScanSpace()) {
+ if (scanString(spell[NDATA], NDATA))
+ return true;
+ putChar(' ');
+ }
+ return false;
+}
+
+bool QXmlStreamReaderPrivate::scanAfterDefaultDecl()
+{
+ switch (peekChar()) {
+ case 'R':
+ return scanString(spell[REQUIRED], REQUIRED, false);
+ case 'I':
+ return scanString(spell[IMPLIED], IMPLIED, false);
+ case 'F':
+ return scanString(spell[FIXED], FIXED, false);
+ default:
+ ;
+ }
+ return false;
+}
+
+bool QXmlStreamReaderPrivate::scanAttType()
+{
+ switch (peekChar()) {
+ case 'C':
+ return scanString(spell[CDATA], CDATA);
+ case 'I':
+ if (scanString(spell[ID], ID))
+ return true;
+ if (scanString(spell[IDREF], IDREF))
+ return true;
+ return scanString(spell[IDREFS], IDREFS);
+ case 'E':
+ if (scanString(spell[ENTITY], ENTITY))
+ return true;
+ return scanString(spell[ENTITIES], ENTITIES);
+ case 'N':
+ if (scanString(spell[NOTATION], NOTATION))
+ return true;
+ if (scanString(spell[NMTOKEN], NMTOKEN))
+ return true;
+ return scanString(spell[NMTOKENS], NMTOKENS);
+ default:
+ ;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Scan strings with quotes or apostrophes surround them. For instance,
+ attributes, the version and encoding field in the XML prolog and
+ entity declarations.
+
+ If normalizeLiterals is set to true, the function also normalizes
+ whitespace. It is set to true when the first start tag is
+ encountered.
+
+ */
+inline int QXmlStreamReaderPrivate::fastScanLiteralContent()
+{
+ int n = 0;
+ uint c;
+ while ((c = getChar())) {
+ switch (ushort(c)) {
+ case 0xfffe:
+ case 0xffff:
+ case 0:
+ /* The putChar() call is necessary so the parser re-gets
+ * the character from the input source, when raising an error. */
+ putChar(c);
+ return n;
+ case '\r':
+ if (filterCarriageReturn() == 0)
+ return n;
+ // fall through
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ // fall through
+ case ' ':
+ case '\t':
+ if (normalizeLiterals)
+ textBuffer += QLatin1Char(' ');
+ else
+ textBuffer += QChar(c);
+ ++n;
+ break;
+ case '&':
+ case '<':
+ case '\"':
+ case '\'':
+ if (!(c & 0xff0000)) {
+ putChar(c);
+ return n;
+ }
+ // fall through
+ default:
+ textBuffer += QChar(c);
+ ++n;
+ }
+ }
+ return n;
+}
+
+inline int QXmlStreamReaderPrivate::fastScanSpace()
+{
+ int n = 0;
+ ushort c;
+ while ((c = getChar())) {
+ switch (c) {
+ case '\r':
+ if ((c = filterCarriageReturn()) == 0)
+ return n;
+ // fall through
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ // fall through
+ case ' ':
+ case '\t':
+ textBuffer += QChar(c);
+ ++n;
+ break;
+ default:
+ putChar(c);
+ return n;
+ }
+ }
+ return n;
+}
+
+/*!
+ \internal
+
+ Used for text nodes essentially. That is, characters appearing
+ inside elements.
+ */
+inline int QXmlStreamReaderPrivate::fastScanContentCharList()
+{
+ int n = 0;
+ uint c;
+ while ((c = getChar())) {
+ switch (ushort(c)) {
+ case 0xfffe:
+ case 0xffff:
+ case 0:
+ putChar(c);
+ return n;
+ case ']': {
+ isWhitespace = false;
+ int pos = textBuffer.size();
+ textBuffer += QChar(ushort(c));
+ ++n;
+ while ((c = getChar()) == ']') {
+ textBuffer += QChar(ushort(c));
+ ++n;
+ }
+ if (c == 0) {
+ putString(textBuffer, pos);
+ textBuffer.resize(pos);
+ } else if (c == '>' && textBuffer.at(textBuffer.size()-2) == QLatin1Char(']')) {
+ raiseWellFormedError(QXmlStream::tr("Sequence ']]>' not allowed in content."));
+ } else {
+ putChar(c);
+ break;
+ }
+ return n;
+ } break;
+ case '\r':
+ if ((c = filterCarriageReturn()) == 0)
+ return n;
+ // fall through
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ // fall through
+ case ' ':
+ case '\t':
+ textBuffer += QChar(ushort(c));
+ ++n;
+ break;
+ case '&':
+ case '<':
+ if (!(c & 0xff0000)) {
+ putChar(c);
+ return n;
+ }
+ // fall through
+ default:
+ if (c < 0x20) {
+ putChar(c);
+ return n;
+ }
+ isWhitespace = false;
+ textBuffer += QChar(ushort(c));
+ ++n;
+ }
+ }
+ return n;
+}
+
+inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
+{
+ int n = 0;
+ ushort c;
+ while ((c = getChar())) {
+ switch (c) {
+ case '\n':
+ case ' ':
+ case '\t':
+ case '\r':
+ case '&':
+ case '#':
+ case '\'':
+ case '\"':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '=':
+ case '%':
+ case '/':
+ case ';':
+ case '?':
+ case '!':
+ case '^':
+ case '|':
+ case ',':
+ case '(':
+ case ')':
+ case '+':
+ case '*':
+ putChar(c);
+ if (prefix && *prefix == n+1) {
+ *prefix = 0;
+ putChar(':');
+ --n;
+ }
+ return n;
+ case ':':
+ if (prefix) {
+ if (*prefix == 0) {
+ *prefix = n+2;
+ } else { // only one colon allowed according to the namespace spec.
+ putChar(c);
+ return n;
+ }
+ } else {
+ putChar(c);
+ return n;
+ }
+ // fall through
+ default:
+ textBuffer += QChar(c);
+ ++n;
+ }
+ }
+
+ if (prefix)
+ *prefix = 0;
+ int pos = textBuffer.size() - n;
+ putString(textBuffer, pos);
+ textBuffer.resize(pos);
+ return 0;
+}
+
+enum NameChar { NameBeginning, NameNotBeginning, NotName };
+
+static const char Begi = static_cast<char>(NameBeginning);
+static const char NtBg = static_cast<char>(NameNotBeginning);
+static const char NotN = static_cast<char>(NotName);
+
+static const char nameCharTable[128] =
+{
+// 0x00
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+// 0x10
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+// 0x20 (0x2D is '-', 0x2E is '.')
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NtBg, NtBg, NotN,
+// 0x30 (0x30..0x39 are '0'..'9', 0x3A is ':')
+ NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg,
+ NtBg, NtBg, Begi, NotN, NotN, NotN, NotN, NotN,
+// 0x40 (0x41..0x5A are 'A'..'Z')
+ NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+// 0x50 (0x5F is '_')
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, NotN, NotN, NotN, NotN, Begi,
+// 0x60 (0x61..0x7A are 'a'..'z')
+ NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+// 0x70
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, NotN, NotN, NotN, NotN, NotN
+};
+
+static inline NameChar fastDetermineNameChar(QChar ch)
+{
+ ushort uc = ch.unicode();
+ if (!(uc & ~0x7f)) // uc < 128
+ return static_cast<NameChar>(nameCharTable[uc]);
+
+ QChar::Category cat = ch.category();
+ // ### some these categories might be slightly wrong
+ if ((cat >= QChar::Letter_Uppercase && cat <= QChar::Letter_Other)
+ || cat == QChar::Number_Letter)
+ return NameBeginning;
+ if ((cat >= QChar::Number_DecimalDigit && cat <= QChar::Number_Other)
+ || (cat >= QChar::Mark_NonSpacing && cat <= QChar::Mark_Enclosing))
+ return NameNotBeginning;
+ return NotName;
+}
+
+inline int QXmlStreamReaderPrivate::fastScanNMTOKEN()
+{
+ int n = 0;
+ uint c;
+ while ((c = getChar())) {
+ if (fastDetermineNameChar(c) == NotName) {
+ putChar(c);
+ return n;
+ } else {
+ ++n;
+ textBuffer += QChar(c);
+ }
+ }
+
+ int pos = textBuffer.size() - n;
+ putString(textBuffer, pos);
+ textBuffer.resize(pos);
+
+ return n;
+}
+
+void QXmlStreamReaderPrivate::putString(const QString &s, int from)
+{
+ putStack.reserve(s.size());
+ for (int i = s.size()-1; i >= from; --i)
+ putStack.rawPush() = s.at(i).unicode();
+}
+
+void QXmlStreamReaderPrivate::putStringLiteral(const QString &s)
+{
+ putStack.reserve(s.size());
+ for (int i = s.size()-1; i >= 0; --i)
+ putStack.rawPush() = ((LETTER << 16) | s.at(i).unicode());
+}
+
+void QXmlStreamReaderPrivate::putReplacement(const QString &s)
+{
+ putStack.reserve(s.size());
+ for (int i = s.size()-1; i >= 0; --i) {
+ ushort c = s.at(i).unicode();
+ if (c == '\n' || c == '\r')
+ putStack.rawPush() = ((LETTER << 16) | c);
+ else
+ putStack.rawPush() = c;
+ }
+}
+void QXmlStreamReaderPrivate::putReplacementInAttributeValue(const QString &s)
+{
+ putStack.reserve(s.size());
+ for (int i = s.size()-1; i >= 0; --i) {
+ ushort c = s.at(i).unicode();
+ if (c == '&' || c == ';')
+ putStack.rawPush() = c;
+ else if (c == '\n' || c == '\r')
+ putStack.rawPush() = ' ';
+ else
+ putStack.rawPush() = ((LETTER << 16) | c);
+ }
+}
+
+ushort QXmlStreamReaderPrivate::getChar_helper()
+{
+ const int BUFFER_SIZE = 8192;
+ characterOffset += readBufferPos;
+ readBufferPos = 0;
+ readBuffer.resize(0);
+#ifndef QT_NO_TEXTCODEC
+ if (decoder)
+#endif
+ nbytesread = 0;
+ if (device) {
+ rawReadBuffer.resize(BUFFER_SIZE);
+ int nbytesreadOrMinus1 = device->read(rawReadBuffer.data() + nbytesread, BUFFER_SIZE - nbytesread);
+ nbytesread += qMax(nbytesreadOrMinus1, 0);
+ } else {
+ if (nbytesread)
+ rawReadBuffer += dataBuffer;
+ else
+ rawReadBuffer = dataBuffer;
+ nbytesread = rawReadBuffer.size();
+ dataBuffer.clear();
+ }
+ if (!nbytesread) {
+ atEnd = true;
+ return 0;
+ }
+
+#ifndef QT_NO_TEXTCODEC
+ if (!decoder) {
+ if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus
+ // one extra for the utf8 codec
+ atEnd = true;
+ return 0;
+ }
+ int mib = 106; // UTF-8
+
+ // look for byte order mark
+ uchar ch1 = rawReadBuffer.at(0);
+ uchar ch2 = rawReadBuffer.at(1);
+ uchar ch3 = rawReadBuffer.at(2);
+ uchar ch4 = rawReadBuffer.at(3);
+
+ if ((ch1 == 0 && ch2 == 0 && ch3 == 0xfe && ch4 == 0xff) ||
+ (ch1 == 0xff && ch2 == 0xfe && ch3 == 0 && ch4 == 0))
+ mib = 1017; // UTF-32 with byte order mark
+ else if (ch1 == 0x3c && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x00)
+ mib = 1019; // UTF-32LE
+ else if (ch1 == 0x00 && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x3c)
+ mib = 1018; // UTF-32BE
+ else if ((ch1 == 0xfe && ch2 == 0xff) || (ch1 == 0xff && ch2 == 0xfe))
+ mib = 1015; // UTF-16 with byte order mark
+ else if (ch1 == 0x3c && ch2 == 0x00)
+ mib = 1014; // UTF-16LE
+ else if (ch1 == 0x00 && ch2 == 0x3c)
+ mib = 1013; // UTF-16BE
+ codec = QTextCodec::codecForMib(mib);
+ Q_ASSERT(codec);
+ decoder = codec->makeDecoder();
+ }
+
+ decoder->toUnicode(&readBuffer, rawReadBuffer.constData(), nbytesread);
+
+ if(lockEncoding && decoder->hasFailure()) {
+ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+ readBuffer.clear();
+ return 0;
+ }
+#else
+ readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
+#endif // QT_NO_TEXTCODEC
+
+ readBuffer.reserve(1); // keep capacity when calling resize() next time
+
+ if (readBufferPos < readBuffer.size()) {
+ ushort c = readBuffer.at(readBufferPos++).unicode();
+ return c;
+ }
+
+ atEnd = true;
+ return 0;
+}
+
+QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix)
+{
+ for (int j = namespaceDeclarations.size() - 1; j >= 0; --j) {
+ const NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.at(j);
+ if (namespaceDeclaration.prefix == prefix) {
+ return namespaceDeclaration.namespaceUri;
+ }
+ }
+
+#if 1
+ if (namespaceProcessing && !prefix.isEmpty())
+ raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix.toString()));
+#endif
+
+ return QStringRef();
+}
+
+/*
+ uses namespaceForPrefix and builds the attribute vector
+ */
+void QXmlStreamReaderPrivate::resolveTag()
+{
+ int n = attributeStack.size();
+
+ if (namespaceProcessing) {
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (!dtdAttribute.isNamespaceAttribute
+ || dtdAttribute.defaultValue.isNull()
+ || dtdAttribute.tagName != qualifiedName
+ || dtdAttribute.attributeQualifiedName.isNull())
+ continue;
+ int i = 0;
+ while (i < n && symName(attributeStack[i].key) != dtdAttribute.attributeQualifiedName)
+ ++i;
+ if (i != n)
+ continue;
+ if (dtdAttribute.attributePrefix.isEmpty() && dtdAttribute.attributeName == QLatin1String("xmlns")) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+
+ const QStringRef ns(dtdAttribute.defaultValue);
+ if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+ ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+ else
+ namespaceDeclaration.namespaceUri = ns;
+ } else if (dtdAttribute.attributePrefix == QLatin1String("xmlns")) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ QStringRef namespacePrefix = dtdAttribute.attributeName;
+ QStringRef namespaceUri = dtdAttribute.defaultValue;
+ if (((namespacePrefix == QLatin1String("xml"))
+ ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+ || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+ || namespaceUri.isEmpty()
+ || namespacePrefix == QLatin1String("xmlns"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+ namespaceDeclaration.prefix = namespacePrefix;
+ namespaceDeclaration.namespaceUri = namespaceUri;
+ }
+ }
+ }
+
+ tagStack.top().namespaceDeclaration.namespaceUri = namespaceUri = namespaceForPrefix(prefix);
+
+ attributes.resize(n);
+
+ for (int i = 0; i < n; ++i) {
+ QXmlStreamAttribute &attribute = attributes[i];
+ Attribute &attrib = attributeStack[i];
+ QStringRef prefix(symPrefix(attrib.key));
+ QStringRef name(symString(attrib.key));
+ QStringRef qualifiedName(symName(attrib.key));
+ QStringRef value(symString(attrib.value));
+
+ attribute.m_name = QXmlStreamStringRef(name);
+ attribute.m_qualifiedName = QXmlStreamStringRef(qualifiedName);
+ attribute.m_value = QXmlStreamStringRef(value);
+
+ if (!prefix.isEmpty()) {
+ QStringRef attributeNamespaceUri = namespaceForPrefix(prefix);
+ attribute.m_namespaceUri = QXmlStreamStringRef(attributeNamespaceUri);
+ }
+
+ for (int j = 0; j < i; ++j) {
+ if (attributes[j].name() == attribute.name()
+ && attributes[j].namespaceUri() == attribute.namespaceUri()
+ && (namespaceProcessing || attributes[j].qualifiedName() == attribute.qualifiedName()))
+ raiseWellFormedError(QXmlStream::tr("Attribute redefined."));
+ }
+ }
+
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (dtdAttribute.isNamespaceAttribute
+ || dtdAttribute.defaultValue.isNull()
+ || dtdAttribute.tagName != qualifiedName
+ || dtdAttribute.attributeQualifiedName.isNull())
+ continue;
+ int i = 0;
+ while (i < n && symName(attributeStack[i].key) != dtdAttribute.attributeQualifiedName)
+ ++i;
+ if (i != n)
+ continue;
+
+
+
+ QXmlStreamAttribute attribute;
+ attribute.m_name = QXmlStreamStringRef(dtdAttribute.attributeName);
+ attribute.m_qualifiedName = QXmlStreamStringRef(dtdAttribute.attributeQualifiedName);
+ attribute.m_value = QXmlStreamStringRef(dtdAttribute.defaultValue);
+
+ if (!dtdAttribute.attributePrefix.isEmpty()) {
+ QStringRef attributeNamespaceUri = namespaceForPrefix(dtdAttribute.attributePrefix);
+ attribute.m_namespaceUri = QXmlStreamStringRef(attributeNamespaceUri);
+ }
+ attribute.m_isDefault = true;
+ attributes.append(attribute);
+ }
+
+ attributeStack.clear();
+}
+
+void QXmlStreamReaderPrivate::resolvePublicNamespaces()
+{
+ const Tag &tag = tagStack.top();
+ int n = namespaceDeclarations.size() - tag.namespaceDeclarationsSize;
+ publicNamespaceDeclarations.resize(n);
+ for (int i = 0; i < n; ++i) {
+ const NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.at(tag.namespaceDeclarationsSize + i);
+ QXmlStreamNamespaceDeclaration &publicNamespaceDeclaration = publicNamespaceDeclarations[i];
+ publicNamespaceDeclaration.m_prefix = QXmlStreamStringRef(namespaceDeclaration.prefix);
+ publicNamespaceDeclaration.m_namespaceUri = QXmlStreamStringRef(namespaceDeclaration.namespaceUri);
+ }
+}
+
+void QXmlStreamReaderPrivate::resolveDtd()
+{
+ publicNotationDeclarations.resize(notationDeclarations.size());
+ for (int i = 0; i < notationDeclarations.size(); ++i) {
+ const QXmlStreamReaderPrivate::NotationDeclaration &notationDeclaration = notationDeclarations.at(i);
+ QXmlStreamNotationDeclaration &publicNotationDeclaration = publicNotationDeclarations[i];
+ publicNotationDeclaration.m_name = QXmlStreamStringRef(notationDeclaration.name);
+ publicNotationDeclaration.m_systemId = QXmlStreamStringRef(notationDeclaration.systemId);
+ publicNotationDeclaration.m_publicId = QXmlStreamStringRef(notationDeclaration.publicId);
+
+ }
+ notationDeclarations.clear();
+ publicEntityDeclarations.resize(entityDeclarations.size());
+ for (int i = 0; i < entityDeclarations.size(); ++i) {
+ const QXmlStreamReaderPrivate::EntityDeclaration &entityDeclaration = entityDeclarations.at(i);
+ QXmlStreamEntityDeclaration &publicEntityDeclaration = publicEntityDeclarations[i];
+ publicEntityDeclaration.m_name = QXmlStreamStringRef(entityDeclaration.name);
+ publicEntityDeclaration.m_notationName = QXmlStreamStringRef(entityDeclaration.notationName);
+ publicEntityDeclaration.m_systemId = QXmlStreamStringRef(entityDeclaration.systemId);
+ publicEntityDeclaration.m_publicId = QXmlStreamStringRef(entityDeclaration.publicId);
+ publicEntityDeclaration.m_value = QXmlStreamStringRef(entityDeclaration.value);
+ }
+ entityDeclarations.clear();
+ parameterEntityHash.clear();
+}
+
+uint QXmlStreamReaderPrivate::resolveCharRef(int symbolIndex)
+{
+ bool ok = true;
+ uint s;
+ // ### add toXShort to QStringRef?
+ if (sym(symbolIndex).c == 'x')
+ s = symString(symbolIndex, 1).toString().toUInt(&ok, 16);
+ else
+ s = symString(symbolIndex).toString().toUInt(&ok, 10);
+
+ ok &= (s == 0x9 || s == 0xa || s == 0xd || (s >= 0x20 && s <= 0xd7ff)
+ || (s >= 0xe000 && s <= 0xfffd) || (s >= 0x10000 && s <= 0x10ffff));
+
+ return ok ? s : 0;
+}
+
+
+void QXmlStreamReaderPrivate::checkPublicLiteral(const QStringRef &publicId)
+{
+//#x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+
+ const ushort *data = reinterpret_cast<const ushort *>(publicId.constData());
+ uchar c = 0;
+ int i;
+ for (i = publicId.size() - 1; i >= 0; --i) {
+ if (data[i] < 256)
+ switch ((c = data[i])) {
+ case ' ': case '\n': case '\r': case '-': case '(': case ')':
+ case '+': case ',': case '.': case '/': case ':': case '=':
+ case '?': case ';': case '!': case '*': case '#': case '@':
+ case '$': case '_': case '%': case '\'': case '\"':
+ continue;
+ default:
+ if ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9'))
+ continue;
+ }
+ break;
+ }
+ if (i >= 0)
+ raiseWellFormedError(QXmlStream::tr("Unexpected character '%1' in public id literal.").arg(QChar(QLatin1Char(c))));
+}
+
+/*
+ Checks whether the document starts with an xml declaration. If it
+ does, this function returns true; otherwise it sets up everything
+ for a synthetic start document event and returns false.
+ */
+bool QXmlStreamReaderPrivate::checkStartDocument()
+{
+ hasCheckedStartDocument = true;
+
+ if (scanString(spell[XML], XML))
+ return true;
+
+ type = QXmlStreamReader::StartDocument;
+ if (atEnd) {
+ hasCheckedStartDocument = false;
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ }
+ return false;
+}
+
+void QXmlStreamReaderPrivate::startDocument()
+{
+ QString err;
+ if (documentVersion != QLatin1String("1.0")) {
+ if (documentVersion.toString().contains(QLatin1Char(' ')))
+ err = QXmlStream::tr("Invalid XML version string.");
+ else
+ err = QXmlStream::tr("Unsupported XML version.");
+ }
+ int n = attributeStack.size();
+
+ /* We use this bool to ensure that the pesudo attributes are in the
+ * proper order:
+ *
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */
+ bool hasStandalone = false;
+
+ for (int i = 0; err.isNull() && i < n; ++i) {
+ Attribute &attrib = attributeStack[i];
+ QStringRef prefix(symPrefix(attrib.key));
+ QStringRef key(symString(attrib.key));
+ QStringRef value(symString(attrib.value));
+
+ if (prefix.isEmpty() && key == QLatin1String("encoding")) {
+ const QString name(value.toString());
+ documentEncoding = value;
+
+ if(hasStandalone)
+ err = QXmlStream::tr("The standalone pseudo attribute must appear after the encoding.");
+ if(!QXmlUtils::isEncName(name))
+ err = QXmlStream::tr("%1 is an invalid encoding name.").arg(name);
+ else {
+#ifdef QT_NO_TEXTCODEC
+ readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
+#else
+ QTextCodec *const newCodec = QTextCodec::codecForName(name.toLatin1());
+ if (!newCodec)
+ err = QXmlStream::tr("Encoding %1 is unsupported").arg(name);
+ else if (newCodec != codec && !lockEncoding) {
+ codec = newCodec;
+ delete decoder;
+ decoder = codec->makeDecoder();
+ decoder->toUnicode(&readBuffer, rawReadBuffer.data(), nbytesread);
+ }
+#endif // QT_NO_TEXTCODEC
+ }
+ } else if (prefix.isEmpty() && key == QLatin1String("standalone")) {
+ hasStandalone = true;
+ if (value == QLatin1String("yes"))
+ standalone = true;
+ else if (value == QLatin1String("no"))
+ standalone = false;
+ else
+ err = QXmlStream::tr("Standalone accepts only yes or no.");
+ } else {
+ err = QXmlStream::tr("Invalid attribute in XML declaration.");
+ }
+ }
+
+ if (!err.isNull())
+ raiseWellFormedError(err);
+ attributeStack.clear();
+}
+
+
+void QXmlStreamReaderPrivate::raiseError(QXmlStreamReader::Error error, const QString& message)
+{
+ this->error = error;
+ errorString = message;
+ if (errorString.isNull()) {
+ if (error == QXmlStreamReader::PrematureEndOfDocumentError)
+ errorString = QXmlStream::tr("Premature end of document.");
+ else if (error == QXmlStreamReader::CustomError)
+ errorString = QXmlStream::tr("Invalid document.");
+ }
+
+ type = QXmlStreamReader::Invalid;
+}
+
+void QXmlStreamReaderPrivate::raiseWellFormedError(const QString &message)
+{
+ raiseError(QXmlStreamReader::NotWellFormedError, message);
+}
+
+void QXmlStreamReaderPrivate::parseError()
+{
+
+ if (token == EOF_SYMBOL) {
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ return;
+ }
+ const int nmax = 4;
+ QString error_message;
+ int ers = state_stack[tos];
+ int nexpected = 0;
+ int expected[nmax];
+ if (token != ERROR)
+ for (int tk = 0; tk < TERMINAL_COUNT; ++tk) {
+ int k = t_action(ers, tk);
+ if (k <= 0)
+ continue;
+ if (spell[tk]) {
+ if (nexpected < nmax)
+ expected[nexpected++] = tk;
+ }
+ }
+
+ error_message.clear ();
+ if (nexpected && nexpected < nmax) {
+ bool first = true;
+
+ for (int s = 0; s < nexpected; ++s) {
+ if (first)
+ error_message += QXmlStream::tr ("Expected ");
+ else if (s == nexpected - 1)
+ error_message += QLatin1String (nexpected > 2 ? ", or " : " or ");
+ else
+ error_message += QLatin1String (", ");
+
+ first = false;
+ error_message += QLatin1String("\'");
+ error_message += QLatin1String (spell [expected[s]]);
+ error_message += QLatin1String("\'");
+ }
+ error_message += QXmlStream::tr(", but got \'");
+ error_message += QLatin1String(spell [token]);
+ error_message += QLatin1String("\'");
+ } else {
+ error_message += QXmlStream::tr("Unexpected \'");
+ error_message += QLatin1String(spell [token]);
+ error_message += QLatin1String("\'");
+ }
+ error_message += QLatin1Char('.');
+
+ raiseWellFormedError(error_message);
+}
+
+void QXmlStreamReaderPrivate::resume(int rule) {
+ resumeReduction = rule;
+ if (error == QXmlStreamReader::NoError)
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+}
+
+/*! Returns the current line number, starting with 1.
+
+\sa columnNumber(), characterOffset()
+ */
+qint64 QXmlStreamReader::lineNumber() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->lineNumber + 1; // in public we start with 1
+}
+
+/*! Returns the current column number, starting with 0.
+
+\sa lineNumber(), characterOffset()
+ */
+qint64 QXmlStreamReader::columnNumber() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->characterOffset - d->lastLineStart + d->readBufferPos;
+}
+
+/*! Returns the current character offset, starting with 0.
+
+\sa lineNumber(), columnNumber()
+*/
+qint64 QXmlStreamReader::characterOffset() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->characterOffset + d->readBufferPos;
+}
+
+
+/*! Returns the text of \l Characters, \l Comment, \l DTD, or
+ EntityReference.
+ */
+QStringRef QXmlStreamReader::text() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->text;
+}
+
+
+/*! If the state() is \l DTD, this function returns the DTD's
+ notation declarations. Otherwise an empty vector is returned.
+
+ The QXmlStreamNotationDeclarations class is defined to be a QVector
+ of QXmlStreamNotationDeclaration.
+ */
+QXmlStreamNotationDeclarations QXmlStreamReader::notationDeclarations() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->notationDeclarations.size())
+ const_cast<QXmlStreamReaderPrivate *>(d)->resolveDtd();
+ return d->publicNotationDeclarations;
+}
+
+
+/*! If the state() is \l DTD, this function returns the DTD's
+ unparsed (external) entity declarations. Otherwise an empty vector is returned.
+
+ The QXmlStreamEntityDeclarations class is defined to be a QVector
+ of QXmlStreamEntityDeclaration.
+ */
+QXmlStreamEntityDeclarations QXmlStreamReader::entityDeclarations() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->entityDeclarations.size())
+ const_cast<QXmlStreamReaderPrivate *>(d)->resolveDtd();
+ return d->publicEntityDeclarations;
+}
+
+/*!
+ \since 4.4
+
+ If the state() is \l DTD, this function returns the DTD's
+ name. Otherwise an empty string is returned.
+
+ */
+QStringRef QXmlStreamReader::dtdName() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::DTD)
+ return d->dtdName;
+ return QStringRef();
+}
+
+/*!
+ \since 4.4
+
+ If the state() is \l DTD, this function returns the DTD's
+ public identifier. Otherwise an empty string is returned.
+
+ */
+QStringRef QXmlStreamReader::dtdPublicId() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::DTD)
+ return d->dtdPublicId;
+ return QStringRef();
+}
+
+/*!
+ \since 4.4
+
+ If the state() is \l DTD, this function returns the DTD's
+ system identifier. Otherwise an empty string is returned.
+
+ */
+QStringRef QXmlStreamReader::dtdSystemId() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::DTD)
+ return d->dtdSystemId;
+ return QStringRef();
+}
+
+/*! If the state() is \l StartElement, this function returns the
+ element's namespace declarations. Otherwise an empty vector is
+ returned.
+
+ The QXmlStreamNamespaceDeclaration class is defined to be a QVector
+ of QXmlStreamNamespaceDeclaration.
+
+ \sa addExtraNamespaceDeclaration(), addExtraNamespaceDeclarations()
+ */
+QXmlStreamNamespaceDeclarations QXmlStreamReader::namespaceDeclarations() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->publicNamespaceDeclarations.isEmpty() && d->type == StartElement)
+ const_cast<QXmlStreamReaderPrivate *>(d)->resolvePublicNamespaces();
+ return d->publicNamespaceDeclarations;
+}
+
+
+/*!
+ \since 4.4
+
+ Adds an \a extraNamespaceDeclaration. The declaration will be
+ valid for children of the current element, or - should the function
+ be called before any elements are read - for the entire XML
+ document.
+
+ \sa namespaceDeclarations(), addExtraNamespaceDeclarations(), setNamespaceProcessing()
+ */
+void QXmlStreamReader::addExtraNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &extraNamespaceDeclaration)
+{
+ Q_D(QXmlStreamReader);
+ QXmlStreamReaderPrivate::NamespaceDeclaration &namespaceDeclaration = d->namespaceDeclarations.push();
+ namespaceDeclaration.prefix = d->addToStringStorage(extraNamespaceDeclaration.prefix());
+ namespaceDeclaration.namespaceUri = d->addToStringStorage(extraNamespaceDeclaration.namespaceUri());
+}
+
+/*!
+ \since 4.4
+
+ Adds a vector of declarations specified by \a extraNamespaceDeclarations.
+
+ \sa namespaceDeclarations(), addExtraNamespaceDeclaration()
+ */
+void QXmlStreamReader::addExtraNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &extraNamespaceDeclarations)
+{
+ for (int i = 0; i < extraNamespaceDeclarations.size(); ++i)
+ addExtraNamespaceDeclaration(extraNamespaceDeclarations.at(i));
+}
+
+
+/*! Convenience function to be called in case a StartElement was
+ read. Reads until the corresponding EndElement and returns all text
+ in-between. In case of no error, the current token (see tokenType())
+ after having called this function is EndElement.
+
+ The function concatenates text() when it reads either \l Characters
+ or EntityReference tokens, but skips ProcessingInstruction and \l
+ Comment. If the current token is not StartElement, an empty string is
+ returned.
+
+ The \a behaviour defines what happens in case anything else is
+ read before reaching EndElement. The function can include the text from
+ child elements (useful for example for HTML), ignore child elements, or
+ raise an UnexpectedElementError and return what was read so far.
+
+ \since 4.6
+ */
+QString QXmlStreamReader::readElementText(ReadElementTextBehaviour behaviour)
+{
+ Q_D(QXmlStreamReader);
+ if (isStartElement()) {
+ QString result;
+ forever {
+ switch (readNext()) {
+ case Characters:
+ case EntityReference:
+ result.insert(result.size(), d->text.unicode(), d->text.size());
+ break;
+ case EndElement:
+ return result;
+ case ProcessingInstruction:
+ case Comment:
+ break;
+ case StartElement:
+ if (behaviour == SkipChildElements) {
+ skipCurrentElement();
+ break;
+ } else if (behaviour == IncludeChildElements) {
+ result += readElementText(behaviour);
+ break;
+ }
+ // Fall through (for ErrorOnUnexpectedElement)
+ default:
+ if (d->error || behaviour == ErrorOnUnexpectedElement) {
+ if (!d->error)
+ d->raiseError(UnexpectedElementError, QXmlStream::tr("Expected character data."));
+ return result;
+ }
+ }
+ }
+ }
+ return QString();
+}
+
+/*!
+ \overload readElementText()
+
+ Calling this function is equivalent to calling readElementText(ErrorOnUnexpectedElement).
+ */
+QString QXmlStreamReader::readElementText()
+{
+ return readElementText(ErrorOnUnexpectedElement);
+}
+
+/*! Raises a custom error with an optional error \a message.
+
+ \sa error(), errorString()
+ */
+void QXmlStreamReader::raiseError(const QString& message)
+{
+ Q_D(QXmlStreamReader);
+ d->raiseError(CustomError, message);
+}
+
+/*!
+ Returns the error message that was set with raiseError().
+
+ \sa error(), lineNumber(), columnNumber(), characterOffset()
+ */
+QString QXmlStreamReader::errorString() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::Invalid)
+ return d->errorString;
+ return QString();
+}
+
+/*! Returns the type of the current error, or NoError if no error occurred.
+
+ \sa errorString(), raiseError()
+ */
+QXmlStreamReader::Error QXmlStreamReader::error() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::Invalid)
+ return d->error;
+ return NoError;
+}
+
+/*!
+ Returns the target of a ProcessingInstruction.
+ */
+QStringRef QXmlStreamReader::processingInstructionTarget() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->processingInstructionTarget;
+}
+
+/*!
+ Returns the data of a ProcessingInstruction.
+ */
+QStringRef QXmlStreamReader::processingInstructionData() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->processingInstructionData;
+}
+
+
+
+/*!
+ Returns the local name of a StartElement, EndElement, or an EntityReference.
+
+ \sa namespaceUri(), qualifiedName()
+ */
+QStringRef QXmlStreamReader::name() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->name;
+}
+
+/*!
+ Returns the namespaceUri of a StartElement or EndElement.
+
+ \sa name(), qualifiedName()
+ */
+QStringRef QXmlStreamReader::namespaceUri() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->namespaceUri;
+}
+
+/*!
+ Returns the qualified name of a StartElement or EndElement;
+
+ A qualified name is the raw name of an element in the XML data. It
+ consists of the namespace prefix, followed by colon, followed by the
+ element's local name. Since the namespace prefix is not unique (the
+ same prefix can point to different namespaces and different prefixes
+ can point to the same namespace), you shouldn't use qualifiedName(),
+ but the resolved namespaceUri() and the attribute's local name().
+
+ \sa name(), prefix(), namespaceUri()
+ */
+QStringRef QXmlStreamReader::qualifiedName() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->qualifiedName;
+}
+
+
+
+/*!
+ \since 4.4
+
+ Returns the prefix of a StartElement or EndElement.
+
+ \sa name(), qualifiedName()
+*/
+QStringRef QXmlStreamReader::prefix() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->prefix;
+}
+
+/*!
+ Returns the attributes of a StartElement.
+ */
+QXmlStreamAttributes QXmlStreamReader::attributes() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->attributes;
+}
+
+#endif // QT_NO_XMLSTREAMREADER
+
+/*!
+ \class QXmlStreamAttribute
+ \since 4.3
+ \reentrant
+ \brief The QXmlStreamAttribute class represents a single XML attribute
+
+ \ingroup xml-tools
+
+ An attribute consists of an optionally empty namespaceUri(), a
+ name(), a value(), and an isDefault() attribute.
+
+ The raw XML attribute name is returned as qualifiedName().
+*/
+
+/*!
+ Creates an empty attribute.
+ */
+QXmlStreamAttribute::QXmlStreamAttribute()
+{
+ m_isDefault = false;
+}
+
+/*!
+ Destructs an attribute.
+ */
+QXmlStreamAttribute::~QXmlStreamAttribute()
+{
+}
+
+/*! Constructs an attribute in the namespace described with \a
+ namespaceUri with \a name and value \a value.
+ */
+QXmlStreamAttribute::QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value)
+{
+ m_namespaceUri = QXmlStreamStringRef(QStringRef(&namespaceUri));
+ m_name = m_qualifiedName = QXmlStreamStringRef(QStringRef(&name));
+ m_value = QXmlStreamStringRef(QStringRef(&value));
+ m_namespaceUri = QXmlStreamStringRef(QStringRef(&namespaceUri));
+}
+
+/*!
+ Constructs an attribute with qualified name \a qualifiedName and value \a value.
+ */
+QXmlStreamAttribute::QXmlStreamAttribute(const QString &qualifiedName, const QString &value)
+{
+ int colon = qualifiedName.indexOf(QLatin1Char(':'));
+ m_name = QXmlStreamStringRef(QStringRef(&qualifiedName,
+ colon + 1,
+ qualifiedName.size() - (colon + 1)));
+ m_qualifiedName = QXmlStreamStringRef(QStringRef(&qualifiedName));
+ m_value = QXmlStreamStringRef(QStringRef(&value));
+}
+
+/*! \fn QStringRef QXmlStreamAttribute::namespaceUri() const
+
+ Returns the attribute's resolved namespaceUri, or an empty string
+ reference if the attribute does not have a defined namespace.
+ */
+/*! \fn QStringRef QXmlStreamAttribute::name() const
+ Returns the attribute's local name.
+ */
+/*! \fn QStringRef QXmlStreamAttribute::qualifiedName() const
+ Returns the attribute's qualified name.
+
+ A qualified name is the raw name of an attribute in the XML
+ data. It consists of the namespace prefix(), followed by colon,
+ followed by the attribute's local name(). Since the namespace prefix
+ is not unique (the same prefix can point to different namespaces
+ and different prefixes can point to the same namespace), you
+ shouldn't use qualifiedName(), but the resolved namespaceUri() and
+ the attribute's local name().
+ */
+/*!
+ \fn QStringRef QXmlStreamAttribute::prefix() const
+ \since 4.4
+ Returns the attribute's namespace prefix.
+
+ \sa name(), qualifiedName()
+
+*/
+
+/*! \fn QStringRef QXmlStreamAttribute::value() const
+ Returns the attribute's value.
+ */
+
+/*! \fn bool QXmlStreamAttribute::isDefault() const
+
+ Returns true if the parser added this attribute with a default
+ value following an ATTLIST declaration in the DTD; otherwise
+ returns false.
+*/
+/*! \fn bool QXmlStreamAttribute::operator==(const QXmlStreamAttribute &other) const
+
+ Compares this attribute with \a other and returns true if they are
+ equal; otherwise returns false.
+ */
+/*! \fn bool QXmlStreamAttribute::operator!=(const QXmlStreamAttribute &other) const
+
+ Compares this attribute with \a other and returns true if they are
+ not equal; otherwise returns false.
+ */
+
+
+/*!
+ Creates a copy of \a other.
+ */
+QXmlStreamAttribute::QXmlStreamAttribute(const QXmlStreamAttribute &other)
+{
+ *this = other;
+}
+
+/*!
+ Assigns \a other to this attribute.
+ */
+QXmlStreamAttribute& QXmlStreamAttribute::operator=(const QXmlStreamAttribute &other)
+{
+ m_name = other.m_name;
+ m_namespaceUri = other.m_namespaceUri;
+ m_qualifiedName = other.m_qualifiedName;
+ m_value = other.m_value;
+ m_isDefault = other.m_isDefault;
+ return *this;
+}
+
+
+/*!
+ \class QXmlStreamAttributes
+ \since 4.3
+ \reentrant
+ \brief The QXmlStreamAttributes class represents a vector of QXmlStreamAttribute.
+
+ Attributes are returned by a QXmlStreamReader in
+ \l{QXmlStreamReader::attributes()} {attributes()} when the reader
+ reports a \l {QXmlStreamReader::StartElement}{start element}. The
+ class can also be used with a QXmlStreamWriter as an argument to
+ \l {QXmlStreamWriter::writeAttributes()}{writeAttributes()}.
+
+ The convenience function value() loops over the vector and returns
+ an attribute value for a given namespaceUri and an attribute's
+ name.
+
+ New attributes can be added with append().
+
+ \ingroup xml-tools
+*/
+
+/*!
+ \fn void QXmlStreamAttributes::append(const QXmlStreamAttribute &attribute)
+
+ Appends the given \a attribute to the end of the vector.
+
+ \sa QVector::append()
+*/
+
+
+/*!
+ \typedef QXmlStreamNotationDeclarations
+ \relates QXmlStreamNotationDeclaration
+
+ Synonym for QVector<QXmlStreamNotationDeclaration>.
+*/
+
+
+/*!
+ \class QXmlStreamNotationDeclaration
+ \since 4.3
+ \reentrant
+ \brief The QXmlStreamNotationDeclaration class represents a DTD notation declaration.
+
+ \ingroup xml-tools
+
+ An notation declaration consists of a name(), a systemId(), and a publicId().
+*/
+
+/*!
+ Creates an empty notation declaration.
+*/
+QXmlStreamNotationDeclaration::QXmlStreamNotationDeclaration()
+{
+}
+/*!
+ Creates a copy of \a other.
+ */
+QXmlStreamNotationDeclaration::QXmlStreamNotationDeclaration(const QXmlStreamNotationDeclaration &other)
+{
+ *this = other;
+}
+
+/*!
+ Assigns \a other to this notation declaration.
+ */
+QXmlStreamNotationDeclaration& QXmlStreamNotationDeclaration::operator=(const QXmlStreamNotationDeclaration &other)
+{
+ m_name = other.m_name;
+ m_systemId = other.m_systemId;
+ m_publicId = other.m_publicId;
+ return *this;
+}
+
+/*!
+Destructs this notation declaration.
+*/
+QXmlStreamNotationDeclaration::~QXmlStreamNotationDeclaration()
+{
+}
+
+/*! \fn QStringRef QXmlStreamNotationDeclaration::name() const
+
+Returns the notation name.
+*/
+/*! \fn QStringRef QXmlStreamNotationDeclaration::systemId() const
+
+Returns the system identifier.
+*/
+/*! \fn QStringRef QXmlStreamNotationDeclaration::publicId() const
+
+Returns the public identifier.
+*/
+
+/*! \fn inline bool QXmlStreamNotationDeclaration::operator==(const QXmlStreamNotationDeclaration &other) const
+
+ Compares this notation declaration with \a other and returns true
+ if they are equal; otherwise returns false.
+ */
+/*! \fn inline bool QXmlStreamNotationDeclaration::operator!=(const QXmlStreamNotationDeclaration &other) const
+
+ Compares this notation declaration with \a other and returns true
+ if they are not equal; otherwise returns false.
+ */
+
+/*!
+ \typedef QXmlStreamNamespaceDeclarations
+ \relates QXmlStreamNamespaceDeclaration
+
+ Synonym for QVector<QXmlStreamNamespaceDeclaration>.
+*/
+
+/*!
+ \class QXmlStreamNamespaceDeclaration
+ \since 4.3
+ \reentrant
+ \brief The QXmlStreamNamespaceDeclaration class represents a namespace declaration.
+
+ \ingroup xml-tools
+
+ An namespace declaration consists of a prefix() and a namespaceUri().
+*/
+/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator==(const QXmlStreamNamespaceDeclaration &other) const
+
+ Compares this namespace declaration with \a other and returns true
+ if they are equal; otherwise returns false.
+ */
+/*! \fn inline bool QXmlStreamNamespaceDeclaration::operator!=(const QXmlStreamNamespaceDeclaration &other) const
+
+ Compares this namespace declaration with \a other and returns true
+ if they are not equal; otherwise returns false.
+ */
+
+/*!
+ Creates an empty namespace declaration.
+*/
+QXmlStreamNamespaceDeclaration::QXmlStreamNamespaceDeclaration()
+{
+}
+
+/*!
+ \since 4.4
+
+ Creates a namespace declaration with \a prefix and \a namespaceUri.
+*/
+QXmlStreamNamespaceDeclaration::QXmlStreamNamespaceDeclaration(const QString &prefix, const QString &namespaceUri)
+{
+ m_prefix = prefix;
+ m_namespaceUri = namespaceUri;
+}
+
+/*!
+ Creates a copy of \a other.
+ */
+QXmlStreamNamespaceDeclaration::QXmlStreamNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &other)
+{
+ *this = other;
+}
+
+/*!
+ Assigns \a other to this namespace declaration.
+ */
+QXmlStreamNamespaceDeclaration& QXmlStreamNamespaceDeclaration::operator=(const QXmlStreamNamespaceDeclaration &other)
+{
+ m_prefix = other.m_prefix;
+ m_namespaceUri = other.m_namespaceUri;
+ return *this;
+}
+/*!
+Destructs this namespace declaration.
+*/
+QXmlStreamNamespaceDeclaration::~QXmlStreamNamespaceDeclaration()
+{
+}
+
+/*! \fn QStringRef QXmlStreamNamespaceDeclaration::prefix() const
+
+Returns the prefix.
+*/
+/*! \fn QStringRef QXmlStreamNamespaceDeclaration::namespaceUri() const
+
+Returns the namespaceUri.
+*/
+
+
+
+
+/*!
+ \typedef QXmlStreamEntityDeclarations
+ \relates QXmlStreamEntityDeclaration
+
+ Synonym for QVector<QXmlStreamEntityDeclaration>.
+*/
+
+/*!
+ \class QXmlStreamStringRef
+ \since 4.3
+ \internal
+*/
+
+/*!
+ \class QXmlStreamEntityDeclaration
+ \since 4.3
+ \reentrant
+ \brief The QXmlStreamEntityDeclaration class represents a DTD entity declaration.
+
+ \ingroup xml-tools
+
+ An entity declaration consists of a name(), a notationName(), a
+ systemId(), a publicId(), and a value().
+*/
+
+/*!
+ Creates an empty entity declaration.
+*/
+QXmlStreamEntityDeclaration::QXmlStreamEntityDeclaration()
+{
+}
+
+/*!
+ Creates a copy of \a other.
+ */
+QXmlStreamEntityDeclaration::QXmlStreamEntityDeclaration(const QXmlStreamEntityDeclaration &other)
+{
+ *this = other;
+}
+
+/*!
+ Assigns \a other to this entity declaration.
+ */
+QXmlStreamEntityDeclaration& QXmlStreamEntityDeclaration::operator=(const QXmlStreamEntityDeclaration &other)
+{
+ m_name = other.m_name;
+ m_notationName = other.m_notationName;
+ m_systemId = other.m_systemId;
+ m_publicId = other.m_publicId;
+ m_value = other.m_value;
+ return *this;
+}
+
+/*!
+ Destructs this entity declaration.
+*/
+QXmlStreamEntityDeclaration::~QXmlStreamEntityDeclaration()
+{
+}
+
+/*! \fn QStringRef QXmlStreamEntityDeclaration::name() const
+
+Returns the entity name.
+*/
+/*! \fn QStringRef QXmlStreamEntityDeclaration::notationName() const
+
+Returns the notation name.
+*/
+/*! \fn QStringRef QXmlStreamEntityDeclaration::systemId() const
+
+Returns the system identifier.
+*/
+/*! \fn QStringRef QXmlStreamEntityDeclaration::publicId() const
+
+Returns the public identifier.
+*/
+/*! \fn QStringRef QXmlStreamEntityDeclaration::value() const
+
+Returns the entity's value.
+*/
+
+/*! \fn bool QXmlStreamEntityDeclaration::operator==(const QXmlStreamEntityDeclaration &other) const
+
+ Compares this entity declaration with \a other and returns true if
+ they are equal; otherwise returns false.
+ */
+/*! \fn bool QXmlStreamEntityDeclaration::operator!=(const QXmlStreamEntityDeclaration &other) const
+
+ Compares this entity declaration with \a other and returns true if
+ they are not equal; otherwise returns false.
+ */
+
+/*! Returns the value of the attribute \a name in the namespace
+ described with \a namespaceUri, or an empty string reference if the
+ attribute is not defined. The \a namespaceUri can be empty.
+ */
+QStringRef QXmlStreamAttributes::value(const QString &namespaceUri, const QString &name) const
+{
+ for (int i = 0; i < size(); ++i) {
+ const QXmlStreamAttribute &attribute = at(i);
+ if (attribute.name() == name && attribute.namespaceUri() == namespaceUri)
+ return attribute.value();
+ }
+ return QStringRef();
+}
+
+/*!\overload
+ Returns the value of the attribute \a name in the namespace
+ described with \a namespaceUri, or an empty string reference if the
+ attribute is not defined. The \a namespaceUri can be empty.
+ */
+QStringRef QXmlStreamAttributes::value(const QString &namespaceUri, const QLatin1String &name) const
+{
+ for (int i = 0; i < size(); ++i) {
+ const QXmlStreamAttribute &attribute = at(i);
+ if (attribute.name() == name && attribute.namespaceUri() == namespaceUri)
+ return attribute.value();
+ }
+ return QStringRef();
+}
+
+/*!\overload
+ Returns the value of the attribute \a name in the namespace
+ described with \a namespaceUri, or an empty string reference if the
+ attribute is not defined. The \a namespaceUri can be empty.
+ */
+QStringRef QXmlStreamAttributes::value(const QLatin1String &namespaceUri, const QLatin1String &name) const
+{
+ for (int i = 0; i < size(); ++i) {
+ const QXmlStreamAttribute &attribute = at(i);
+ if (attribute.name() == name && attribute.namespaceUri() == namespaceUri)
+ return attribute.value();
+ }
+ return QStringRef();
+}
+
+/*!\overload
+
+ Returns the value of the attribute with qualified name \a
+ qualifiedName , or an empty string reference if the attribute is not
+ defined. A qualified name is the raw name of an attribute in the XML
+ data. It consists of the namespace prefix, followed by colon,
+ followed by the attribute's local name. Since the namespace prefix
+ is not unique (the same prefix can point to different namespaces and
+ different prefixes can point to the same namespace), you shouldn't
+ use qualified names, but a resolved namespaceUri and the attribute's
+ local name.
+ */
+QStringRef QXmlStreamAttributes::value(const QString &qualifiedName) const
+{
+ for (int i = 0; i < size(); ++i) {
+ const QXmlStreamAttribute &attribute = at(i);
+ if (attribute.qualifiedName() == qualifiedName)
+ return attribute.value();
+ }
+ return QStringRef();
+}
+
+/*!\overload
+
+ Returns the value of the attribute with qualified name \a
+ qualifiedName , or an empty string reference if the attribute is not
+ defined. A qualified name is the raw name of an attribute in the XML
+ data. It consists of the namespace prefix, followed by colon,
+ followed by the attribute's local name. Since the namespace prefix
+ is not unique (the same prefix can point to different namespaces and
+ different prefixes can point to the same namespace), you shouldn't
+ use qualified names, but a resolved namespaceUri and the attribute's
+ local name.
+ */
+QStringRef QXmlStreamAttributes::value(const QLatin1String &qualifiedName) const
+{
+ for (int i = 0; i < size(); ++i) {
+ const QXmlStreamAttribute &attribute = at(i);
+ if (attribute.qualifiedName() == qualifiedName)
+ return attribute.value();
+ }
+ return QStringRef();
+}
+
+/*!Appends a new attribute with \a name in the namespace
+ described with \a namespaceUri, and value \a value. The \a
+ namespaceUri can be empty.
+ */
+void QXmlStreamAttributes::append(const QString &namespaceUri, const QString &name, const QString &value)
+{
+ append(QXmlStreamAttribute(namespaceUri, name, value));
+}
+
+/*!\overload
+ Appends a new attribute with qualified name \a qualifiedName and
+ value \a value.
+ */
+void QXmlStreamAttributes::append(const QString &qualifiedName, const QString &value)
+{
+ append(QXmlStreamAttribute(qualifiedName, value));
+}
+
+#ifndef QT_NO_XMLSTREAMREADER
+
+/*! \fn bool QXmlStreamReader::isStartDocument() const
+ Returns true if tokenType() equals \l StartDocument; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isEndDocument() const
+ Returns true if tokenType() equals \l EndDocument; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isStartElement() const
+ Returns true if tokenType() equals \l StartElement; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isEndElement() const
+ Returns true if tokenType() equals \l EndElement; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isCharacters() const
+ Returns true if tokenType() equals \l Characters; otherwise returns false.
+
+ \sa isWhitespace(), isCDATA()
+*/
+/*! \fn bool QXmlStreamReader::isComment() const
+ Returns true if tokenType() equals \l Comment; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isDTD() const
+ Returns true if tokenType() equals \l DTD; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isEntityReference() const
+ Returns true if tokenType() equals \l EntityReference; otherwise returns false.
+*/
+/*! \fn bool QXmlStreamReader::isProcessingInstruction() const
+ Returns true if tokenType() equals \l ProcessingInstruction; otherwise returns false.
+*/
+
+/*! Returns true if the reader reports characters that only consist
+ of white-space; otherwise returns false.
+
+ \sa isCharacters(), text()
+*/
+bool QXmlStreamReader::isWhitespace() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->type == QXmlStreamReader::Characters && d->isWhitespace;
+}
+
+/*! Returns true if the reader reports characters that stem from a
+ CDATA section; otherwise returns false.
+
+ \sa isCharacters(), text()
+*/
+bool QXmlStreamReader::isCDATA() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->type == QXmlStreamReader::Characters && d->isCDATA;
+}
+
+
+
+/*!
+ Returns true if this document has been declared standalone in the
+ XML declaration; otherwise returns false.
+
+ If no XML declaration has been parsed, this function returns false.
+ */
+bool QXmlStreamReader::isStandaloneDocument() const
+{
+ Q_D(const QXmlStreamReader);
+ return d->standalone;
+}
+
+
+/*!
+ \since 4.4
+
+ If the state() is \l StartDocument, this function returns the
+ version string as specified in the XML declaration.
+ Otherwise an empty string is returned.
+ */
+QStringRef QXmlStreamReader::documentVersion() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::StartDocument)
+ return d->documentVersion;
+ return QStringRef();
+}
+
+/*!
+ \since 4.4
+
+ If the state() is \l StartDocument, this function returns the
+ encoding string as specified in the XML declaration.
+ Otherwise an empty string is returned.
+ */
+QStringRef QXmlStreamReader::documentEncoding() const
+{
+ Q_D(const QXmlStreamReader);
+ if (d->type == QXmlStreamReader::StartDocument)
+ return d->documentEncoding;
+ return QStringRef();
+}
+
+#endif // QT_NO_XMLSTREAMREADER
+
+/*!
+ \class QXmlStreamWriter
+ \since 4.3
+ \reentrant
+
+ \brief The QXmlStreamWriter class provides an XML writer with a
+ simple streaming API.
+
+ \ingroup xml-tools
+
+ QXmlStreamWriter is the counterpart to QXmlStreamReader for writing
+ XML. Like its related class, it operates on a QIODevice specified
+ with setDevice(). The API is simple and straightforward: for every
+ XML token or event you want to write, the writer provides a
+ specialized function.
+
+ You start a document with writeStartDocument() and end it with
+ writeEndDocument(). This will implicitly close all remaining open
+ tags.
+
+ Element tags are opened with writeStartElement() followed by
+ writeAttribute() or writeAttributes(), element content, and then
+ writeEndElement(). A shorter form writeEmptyElement() can be used
+ to write empty elements, followed by writeAttributes().
+
+ Element content consists of either characters, entity references or
+ nested elements. It is written with writeCharacters(), which also
+ takes care of escaping all forbidden characters and character
+ sequences, writeEntityReference(), or subsequent calls to
+ writeStartElement(). A convenience method writeTextElement() can be
+ used for writing terminal elements that contain nothing but text.
+
+ The following abridged code snippet shows the basic use of the class
+ to write formatted XML with indentation:
+
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp start stream
+ \dots
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp write element
+ \dots
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp finish stream
+
+ QXmlStreamWriter takes care of prefixing namespaces, all you have to
+ do is specify the \c namespaceUri when writing elements or
+ attributes. If you must conform to certain prefixes, you can force
+ the writer to use them by declaring the namespaces manually with
+ either writeNamespace() or writeDefaultNamespace(). Alternatively,
+ you can bypass the stream writer's namespace support and use
+ overloaded methods that take a qualified name instead. The namespace
+ \e http://www.w3.org/XML/1998/namespace is implicit and mapped to the
+ prefix \e xml.
+
+ The stream writer can automatically format the generated XML data by
+ adding line-breaks and indentation to empty sections between
+ elements, making the XML data more readable for humans and easier to
+ work with for most source code management systems. The feature can
+ be turned on with the \l autoFormatting property, and customized
+ with the \l autoFormattingIndent property.
+
+ Other functions are writeCDATA(), writeComment(),
+ writeProcessingInstruction(), and writeDTD(). Chaining of XML
+ streams is supported with writeCurrentToken().
+
+ By default, QXmlStreamWriter encodes XML in UTF-8. Different
+ encodings can be enforced using setCodec().
+
+ If an error occurs while writing to the underlying device, hasError()
+ starts returning true and subsequent writes are ignored.
+
+ The \l{QXmlStream Bookmarks Example} illustrates how to use a
+ stream writer to write an XML bookmark file (XBEL) that
+ was previously read in by a QXmlStreamReader.
+
+*/
+
+#ifndef QT_NO_XMLSTREAMWRITER
+
+class QXmlStreamWriterPrivate : public QXmlStreamPrivateTagStack {
+ QXmlStreamWriter *q_ptr;
+ Q_DECLARE_PUBLIC(QXmlStreamWriter)
+public:
+ QXmlStreamWriterPrivate(QXmlStreamWriter *q);
+ ~QXmlStreamWriterPrivate() {
+ if (deleteDevice)
+ delete device;
+#ifndef QT_NO_TEXTCODEC
+ delete encoder;
+#endif
+ }
+
+ void write(const QStringRef &);
+ void write(const QString &);
+ void writeEscaped(const QString &, bool escapeWhitespace = false);
+ void write(const char *s, int len);
+ template <int N> void write(const char (&s)[N]) { write(s, N - 1); }
+ bool finishStartElement(bool contents = true);
+ void writeStartElement(const QString &namespaceUri, const QString &name);
+ QIODevice *device;
+ QString *stringDevice;
+ uint deleteDevice :1;
+ uint inStartElement :1;
+ uint inEmptyElement :1;
+ uint lastWasStartElement :1;
+ uint wroteSomething :1;
+ uint hasError :1;
+ uint autoFormatting :1;
+ QByteArray autoFormattingIndent;
+ NamespaceDeclaration emptyNamespace;
+ int lastNamespaceDeclaration;
+
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+ QTextEncoder *encoder;
+#endif
+
+ NamespaceDeclaration &findNamespace(const QString &namespaceUri, bool writeDeclaration = false, bool noDefault = false);
+ void writeNamespaceDeclaration(const NamespaceDeclaration &namespaceDeclaration);
+
+ int namespacePrefixCount;
+
+ void indent(int level);
+};
+
+
+QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
+ :autoFormattingIndent(4, ' ')
+{
+ q_ptr = q;
+ device = 0;
+ stringDevice = 0;
+ deleteDevice = false;
+#ifndef QT_NO_TEXTCODEC
+ codec = QTextCodec::codecForMib(106); // utf8
+ encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8
+#endif
+ inStartElement = inEmptyElement = false;
+ wroteSomething = false;
+ hasError = false;
+ lastWasStartElement = false;
+ lastNamespaceDeclaration = 1;
+ autoFormatting = false;
+ namespacePrefixCount = 0;
+}
+
+void QXmlStreamWriterPrivate::write(const QStringRef &s)
+{
+ if (device) {
+ if (hasError)
+ return;
+#ifdef QT_NO_TEXTCODEC
+ QByteArray bytes = s.toLatin1();
+#else
+ QByteArray bytes = encoder->fromUnicode(s.constData(), s.size());
+#endif
+ if (device->write(bytes) != bytes.size())
+ hasError = true;
+ }
+ else if (stringDevice)
+ s.appendTo(stringDevice);
+ else
+ qWarning("QXmlStreamWriter: No device");
+}
+
+void QXmlStreamWriterPrivate::write(const QString &s)
+{
+ if (device) {
+ if (hasError)
+ return;
+#ifdef QT_NO_TEXTCODEC
+ QByteArray bytes = s.toLatin1();
+#else
+ QByteArray bytes = encoder->fromUnicode(s);
+#endif
+ if (device->write(bytes) != bytes.size())
+ hasError = true;
+ }
+ else if (stringDevice)
+ stringDevice->append(s);
+ else
+ qWarning("QXmlStreamWriter: No device");
+}
+
+void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespace)
+{
+ QString escaped;
+ escaped.reserve(s.size());
+ for ( int i = 0; i < s.size(); ++i ) {
+ QChar c = s.at(i);
+ if (c.unicode() == '<' )
+ escaped.append(QLatin1String("&lt;"));
+ else if (c.unicode() == '>' )
+ escaped.append(QLatin1String("&gt;"));
+ else if (c.unicode() == '&' )
+ escaped.append(QLatin1String("&amp;"));
+ else if (c.unicode() == '\"' )
+ escaped.append(QLatin1String("&quot;"));
+ else if (escapeWhitespace && c.isSpace()) {
+ if (c.unicode() == '\n')
+ escaped.append(QLatin1String("&#10;"));
+ else if (c.unicode() == '\r')
+ escaped.append(QLatin1String("&#13;"));
+ else if (c.unicode() == '\t')
+ escaped.append(QLatin1String("&#9;"));
+ else
+ escaped += c;
+ } else {
+ escaped += QChar(c);
+ }
+ }
+ write(escaped);
+}
+
+// ASCII only!
+void QXmlStreamWriterPrivate::write(const char *s, int len)
+{
+ if (device) {
+ if (hasError)
+ return;
+ if (device->write(s, len) != len)
+ hasError = true;
+ } else if (stringDevice) {
+ stringDevice->append(QString::fromLatin1(s, len));
+ } else
+ qWarning("QXmlStreamWriter: No device");
+}
+
+void QXmlStreamWriterPrivate::writeNamespaceDeclaration(const NamespaceDeclaration &namespaceDeclaration) {
+ if (namespaceDeclaration.prefix.isEmpty()) {
+ write(" xmlns=\"");
+ write(namespaceDeclaration.namespaceUri);
+ write("\"");
+ } else {
+ write(" xmlns:");
+ write(namespaceDeclaration.prefix);
+ write("=\"");
+ write(namespaceDeclaration.namespaceUri);
+ write("\"");
+ }
+}
+
+bool QXmlStreamWriterPrivate::finishStartElement(bool contents)
+{
+ bool hadSomethingWritten = wroteSomething;
+ wroteSomething = contents;
+ if (!inStartElement)
+ return hadSomethingWritten;
+
+ if (inEmptyElement) {
+ write("/>");
+ QXmlStreamWriterPrivate::Tag &tag = tagStack_pop();
+ lastNamespaceDeclaration = tag.namespaceDeclarationsSize;
+ lastWasStartElement = false;
+ } else {
+ write(">");
+ }
+ inStartElement = inEmptyElement = false;
+ lastNamespaceDeclaration = namespaceDeclarations.size();
+ return hadSomethingWritten;
+}
+
+QXmlStreamPrivateTagStack::NamespaceDeclaration &QXmlStreamWriterPrivate::findNamespace(const QString &namespaceUri, bool writeDeclaration, bool noDefault)
+{
+ for (int j = namespaceDeclarations.size() - 1; j >= 0; --j) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations[j];
+ if (namespaceDeclaration.namespaceUri == namespaceUri) {
+ if (!noDefault || !namespaceDeclaration.prefix.isEmpty())
+ return namespaceDeclaration;
+ }
+ }
+ if (namespaceUri.isEmpty())
+ return emptyNamespace;
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ if (namespaceUri.isEmpty()) {
+ namespaceDeclaration.prefix.clear();
+ } else {
+ QString s;
+ int n = ++namespacePrefixCount;
+ forever {
+ s = QLatin1Char('n') + QString::number(n++);
+ int j = namespaceDeclarations.size() - 2;
+ while (j >= 0 && namespaceDeclarations.at(j).prefix != s)
+ --j;
+ if (j < 0)
+ break;
+ }
+ namespaceDeclaration.prefix = addToStringStorage(s);
+ }
+ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+ if (writeDeclaration)
+ writeNamespaceDeclaration(namespaceDeclaration);
+ return namespaceDeclaration;
+}
+
+
+
+void QXmlStreamWriterPrivate::indent(int level)
+{
+ write("\n");
+ for (int i = level; i > 0; --i)
+ write(autoFormattingIndent.constData(), autoFormattingIndent.length());
+}
+
+
+/*!
+ Constructs a stream writer.
+
+ \sa setDevice()
+ */
+QXmlStreamWriter::QXmlStreamWriter()
+ : d_ptr(new QXmlStreamWriterPrivate(this))
+{
+}
+
+/*!
+ Constructs a stream writer that writes into \a device;
+ */
+QXmlStreamWriter::QXmlStreamWriter(QIODevice *device)
+ : d_ptr(new QXmlStreamWriterPrivate(this))
+{
+ Q_D(QXmlStreamWriter);
+ d->device = device;
+}
+
+/*! Constructs a stream writer that writes into \a array. This is the
+ same as creating an xml writer that operates on a QBuffer device
+ which in turn operates on \a array.
+ */
+QXmlStreamWriter::QXmlStreamWriter(QByteArray *array)
+ : d_ptr(new QXmlStreamWriterPrivate(this))
+{
+ Q_D(QXmlStreamWriter);
+ d->device = new QBuffer(array);
+ d->device->open(QIODevice::WriteOnly);
+ d->deleteDevice = true;
+}
+
+
+/*! Constructs a stream writer that writes into \a string.
+ */
+QXmlStreamWriter::QXmlStreamWriter(QString *string)
+ : d_ptr(new QXmlStreamWriterPrivate(this))
+{
+ Q_D(QXmlStreamWriter);
+ d->stringDevice = string;
+}
+
+/*!
+ Destructor.
+*/
+QXmlStreamWriter::~QXmlStreamWriter()
+{
+}
+
+
+/*!
+ Sets the current device to \a device. If you want the stream to
+ write into a QByteArray, you can create a QBuffer device.
+
+ \sa device()
+*/
+void QXmlStreamWriter::setDevice(QIODevice *device)
+{
+ Q_D(QXmlStreamWriter);
+ if (device == d->device)
+ return;
+ d->stringDevice = 0;
+ if (d->deleteDevice) {
+ delete d->device;
+ d->deleteDevice = false;
+ }
+ d->device = device;
+}
+
+/*!
+ Returns the current device associated with the QXmlStreamWriter,
+ or 0 if no device has been assigned.
+
+ \sa setDevice()
+*/
+QIODevice *QXmlStreamWriter::device() const
+{
+ Q_D(const QXmlStreamWriter);
+ return d->device;
+}
+
+
+#ifndef QT_NO_TEXTCODEC
+/*!
+ Sets the codec for this stream to \a codec. The codec is used for
+ encoding any data that is written. By default, QXmlStreamWriter
+ uses UTF-8.
+
+ The encoding information is stored in the initial xml tag which
+ gets written when you call writeStartDocument(). Call this
+ function before calling writeStartDocument().
+
+ \sa codec()
+*/
+void QXmlStreamWriter::setCodec(QTextCodec *codec)
+{
+ Q_D(QXmlStreamWriter);
+ if (codec) {
+ d->codec = codec;
+ delete d->encoder;
+ d->encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8
+ }
+}
+
+/*!
+ Sets the codec for this stream to the QTextCodec for the encoding
+ specified by \a codecName. Common values for \c codecName include
+ "ISO 8859-1", "UTF-8", and "UTF-16". If the encoding isn't
+ recognized, nothing happens.
+
+ \sa QTextCodec::codecForName()
+*/
+void QXmlStreamWriter::setCodec(const char *codecName)
+{
+ setCodec(QTextCodec::codecForName(codecName));
+}
+
+/*!
+ Returns the codec that is currently assigned to the stream.
+
+ \sa setCodec()
+*/
+QTextCodec *QXmlStreamWriter::codec() const
+{
+ Q_D(const QXmlStreamWriter);
+ return d->codec;
+}
+#endif // QT_NO_TEXTCODEC
+
+/*!
+ \property QXmlStreamWriter::autoFormatting
+ \since 4.4
+ the auto-formatting flag of the stream writer
+
+ This property controls whether or not the stream writer
+ automatically formats the generated XML data. If enabled, the
+ writer automatically adds line-breaks and indentation to empty
+ sections between elements (ignorable whitespace). The main purpose
+ of auto-formatting is to split the data into several lines, and to
+ increase readability for a human reader. The indentation depth can
+ be controlled through the \l autoFormattingIndent property.
+
+ By default, auto-formatting is disabled.
+*/
+
+/*!
+ \since 4.4
+
+ Enables auto formatting if \a enable is \c true, otherwise
+ disables it.
+
+ The default value is \c false.
+ */
+void QXmlStreamWriter::setAutoFormatting(bool enable)
+{
+ Q_D(QXmlStreamWriter);
+ d->autoFormatting = enable;
+}
+
+/*!
+ \since 4.4
+
+ Returns \c true if auto formattting is enabled, otherwise \c false.
+ */
+bool QXmlStreamWriter::autoFormatting() const
+{
+ Q_D(const QXmlStreamWriter);
+ return d->autoFormatting;
+}
+
+/*!
+ \property QXmlStreamWriter::autoFormattingIndent
+ \since 4.4
+
+ \brief the number of spaces or tabs used for indentation when
+ auto-formatting is enabled. Positive numbers indicate spaces,
+ negative numbers tabs.
+
+ The default indentation is 4.
+
+ \sa autoFormatting
+*/
+
+
+void QXmlStreamWriter::setAutoFormattingIndent(int spacesOrTabs)
+{
+ Q_D(QXmlStreamWriter);
+ d->autoFormattingIndent = QByteArray(qAbs(spacesOrTabs), spacesOrTabs >= 0 ? ' ' : '\t');
+}
+
+int QXmlStreamWriter::autoFormattingIndent() const
+{
+ Q_D(const QXmlStreamWriter);
+ return d->autoFormattingIndent.count(' ') - d->autoFormattingIndent.count('\t');
+}
+
+/*!
+ Returns \c true if the stream failed to write to the underlying device.
+
+ The error status is never reset. Writes happening after the error
+ occurred are ignored, even if the error condition is cleared.
+ */
+bool QXmlStreamWriter::hasError() const
+{
+ Q_D(const QXmlStreamWriter);
+ return d->hasError;
+}
+
+/*!
+ \overload
+ Writes an attribute with \a qualifiedName and \a value.
+
+
+ This function can only be called after writeStartElement() before
+ any content is written, or after writeEmptyElement().
+ */
+void QXmlStreamWriter::writeAttribute(const QString &qualifiedName, const QString &value)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(d->inStartElement);
+ Q_ASSERT(qualifiedName.count(QLatin1Char(':')) <= 1);
+ d->write(" ");
+ d->write(qualifiedName);
+ d->write("=\"");
+ d->writeEscaped(value, true);
+ d->write("\"");
+}
+
+/*! Writes an attribute with \a name and \a value, prefixed for
+ the specified \a namespaceUri. If the namespace has not been
+ declared yet, QXmlStreamWriter will generate a namespace declaration
+ for it.
+
+ This function can only be called after writeStartElement() before
+ any content is written, or after writeEmptyElement().
+ */
+void QXmlStreamWriter::writeAttribute(const QString &namespaceUri, const QString &name, const QString &value)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(d->inStartElement);
+ Q_ASSERT(!name.contains(QLatin1Char(':')));
+ QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration = d->findNamespace(namespaceUri, true, true);
+ d->write(" ");
+ if (!namespaceDeclaration.prefix.isEmpty()) {
+ d->write(namespaceDeclaration.prefix);
+ d->write(":");
+ }
+ d->write(name);
+ d->write("=\"");
+ d->writeEscaped(value, true);
+ d->write("\"");
+}
+
+/*!
+ \overload
+
+ Writes the \a attribute.
+
+ This function can only be called after writeStartElement() before
+ any content is written, or after writeEmptyElement().
+ */
+void QXmlStreamWriter::writeAttribute(const QXmlStreamAttribute& attribute)
+{
+ if (attribute.namespaceUri().isEmpty())
+ writeAttribute(attribute.qualifiedName().toString(),
+ attribute.value().toString());
+ else
+ writeAttribute(attribute.namespaceUri().toString(),
+ attribute.name().toString(),
+ attribute.value().toString());
+}
+
+
+/*! Writes the attribute vector \a attributes. If a namespace
+ referenced in an attribute not been declared yet, QXmlStreamWriter
+ will generate a namespace declaration for it.
+
+ This function can only be called after writeStartElement() before
+ any content is written, or after writeEmptyElement().
+
+ \sa writeAttribute(), writeNamespace()
+ */
+void QXmlStreamWriter::writeAttributes(const QXmlStreamAttributes& attributes)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(d->inStartElement);
+ Q_UNUSED(d);
+ for (int i = 0; i < attributes.size(); ++i)
+ writeAttribute(attributes.at(i));
+}
+
+
+/*! Writes \a text as CDATA section. If \a text contains the
+ forbidden character sequence "]]>", it is split into different CDATA
+ sections.
+
+ This function mainly exists for completeness. Normally you should
+ not need use it, because writeCharacters() automatically escapes all
+ non-content characters.
+ */
+void QXmlStreamWriter::writeCDATA(const QString &text)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement();
+ QString copy(text);
+ copy.replace(QLatin1String("]]>"), QLatin1String("]]]]><![CDATA[>"));
+ d->write("<![CDATA[");
+ d->write(copy);
+ d->write("]]>");
+}
+
+
+/*! Writes \a text. The characters "<", "&", and "\"" are escaped as entity
+ references "&lt;", "&amp;, and "&quot;". To avoid the forbidden sequence
+ "]]>", ">" is also escaped as "&gt;".
+
+ \sa writeEntityReference()
+ */
+void QXmlStreamWriter::writeCharacters(const QString &text)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement();
+ d->writeEscaped(text);
+}
+
+
+/*! Writes \a text as XML comment, where \a text must not contain the
+ forbidden sequence "--" or end with "-". Note that XML does not
+ provide any way to escape "-" in a comment.
+ */
+void QXmlStreamWriter::writeComment(const QString &text)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(!text.contains(QLatin1String("--")) && !text.endsWith(QLatin1Char('-')));
+ if (!d->finishStartElement(false) && d->autoFormatting)
+ d->indent(d->tagStack.size());
+ d->write("<!--");
+ d->write(text);
+ d->write("-->");
+ d->inStartElement = d->lastWasStartElement = false;
+}
+
+
+/*! Writes a DTD section. The \a dtd represents the entire
+ doctypedecl production from the XML 1.0 specification.
+ */
+void QXmlStreamWriter::writeDTD(const QString &dtd)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement();
+ if (d->autoFormatting)
+ d->write("\n");
+ d->write(dtd);
+ if (d->autoFormatting)
+ d->write("\n");
+}
+
+
+
+/*! \overload
+ Writes an empty element with qualified name \a qualifiedName.
+ Subsequent calls to writeAttribute() will add attributes to this element.
+*/
+void QXmlStreamWriter::writeEmptyElement(const QString &qualifiedName)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(qualifiedName.count(QLatin1Char(':')) <= 1);
+ d->writeStartElement(QString(), qualifiedName);
+ d->inEmptyElement = true;
+}
+
+
+/*! Writes an empty element with \a name, prefixed for the specified
+ \a namespaceUri. If the namespace has not been declared,
+ QXmlStreamWriter will generate a namespace declaration for it.
+ Subsequent calls to writeAttribute() will add attributes to this element.
+
+ \sa writeNamespace()
+ */
+void QXmlStreamWriter::writeEmptyElement(const QString &namespaceUri, const QString &name)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(!name.contains(QLatin1Char(':')));
+ d->writeStartElement(namespaceUri, name);
+ d->inEmptyElement = true;
+}
+
+
+/*!\overload
+ Writes a text element with \a qualifiedName and \a text.
+
+
+ This is a convenience function equivalent to:
+ \snippet doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp 1
+
+*/
+void QXmlStreamWriter::writeTextElement(const QString &qualifiedName, const QString &text)
+{
+ writeStartElement(qualifiedName);
+ writeCharacters(text);
+ writeEndElement();
+}
+
+/*! Writes a text element with \a name, prefixed for the specified \a
+ namespaceUri, and \a text. If the namespace has not been
+ declared, QXmlStreamWriter will generate a namespace declaration
+ for it.
+
+
+ This is a convenience function equivalent to:
+ \snippet doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp 2
+
+*/
+void QXmlStreamWriter::writeTextElement(const QString &namespaceUri, const QString &name, const QString &text)
+{
+ writeStartElement(namespaceUri, name);
+ writeCharacters(text);
+ writeEndElement();
+}
+
+
+/*!
+ Closes all remaining open start elements and writes a newline.
+
+ \sa writeStartDocument()
+ */
+void QXmlStreamWriter::writeEndDocument()
+{
+ Q_D(QXmlStreamWriter);
+ while (d->tagStack.size())
+ writeEndElement();
+ d->write("\n");
+}
+
+/*!
+ Closes the previous start element.
+
+ \sa writeStartElement()
+ */
+void QXmlStreamWriter::writeEndElement()
+{
+ Q_D(QXmlStreamWriter);
+ if (d->tagStack.isEmpty())
+ return;
+
+ // shortcut: if nothing was written, close as empty tag
+ if (d->inStartElement && !d->inEmptyElement) {
+ d->write("/>");
+ d->lastWasStartElement = d->inStartElement = false;
+ QXmlStreamWriterPrivate::Tag &tag = d->tagStack_pop();
+ d->lastNamespaceDeclaration = tag.namespaceDeclarationsSize;
+ return;
+ }
+
+ if (!d->finishStartElement(false) && !d->lastWasStartElement && d->autoFormatting)
+ d->indent(d->tagStack.size()-1);
+ if (d->tagStack.isEmpty())
+ return;
+ d->lastWasStartElement = false;
+ QXmlStreamWriterPrivate::Tag &tag = d->tagStack_pop();
+ d->lastNamespaceDeclaration = tag.namespaceDeclarationsSize;
+ d->write("</");
+ if (!tag.namespaceDeclaration.prefix.isEmpty()) {
+ d->write(tag.namespaceDeclaration.prefix);
+ d->write(":");
+ }
+ d->write(tag.name);
+ d->write(">");
+}
+
+
+
+/*!
+ Writes the entity reference \a name to the stream, as "&\a{name};".
+ */
+void QXmlStreamWriter::writeEntityReference(const QString &name)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement();
+ d->write("&");
+ d->write(name);
+ d->write(";");
+}
+
+
+/*! Writes a namespace declaration for \a namespaceUri with \a
+ prefix. If \a prefix is empty, QXmlStreamWriter assigns a unique
+ prefix consisting of the letter 'n' followed by a number.
+
+ If writeStartElement() or writeEmptyElement() was called, the
+ declaration applies to the current element; otherwise it applies to
+ the next child element.
+
+ Note that the prefix \e xml is both predefined and reserved for
+ \e http://www.w3.org/XML/1998/namespace, which in turn cannot be
+ bound to any other prefix. The prefix \e xmlns and its URI
+ \e http://www.w3.org/2000/xmlns/ are used for the namespace mechanism
+ itself and thus completely forbidden in declarations.
+
+ */
+void QXmlStreamWriter::writeNamespace(const QString &namespaceUri, const QString &prefix)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(!namespaceUri.isEmpty());
+ Q_ASSERT(prefix != QLatin1String("xmlns"));
+ if (prefix.isEmpty()) {
+ d->findNamespace(namespaceUri, d->inStartElement);
+ } else {
+ Q_ASSERT(!((prefix == QLatin1String("xml")) ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace"))));
+ Q_ASSERT(namespaceUri != QLatin1String("http://www.w3.org/2000/xmlns/"));
+ QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration = d->namespaceDeclarations.push();
+ namespaceDeclaration.prefix = d->addToStringStorage(prefix);
+ namespaceDeclaration.namespaceUri = d->addToStringStorage(namespaceUri);
+ if (d->inStartElement)
+ d->writeNamespaceDeclaration(namespaceDeclaration);
+ }
+}
+
+
+/*! Writes a default namespace declaration for \a namespaceUri.
+
+ If writeStartElement() or writeEmptyElement() was called, the
+ declaration applies to the current element; otherwise it applies to
+ the next child element.
+
+ Note that the namespaces \e http://www.w3.org/XML/1998/namespace
+ (bound to \e xmlns) and \e http://www.w3.org/2000/xmlns/ (bound to
+ \e xml) by definition cannot be declared as default.
+ */
+void QXmlStreamWriter::writeDefaultNamespace(const QString &namespaceUri)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(namespaceUri != QLatin1String("http://www.w3.org/XML/1998/namespace"));
+ Q_ASSERT(namespaceUri != QLatin1String("http://www.w3.org/2000/xmlns/"));
+ QXmlStreamWriterPrivate::NamespaceDeclaration &namespaceDeclaration = d->namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+ namespaceDeclaration.namespaceUri = d->addToStringStorage(namespaceUri);
+ if (d->inStartElement)
+ d->writeNamespaceDeclaration(namespaceDeclaration);
+}
+
+
+/*!
+ Writes an XML processing instruction with \a target and \a data,
+ where \a data must not contain the sequence "?>".
+ */
+void QXmlStreamWriter::writeProcessingInstruction(const QString &target, const QString &data)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(!data.contains(QLatin1String("?>")));
+ if (!d->finishStartElement(false) && d->autoFormatting)
+ d->indent(d->tagStack.size());
+ d->write("<?");
+ d->write(target);
+ if (!data.isNull()) {
+ d->write(" ");
+ d->write(data);
+ }
+ d->write("?>");
+}
+
+
+
+/*!\overload
+
+ Writes a document start with XML version number "1.0". This also
+ writes the encoding information.
+
+ \sa writeEndDocument(), setCodec()
+ \since 4.5
+ */
+void QXmlStreamWriter::writeStartDocument()
+{
+ writeStartDocument(QLatin1String("1.0"));
+}
+
+
+/*!
+ Writes a document start with the XML version number \a version.
+
+ \sa writeEndDocument()
+ */
+void QXmlStreamWriter::writeStartDocument(const QString &version)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement(false);
+ d->write("<?xml version=\"");
+ d->write(version);
+ if (d->device) { // stringDevice does not get any encoding
+ d->write("\" encoding=\"");
+#ifdef QT_NO_TEXTCODEC
+ d->write("iso-8859-1");
+#else
+ d->write(d->codec->name().constData(), d->codec->name().length());
+#endif
+ }
+ d->write("\"?>");
+}
+
+/*! Writes a document start with the XML version number \a version
+ and a standalone attribute \a standalone.
+
+ \sa writeEndDocument()
+ \since 4.5
+ */
+void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalone)
+{
+ Q_D(QXmlStreamWriter);
+ d->finishStartElement(false);
+ d->write("<?xml version=\"");
+ d->write(version);
+ if (d->device) { // stringDevice does not get any encoding
+ d->write("\" encoding=\"");
+#ifdef QT_NO_TEXTCODEC
+ d->write("iso-8859-1");
+#else
+ d->write(d->codec->name().constData(), d->codec->name().length());
+#endif
+ }
+ if (standalone)
+ d->write("\" standalone=\"yes\"?>");
+ else
+ d->write("\" standalone=\"no\"?>");
+}
+
+
+/*!\overload
+
+ Writes a start element with \a qualifiedName. Subsequent calls to
+ writeAttribute() will add attributes to this element.
+
+ \sa writeEndElement(), writeEmptyElement()
+ */
+void QXmlStreamWriter::writeStartElement(const QString &qualifiedName)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(qualifiedName.count(QLatin1Char(':')) <= 1);
+ d->writeStartElement(QString(), qualifiedName);
+}
+
+
+/*! Writes a start element with \a name, prefixed for the specified
+ \a namespaceUri. If the namespace has not been declared yet,
+ QXmlStreamWriter will generate a namespace declaration for
+ it. Subsequent calls to writeAttribute() will add attributes to this
+ element.
+
+ \sa writeNamespace(), writeEndElement(), writeEmptyElement()
+ */
+void QXmlStreamWriter::writeStartElement(const QString &namespaceUri, const QString &name)
+{
+ Q_D(QXmlStreamWriter);
+ Q_ASSERT(!name.contains(QLatin1Char(':')));
+ d->writeStartElement(namespaceUri, name);
+}
+
+void QXmlStreamWriterPrivate::writeStartElement(const QString &namespaceUri, const QString &name)
+{
+ if (!finishStartElement(false) && autoFormatting)
+ indent(tagStack.size());
+
+ Tag &tag = tagStack_push();
+ tag.name = addToStringStorage(name);
+ tag.namespaceDeclaration = findNamespace(namespaceUri);
+ write("<");
+ if (!tag.namespaceDeclaration.prefix.isEmpty()) {
+ write(tag.namespaceDeclaration.prefix);
+ write(":");
+ }
+ write(tag.name);
+ inStartElement = lastWasStartElement = true;
+
+ for (int i = lastNamespaceDeclaration; i < namespaceDeclarations.size(); ++i)
+ writeNamespaceDeclaration(namespaceDeclarations[i]);
+ tag.namespaceDeclarationsSize = lastNamespaceDeclaration;
+}
+
+#ifndef QT_NO_XMLSTREAMREADER
+/*! Writes the current state of the \a reader. All possible valid
+ states are supported.
+
+ The purpose of this function is to support chained processing of XML data.
+
+ \sa QXmlStreamReader::tokenType()
+ */
+void QXmlStreamWriter::writeCurrentToken(const QXmlStreamReader &reader)
+{
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::NoToken:
+ break;
+ case QXmlStreamReader::StartDocument:
+ writeStartDocument();
+ break;
+ case QXmlStreamReader::EndDocument:
+ writeEndDocument();
+ break;
+ case QXmlStreamReader::StartElement: {
+ QXmlStreamNamespaceDeclarations namespaceDeclarations = reader.namespaceDeclarations();
+ for (int i = 0; i < namespaceDeclarations.size(); ++i) {
+ const QXmlStreamNamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.at(i);
+ writeNamespace(namespaceDeclaration.namespaceUri().toString(),
+ namespaceDeclaration.prefix().toString());
+ }
+ writeStartElement(reader.namespaceUri().toString(), reader.name().toString());
+ writeAttributes(reader.attributes());
+ } break;
+ case QXmlStreamReader::EndElement:
+ writeEndElement();
+ break;
+ case QXmlStreamReader::Characters:
+ if (reader.isCDATA())
+ writeCDATA(reader.text().toString());
+ else
+ writeCharacters(reader.text().toString());
+ break;
+ case QXmlStreamReader::Comment:
+ writeComment(reader.text().toString());
+ break;
+ case QXmlStreamReader::DTD:
+ writeDTD(reader.text().toString());
+ break;
+ case QXmlStreamReader::EntityReference:
+ writeEntityReference(reader.name().toString());
+ break;
+ case QXmlStreamReader::ProcessingInstruction:
+ writeProcessingInstruction(reader.processingInstructionTarget().toString(),
+ reader.processingInstructionData().toString());
+ break;
+ default:
+ Q_ASSERT(reader.tokenType() != QXmlStreamReader::Invalid);
+ qWarning("QXmlStreamWriter: writeCurrentToken() with invalid state.");
+ break;
+ }
+}
+
+/*!
+ \fn bool QXmlStreamAttributes::hasAttribute(const QString &qualifiedName) const
+ \since 4.5
+
+ Returns true if this QXmlStreamAttributes has an attribute whose
+ qualified name is \a qualifiedName; otherwise returns false.
+
+ Note that this is not namespace aware. For instance, if this
+ QXmlStreamAttributes contains an attribute whose lexical name is "xlink:href"
+ this doesn't tell that an attribute named \c href in the XLink namespace is
+ present, since the \c xlink prefix can be bound to any namespace. Use the
+ overload that takes a namespace URI and a local name as parameter, for
+ namespace aware code.
+*/
+
+/*!
+ \fn bool QXmlStreamAttributes::hasAttribute(const QLatin1String &qualifiedName) const
+ \overload
+ \since 4.5
+*/
+
+/*!
+ \fn bool QXmlStreamAttributes::hasAttribute(const QString &namespaceUri,
+ const QString &name) const
+ \overload
+ \since 4.5
+
+ Returns true if this QXmlStreamAttributes has an attribute whose
+ namespace URI and name correspond to \a namespaceUri and \a name;
+ otherwise returns false.
+*/
+
+#endif // QT_NO_XMLSTREAMREADER
+#endif // QT_NO_XMLSTREAMWRITER
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_XMLSTREAM
diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g
new file mode 100644
index 0000000000..3088632e34
--- /dev/null
+++ b/src/corelib/xml/qxmlstream.g
@@ -0,0 +1,1847 @@
+----------------------------------------------------------------------------
+--
+-- 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 QtCore module 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 Technology Preview License Agreement accompanying
+-- this package.
+--
+-- 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+--
+-- If you have questions regarding the use of this file, please contact
+-- Nokia at qt-info@nokia.com.
+--
+--
+--
+--
+--
+--
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+%parser QXmlStreamReader_Table
+
+%merged_output qxmlstream_p.h
+
+%token NOTOKEN
+%token SPACE " "
+%token LANGLE "<"
+%token RANGLE ">"
+%token AMPERSAND "&"
+%token HASH "#"
+%token QUOTE "\'"
+%token DBLQUOTE "\""
+%token LBRACK "["
+%token RBRACK "]"
+%token LPAREN "("
+%token RPAREN ")"
+%token PIPE "|"
+%token EQ "="
+%token PERCENT "%"
+%token SLASH "/"
+%token COLON ":"
+%token SEMICOLON ";"
+%token COMMA ","
+%token DASH "-"
+%token PLUS "+"
+%token STAR "*"
+%token DOT "."
+%token QUESTIONMARK "?"
+%token BANG "!"
+%token LETTER "[a-zA-Z]"
+%token DIGIT "[0-9]"
+
+-- after langle_bang
+%token CDATA_START "[CDATA["
+%token DOCTYPE "DOCTYPE"
+%token ELEMENT "ELEMENT"
+%token ATTLIST "ATTLIST"
+%token ENTITY "ENTITY"
+%token NOTATION "NOTATION"
+
+-- entity decl
+%token SYSTEM "SYSTEM"
+%token PUBLIC "PUBLIC"
+%token NDATA "NDATA"
+
+-- default decl
+%token REQUIRED "REQUIRED"
+%token IMPLIED "IMPLIED"
+%token FIXED "FIXED"
+
+-- conent spec
+%token EMPTY "EMPTY"
+%token ANY "ANY"
+%token PCDATA "PCDATA"
+
+-- error
+%token ERROR
+
+-- entities
+%token PARSE_ENTITY
+%token ENTITY_DONE
+%token UNRESOLVED_ENTITY
+
+-- att type
+%token CDATA "CDATA"
+%token ID "ID"
+%token IDREF "IDREF"
+%token IDREFS "IDREFS"
+%token ENTITY "ENTITY"
+%token ENTITIES "ENTITIES"
+%token NMTOKEN "NMTOKEN"
+%token NMTOKENS "NMTOKENS"
+
+-- xml declaration
+%token XML "<?xml"
+%token VERSION "version"
+
+%nonassoc SHIFT_THERE
+%nonassoc AMPERSAND
+ BANG
+ COLON
+ COMMA
+ DASH
+ DBLQUOTE
+ DIGIT
+ DOT
+ ENTITY_DONE
+ EQ
+ HASH
+ LBRACK
+ LETTER
+ LPAREN
+ PERCENT
+ PIPE
+ PLUS
+ QUESTIONMARK
+ QUOTE
+ RANGLE
+ RBRACK
+ RPAREN
+ SEMICOLON
+ SLASH
+ SPACE
+ STAR
+
+%start document
+
+/.
+template <typename T> class QXmlStreamSimpleStack {
+ T *data;
+ int tos, cap;
+public:
+ inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline ~QXmlStreamSimpleStack(){ if (data) qFree(data); }
+
+ inline void reserve(int extraCapacity) {
+ if (tos + extraCapacity + 1 > cap) {
+ cap = qMax(tos + extraCapacity + 1, cap << 1 );
+ data = reinterpret_cast<T *>(qRealloc(data, cap * sizeof(T)));
+ Q_CHECK_PTR(data);
+ }
+ }
+
+ inline T &push() { reserve(1); return data[++tos]; }
+ inline T &rawPush() { return data[++tos]; }
+ inline const T &top() const { return data[tos]; }
+ inline T &top() { return data[tos]; }
+ inline T &pop() { return data[tos--]; }
+ inline T &operator[](int index) { return data[index]; }
+ inline const T &at(int index) const { return data[index]; }
+ inline int size() const { return tos + 1; }
+ inline void resize(int s) { tos = s - 1; }
+ inline bool isEmpty() const { return tos < 0; }
+ inline void clear() { tos = -1; }
+};
+
+
+class QXmlStream
+{
+ Q_DECLARE_TR_FUNCTIONS(QXmlStream)
+};
+
+class QXmlStreamPrivateTagStack {
+public:
+ struct NamespaceDeclaration
+ {
+ QStringRef prefix;
+ QStringRef namespaceUri;
+ };
+
+ struct Tag
+ {
+ QStringRef name;
+ QStringRef qualifiedName;
+ NamespaceDeclaration namespaceDeclaration;
+ int tagStackStringStorageSize;
+ int namespaceDeclarationsSize;
+ };
+
+
+ QXmlStreamPrivateTagStack();
+ QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
+ QString tagStackStringStorage;
+ int tagStackStringStorageSize;
+ bool tagsDone;
+
+ inline QStringRef addToStringStorage(const QStringRef &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+ inline QStringRef addToStringStorage(const QString &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+
+ QXmlStreamSimpleStack<Tag> tagStack;
+
+
+ inline Tag &tagStack_pop() {
+ Tag& tag = tagStack.pop();
+ tagStackStringStorageSize = tag.tagStackStringStorageSize;
+ namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
+ tagsDone = tagStack.isEmpty();
+ return tag;
+ }
+ inline Tag &tagStack_push() {
+ Tag &tag = tagStack.push();
+ tag.tagStackStringStorageSize = tagStackStringStorageSize;
+ tag.namespaceDeclarationsSize = namespaceDeclarations.size();
+ return tag;
+ }
+};
+
+
+class QXmlStreamEntityResolver;
+#ifndef QT_NO_XMLSTREAMREADER
+class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
+ QXmlStreamReader *q_ptr;
+ Q_DECLARE_PUBLIC(QXmlStreamReader)
+public:
+ QXmlStreamReaderPrivate(QXmlStreamReader *q);
+ ~QXmlStreamReaderPrivate();
+ void init();
+
+ QByteArray rawReadBuffer;
+ QByteArray dataBuffer;
+ uchar firstByte;
+ qint64 nbytesread;
+ QString readBuffer;
+ int readBufferPos;
+ QXmlStreamSimpleStack<uint> putStack;
+ struct Entity {
+ Entity(const QString& str = QString())
+ :value(str), external(false), unparsed(false), literal(false),
+ hasBeenParsed(false), isCurrentlyReferenced(false){}
+ static inline Entity createLiteral(const QString &entity)
+ { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
+ QString value;
+ uint external : 1;
+ uint unparsed : 1;
+ uint literal : 1;
+ uint hasBeenParsed : 1;
+ uint isCurrentlyReferenced : 1;
+ };
+ QHash<QString, Entity> entityHash;
+ QHash<QString, Entity> parameterEntityHash;
+ QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ inline bool referenceEntity(Entity &entity) {
+ if (entity.isCurrentlyReferenced) {
+ raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ return false;
+ }
+ entity.isCurrentlyReferenced = true;
+ entityReferenceStack.push() = &entity;
+ injectToken(ENTITY_DONE);
+ return true;
+ }
+
+
+ QIODevice *device;
+ bool deleteDevice;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+ QTextDecoder *decoder;
+#endif
+ bool atEnd;
+
+ /*!
+ \sa setType()
+ */
+ QXmlStreamReader::TokenType type;
+ QXmlStreamReader::Error error;
+ QString errorString;
+ QString unresolvedEntity;
+
+ qint64 lineNumber, lastLineStart, characterOffset;
+
+
+ void write(const QString &);
+ void write(const char *);
+
+
+ QXmlStreamAttributes attributes;
+ QStringRef namespaceForPrefix(const QStringRef &prefix);
+ void resolveTag();
+ void resolvePublicNamespaces();
+ void resolveDtd();
+ uint resolveCharRef(int symbolIndex);
+ bool checkStartDocument();
+ void startDocument();
+ void parseError();
+ void checkPublicLiteral(const QStringRef &publicId);
+
+ bool scanDtd;
+ QStringRef lastAttributeValue;
+ bool lastAttributeIsCData;
+ struct DtdAttribute {
+ QStringRef tagName;
+ QStringRef attributeQualifiedName;
+ QStringRef attributePrefix;
+ QStringRef attributeName;
+ QStringRef defaultValue;
+ bool isCDATA;
+ bool isNamespaceAttribute;
+ };
+ QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
+ struct NotationDeclaration {
+ QStringRef name;
+ QStringRef publicId;
+ QStringRef systemId;
+ };
+ QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
+ QXmlStreamNotationDeclarations publicNotationDeclarations;
+ QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
+
+ struct EntityDeclaration {
+ QStringRef name;
+ QStringRef notationName;
+ QStringRef publicId;
+ QStringRef systemId;
+ QStringRef value;
+ bool parameter;
+ bool external;
+ inline void clear() {
+ name.clear();
+ notationName.clear();
+ publicId.clear();
+ systemId.clear();
+ value.clear();
+ parameter = external = false;
+ }
+ };
+ QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
+ QXmlStreamEntityDeclarations publicEntityDeclarations;
+
+ QStringRef text;
+
+ QStringRef prefix, namespaceUri, qualifiedName, name;
+ QStringRef processingInstructionTarget, processingInstructionData;
+ QStringRef dtdName, dtdPublicId, dtdSystemId;
+ QStringRef documentVersion, documentEncoding;
+ uint isEmptyElement : 1;
+ uint isWhitespace : 1;
+ uint isCDATA : 1;
+ uint standalone : 1;
+ uint hasCheckedStartDocument : 1;
+ uint normalizeLiterals : 1;
+ uint hasSeenTag : 1;
+ uint inParseEntity : 1;
+ uint referenceToUnparsedEntityDetected : 1;
+ uint referenceToParameterEntityDetected : 1;
+ uint hasExternalDtdSubset : 1;
+ uint lockEncoding : 1;
+ uint namespaceProcessing : 1;
+
+ int resumeReduction;
+ void resume(int rule);
+
+ inline bool entitiesMustBeDeclared() const {
+ return (!inParseEntity
+ && (standalone
+ || (!referenceToUnparsedEntityDetected
+ && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
+ && !hasExternalDtdSubset)));
+ }
+
+ // qlalr parser
+ int tos;
+ int stack_size;
+ struct Value {
+ int pos;
+ int len;
+ int prefix;
+ ushort c;
+ };
+
+ Value *sym_stack;
+ int *state_stack;
+ inline void reallocateStack();
+ inline Value &sym(int index) const
+ { return sym_stack[tos + index - 1]; }
+ QString textBuffer;
+ inline void clearTextBuffer() {
+ if (!scanDtd) {
+ textBuffer.resize(0);
+ textBuffer.reserve(256);
+ }
+ }
+ struct Attribute {
+ Value key;
+ Value value;
+ };
+ QXmlStreamSimpleStack<Attribute> attributeStack;
+
+ inline QStringRef symString(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symString(int index, int offset) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
+ }
+ inline QStringRef symPrefix(int index) {
+ const Value &symbol = sym(index);
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+ inline QStringRef symString(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symPrefix(const Value &symbol) {
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+
+ inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
+
+
+ short token;
+ ushort token_char;
+
+ uint filterCarriageReturn();
+ inline uint getChar();
+ inline uint peekChar();
+ inline void putChar(uint c) { putStack.push() = c; }
+ inline void putChar(QChar c) { putStack.push() = c.unicode(); }
+ void putString(const QString &s, int from = 0);
+ void putStringLiteral(const QString &s);
+ void putReplacement(const QString &s);
+ void putReplacementInAttributeValue(const QString &s);
+ ushort getChar_helper();
+
+ bool scanUntil(const char *str, short tokenToInject = -1);
+ bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
+ inline void injectToken(ushort tokenToInject) {
+ putChar(int(tokenToInject) << 16);
+ }
+
+ QString resolveUndeclaredEntity(const QString &name);
+ void parseEntity(const QString &value);
+ QXmlStreamReaderPrivate *entityParser;
+
+ bool scanAfterLangleBang();
+ bool scanPublicOrSystem();
+ bool scanNData();
+ bool scanAfterDefaultDecl();
+ bool scanAttType();
+
+
+ // scan optimization functions. Not strictly necessary but LALR is
+ // not very well suited for scanning fast
+ int fastScanLiteralContent();
+ int fastScanSpace();
+ int fastScanContentCharList();
+ int fastScanName(int *prefix = 0);
+ inline int fastScanNMTOKEN();
+
+
+ bool parse();
+ inline void consumeRule(int);
+
+ void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
+ void raiseWellFormedError(const QString &message);
+
+ QXmlStreamEntityResolver *entityResolver;
+
+private:
+ /*! \internal
+ Never assign to variable type directly. Instead use this function.
+
+ This prevents errors from being ignored.
+ */
+ inline void setType(const QXmlStreamReader::TokenType t)
+ {
+ if(type != QXmlStreamReader::Invalid)
+ type = t;
+ }
+};
+
+bool QXmlStreamReaderPrivate::parse()
+{
+ // cleanup currently reported token
+
+ switch (type) {
+ case QXmlStreamReader::StartElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ if (publicNamespaceDeclarations.size())
+ publicNamespaceDeclarations.clear();
+ if (attributes.size())
+ attributes.resize(0);
+ if (isEmptyElement) {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ isEmptyElement = false;
+ return true;
+ }
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EndElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::DTD:
+ publicNotationDeclarations.clear();
+ publicEntityDeclarations.clear();
+ dtdName.clear();
+ dtdPublicId.clear();
+ dtdSystemId.clear();
+ // fall through
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::Characters:
+ isCDATA = false;
+ isWhitespace = true;
+ text.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EntityReference:
+ text.clear();
+ name.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::ProcessingInstruction:
+ processingInstructionTarget.clear();
+ processingInstructionData.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ break;
+ case QXmlStreamReader::StartDocument:
+ lockEncoding = true;
+ documentVersion.clear();
+ documentEncoding.clear();
+#ifndef QT_NO_TEXTCODEC
+ if(decoder->hasFailure()) {
+ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+ readBuffer.clear();
+ return false;
+ }
+#endif
+ // fall through
+ default:
+ clearTextBuffer();
+ ;
+ }
+
+ setType(QXmlStreamReader::NoToken);
+
+
+ // the main parse loop
+ int act, r;
+
+ if (resumeReduction) {
+ act = state_stack[tos-1];
+ r = resumeReduction;
+ resumeReduction = 0;
+ goto ResumeReduction;
+ }
+
+ act = state_stack[tos];
+
+ forever {
+ if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
+ uint cu = getChar();
+ token = NOTOKEN;
+ token_char = cu;
+ if (cu & 0xff0000) {
+ token = cu >> 16;
+ } else switch (token_char) {
+ case 0xfffe:
+ case 0xffff:
+ token = ERROR;
+ break;
+ case '\r':
+ token = SPACE;
+ if (cu == '\r') {
+ if ((token_char = filterCarriageReturn())) {
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ break;
+ }
+ } else {
+ break;
+ }
+ // fall through
+ case '\0': {
+ token = EOF_SYMBOL;
+ if (!tagsDone && !inParseEntity) {
+ int a = t_action(act, token);
+ if (a < 0) {
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ return false;
+ }
+ }
+
+ } break;
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ case ' ':
+ case '\t':
+ token = SPACE;
+ break;
+ case '&':
+ token = AMPERSAND;
+ break;
+ case '#':
+ token = HASH;
+ break;
+ case '\'':
+ token = QUOTE;
+ break;
+ case '\"':
+ token = DBLQUOTE;
+ break;
+ case '<':
+ token = LANGLE;
+ break;
+ case '>':
+ token = RANGLE;
+ break;
+ case '[':
+ token = LBRACK;
+ break;
+ case ']':
+ token = RBRACK;
+ break;
+ case '(':
+ token = LPAREN;
+ break;
+ case ')':
+ token = RPAREN;
+ break;
+ case '|':
+ token = PIPE;
+ break;
+ case '=':
+ token = EQ;
+ break;
+ case '%':
+ token = PERCENT;
+ break;
+ case '/':
+ token = SLASH;
+ break;
+ case ':':
+ token = COLON;
+ break;
+ case ';':
+ token = SEMICOLON;
+ break;
+ case ',':
+ token = COMMA;
+ break;
+ case '-':
+ token = DASH;
+ break;
+ case '+':
+ token = PLUS;
+ break;
+ case '*':
+ token = STAR;
+ break;
+ case '.':
+ token = DOT;
+ break;
+ case '?':
+ token = QUESTIONMARK;
+ break;
+ case '!':
+ token = BANG;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ token = DIGIT;
+ break;
+ default:
+ if (cu < 0x20)
+ token = NOTOKEN;
+ else
+ token = LETTER;
+ break;
+ }
+ }
+
+ act = t_action (act, token);
+ if (act == ACCEPT_STATE) {
+ // reset the parser in case someone resumes (process instructions can follow a valid document)
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return true;
+ } else if (act > 0) {
+ if (++tos == stack_size-1)
+ reallocateStack();
+
+ Value &val = sym_stack[tos];
+ val.c = token_char;
+ val.pos = textBuffer.size();
+ val.prefix = 0;
+ val.len = 1;
+ if (token_char)
+ textBuffer += QChar(token_char);
+
+ state_stack[tos] = act;
+ token = -1;
+
+
+ } else if (act < 0) {
+ r = - act - 1;
+
+#if defined (QLALR_DEBUG)
+ int ridx = rule_index[r];
+ printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs[r]; ++i) {
+ int symbol = rule_info[i];
+ if (const char *name = spell[symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+#endif
+
+ tos -= rhs[r];
+ act = state_stack[tos++];
+ ResumeReduction:
+ switch (r) {
+./
+
+document ::= PARSE_ENTITY content;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::EndDocument);
+ break;
+./
+
+document ::= prolog;
+/.
+ case $rule_number:
+ if (type != QXmlStreamReader::Invalid) {
+ if (hasSeenTag || inParseEntity) {
+ setType(QXmlStreamReader::EndDocument);
+ } else {
+ raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
+ // reset the parser
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return false;
+ }
+ }
+ break;
+./
+
+
+prolog ::= prolog stag content etag;
+prolog ::= prolog empty_element_tag;
+prolog ::= prolog comment;
+prolog ::= prolog xml_decl;
+prolog ::= prolog processing_instruction;
+prolog ::= prolog doctype_decl;
+prolog ::= prolog SPACE;
+prolog ::=;
+
+entity_done ::= ENTITY_DONE;
+/.
+ case $rule_number:
+ entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ clearSym();
+ break;
+./
+
+
+xml_decl_start ::= XML;
+/.
+ case $rule_number:
+ if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+xml_decl ::= xml_decl_start VERSION space_opt EQ space_opt literal attribute_list_opt QUESTIONMARK RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::StartDocument);
+ documentVersion = symString(6);
+ startDocument();
+ break;
+./
+
+external_id ::= SYSTEM literal;
+/.
+ case $rule_number:
+ hasExternalDtdSubset = true;
+ dtdSystemId = symString(2);
+ break;
+./
+external_id ::= PUBLIC public_literal space literal;
+/.
+ case $rule_number:
+ checkPublicLiteral(symString(2));
+ dtdPublicId = symString(2);
+ dtdSystemId = symString(4);
+ hasExternalDtdSubset = true;
+ break;
+./
+external_id ::=;
+
+doctype_decl_start ::= langle_bang DOCTYPE qname space;
+/.
+ case $rule_number:
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ dtdName = symString(3);
+ break;
+./
+
+doctype_decl ::= langle_bang DOCTYPE qname RANGLE;
+/.
+ case $rule_number:./
+doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
+/.
+ case $rule_number:
+ dtdName = symString(3);
+ // fall through
+./
+doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
+/.
+ case $rule_number:./
+doctype_decl ::= doctype_decl_start external_id space_opt RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::DTD);
+ text = &textBuffer;
+ break;
+./
+
+markup_start ::= LBRACK;
+/.
+ case $rule_number:
+ scanDtd = true;
+ break;
+./
+
+markup ::= markup_start markup_list RBRACK;
+/.
+ case $rule_number:
+ scanDtd = false;
+ break;
+./
+
+
+markup_list ::= markup_decl | space | pereference;
+markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference;
+markup_list ::=;
+
+markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment;
+
+
+element_decl_start ::= langle_bang ELEMENT qname space;
+/.
+ case $rule_number:
+ if (!scanString(spell[EMPTY], EMPTY, false)
+ && !scanString(spell[ANY], ANY, false)
+ && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+element_decl ::= element_decl_start content_spec space_opt RANGLE;
+
+
+content_spec ::= EMPTY | ANY | mixed | children;
+
+pcdata_start ::= HASH;
+/.
+ case $rule_number:
+ if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+pcdata ::= pcdata_start PCDATA;
+
+questionmark_or_star_or_plus_opt ::= QUESTIONMARK | STAR | PLUS;
+questionmark_or_star_or_plus_opt ::=;
+
+cp ::= qname questionmark_or_star_or_plus_opt | choice_or_seq questionmark_or_star_or_plus_opt;
+
+cp_pipe_or_comma_list ::= cp space_opt;
+cp_pipe_or_comma_list ::= cp space_opt PIPE space_opt cp_pipe_list space_opt;
+cp_pipe_or_comma_list ::= cp space_opt COMMA space_opt cp_comma_list space_opt;
+cp_pipe_list ::= cp | cp_pipe_list space_opt PIPE space_opt cp;
+cp_comma_list ::= cp | cp_comma_list space_opt COMMA space_opt cp;
+
+
+name_pipe_list ::= PIPE space_opt qname;
+name_pipe_list ::= name_pipe_list space_opt PIPE space_opt qname;
+
+star_opt ::= | STAR;
+
+mixed ::= LPAREN space_opt pcdata space_opt RPAREN star_opt;
+mixed ::= LPAREN space_opt pcdata space_opt name_pipe_list space_opt RPAREN STAR;
+
+choice_or_seq ::= LPAREN space_opt cp_pipe_or_comma_list RPAREN;
+
+children ::= choice_or_seq questionmark_or_star_or_plus_opt;
+
+
+nmtoken_pipe_list ::= nmtoken;
+nmtoken_pipe_list ::= nmtoken_pipe_list space_opt PIPE space_opt nmtoken;
+
+
+att_type ::= CDATA;
+/.
+ case $rule_number: {
+ lastAttributeIsCData = true;
+ } break;
+./
+att_type ::= ID | IDREF | IDREFS | ENTITY | ENTITIES | NMTOKEN | NMTOKENS;
+att_type ::= LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+att_type ::= NOTATION LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+
+
+default_declhash ::= HASH;
+/.
+ case $rule_number:
+ if (!scanAfterDefaultDecl() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+default_decl ::= default_declhash REQUIRED;
+default_decl ::= default_declhash IMPLIED;
+default_decl ::= attribute_value;
+default_decl ::= default_declhash FIXED space attribute_value;
+attdef_start ::= space qname space;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ lastAttributeValue.clear();
+ lastAttributeIsCData = false;
+ if (!scanAttType() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+attdef ::= attdef_start att_type default_decl;
+/.
+ case $rule_number: {
+ DtdAttribute &dtdAttribute = dtdAttributes.push();
+ dtdAttribute.tagName.clear();
+ dtdAttribute.isCDATA = lastAttributeIsCData;
+ dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
+ dtdAttribute.attributeName = addToStringStorage(symString(1));
+ dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
+ dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
+ || (dtdAttribute.attributePrefix.isEmpty()
+ && dtdAttribute.attributeName == QLatin1String("xmlns")));
+ if (lastAttributeValue.isNull()) {
+ dtdAttribute.defaultValue.clear();
+ } else {
+ if (dtdAttribute.isCDATA)
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
+ else
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
+
+ }
+ } break;
+./
+
+attdef_list ::= attdef;
+attdef_list ::= attdef_list attdef;
+
+attlist_decl ::= langle_bang ATTLIST qname space_opt RANGLE;
+attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
+/.
+ case $rule_number: {
+ if (referenceToUnparsedEntityDetected && !standalone)
+ break;
+ int n = dtdAttributes.size();
+ QStringRef tagName = addToStringStorage(symName(3));
+ while (n--) {
+ DtdAttribute &dtdAttribute = dtdAttributes[n];
+ if (!dtdAttribute.tagName.isNull())
+ break;
+ dtdAttribute.tagName = tagName;
+ for (int i = 0; i < n; ++i) {
+ if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
+ && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
+ dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
+ break;
+ }
+ }
+ }
+ } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(3);
+ } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY PERCENT space name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(5);
+ entityDeclaration.parameter = true;
+ } break;
+./
+
+entity_decl_external ::= entity_decl_start SYSTEM literal;
+/.
+ case $rule_number: {
+ if (!scanNData() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.systemId = symString(3);
+ entityDeclaration.external = true;
+ } break;
+./
+
+entity_decl_external ::= entity_decl_start PUBLIC public_literal space literal;
+/.
+ case $rule_number: {
+ if (!scanNData() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ checkPublicLiteral((entityDeclaration.publicId = symString(3)));
+ entityDeclaration.systemId = symString(5);
+ entityDeclaration.external = true;
+ } break;
+./
+
+entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
+/.
+ case $rule_number: {
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.notationName = symString(3);
+ if (entityDeclaration.parameter)
+ raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
+ }
+ //fall through
+./
+
+entity_decl ::= entity_decl_external space_opt RANGLE;
+/.
+ case $rule_number:./
+
+entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
+/.
+ case $rule_number: {
+ if (referenceToUnparsedEntityDetected && !standalone) {
+ entityDeclarations.pop();
+ break;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ if (!entityDeclaration.external)
+ entityDeclaration.value = symString(2);
+ QString entityName = entityDeclaration.name.toString();
+ QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+ if (!hash.contains(entityName)) {
+ Entity entity(entityDeclaration.value.toString());
+ entity.unparsed = (!entityDeclaration.notationName.isNull());
+ entity.external = entityDeclaration.external;
+ hash.insert(entityName, entity);
+ }
+ } break;
+./
+
+
+processing_instruction ::= LANGLE QUESTIONMARK name space;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::ProcessingInstruction);
+ int pos = sym(4).pos + sym(4).len;
+ processingInstructionTarget = symString(3);
+ if (scanUntil("?>")) {
+ processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
+ const QString piTarget(processingInstructionTarget.toString());
+ if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+ raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
+ }
+ else if(!QXmlUtils::isNCName(piTarget))
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
+ } else if (type != QXmlStreamReader::Invalid){
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::ProcessingInstruction);
+ processingInstructionTarget = symString(3);
+ if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
+ raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
+ break;
+./
+
+
+langle_bang ::= LANGLE BANG;
+/.
+ case $rule_number:
+ if (!scanAfterLangleBang() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+comment_start ::= langle_bang DASH DASH;
+/.
+ case $rule_number:
+ if (!scanUntil("--")) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+comment ::= comment_start RANGLE;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::Comment);
+ int pos = sym(1).pos + 4;
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } break;
+./
+
+
+cdata ::= langle_bang CDATA_START;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::Characters);
+ isCDATA = true;
+ isWhitespace = false;
+ int pos = sym(2).pos;
+ if (scanUntil("]]>", -1)) {
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } else {
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+notation_decl_start ::= langle_bang NOTATION name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ NotationDeclaration &notationDeclaration = notationDeclarations.push();
+ notationDeclaration.name = symString(3);
+ } break;
+./
+
+notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId = symString(3);
+ notationDeclaration.publicId.clear();
+ } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId.clear();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ notationDeclaration.systemId = symString(5);
+ } break;
+./
+
+
+
+content_char ::= RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG | QUOTE | DBLQUOTE | LETTER | DIGIT;
+
+scan_content_char ::= content_char;
+/.
+ case $rule_number:
+ isWhitespace = false;
+ // fall through
+./
+
+scan_content_char ::= SPACE;
+/.
+ case $rule_number:
+ sym(1).len += fastScanContentCharList();
+ if (atEnd && !inParseEntity) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+content_char_list ::= content_char_list char_ref;
+content_char_list ::= content_char_list entity_ref;
+content_char_list ::= content_char_list entity_done;
+content_char_list ::= content_char_list scan_content_char;
+content_char_list ::= char_ref;
+content_char_list ::= entity_ref;
+content_char_list ::= entity_done;
+content_char_list ::= scan_content_char;
+
+
+character_content ::= content_char_list %prec SHIFT_THERE;
+/.
+ case $rule_number:
+ if (!textBuffer.isEmpty()) {
+ setType(QXmlStreamReader::Characters);
+ text = &textBuffer;
+ }
+ break;
+./
+
+literal ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+literal ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+literal ::= QUOTE literal_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+literal ::= DBLQUOTE literal_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ break;
+./
+
+literal_content_with_dblquote ::= literal_content_with_dblquote literal_content;
+/.
+ case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote literal_content;
+/.
+ case $rule_number:./
+literal_content_with_dblquote ::= literal_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+literal_content_with_dblquote ::= literal_content;
+literal_content_with_quote ::= literal_content;
+literal_content_with_dblquote ::= DBLQUOTE;
+literal_content_with_quote ::= QUOTE;
+
+literal_content_start ::= LETTER | DIGIT | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+
+literal_content_start ::= SPACE;
+/.
+ case $rule_number:
+ if (normalizeLiterals)
+ textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
+ break;
+./
+
+literal_content ::= literal_content_start;
+/.
+ case $rule_number:
+ sym(1).len += fastScanLiteralContent();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+
+public_literal ::= literal;
+/.
+ case $rule_number: {
+ if (!QXmlUtils::isPublicID(symString(1).toString())) {
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+entity_value ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+entity_value ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+
+entity_value ::= QUOTE entity_value_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+entity_value ::= DBLQUOTE entity_value_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ break;
+./
+
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote entity_value_content;
+/.
+ case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote entity_value_content;
+/.
+ case $rule_number:./
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+entity_value_content_with_dblquote ::= entity_value_content;
+entity_value_content_with_quote ::= entity_value_content;
+entity_value_content_with_dblquote ::= DBLQUOTE;
+entity_value_content_with_quote ::= QUOTE;
+
+entity_value_content ::= LETTER | DIGIT | LANGLE | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | SLASH | COLON | SEMICOLON | COMMA | SPACE | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+entity_value_content ::= char_ref | entity_ref_in_entity_value | entity_done;
+
+
+attribute_value ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+attribute_value ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+attribute_value ::= QUOTE attribute_value_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+attribute_value ::= DBLQUOTE attribute_value_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ lastAttributeValue = symString(1);
+ break;
+./
+
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote attribute_value_content;
+/.
+ case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote attribute_value_content;
+/.
+ case $rule_number:./
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+attribute_value_content_with_dblquote ::= attribute_value_content | DBLQUOTE;
+attribute_value_content_with_quote ::= attribute_value_content | QUOTE;
+
+attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute_value | entity_done;
+
+attribute ::= qname space_opt EQ space_opt attribute_value;
+/.
+ case $rule_number: {
+ QStringRef prefix = symPrefix(1);
+ if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+
+ const QStringRef ns(symString(5));
+ if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+ ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+ else
+ namespaceDeclaration.namespaceUri = addToStringStorage(ns);
+ } else {
+ Attribute &attribute = attributeStack.push();
+ attribute.key = sym(1);
+ attribute.value = sym(5);
+
+ QStringRef attributeQualifiedName = symName(1);
+ bool normalize = false;
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (!dtdAttribute.isCDATA
+ && dtdAttribute.tagName == qualifiedName
+ && dtdAttribute.attributeQualifiedName == attributeQualifiedName
+ ) {
+ normalize = true;
+ break;
+ }
+ }
+ if (normalize) {
+ // normalize attribute value (simplify and trim)
+ int pos = textBuffer.size();
+ int n = 0;
+ bool wasSpace = true;
+ for (int i = 0; i < attribute.value.len; ++i) {
+ QChar c = textBuffer.at(attribute.value.pos + i);
+ if (c.unicode() == ' ') {
+ if (wasSpace)
+ continue;
+ wasSpace = true;
+ } else {
+ wasSpace = false;
+ }
+ textBuffer += textBuffer.at(attribute.value.pos + i);
+ ++n;
+ }
+ if (wasSpace)
+ while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
+ --n;
+ attribute.value.pos = pos;
+ attribute.value.len = n;
+ }
+ if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ QStringRef namespacePrefix = symString(attribute.key);
+ QStringRef namespaceUri = symString(attribute.value);
+ attributeStack.pop();
+ if (((namespacePrefix == QLatin1String("xml"))
+ ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+ || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+ || namespaceUri.isEmpty()
+ || namespacePrefix == QLatin1String("xmlns"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+ namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
+ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+ }
+ }
+ } break;
+./
+
+
+
+attribute_list_opt ::= | space | space attribute_list space_opt;
+attribute_list ::= attribute | attribute_list space attribute;
+
+stag_start ::= LANGLE qname;
+/.
+ case $rule_number: {
+ normalizeLiterals = true;
+ Tag &tag = tagStack_push();
+ prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
+ name = tag.name = addToStringStorage(symString(2));
+ qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
+ if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
+ raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
+ } break;
+./
+
+
+empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
+/.
+ case $rule_number:
+ isEmptyElement = true;
+ // fall through
+./
+
+
+stag ::= stag_start attribute_list_opt RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::StartElement);
+ resolveTag();
+ if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
+ raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+ hasSeenTag = true;
+ break;
+./
+
+
+etag ::= LANGLE SLASH qname space_opt RANGLE;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ if (qualifiedName != symName(3))
+ raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
+ } break;
+./
+
+
+unresolved_entity ::= UNRESOLVED_ENTITY;
+/.
+ case $rule_number:
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
+ break;
+ }
+ setType(QXmlStreamReader::EntityReference);
+ name = &unresolvedEntity;
+ break;
+./
+
+entity_ref ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed) {
+ raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
+ } else {
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacement(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+
+ injectToken(UNRESOLVED_ENTITY);
+ unresolvedEntity = symString(2).toString();
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+
+ } break;
+./
+
+pereference ::= PERCENT name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (parameterEntityHash.contains(reference)) {
+ referenceToParameterEntityDetected = true;
+ Entity &entity = parameterEntityHash[reference];
+ if (entity.unparsed || entity.external) {
+ referenceToUnparsedEntityDetected = true;
+ } else {
+ if (referenceEntity(entity))
+ putString(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ } else if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
+ }
+ } break;
+./
+
+
+
+entity_ref_in_entity_value ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len + 1;
+ break;
+./
+
+entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed || entity.value.isNull()) {
+ raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
+ break;
+ }
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacementInAttributeValue(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
+ }
+ } break;
+./
+
+char_ref ::= AMPERSAND HASH char_ref_value SEMICOLON;
+/.
+ case $rule_number: {
+ if (uint s = resolveCharRef(3)) {
+ if (s >= 0xffff)
+ putStringLiteral(QString::fromUcs4(&s, 1));
+ else
+ putChar((LETTER << 16) | s);
+
+ textBuffer.chop(3 + sym(3).len);
+ clearSym();
+ } else {
+ raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
+ }
+ } break;
+./
+
+
+char_ref_value ::= LETTER | DIGIT;
+char_ref_value ::= char_ref_value LETTER;
+/.
+ case $rule_number:./
+char_ref_value ::= char_ref_value DIGIT;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+
+
+content ::= content character_content;
+content ::= content stag content etag;
+content ::= content empty_element_tag;
+content ::= content comment;
+content ::= content cdata;
+content ::= content xml_decl;
+content ::= content processing_instruction;
+content ::= content doctype_decl;
+content ::= content unresolved_entity;
+content ::= ;
+
+
+space ::= SPACE;
+/.
+ case $rule_number:
+ sym(1).len += fastScanSpace();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+
+space_opt ::=;
+space_opt ::= space;
+
+qname ::= LETTER;
+/.
+ case $rule_number: {
+ sym(1).len += fastScanName(&sym(1).prefix);
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+name ::= LETTER;
+/.
+ case $rule_number:
+ sym(1).len += fastScanName();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+nmtoken ::= LETTER;
+/.
+ case $rule_number:./
+nmtoken ::= DIGIT;
+/.
+ case $rule_number:./
+nmtoken ::= DOT;
+/.
+ case $rule_number:./
+nmtoken ::= DASH;
+/.
+ case $rule_number:./
+nmtoken ::= COLON;
+/.
+ case $rule_number:
+ sym(1).len += fastScanNMTOKEN();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+
+ break;
+./
+
+
+/.
+ default:
+ ;
+ } // switch
+ act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
+ if (type != QXmlStreamReader::NoToken)
+ return true;
+ } else {
+ parseError();
+ break;
+ }
+ }
+ return false;
+}
+#endif //QT_NO_XMLSTREAMREADER.xml
+
+./
diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h
new file mode 100644
index 0000000000..e5cb61e512
--- /dev/null
+++ b/src/corelib/xml/qxmlstream.h
@@ -0,0 +1,491 @@
+/****************************************************************************
+**
+** 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 QtCore module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLSTREAM_H
+#define QXMLSTREAM_H
+
+#include <QtCore/qiodevice.h>
+
+#ifndef QT_NO_XMLSTREAM
+
+#include <QtCore/qstring.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// QXmlStream* was originally in the QtXml module
+// since we've moved it to QtCore in Qt 4.4.0, we need to
+// keep binary compatibility
+//
+// The list of supported platforms is in:
+// http://qt.nokia.com/doc/supported_platforms.html
+//
+// These platforms do not support symbol moving nor duplication
+// (because duplicate symbols cause warnings when linking):
+// Apple MacOS X (Mach-O executable format)
+// special case: 64-bit on Mac wasn't supported before 4.5.0
+// IBM AIX (XCOFF executable format)
+//
+// These platforms do not support symbol moving but allow it to be duplicated:
+// Microsoft Windows (COFF PE executable format)
+// special case: Windows CE wasn't supported before 4.4.0
+//
+// These platforms support symbol moving:
+// HP HP-UX (PA-RISC2.0 shared executables)
+// HP HP-UXi (ELF executable format)
+// FreeBSD (ELF executable format)
+// Linux (ELF executable format)
+// SGI IRIX (ELF executable format)
+// Sun Solaris (ELF executable format)
+//
+// Other platforms are supported through community contributions only.
+// We are taking the optimist scenario here to avoid creating more
+// symbols to be supported.
+
+#if defined(Q_OS_MAC32) || defined(Q_OS_AIX)
+# if !defined QT_BUILD_XML_LIB
+# define Q_XMLSTREAM_RENAME_SYMBOLS
+# endif
+#endif
+
+#if defined QT_BUILD_XML_LIB
+# define Q_XMLSTREAM_EXPORT Q_XML_EXPORT
+#else
+# define Q_XMLSTREAM_EXPORT Q_CORE_EXPORT
+#endif
+
+#if defined Q_XMLSTREAM_RENAME_SYMBOLS
+// don't worry, we'll undef and change to typedef at the bottom of the file
+# define QXmlStreamAttribute QCoreXmlStreamAttribute
+# define QXmlStreamAttributes QCoreXmlStreamAttributes
+# define QXmlStreamEntityDeclaration QCoreXmlStreamEntityDeclaration
+# define QXmlStreamEntityDeclarations QCoreXmlStreamEntityDeclarations
+# define QXmlStreamEntityResolver QCoreXmlStreamEntityResolver
+# define QXmlStreamNamespaceDeclaration QCoreXmlStreamNamespaceDeclaration
+# define QXmlStreamNamespaceDeclarations QCoreXmlStreamNamespaceDeclarations
+# define QXmlStreamNotationDeclaration QCoreXmlStreamNotationDeclaration
+# define QXmlStreamNotationDeclarations QCoreXmlStreamNotationDeclarations
+# define QXmlStreamReader QCoreXmlStreamReader
+# define QXmlStreamStringRef QCoreXmlStreamStringRef
+# define QXmlStreamWriter QCoreXmlStreamWriter
+#endif
+
+class Q_XMLSTREAM_EXPORT QXmlStreamStringRef {
+ QString m_string;
+ int m_position, m_size;
+public:
+ inline QXmlStreamStringRef():m_position(0), m_size(0){}
+ inline QXmlStreamStringRef(const QStringRef &aString)
+ :m_string(aString.string()?*aString.string():QString()), m_position(aString.position()), m_size(aString.size()){}
+ inline QXmlStreamStringRef(const QString &aString):m_string(aString), m_position(0), m_size(aString.size()){}
+ inline ~QXmlStreamStringRef(){}
+ inline void clear() { m_string.clear(); m_position = m_size = 0; }
+ inline operator QStringRef() const { return QStringRef(&m_string, m_position, m_size); }
+ inline const QString *string() const { return &m_string; }
+ inline int position() const { return m_position; }
+ inline int size() const { return m_size; }
+};
+
+
+class QXmlStreamReaderPrivate;
+class QXmlStreamAttributes;
+class Q_XMLSTREAM_EXPORT QXmlStreamAttribute {
+ QXmlStreamStringRef m_name, m_namespaceUri, m_qualifiedName, m_value;
+ void *reserved;
+ uint m_isDefault : 1;
+ friend class QXmlStreamReaderPrivate;
+ friend class QXmlStreamAttributes;
+public:
+ QXmlStreamAttribute();
+ QXmlStreamAttribute(const QString &qualifiedName, const QString &value);
+ QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value);
+ QXmlStreamAttribute(const QXmlStreamAttribute &);
+ QXmlStreamAttribute& operator=(const QXmlStreamAttribute &);
+ ~QXmlStreamAttribute();
+ inline QStringRef namespaceUri() const { return m_namespaceUri; }
+ inline QStringRef name() const { return m_name; }
+ inline QStringRef qualifiedName() const { return m_qualifiedName; }
+ inline QStringRef prefix() const {
+ return QStringRef(m_qualifiedName.string(),
+ m_qualifiedName.position(),
+ qMax(0, m_qualifiedName.size() - m_name.size() - 1));
+ }
+ inline QStringRef 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())));
+ }
+ inline bool operator!=(const QXmlStreamAttribute &other) const
+ { return !operator==(other); }
+};
+
+Q_DECLARE_TYPEINFO(QXmlStreamAttribute, Q_MOVABLE_TYPE);
+
+class Q_XMLSTREAM_EXPORT QXmlStreamAttributes : public QVector<QXmlStreamAttribute>
+{
+public:
+ inline QXmlStreamAttributes() {}
+ QStringRef value(const QString &namespaceUri, const QString &name) const;
+ QStringRef value(const QString &namespaceUri, const QLatin1String &name) const;
+ QStringRef value(const QLatin1String &namespaceUri, const QLatin1String &name) const;
+ QStringRef value(const QString &qualifiedName) const;
+ QStringRef value(const QLatin1String &qualifiedName) const;
+ void append(const QString &namespaceUri, const QString &name, const QString &value);
+ void append(const QString &qualifiedName, const QString &value);
+
+ inline bool hasAttribute(const QString &qualifiedName) const
+ {
+ return !value(qualifiedName).isNull();
+ }
+
+ inline bool hasAttribute(const QLatin1String &qualifiedName) const
+ {
+ return !value(qualifiedName).isNull();
+ }
+
+ inline bool hasAttribute(const QString &namespaceUri, const QString &name) const
+ {
+ return !value(namespaceUri, name).isNull();
+ }
+
+#if !defined(Q_NO_USING_KEYWORD)
+ using QVector<QXmlStreamAttribute>::append;
+#else
+ inline void append(const QXmlStreamAttribute &attribute)
+ { QVector<QXmlStreamAttribute>::append(attribute); }
+#endif
+};
+
+class Q_XMLSTREAM_EXPORT QXmlStreamNamespaceDeclaration {
+ QXmlStreamStringRef m_prefix, m_namespaceUri;
+ void *reserved;
+
+ friend class QXmlStreamReaderPrivate;
+public:
+ QXmlStreamNamespaceDeclaration();
+ QXmlStreamNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &);
+ QXmlStreamNamespaceDeclaration(const QString &prefix, const QString &namespaceUri);
+ ~QXmlStreamNamespaceDeclaration();
+ QXmlStreamNamespaceDeclaration& operator=(const QXmlStreamNamespaceDeclaration &);
+ inline QStringRef prefix() const { return m_prefix; }
+ inline QStringRef namespaceUri() const { return m_namespaceUri; }
+ inline bool operator==(const QXmlStreamNamespaceDeclaration &other) const {
+ return (prefix() == other.prefix() && namespaceUri() == other.namespaceUri());
+ }
+ inline bool operator!=(const QXmlStreamNamespaceDeclaration &other) const
+ { return !operator==(other); }
+};
+
+Q_DECLARE_TYPEINFO(QXmlStreamNamespaceDeclaration, Q_MOVABLE_TYPE);
+typedef QVector<QXmlStreamNamespaceDeclaration> QXmlStreamNamespaceDeclarations;
+
+class Q_XMLSTREAM_EXPORT QXmlStreamNotationDeclaration {
+ QXmlStreamStringRef m_name, m_systemId, m_publicId;
+ void *reserved;
+
+ friend class QXmlStreamReaderPrivate;
+public:
+ QXmlStreamNotationDeclaration();
+ ~QXmlStreamNotationDeclaration();
+ QXmlStreamNotationDeclaration(const QXmlStreamNotationDeclaration &);
+ QXmlStreamNotationDeclaration& operator=(const QXmlStreamNotationDeclaration &);
+ inline QStringRef name() const { return m_name; }
+ inline QStringRef systemId() const { return m_systemId; }
+ inline QStringRef publicId() const { return m_publicId; }
+ inline bool operator==(const QXmlStreamNotationDeclaration &other) const {
+ return (name() == other.name() && systemId() == other.systemId()
+ && publicId() == other.publicId());
+ }
+ inline bool operator!=(const QXmlStreamNotationDeclaration &other) const
+ { return !operator==(other); }
+};
+
+Q_DECLARE_TYPEINFO(QXmlStreamNotationDeclaration, Q_MOVABLE_TYPE);
+typedef QVector<QXmlStreamNotationDeclaration> QXmlStreamNotationDeclarations;
+
+class Q_XMLSTREAM_EXPORT QXmlStreamEntityDeclaration {
+ QXmlStreamStringRef m_name, m_notationName, m_systemId, m_publicId, m_value;
+ void *reserved;
+
+ friend class QXmlStreamReaderPrivate;
+public:
+ QXmlStreamEntityDeclaration();
+ ~QXmlStreamEntityDeclaration();
+ QXmlStreamEntityDeclaration(const QXmlStreamEntityDeclaration &);
+ QXmlStreamEntityDeclaration& operator=(const QXmlStreamEntityDeclaration &);
+ inline QStringRef name() const { return m_name; }
+ inline QStringRef notationName() const { return m_notationName; }
+ inline QStringRef systemId() const { return m_systemId; }
+ inline QStringRef publicId() const { return m_publicId; }
+ inline QStringRef 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());
+ }
+ inline bool operator!=(const QXmlStreamEntityDeclaration &other) const
+ { return !operator==(other); }
+};
+
+Q_DECLARE_TYPEINFO(QXmlStreamEntityDeclaration, Q_MOVABLE_TYPE);
+typedef QVector<QXmlStreamEntityDeclaration> QXmlStreamEntityDeclarations;
+
+
+class Q_XMLSTREAM_EXPORT QXmlStreamEntityResolver
+{
+public:
+ virtual ~QXmlStreamEntityResolver();
+ virtual QString resolveEntity(const QString& publicId, const QString& systemId);
+ virtual QString resolveUndeclaredEntity(const QString &name);
+};
+
+#ifndef QT_NO_XMLSTREAMREADER
+class Q_XMLSTREAM_EXPORT QXmlStreamReader {
+ QDOC_PROPERTY(bool namespaceProcessing READ namespaceProcessing WRITE setNamespaceProcessing)
+public:
+ enum TokenType {
+ NoToken = 0,
+ Invalid,
+ StartDocument,
+ EndDocument,
+ StartElement,
+ EndElement,
+ Characters,
+ Comment,
+ DTD,
+ EntityReference,
+ ProcessingInstruction
+ };
+
+
+ QXmlStreamReader();
+ QXmlStreamReader(QIODevice *device);
+ QXmlStreamReader(const QByteArray &data);
+ QXmlStreamReader(const QString &data);
+ QXmlStreamReader(const char * data);
+ ~QXmlStreamReader();
+
+ void setDevice(QIODevice *device);
+ QIODevice *device() const;
+ void addData(const QByteArray &data);
+ void addData(const QString &data);
+ void addData(const char *data);
+ void clear();
+
+
+ bool atEnd() const;
+ TokenType readNext();
+
+ bool readNextStartElement();
+ void skipCurrentElement();
+
+ TokenType tokenType() const;
+ QString tokenString() const;
+
+ void setNamespaceProcessing(bool);
+ bool namespaceProcessing() const;
+
+ inline bool isStartDocument() const { return tokenType() == StartDocument; }
+ inline bool isEndDocument() const { return tokenType() == EndDocument; }
+ inline bool isStartElement() const { return tokenType() == StartElement; }
+ inline bool isEndElement() const { return tokenType() == EndElement; }
+ inline bool isCharacters() const { return tokenType() == Characters; }
+ bool isWhitespace() const;
+ bool isCDATA() const;
+ inline bool isComment() const { return tokenType() == Comment; }
+ inline bool isDTD() const { return tokenType() == DTD; }
+ inline bool isEntityReference() const { return tokenType() == EntityReference; }
+ inline bool isProcessingInstruction() const { return tokenType() == ProcessingInstruction; }
+
+ bool isStandaloneDocument() const;
+ QStringRef documentVersion() const;
+ QStringRef documentEncoding() const;
+
+ qint64 lineNumber() const;
+ qint64 columnNumber() const;
+ qint64 characterOffset() const;
+
+ QXmlStreamAttributes attributes() const;
+
+ enum ReadElementTextBehaviour {
+ ErrorOnUnexpectedElement,
+ IncludeChildElements,
+ SkipChildElements
+ };
+ QString readElementText(ReadElementTextBehaviour behaviour);
+ QString readElementText();
+
+ QStringRef name() const;
+ QStringRef namespaceUri() const;
+ QStringRef qualifiedName() const;
+ QStringRef prefix() const;
+
+ QStringRef processingInstructionTarget() const;
+ QStringRef processingInstructionData() const;
+
+ QStringRef text() const;
+
+ QXmlStreamNamespaceDeclarations namespaceDeclarations() const;
+ void addExtraNamespaceDeclaration(const QXmlStreamNamespaceDeclaration &extraNamespaceDeclaraction);
+ void addExtraNamespaceDeclarations(const QXmlStreamNamespaceDeclarations &extraNamespaceDeclaractions);
+ QXmlStreamNotationDeclarations notationDeclarations() const;
+ QXmlStreamEntityDeclarations entityDeclarations() const;
+ QStringRef dtdName() const;
+ QStringRef dtdPublicId() const;
+ QStringRef dtdSystemId() const;
+
+
+ enum Error {
+ NoError,
+ UnexpectedElementError,
+ CustomError,
+ NotWellFormedError,
+ PrematureEndOfDocumentError
+ };
+ void raiseError(const QString& message = QString());
+ QString errorString() const;
+ Error error() const;
+
+ inline bool hasError() const
+ {
+ return error() != NoError;
+ }
+
+ void setEntityResolver(QXmlStreamEntityResolver *resolver);
+ QXmlStreamEntityResolver *entityResolver() const;
+
+private:
+ Q_DISABLE_COPY(QXmlStreamReader)
+ Q_DECLARE_PRIVATE(QXmlStreamReader)
+ QScopedPointer<QXmlStreamReaderPrivate> d_ptr;
+
+};
+#endif // QT_NO_XMLSTREAMREADER
+
+#ifndef QT_NO_XMLSTREAMWRITER
+
+class QXmlStreamWriterPrivate;
+
+class Q_XMLSTREAM_EXPORT QXmlStreamWriter
+{
+ QDOC_PROPERTY(bool autoFormatting READ autoFormatting WRITE setAutoFormatting)
+ QDOC_PROPERTY(int autoFormattingIndent READ autoFormattingIndent WRITE setAutoFormattingIndent)
+public:
+ QXmlStreamWriter();
+ QXmlStreamWriter(QIODevice *device);
+ QXmlStreamWriter(QByteArray *array);
+ QXmlStreamWriter(QString *string);
+ ~QXmlStreamWriter();
+
+ void setDevice(QIODevice *device);
+ QIODevice *device() const;
+
+#ifndef QT_NO_TEXTCODEC
+ void setCodec(QTextCodec *codec);
+ void setCodec(const char *codecName);
+ QTextCodec *codec() const;
+#endif
+
+ void setAutoFormatting(bool);
+ bool autoFormatting() const;
+
+ void setAutoFormattingIndent(int spacesOrTabs);
+ int autoFormattingIndent() const;
+
+ void writeAttribute(const QString &qualifiedName, const QString &value);
+ void writeAttribute(const QString &namespaceUri, const QString &name, const QString &value);
+ void writeAttribute(const QXmlStreamAttribute& attribute);
+ void writeAttributes(const QXmlStreamAttributes& attributes);
+
+ void writeCDATA(const QString &text);
+ void writeCharacters(const QString &text);
+ void writeComment(const QString &text);
+
+ void writeDTD(const QString &dtd);
+
+ void writeEmptyElement(const QString &qualifiedName);
+ void writeEmptyElement(const QString &namespaceUri, const QString &name);
+
+ void writeTextElement(const QString &qualifiedName, const QString &text);
+ void writeTextElement(const QString &namespaceUri, const QString &name, const QString &text);
+
+ void writeEndDocument();
+ void writeEndElement();
+
+ void writeEntityReference(const QString &name);
+ void writeNamespace(const QString &namespaceUri, const QString &prefix = QString());
+ void writeDefaultNamespace(const QString &namespaceUri);
+ void writeProcessingInstruction(const QString &target, const QString &data = QString());
+
+ void writeStartDocument();
+ void writeStartDocument(const QString &version);
+ void writeStartDocument(const QString &version, bool standalone);
+ void writeStartElement(const QString &qualifiedName);
+ void writeStartElement(const QString &namespaceUri, const QString &name);
+
+#ifndef QT_NO_XMLSTREAMREADER
+ void writeCurrentToken(const QXmlStreamReader &reader);
+#endif
+
+ bool hasError() const;
+
+private:
+ Q_DISABLE_COPY(QXmlStreamWriter)
+ Q_DECLARE_PRIVATE(QXmlStreamWriter)
+ QScopedPointer<QXmlStreamWriterPrivate> d_ptr;
+};
+#endif // QT_NO_XMLSTREAMWRITER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_XMLSTREAM
+#endif // QXMLSTREAM_H
diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h
new file mode 100644
index 0000000000..a601a81830
--- /dev/null
+++ b/src/corelib/xml/qxmlstream_p.h
@@ -0,0 +1,1965 @@
+/****************************************************************************
+**
+** 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 QtCore module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// This file was generated by qlalr - DO NOT EDIT!
+#ifndef QXMLSTREAM_P_H
+#define QXMLSTREAM_P_H
+
+#if defined(ERROR)
+# undef ERROR
+#endif
+
+class QXmlStreamReader_Table
+{
+public:
+ enum VariousConstants {
+ EOF_SYMBOL = 0,
+ AMPERSAND = 5,
+ ANY = 41,
+ ATTLIST = 31,
+ BANG = 25,
+ CDATA = 47,
+ CDATA_START = 28,
+ COLON = 17,
+ COMMA = 19,
+ DASH = 20,
+ DBLQUOTE = 8,
+ DIGIT = 27,
+ DOCTYPE = 29,
+ DOT = 23,
+ ELEMENT = 30,
+ EMPTY = 40,
+ ENTITIES = 51,
+ ENTITY = 32,
+ ENTITY_DONE = 45,
+ EQ = 14,
+ ERROR = 43,
+ FIXED = 39,
+ HASH = 6,
+ ID = 48,
+ IDREF = 49,
+ IDREFS = 50,
+ IMPLIED = 38,
+ LANGLE = 3,
+ LBRACK = 9,
+ LETTER = 26,
+ LPAREN = 11,
+ NDATA = 36,
+ NMTOKEN = 52,
+ NMTOKENS = 53,
+ NOTATION = 33,
+ NOTOKEN = 1,
+ PARSE_ENTITY = 44,
+ PCDATA = 42,
+ PERCENT = 15,
+ PIPE = 13,
+ PLUS = 21,
+ PUBLIC = 35,
+ QUESTIONMARK = 24,
+ QUOTE = 7,
+ RANGLE = 4,
+ RBRACK = 10,
+ REQUIRED = 37,
+ RPAREN = 12,
+ SEMICOLON = 18,
+ SHIFT_THERE = 56,
+ SLASH = 16,
+ SPACE = 2,
+ STAR = 22,
+ SYSTEM = 34,
+ UNRESOLVED_ENTITY = 46,
+ VERSION = 55,
+ XML = 54,
+
+ ACCEPT_STATE = 416,
+ RULE_COUNT = 270,
+ STATE_COUNT = 427,
+ TERMINAL_COUNT = 57,
+ NON_TERMINAL_COUNT = 84,
+
+ GOTO_INDEX_OFFSET = 427,
+ GOTO_INFO_OFFSET = 1017,
+ GOTO_CHECK_OFFSET = 1017
+ };
+
+ static const char *const spell [];
+ static const short lhs [];
+ static const short rhs [];
+ static const short goto_default [];
+ static const short action_default [];
+ static const short action_index [];
+ static const short action_info [];
+ static const short action_check [];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
+ if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
+ return goto_default [nt];
+
+ return action_info [GOTO_INFO_OFFSET + yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
+};
+
+
+const char *const QXmlStreamReader_Table::spell [] = {
+ "end of file", 0, " ", "<", ">", "&", "#", "\'", "\"", "[",
+ "]", "(", ")", "|", "=", "%", "/", ":", ";", ",",
+ "-", "+", "*", ".", "?", "!", "[a-zA-Z]", "[0-9]", "[CDATA[", "DOCTYPE",
+ "ELEMENT", "ATTLIST", "ENTITY", "NOTATION", "SYSTEM", "PUBLIC", "NDATA", "REQUIRED", "IMPLIED", "FIXED",
+ "EMPTY", "ANY", "PCDATA", 0, 0, 0, 0, "CDATA", "ID", "IDREF",
+ "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", 0};
+
+const short QXmlStreamReader_Table::lhs [] = {
+ 57, 57, 59, 59, 59, 59, 59, 59, 59, 59,
+ 67, 68, 64, 72, 72, 72, 75, 66, 66, 66,
+ 66, 79, 78, 80, 80, 80, 80, 80, 80, 80,
+ 81, 81, 81, 81, 81, 81, 81, 87, 83, 88,
+ 88, 88, 88, 91, 92, 93, 93, 93, 93, 94,
+ 94, 96, 96, 96, 97, 97, 98, 98, 99, 99,
+ 100, 100, 89, 89, 95, 90, 101, 101, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 104, 105,
+ 105, 105, 105, 107, 108, 109, 109, 84, 84, 110,
+ 110, 112, 112, 85, 85, 85, 65, 65, 76, 114,
+ 63, 115, 116, 86, 86, 86, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 118,
+ 118, 119, 119, 119, 119, 119, 119, 119, 119, 122,
+ 70, 70, 70, 70, 123, 124, 123, 124, 123, 124,
+ 123, 124, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 125, 73, 113, 113, 113, 113,
+ 127, 128, 127, 128, 127, 128, 127, 128, 129, 129,
+ 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
+ 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
+ 129, 129, 129, 106, 106, 106, 106, 131, 132, 131,
+ 132, 131, 131, 132, 132, 133, 133, 133, 133, 135,
+ 71, 71, 71, 136, 136, 137, 62, 60, 61, 138,
+ 121, 82, 130, 134, 120, 139, 139, 139, 139, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 74,
+ 69, 69, 77, 111, 102, 102, 102, 102, 102, 140};
+
+const short QXmlStreamReader_Table::rhs [] = {
+ 2, 1, 4, 2, 2, 2, 2, 2, 2, 0,
+ 1, 1, 9, 2, 4, 0, 4, 4, 6, 6,
+ 4, 1, 3, 1, 1, 1, 2, 2, 2, 0,
+ 1, 1, 1, 1, 1, 1, 1, 4, 4, 1,
+ 1, 1, 1, 1, 2, 1, 1, 1, 0, 2,
+ 2, 2, 6, 6, 1, 5, 1, 5, 3, 5,
+ 0, 1, 6, 8, 4, 2, 1, 5, 1, 1,
+ 1, 1, 1, 1, 1, 1, 6, 7, 1, 2,
+ 2, 1, 4, 3, 3, 1, 2, 5, 6, 4,
+ 6, 3, 5, 5, 3, 4, 4, 5, 2, 3,
+ 2, 2, 4, 5, 5, 7, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 2, 2, 3, 3, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 3, 3,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 3, 3, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 5,
+ 0, 1, 3, 1, 3, 2, 4, 3, 5, 1,
+ 3, 3, 3, 3, 4, 1, 1, 2, 2, 2,
+ 4, 2, 2, 2, 2, 2, 2, 2, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 2};
+
+const short QXmlStreamReader_Table::action_default [] = {
+ 10, 259, 0, 2, 1, 0, 125, 117, 119, 120,
+ 127, 129, 123, 11, 114, 108, 0, 109, 128, 111,
+ 115, 113, 121, 124, 126, 107, 110, 112, 118, 116,
+ 131, 122, 240, 12, 254, 136, 250, 253, 0, 130,
+ 140, 257, 16, 252, 138, 137, 0, 256, 139, 259,
+ 231, 258, 255, 0, 0, 264, 0, 247, 246, 0,
+ 249, 248, 245, 241, 99, 263, 0, 236, 0, 0,
+ 260, 97, 98, 101, 0, 132, 134, 133, 135, 0,
+ 0, 261, 0, 0, 176, 0, 173, 165, 167, 168,
+ 142, 154, 171, 162, 156, 157, 153, 159, 163, 161,
+ 169, 172, 152, 155, 158, 160, 166, 164, 174, 170,
+ 150, 175, 0, 144, 148, 146, 151, 141, 149, 0,
+ 147, 143, 145, 0, 15, 14, 262, 0, 22, 21,
+ 261, 30, 0, 20, 0, 0, 32, 37, 31, 0,
+ 33, 261, 0, 34, 0, 24, 0, 35, 0, 26,
+ 36, 25, 0, 242, 41, 40, 261, 43, 49, 261,
+ 42, 0, 44, 261, 49, 261, 0, 261, 0, 49,
+ 0, 48, 46, 47, 51, 52, 261, 261, 0, 57,
+ 261, 54, 261, 0, 58, 0, 55, 261, 53, 261,
+ 0, 56, 65, 0, 261, 61, 261, 0, 59, 62,
+ 63, 0, 261, 0, 0, 60, 64, 45, 50, 66,
+ 0, 39, 0, 0, 261, 0, 94, 95, 0, 0,
+ 0, 0, 261, 0, 210, 201, 203, 205, 178, 190,
+ 208, 199, 193, 191, 194, 189, 196, 198, 206, 209,
+ 188, 192, 195, 197, 202, 200, 204, 207, 211, 213,
+ 212, 186, 0, 0, 243, 180, 184, 182, 0, 0,
+ 93, 187, 177, 185, 0, 183, 179, 181, 92, 0,
+ 96, 0, 0, 0, 0, 0, 261, 86, 261, 0,
+ 262, 0, 87, 0, 89, 69, 74, 73, 70, 71,
+ 72, 261, 75, 76, 0, 0, 0, 269, 268, 266,
+ 267, 265, 67, 261, 0, 261, 0, 0, 68, 77,
+ 261, 0, 261, 0, 0, 78, 0, 79, 0, 82,
+ 85, 0, 0, 215, 225, 224, 0, 227, 229, 228,
+ 226, 0, 244, 217, 221, 219, 223, 214, 222, 0,
+ 220, 216, 218, 0, 81, 80, 0, 83, 0, 84,
+ 88, 100, 0, 38, 0, 0, 0, 0, 91, 90,
+ 0, 103, 23, 27, 29, 28, 0, 0, 261, 262,
+ 0, 261, 0, 106, 105, 261, 0, 104, 102, 0,
+ 0, 18, 261, 17, 0, 19, 0, 0, 251, 0,
+ 261, 0, 239, 0, 232, 238, 0, 237, 234, 261,
+ 261, 262, 233, 235, 0, 261, 0, 230, 261, 0,
+ 261, 0, 231, 0, 0, 13, 270, 9, 5, 8,
+ 4, 0, 7, 259, 6, 0, 3};
+
+const short QXmlStreamReader_Table::goto_default [] = {
+ 2, 4, 3, 49, 388, 43, 37, 52, 47, 41,
+ 249, 53, 127, 84, 393, 81, 85, 126, 42, 46,
+ 169, 130, 131, 146, 145, 149, 138, 136, 140, 147,
+ 139, 159, 160, 157, 168, 167, 209, 165, 164, 166,
+ 187, 180, 196, 200, 303, 302, 295, 321, 320, 319,
+ 279, 277, 278, 142, 56, 141, 222, 38, 34, 148,
+ 39, 48, 40, 248, 45, 36, 119, 112, 330, 111,
+ 264, 252, 251, 250, 339, 326, 325, 329, 398, 399,
+ 50, 51, 59, 0};
+
+const short QXmlStreamReader_Table::action_index [] = {
+ -21, -57, 33, 119, 960, 70, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, 105, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, 40, -57,
+ 795, -57, 47, -57, -57, -57, 107, -57, -57, -57,
+ 84, -57, -57, -38, 80, -57, 12, -57, -57, 97,
+ -57, -57, -57, -57, -57, -57, 13, -57, 56, 34,
+ -57, -57, -57, -57, 51, -57, -57, -57, -57, 53,
+ 57, 84, 300, 255, -57, 84, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, 355, -57, -57, -57, -57, -57, -57, 326,
+ -57, -57, -57, 48, -57, -57, -57, 50, -57, -57,
+ 84, 155, 32, -57, 38, 22, -57, -57, -57, 115,
+ -57, 35, 156, -57, 173, -57, 245, -57, 44, -57,
+ -57, -57, 16, -57, -57, -57, 29, -57, 116, 29,
+ -57, 133, -57, 29, 129, 84, 15, 29, -22, 121,
+ 74, -57, -57, -57, -57, 82, 29, 29, 88, -57,
+ 29, 7, 29, 86, -57, 83, -57, 27, 19, 26,
+ 94, -57, -57, 106, 29, 3, 29, -8, -57, -57,
+ -57, 104, 29, -6, -7, -57, -57, -57, -57, -57,
+ 17, -57, -2, 11, 29, 18, -57, -57, 850, 65,
+ 465, 67, 84, 135, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, 630, 24, -57, -57, -57, -57, 84, 76,
+ -57, -57, -57, -57, 740, -57, -57, -57, -57, 39,
+ -57, 23, 21, 14, 78, 22, 84, -57, 84, 184,
+ 20, 31, -57, 41, -57, -57, -57, -57, -57, -57,
+ -57, 84, -57, -57, 36, 126, 162, -57, -57, -57,
+ -57, -57, -57, 29, 79, 29, 29, 160, -57, -57,
+ 29, 145, 29, 75, 29, -57, 575, -57, 410, -57,
+ -57, 110, 64, -57, -57, -57, 685, -57, -57, -57,
+ -57, -17, -57, -57, -57, -57, -57, -57, -57, 520,
+ -57, -57, -57, 29, -57, -57, 61, -57, 29, -57,
+ -57, -57, 29, -57, 29, 29, -15, 29, -57, -57,
+ 29, -57, -57, -57, -57, -57, 95, 43, 29, 45,
+ 9, 29, 10, -57, -57, 29, 2, -57, -57, -24,
+ 190, -57, 29, -57, 1, -57, 905, 150, -57, -26,
+ 29, 0, -57, 109, -26, -57, 8, -57, -57, 29,
+ 29, -19, -57, -57, -11, 29, 59, -57, 29, -5,
+ 29, 103, 29, -16, 6, -57, -57, -57, -57, -57,
+ -57, 69, -57, -57, -57, 905, -57,
+
+ -84, -84, -84, 204, 75, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, 7, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ 101, -84, -84, -84, -84, -84, -84, -84, -84, 64,
+ 54, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, 68, -84, 30, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ 32, -84, -16, -7, -84, 42, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, 45, -84, -84, -84, -84, -84, -84, 44,
+ -84, -84, -84, 33, -84, -84, -84, -84, -84, -84,
+ 36, 108, -84, -84, -84, 69, -84, -84, -84, 62,
+ -84, 63, -84, -84, -84, -84, 118, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -2, -84, -84, -10,
+ -84, -84, -84, 25, -21, 11, -84, 20, -84, -25,
+ -84, -84, -84, -84, -84, -84, 1, 2, -36, -84,
+ -9, -84, 5, -13, -84, -8, -84, 6, -84, 8,
+ 12, -84, -84, -84, 23, -84, 4, -1, -84, -84,
+ -84, -84, 0, -84, -14, -84, -84, -84, -84, -84,
+ -84, -84, 55, -84, 58, -84, -84, -84, -84, 53,
+ 47, 123, 67, 66, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -15, -84, -84, -84, -84, -84, 41, 40,
+ -84, -84, -84, -84, -46, -84, -84, -84, -84, -84,
+ -84, 35, -84, 34, 37, 18, 70, -84, 89, -84,
+ 43, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, 48, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, 31, -84, 29, 27, 17, -84, -84,
+ 38, 24, 39, -84, 49, -84, 71, -84, 93, -84,
+ -84, -84, -12, -84, -84, -84, 94, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, 78,
+ -84, -84, -84, 50, -84, -84, 46, -84, 56, -84,
+ -84, -84, 60, -84, 61, 59, 51, 57, -84, -84,
+ 14, -84, -84, -84, -84, -84, -11, -6, 72, -5,
+ -84, -3, -84, -84, -84, 52, -84, -84, -84, -20,
+ 77, -84, 21, -84, -84, -84, 76, 16, -84, 19,
+ 26, -84, -84, -84, 10, -84, -84, -84, -84, 80,
+ 13, 73, -84, -84, -84, 22, -27, -84, 9, -84,
+ 28, 15, 82, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, 3, -84, 98, -84};
+
+const short QXmlStreamReader_Table::action_info [] = {
+ 65, 332, 65, 405, 392, 385, 377, 65, 414, 410,
+ 415, 55, 397, 374, 373, 217, 206, 408, 65, 65,
+ 207, 211, 216, 1, 55, 199, 182, 192, 70, 70,
+ 63, 70, 189, 416, 153, 350, 133, 70, 72, 55,
+ 65, 351, 254, 270, 73, 284, 65, 310, 55, 65,
+ 83, 82, 83, 82, 129, 83, 82, 54, 70, 128,
+ 83, 82, 66, 64, 83, 82, 318, 316, 318, 316,
+ 54, 212, 83, 82, 83, 82, 54, 55, 367, 366,
+ 69, 80, 79, 83, 82, 163, 70, 314, 305, 272,
+ 55, 306, 305, 354, 163, 177, 55, 163, 379, 163,
+ 65, 176, 83, 82, 55, 163, 58, 57, 0, 65,
+ 83, 82, 65, 395, 65, 62, 203, 202, 195, 194,
+ 65, 417, 16, 61, 60, 396, 156, 272, 0, 66,
+ 64, 65, 317, 318, 316, 378, 379, 171, 173, 162,
+ 172, 54, 171, 173, 163, 172, 0, 345, 344, 343,
+ 171, 173, 0, 172, 0, 155, 154, 70, 134, 65,
+ 0, 55, 297, 220, 218, 298, 389, 0, 300, 0,
+ 135, 301, 299, 33, 66, 64, 65, 297, 0, 297,
+ 298, 0, 298, 300, 0, 300, 301, 299, 301, 299,
+ 221, 219, 70, 272, 381, 291, 0, 0, 0, 128,
+ 13, 0, 0, 273, 271, 274, 275, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 287, 294, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 285, 288, 289, 290, 286, 292, 293, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 70, 134, 0,
+ 0, 0, 0, 0, 0, 362, 0, 108, 0, 103,
+ 135, 94, 117, 116, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 0, 94, 102, 90, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 108, 0,
+ 103, 0, 94, 121, 120, 95, 104, 97, 105, 99,
+ 93, 98, 107, 87, 106, 88, 89, 100, 109, 92,
+ 101, 86, 96, 91, 0, 0, 0, 108, 0, 103,
+ 0, 94, 114, 113, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 322, 94, 337, 336, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 246, 233, 241,
+ 223, 232, 262, 261, 234, 242, 236, 243, 237, 231,
+ 0, 245, 225, 244, 226, 227, 238, 247, 230, 239,
+ 224, 235, 229, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 322, 94, 341, 340, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 108, 0, 103,
+ 322, 94, 324, 323, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 256, 255, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 108, 0, 103,
+ 322, 94, 334, 333, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 266, 265, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 0, 25,
+ 74, 15, 24, 10, 17, 26, 19, 27, 21, 14,
+ 20, 29, 7, 28, 8, 9, 22, 31, 12, 23,
+ 6, 18, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 240, 228, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 387, 25,
+ 5, 15, 24, 10, 17, 26, 19, 27, 21, 14,
+ 20, 29, 7, 28, 8, 9, 22, 31, 12, 23,
+ 6, 18, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 32, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 30, 16, 25, 5, 15, 24, 10, 17,
+ 26, 19, 27, 21, 14, 20, 29, 7, 28, 8,
+ 9, 22, 31, 12, 23, 6, 18, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 32, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0,
+
+ 380, 179, 210, 181, 425, 368, 205, 375, 371, 372,
+ 161, 208, 204, 178, 185, 174, 201, 183, 188, 198,
+ 190, 409, 407, 175, 184, 404, 267, 67, 412, 186,
+ 400, 361, 193, 384, 406, 197, 67, 170, 391, 390,
+ 411, 307, 331, 304, 309, 125, 124, 71, 132, 191,
+ 311, 313, 110, 260, 352, 276, 0, 257, 259, 123,
+ 296, 118, 308, 348, 376, 386, 315, 346, 312, 258,
+ 215, 394, 360, 349, 358, 213, 359, 353, 356, 269,
+ 0, 328, 281, 0, 370, 44, 44, 280, 328, 369,
+ 0, 355, 402, 400, 383, 347, 413, 401, 382, 394,
+ 158, 283, 426, 328, 328, 357, 280, 0, 44, 214,
+ 0, 76, 122, 115, 137, 0, 150, 0, 143, 263,
+ 253, 0, 68, 152, 137, 151, 150, 144, 143, 0,
+ 0, 0, 0, 0, 327, 365, 268, 144, 35, 35,
+ 282, 327, 363, 364, 0, 0, 0, 0, 0, 0,
+ 0, 403, 0, 0, 342, 0, 327, 327, 0, 0,
+ 0, 35, 78, 0, 75, 77, 0, 0, 0, 338,
+ 335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 423, 0, 420,
+ 418, 424, 422, 419, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 421, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+const short QXmlStreamReader_Table::action_check [] = {
+ 26, 18, 26, 14, 4, 4, 4, 26, 24, 14,
+ 4, 26, 4, 4, 4, 4, 22, 55, 26, 26,
+ 42, 4, 4, 44, 26, 22, 19, 12, 2, 2,
+ 18, 2, 13, 0, 18, 4, 4, 2, 4, 26,
+ 26, 20, 18, 4, 4, 4, 26, 11, 26, 26,
+ 7, 8, 7, 8, 4, 7, 8, 6, 2, 9,
+ 7, 8, 24, 25, 7, 8, 7, 8, 7, 8,
+ 6, 36, 7, 8, 7, 8, 6, 26, 34, 35,
+ 24, 34, 35, 7, 8, 11, 2, 12, 13, 20,
+ 26, 12, 13, 15, 11, 13, 26, 11, 29, 11,
+ 26, 19, 7, 8, 26, 11, 26, 27, -1, 26,
+ 7, 8, 26, 4, 26, 18, 12, 13, 12, 13,
+ 26, 2, 3, 26, 27, 16, 11, 20, -1, 24,
+ 25, 26, 6, 7, 8, 28, 29, 21, 22, 6,
+ 24, 6, 21, 22, 11, 24, -1, 37, 38, 39,
+ 21, 22, -1, 24, -1, 40, 41, 2, 3, 26,
+ -1, 26, 17, 7, 8, 20, 16, -1, 23, -1,
+ 15, 26, 27, 54, 24, 25, 26, 17, -1, 17,
+ 20, -1, 20, 23, -1, 23, 26, 27, 26, 27,
+ 34, 35, 2, 20, 4, 11, -1, -1, -1, 9,
+ 45, -1, -1, 30, 31, 32, 33, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 32, 33, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, 51, 52, 53, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, -1,
+ -1, -1, -1, -1, -1, 10, -1, 2, -1, 4,
+ 15, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, -1, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 2, -1,
+ 4, -1, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, -1, -1, -1, 2, -1, 4,
+ -1, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, 46, -1, -1, -1, -1, -1, -1, -1, 54,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, 46, -1, -1, -1,
+ -1, -1, -1, -1, 54, -1, -1,
+
+ 20, 37, 12, 12, 1, 16, 20, 13, 13, 12,
+ 12, 36, 12, 12, 12, 36, 12, 12, 12, 20,
+ 12, 12, 49, 12, 37, 12, 72, 20, 13, 37,
+ 20, 17, 12, 12, 12, 12, 20, 12, 12, 20,
+ 12, 12, 54, 12, 17, 13, 13, 17, 12, 37,
+ 12, 12, 68, 13, 20, 20, -1, 72, 17, 17,
+ 12, 68, 45, 20, 12, 1, 17, 17, 44, 16,
+ 12, 17, 54, 17, 17, 12, 17, 17, 17, 12,
+ -1, 10, 12, -1, 12, 10, 10, 17, 10, 17,
+ -1, 54, 12, 20, 17, 49, 14, 17, 21, 17,
+ 38, 12, 4, 10, 10, 54, 17, -1, 10, 54,
+ -1, 10, 68, 68, 6, -1, 8, -1, 10, 72,
+ 54, -1, 54, 54, 6, 17, 8, 19, 10, -1,
+ -1, -1, -1, -1, 63, 17, 13, 19, 63, 63,
+ 51, 63, 24, 25, -1, -1, -1, -1, -1, -1,
+ -1, 78, -1, -1, 76, -1, 63, 63, -1, -1,
+ -1, 63, 61, -1, 63, 64, -1, -1, -1, 76,
+ 76, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, -1, 5,
+ 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 19, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1};
+
+
+template <typename T> class QXmlStreamSimpleStack {
+ T *data;
+ int tos, cap;
+public:
+ inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline ~QXmlStreamSimpleStack(){ if (data) qFree(data); }
+
+ inline void reserve(int extraCapacity) {
+ if (tos + extraCapacity + 1 > cap) {
+ cap = qMax(tos + extraCapacity + 1, cap << 1 );
+ data = reinterpret_cast<T *>(qRealloc(data, cap * sizeof(T)));
+ Q_CHECK_PTR(data);
+ }
+ }
+
+ inline T &push() { reserve(1); return data[++tos]; }
+ inline T &rawPush() { return data[++tos]; }
+ inline const T &top() const { return data[tos]; }
+ inline T &top() { return data[tos]; }
+ inline T &pop() { return data[tos--]; }
+ inline T &operator[](int index) { return data[index]; }
+ inline const T &at(int index) const { return data[index]; }
+ inline int size() const { return tos + 1; }
+ inline void resize(int s) { tos = s - 1; }
+ inline bool isEmpty() const { return tos < 0; }
+ inline void clear() { tos = -1; }
+};
+
+
+class QXmlStream
+{
+ Q_DECLARE_TR_FUNCTIONS(QXmlStream)
+};
+
+class QXmlStreamPrivateTagStack {
+public:
+ struct NamespaceDeclaration
+ {
+ QStringRef prefix;
+ QStringRef namespaceUri;
+ };
+
+ struct Tag
+ {
+ QStringRef name;
+ QStringRef qualifiedName;
+ NamespaceDeclaration namespaceDeclaration;
+ int tagStackStringStorageSize;
+ int namespaceDeclarationsSize;
+ };
+
+
+ QXmlStreamPrivateTagStack();
+ QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
+ QString tagStackStringStorage;
+ int tagStackStringStorageSize;
+ bool tagsDone;
+
+ inline QStringRef addToStringStorage(const QStringRef &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+ inline QStringRef addToStringStorage(const QString &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+
+ QXmlStreamSimpleStack<Tag> tagStack;
+
+
+ inline Tag &tagStack_pop() {
+ Tag& tag = tagStack.pop();
+ tagStackStringStorageSize = tag.tagStackStringStorageSize;
+ namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
+ tagsDone = tagStack.isEmpty();
+ return tag;
+ }
+ inline Tag &tagStack_push() {
+ Tag &tag = tagStack.push();
+ tag.tagStackStringStorageSize = tagStackStringStorageSize;
+ tag.namespaceDeclarationsSize = namespaceDeclarations.size();
+ return tag;
+ }
+};
+
+
+class QXmlStreamEntityResolver;
+#ifndef QT_NO_XMLSTREAMREADER
+class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
+ QXmlStreamReader *q_ptr;
+ Q_DECLARE_PUBLIC(QXmlStreamReader)
+public:
+ QXmlStreamReaderPrivate(QXmlStreamReader *q);
+ ~QXmlStreamReaderPrivate();
+ void init();
+
+ QByteArray rawReadBuffer;
+ QByteArray dataBuffer;
+ uchar firstByte;
+ qint64 nbytesread;
+ QString readBuffer;
+ int readBufferPos;
+ QXmlStreamSimpleStack<uint> putStack;
+ struct Entity {
+ Entity(const QString& str = QString())
+ :value(str), external(false), unparsed(false), literal(false),
+ hasBeenParsed(false), isCurrentlyReferenced(false){}
+ static inline Entity createLiteral(const QString &entity)
+ { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
+ QString value;
+ uint external : 1;
+ uint unparsed : 1;
+ uint literal : 1;
+ uint hasBeenParsed : 1;
+ uint isCurrentlyReferenced : 1;
+ };
+ QHash<QString, Entity> entityHash;
+ QHash<QString, Entity> parameterEntityHash;
+ QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ inline bool referenceEntity(Entity &entity) {
+ if (entity.isCurrentlyReferenced) {
+ raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ return false;
+ }
+ entity.isCurrentlyReferenced = true;
+ entityReferenceStack.push() = &entity;
+ injectToken(ENTITY_DONE);
+ return true;
+ }
+
+
+ QIODevice *device;
+ bool deleteDevice;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+ QTextDecoder *decoder;
+#endif
+ bool atEnd;
+
+ /*!
+ \sa setType()
+ */
+ QXmlStreamReader::TokenType type;
+ QXmlStreamReader::Error error;
+ QString errorString;
+ QString unresolvedEntity;
+
+ qint64 lineNumber, lastLineStart, characterOffset;
+
+
+ void write(const QString &);
+ void write(const char *);
+
+
+ QXmlStreamAttributes attributes;
+ QStringRef namespaceForPrefix(const QStringRef &prefix);
+ void resolveTag();
+ void resolvePublicNamespaces();
+ void resolveDtd();
+ uint resolveCharRef(int symbolIndex);
+ bool checkStartDocument();
+ void startDocument();
+ void parseError();
+ void checkPublicLiteral(const QStringRef &publicId);
+
+ bool scanDtd;
+ QStringRef lastAttributeValue;
+ bool lastAttributeIsCData;
+ struct DtdAttribute {
+ QStringRef tagName;
+ QStringRef attributeQualifiedName;
+ QStringRef attributePrefix;
+ QStringRef attributeName;
+ QStringRef defaultValue;
+ bool isCDATA;
+ bool isNamespaceAttribute;
+ };
+ QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
+ struct NotationDeclaration {
+ QStringRef name;
+ QStringRef publicId;
+ QStringRef systemId;
+ };
+ QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
+ QXmlStreamNotationDeclarations publicNotationDeclarations;
+ QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
+
+ struct EntityDeclaration {
+ QStringRef name;
+ QStringRef notationName;
+ QStringRef publicId;
+ QStringRef systemId;
+ QStringRef value;
+ bool parameter;
+ bool external;
+ inline void clear() {
+ name.clear();
+ notationName.clear();
+ publicId.clear();
+ systemId.clear();
+ value.clear();
+ parameter = external = false;
+ }
+ };
+ QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
+ QXmlStreamEntityDeclarations publicEntityDeclarations;
+
+ QStringRef text;
+
+ QStringRef prefix, namespaceUri, qualifiedName, name;
+ QStringRef processingInstructionTarget, processingInstructionData;
+ QStringRef dtdName, dtdPublicId, dtdSystemId;
+ QStringRef documentVersion, documentEncoding;
+ uint isEmptyElement : 1;
+ uint isWhitespace : 1;
+ uint isCDATA : 1;
+ uint standalone : 1;
+ uint hasCheckedStartDocument : 1;
+ uint normalizeLiterals : 1;
+ uint hasSeenTag : 1;
+ uint inParseEntity : 1;
+ uint referenceToUnparsedEntityDetected : 1;
+ uint referenceToParameterEntityDetected : 1;
+ uint hasExternalDtdSubset : 1;
+ uint lockEncoding : 1;
+ uint namespaceProcessing : 1;
+
+ int resumeReduction;
+ void resume(int rule);
+
+ inline bool entitiesMustBeDeclared() const {
+ return (!inParseEntity
+ && (standalone
+ || (!referenceToUnparsedEntityDetected
+ && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
+ && !hasExternalDtdSubset)));
+ }
+
+ // qlalr parser
+ int tos;
+ int stack_size;
+ struct Value {
+ int pos;
+ int len;
+ int prefix;
+ ushort c;
+ };
+
+ Value *sym_stack;
+ int *state_stack;
+ inline void reallocateStack();
+ inline Value &sym(int index) const
+ { return sym_stack[tos + index - 1]; }
+ QString textBuffer;
+ inline void clearTextBuffer() {
+ if (!scanDtd) {
+ textBuffer.resize(0);
+ textBuffer.reserve(256);
+ }
+ }
+ struct Attribute {
+ Value key;
+ Value value;
+ };
+ QXmlStreamSimpleStack<Attribute> attributeStack;
+
+ inline QStringRef symString(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symString(int index, int offset) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
+ }
+ inline QStringRef symPrefix(int index) {
+ const Value &symbol = sym(index);
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+ inline QStringRef symString(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symPrefix(const Value &symbol) {
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+
+ inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
+
+
+ short token;
+ ushort token_char;
+
+ uint filterCarriageReturn();
+ inline uint getChar();
+ inline uint peekChar();
+ inline void putChar(uint c) { putStack.push() = c; }
+ inline void putChar(QChar c) { putStack.push() = c.unicode(); }
+ void putString(const QString &s, int from = 0);
+ void putStringLiteral(const QString &s);
+ void putReplacement(const QString &s);
+ void putReplacementInAttributeValue(const QString &s);
+ ushort getChar_helper();
+
+ bool scanUntil(const char *str, short tokenToInject = -1);
+ bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
+ inline void injectToken(ushort tokenToInject) {
+ putChar(int(tokenToInject) << 16);
+ }
+
+ QString resolveUndeclaredEntity(const QString &name);
+ void parseEntity(const QString &value);
+ QXmlStreamReaderPrivate *entityParser;
+
+ bool scanAfterLangleBang();
+ bool scanPublicOrSystem();
+ bool scanNData();
+ bool scanAfterDefaultDecl();
+ bool scanAttType();
+
+
+ // scan optimization functions. Not strictly necessary but LALR is
+ // not very well suited for scanning fast
+ int fastScanLiteralContent();
+ int fastScanSpace();
+ int fastScanContentCharList();
+ int fastScanName(int *prefix = 0);
+ inline int fastScanNMTOKEN();
+
+
+ bool parse();
+ inline void consumeRule(int);
+
+ void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
+ void raiseWellFormedError(const QString &message);
+
+ QXmlStreamEntityResolver *entityResolver;
+
+private:
+ /*! \internal
+ Never assign to variable type directly. Instead use this function.
+
+ This prevents errors from being ignored.
+ */
+ inline void setType(const QXmlStreamReader::TokenType t)
+ {
+ if(type != QXmlStreamReader::Invalid)
+ type = t;
+ }
+};
+
+bool QXmlStreamReaderPrivate::parse()
+{
+ // cleanup currently reported token
+
+ switch (type) {
+ case QXmlStreamReader::StartElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ if (publicNamespaceDeclarations.size())
+ publicNamespaceDeclarations.clear();
+ if (attributes.size())
+ attributes.resize(0);
+ if (isEmptyElement) {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ isEmptyElement = false;
+ return true;
+ }
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EndElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::DTD:
+ publicNotationDeclarations.clear();
+ publicEntityDeclarations.clear();
+ dtdName.clear();
+ dtdPublicId.clear();
+ dtdSystemId.clear();
+ // fall through
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::Characters:
+ isCDATA = false;
+ isWhitespace = true;
+ text.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EntityReference:
+ text.clear();
+ name.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::ProcessingInstruction:
+ processingInstructionTarget.clear();
+ processingInstructionData.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ break;
+ case QXmlStreamReader::StartDocument:
+ lockEncoding = true;
+ documentVersion.clear();
+ documentEncoding.clear();
+#ifndef QT_NO_TEXTCODEC
+ if(decoder->hasFailure()) {
+ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+ readBuffer.clear();
+ return false;
+ }
+#endif
+ // fall through
+ default:
+ clearTextBuffer();
+ ;
+ }
+
+ setType(QXmlStreamReader::NoToken);
+
+
+ // the main parse loop
+ int act, r;
+
+ if (resumeReduction) {
+ act = state_stack[tos-1];
+ r = resumeReduction;
+ resumeReduction = 0;
+ goto ResumeReduction;
+ }
+
+ act = state_stack[tos];
+
+ forever {
+ if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
+ uint cu = getChar();
+ token = NOTOKEN;
+ token_char = cu;
+ if (cu & 0xff0000) {
+ token = cu >> 16;
+ } else switch (token_char) {
+ case 0xfffe:
+ case 0xffff:
+ token = ERROR;
+ break;
+ case '\r':
+ token = SPACE;
+ if (cu == '\r') {
+ if ((token_char = filterCarriageReturn())) {
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ break;
+ }
+ } else {
+ break;
+ }
+ // fall through
+ case '\0': {
+ token = EOF_SYMBOL;
+ if (!tagsDone && !inParseEntity) {
+ int a = t_action(act, token);
+ if (a < 0) {
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ return false;
+ }
+ }
+
+ } break;
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ case ' ':
+ case '\t':
+ token = SPACE;
+ break;
+ case '&':
+ token = AMPERSAND;
+ break;
+ case '#':
+ token = HASH;
+ break;
+ case '\'':
+ token = QUOTE;
+ break;
+ case '\"':
+ token = DBLQUOTE;
+ break;
+ case '<':
+ token = LANGLE;
+ break;
+ case '>':
+ token = RANGLE;
+ break;
+ case '[':
+ token = LBRACK;
+ break;
+ case ']':
+ token = RBRACK;
+ break;
+ case '(':
+ token = LPAREN;
+ break;
+ case ')':
+ token = RPAREN;
+ break;
+ case '|':
+ token = PIPE;
+ break;
+ case '=':
+ token = EQ;
+ break;
+ case '%':
+ token = PERCENT;
+ break;
+ case '/':
+ token = SLASH;
+ break;
+ case ':':
+ token = COLON;
+ break;
+ case ';':
+ token = SEMICOLON;
+ break;
+ case ',':
+ token = COMMA;
+ break;
+ case '-':
+ token = DASH;
+ break;
+ case '+':
+ token = PLUS;
+ break;
+ case '*':
+ token = STAR;
+ break;
+ case '.':
+ token = DOT;
+ break;
+ case '?':
+ token = QUESTIONMARK;
+ break;
+ case '!':
+ token = BANG;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ token = DIGIT;
+ break;
+ default:
+ if (cu < 0x20)
+ token = NOTOKEN;
+ else
+ token = LETTER;
+ break;
+ }
+ }
+
+ act = t_action (act, token);
+ if (act == ACCEPT_STATE) {
+ // reset the parser in case someone resumes (process instructions can follow a valid document)
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return true;
+ } else if (act > 0) {
+ if (++tos == stack_size-1)
+ reallocateStack();
+
+ Value &val = sym_stack[tos];
+ val.c = token_char;
+ val.pos = textBuffer.size();
+ val.prefix = 0;
+ val.len = 1;
+ if (token_char)
+ textBuffer += QChar(token_char);
+
+ state_stack[tos] = act;
+ token = -1;
+
+
+ } else if (act < 0) {
+ r = - act - 1;
+
+#if defined (QLALR_DEBUG)
+ int ridx = rule_index[r];
+ printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs[r]; ++i) {
+ int symbol = rule_info[i];
+ if (const char *name = spell[symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+#endif
+
+ tos -= rhs[r];
+ act = state_stack[tos++];
+ ResumeReduction:
+ switch (r) {
+
+ case 0:
+ setType(QXmlStreamReader::EndDocument);
+ break;
+
+ case 1:
+ if (type != QXmlStreamReader::Invalid) {
+ if (hasSeenTag || inParseEntity) {
+ setType(QXmlStreamReader::EndDocument);
+ } else {
+ raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
+ // reset the parser
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return false;
+ }
+ }
+ break;
+
+ case 10:
+ entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ clearSym();
+ break;
+
+ case 11:
+ if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
+ resume(11);
+ return false;
+ }
+ break;
+
+ case 12:
+ setType(QXmlStreamReader::StartDocument);
+ documentVersion = symString(6);
+ startDocument();
+ break;
+
+ case 13:
+ hasExternalDtdSubset = true;
+ dtdSystemId = symString(2);
+ break;
+
+ case 14:
+ checkPublicLiteral(symString(2));
+ dtdPublicId = symString(2);
+ dtdSystemId = symString(4);
+ hasExternalDtdSubset = true;
+ break;
+
+ case 16:
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(16);
+ return false;
+ }
+ dtdName = symString(3);
+ break;
+
+ case 17:
+ case 18:
+ dtdName = symString(3);
+ // fall through
+
+ case 19:
+ case 20:
+ setType(QXmlStreamReader::DTD);
+ text = &textBuffer;
+ break;
+
+ case 21:
+ scanDtd = true;
+ break;
+
+ case 22:
+ scanDtd = false;
+ break;
+
+ case 37:
+ if (!scanString(spell[EMPTY], EMPTY, false)
+ && !scanString(spell[ANY], ANY, false)
+ && atEnd) {
+ resume(37);
+ return false;
+ }
+ break;
+
+ case 43:
+ if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
+ resume(43);
+ return false;
+ }
+ break;
+
+ case 68: {
+ lastAttributeIsCData = true;
+ } break;
+
+ case 78:
+ if (!scanAfterDefaultDecl() && atEnd) {
+ resume(78);
+ return false;
+ }
+ break;
+
+ case 83:
+ sym(1) = sym(2);
+ lastAttributeValue.clear();
+ lastAttributeIsCData = false;
+ if (!scanAttType() && atEnd) {
+ resume(83);
+ return false;
+ }
+ break;
+
+ case 84: {
+ DtdAttribute &dtdAttribute = dtdAttributes.push();
+ dtdAttribute.tagName.clear();
+ dtdAttribute.isCDATA = lastAttributeIsCData;
+ dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
+ dtdAttribute.attributeName = addToStringStorage(symString(1));
+ dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
+ dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
+ || (dtdAttribute.attributePrefix.isEmpty()
+ && dtdAttribute.attributeName == QLatin1String("xmlns")));
+ if (lastAttributeValue.isNull()) {
+ dtdAttribute.defaultValue.clear();
+ } else {
+ if (dtdAttribute.isCDATA)
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
+ else
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
+
+ }
+ } break;
+
+ case 88: {
+ if (referenceToUnparsedEntityDetected && !standalone)
+ break;
+ int n = dtdAttributes.size();
+ QStringRef tagName = addToStringStorage(symName(3));
+ while (n--) {
+ DtdAttribute &dtdAttribute = dtdAttributes[n];
+ if (!dtdAttribute.tagName.isNull())
+ break;
+ dtdAttribute.tagName = tagName;
+ for (int i = 0; i < n; ++i) {
+ if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
+ && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
+ dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
+ break;
+ }
+ }
+ }
+ } break;
+
+ case 89: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(89);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(3);
+ } break;
+
+ case 90: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(90);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(5);
+ entityDeclaration.parameter = true;
+ } break;
+
+ case 91: {
+ if (!scanNData() && atEnd) {
+ resume(91);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.systemId = symString(3);
+ entityDeclaration.external = true;
+ } break;
+
+ case 92: {
+ if (!scanNData() && atEnd) {
+ resume(92);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ checkPublicLiteral((entityDeclaration.publicId = symString(3)));
+ entityDeclaration.systemId = symString(5);
+ entityDeclaration.external = true;
+ } break;
+
+ case 93: {
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.notationName = symString(3);
+ if (entityDeclaration.parameter)
+ raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
+ }
+ //fall through
+
+ case 94:
+ case 95: {
+ if (referenceToUnparsedEntityDetected && !standalone) {
+ entityDeclarations.pop();
+ break;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ if (!entityDeclaration.external)
+ entityDeclaration.value = symString(2);
+ QString entityName = entityDeclaration.name.toString();
+ QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+ if (!hash.contains(entityName)) {
+ Entity entity(entityDeclaration.value.toString());
+ entity.unparsed = (!entityDeclaration.notationName.isNull());
+ entity.external = entityDeclaration.external;
+ hash.insert(entityName, entity);
+ }
+ } break;
+
+ case 96: {
+ setType(QXmlStreamReader::ProcessingInstruction);
+ int pos = sym(4).pos + sym(4).len;
+ processingInstructionTarget = symString(3);
+ if (scanUntil("?>")) {
+ processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
+ const QString piTarget(processingInstructionTarget.toString());
+ if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+ raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
+ }
+ else if(!QXmlUtils::isNCName(piTarget))
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
+ } else if (type != QXmlStreamReader::Invalid){
+ resume(96);
+ return false;
+ }
+ } break;
+
+ case 97:
+ setType(QXmlStreamReader::ProcessingInstruction);
+ processingInstructionTarget = symString(3);
+ if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
+ raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
+ break;
+
+ case 98:
+ if (!scanAfterLangleBang() && atEnd) {
+ resume(98);
+ return false;
+ }
+ break;
+
+ case 99:
+ if (!scanUntil("--")) {
+ resume(99);
+ return false;
+ }
+ break;
+
+ case 100: {
+ setType(QXmlStreamReader::Comment);
+ int pos = sym(1).pos + 4;
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } break;
+
+ case 101: {
+ setType(QXmlStreamReader::Characters);
+ isCDATA = true;
+ isWhitespace = false;
+ int pos = sym(2).pos;
+ if (scanUntil("]]>", -1)) {
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } else {
+ resume(101);
+ return false;
+ }
+ } break;
+
+ case 102: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(102);
+ return false;
+ }
+ NotationDeclaration &notationDeclaration = notationDeclarations.push();
+ notationDeclaration.name = symString(3);
+ } break;
+
+ case 103: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId = symString(3);
+ notationDeclaration.publicId.clear();
+ } break;
+
+ case 104: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId.clear();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ } break;
+
+ case 105: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ notationDeclaration.systemId = symString(5);
+ } break;
+
+ case 129:
+ isWhitespace = false;
+ // fall through
+
+ case 130:
+ sym(1).len += fastScanContentCharList();
+ if (atEnd && !inParseEntity) {
+ resume(130);
+ return false;
+ }
+ break;
+
+ case 139:
+ if (!textBuffer.isEmpty()) {
+ setType(QXmlStreamReader::Characters);
+ text = &textBuffer;
+ }
+ break;
+
+ case 140:
+ case 141:
+ clearSym();
+ break;
+
+ case 142:
+ case 143:
+ sym(1) = sym(2);
+ break;
+
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 173:
+ if (normalizeLiterals)
+ textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
+ break;
+
+ case 174:
+ sym(1).len += fastScanLiteralContent();
+ if (atEnd) {
+ resume(174);
+ return false;
+ }
+ break;
+
+ case 175: {
+ if (!QXmlUtils::isPublicID(symString(1).toString())) {
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
+ resume(175);
+ return false;
+ }
+ } break;
+
+ case 176:
+ case 177:
+ clearSym();
+ break;
+
+ case 178:
+ case 179:
+ sym(1) = sym(2);
+ break;
+
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 213:
+ case 214:
+ clearSym();
+ break;
+
+ case 215:
+ case 216:
+ sym(1) = sym(2);
+ lastAttributeValue = symString(1);
+ break;
+
+ case 217:
+ case 218:
+ case 219:
+ case 220:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 229: {
+ QStringRef prefix = symPrefix(1);
+ if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+
+ const QStringRef ns(symString(5));
+ if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+ ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+ else
+ namespaceDeclaration.namespaceUri = addToStringStorage(ns);
+ } else {
+ Attribute &attribute = attributeStack.push();
+ attribute.key = sym(1);
+ attribute.value = sym(5);
+
+ QStringRef attributeQualifiedName = symName(1);
+ bool normalize = false;
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (!dtdAttribute.isCDATA
+ && dtdAttribute.tagName == qualifiedName
+ && dtdAttribute.attributeQualifiedName == attributeQualifiedName
+ ) {
+ normalize = true;
+ break;
+ }
+ }
+ if (normalize) {
+ // normalize attribute value (simplify and trim)
+ int pos = textBuffer.size();
+ int n = 0;
+ bool wasSpace = true;
+ for (int i = 0; i < attribute.value.len; ++i) {
+ QChar c = textBuffer.at(attribute.value.pos + i);
+ if (c.unicode() == ' ') {
+ if (wasSpace)
+ continue;
+ wasSpace = true;
+ } else {
+ wasSpace = false;
+ }
+ textBuffer += textBuffer.at(attribute.value.pos + i);
+ ++n;
+ }
+ if (wasSpace)
+ while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
+ --n;
+ attribute.value.pos = pos;
+ attribute.value.len = n;
+ }
+ if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ QStringRef namespacePrefix = symString(attribute.key);
+ QStringRef namespaceUri = symString(attribute.value);
+ attributeStack.pop();
+ if (((namespacePrefix == QLatin1String("xml"))
+ ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+ || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+ || namespaceUri.isEmpty()
+ || namespacePrefix == QLatin1String("xmlns"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+ namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
+ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+ }
+ }
+ } break;
+
+ case 235: {
+ normalizeLiterals = true;
+ Tag &tag = tagStack_push();
+ prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
+ name = tag.name = addToStringStorage(symString(2));
+ qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
+ if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
+ raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
+ } break;
+
+ case 236:
+ isEmptyElement = true;
+ // fall through
+
+ case 237:
+ setType(QXmlStreamReader::StartElement);
+ resolveTag();
+ if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
+ raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+ hasSeenTag = true;
+ break;
+
+ case 238: {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ if (qualifiedName != symName(3))
+ raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
+ } break;
+
+ case 239:
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
+ break;
+ }
+ setType(QXmlStreamReader::EntityReference);
+ name = &unresolvedEntity;
+ break;
+
+ case 240: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed) {
+ raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
+ } else {
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacement(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+
+ injectToken(UNRESOLVED_ENTITY);
+ unresolvedEntity = symString(2).toString();
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+
+ } break;
+
+ case 241: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (parameterEntityHash.contains(reference)) {
+ referenceToParameterEntityDetected = true;
+ Entity &entity = parameterEntityHash[reference];
+ if (entity.unparsed || entity.external) {
+ referenceToUnparsedEntityDetected = true;
+ } else {
+ if (referenceEntity(entity))
+ putString(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ } else if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
+ }
+ } break;
+
+ case 242:
+ sym(1).len += sym(2).len + 1;
+ break;
+
+ case 243: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed || entity.value.isNull()) {
+ raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
+ break;
+ }
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacementInAttributeValue(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
+ }
+ } break;
+
+ case 244: {
+ if (uint s = resolveCharRef(3)) {
+ if (s >= 0xffff)
+ putStringLiteral(QString::fromUcs4(&s, 1));
+ else
+ putChar((LETTER << 16) | s);
+
+ textBuffer.chop(3 + sym(3).len);
+ clearSym();
+ } else {
+ raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
+ }
+ } break;
+
+ case 247:
+ case 248:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 259:
+ sym(1).len += fastScanSpace();
+ if (atEnd) {
+ resume(259);
+ return false;
+ }
+ break;
+
+ case 262: {
+ sym(1).len += fastScanName(&sym(1).prefix);
+ if (atEnd) {
+ resume(262);
+ return false;
+ }
+ } break;
+
+ case 263:
+ sym(1).len += fastScanName();
+ if (atEnd) {
+ resume(263);
+ return false;
+ }
+ break;
+
+ case 264:
+ case 265:
+ case 266:
+ case 267:
+ case 268:
+ sym(1).len += fastScanNMTOKEN();
+ if (atEnd) {
+ resume(268);
+ return false;
+ }
+
+ break;
+
+ default:
+ ;
+ } // switch
+ act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
+ if (type != QXmlStreamReader::NoToken)
+ return true;
+ } else {
+ parseError();
+ break;
+ }
+ }
+ return false;
+}
+#endif //QT_NO_XMLSTREAMREADER.xml
+
+
+#endif // QXMLSTREAM_P_H
+
diff --git a/src/corelib/xml/qxmlutils.cpp b/src/corelib/xml/qxmlutils.cpp
new file mode 100644
index 0000000000..462fa95a41
--- /dev/null
+++ b/src/corelib/xml/qxmlutils.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** 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 QtCore module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qregexp.h>
+#include <qstring.h>
+
+#include "qxmlutils_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/* TODO:
+ * - isNameChar() doesn't have to be public, it's only needed in
+ * qdom.cpp -- refactor fixedXmlName() to use isNCName()
+ * - A lot of functions can be inlined.
+ */
+
+class QXmlCharRange
+{
+public:
+ ushort min;
+ ushort max;
+};
+typedef const QXmlCharRange *RangeIter;
+
+/*!
+ Performs a binary search between \a begin and \a end inclusive, to check whether \a
+ c is contained. Remember that the QXmlCharRange instances must be in numeric order.
+ */
+bool QXmlUtils::rangeContains(RangeIter begin, RangeIter end, const QChar c)
+{
+ const ushort cp(c.unicode());
+
+ // check the first two ranges "manually" as characters in that
+ // range are checked very often and we avoid the binary search below.
+
+ if (cp <= begin->max)
+ return cp >= begin->min;
+
+ ++begin;
+
+ if (begin == end)
+ return false;
+
+ if (cp <= begin->max)
+ return cp >= begin->min;
+
+ while (begin != end) {
+ int delta = (end - begin) / 2;
+ RangeIter mid = begin + delta;
+
+ if (mid->min > cp)
+ end = mid;
+ else if (mid->max < cp)
+ begin = mid;
+ else
+ return true;
+
+ if (delta == 0)
+ break;
+ }
+
+ return false;
+}
+
+// [85] BaseChar ::= ...
+
+static const QXmlCharRange g_base_begin[] =
+{
+ {0x0041, 0x005A}, {0x0061, 0x007A}, {0x00C0, 0x00D6}, {0x00D8, 0x00F6}, {0x00F8, 0x00FF},
+ {0x0100, 0x0131}, {0x0134, 0x013E}, {0x0141, 0x0148}, {0x014A, 0x017E}, {0x0180, 0x01C3},
+ {0x01CD, 0x01F0}, {0x01F4, 0x01F5}, {0x01FA, 0x0217}, {0x0250, 0x02A8}, {0x02BB, 0x02C1},
+ {0x0386, 0x0386}, {0x0388, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x03A1}, {0x03A3, 0x03CE},
+ {0x03D0, 0x03D6}, {0x03DA, 0x03DA}, {0x03DC, 0x03DC}, {0x03DE, 0x03DE}, {0x03E0, 0x03E0},
+ {0x03E2, 0x03F3}, {0x0401, 0x040C}, {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0481},
+ {0x0490, 0x04C4}, {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB}, {0x04EE, 0x04F5},
+ {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0559, 0x0559}, {0x0561, 0x0586}, {0x05D0, 0x05EA},
+ {0x05F0, 0x05F2}, {0x0621, 0x063A}, {0x0641, 0x064A}, {0x0671, 0x06B7}, {0x06BA, 0x06BE},
+ {0x06C0, 0x06CE}, {0x06D0, 0x06D3}, {0x06D5, 0x06D5}, {0x06E5, 0x06E6}, {0x0905, 0x0939},
+ {0x093D, 0x093D}, {0x0958, 0x0961}, {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
+ {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, {0x09DC, 0x09DD}, {0x09DF, 0x09E1},
+ {0x09F0, 0x09F1}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
+ {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E},
+ {0x0A72, 0x0A74}, {0x0A85, 0x0A8B}, {0x0A8D, 0x0A8D}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
+ {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABD, 0x0ABD}, {0x0AE0, 0x0AE0},
+ {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33},
+ {0x0B36, 0x0B39}, {0x0B3D, 0x0B3D}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B85, 0x0B8A},
+ {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F},
+ {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB5}, {0x0BB7, 0x0BB9}, {0x0C05, 0x0C0C},
+ {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C33}, {0x0C35, 0x0C39}, {0x0C60, 0x0C61},
+ {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
+ {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D28},
+ {0x0D2A, 0x0D39}, {0x0D60, 0x0D61}, {0x0E01, 0x0E2E}, {0x0E30, 0x0E30}, {0x0E32, 0x0E33},
+ {0x0E40, 0x0E45}, {0x0E81, 0x0E82}, {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A},
+ {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5},
+ {0x0EA7, 0x0EA7}, {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EAE}, {0x0EB0, 0x0EB0}, {0x0EB2, 0x0EB3},
+ {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0F40, 0x0F47}, {0x0F49, 0x0F69}, {0x10A0, 0x10C5},
+ {0x10D0, 0x10F6}, {0x1100, 0x1100}, {0x1102, 0x1103}, {0x1105, 0x1107}, {0x1109, 0x1109},
+ {0x110B, 0x110C}, {0x110E, 0x1112}, {0x113C, 0x113C}, {0x113E, 0x113E}, {0x1140, 0x1140},
+ {0x114C, 0x114C}, {0x114E, 0x114E}, {0x1150, 0x1150}, {0x1154, 0x1155}, {0x1159, 0x1159},
+ {0x115F, 0x1161}, {0x1163, 0x1163}, {0x1165, 0x1165}, {0x1167, 0x1167}, {0x1169, 0x1169},
+ {0x116D, 0x116E}, {0x1172, 0x1173}, {0x1175, 0x1175}, {0x119E, 0x119E}, {0x11A8, 0x11A8},
+ {0x11AB, 0x11AB}, {0x11AE, 0x11AF}, {0x11B7, 0x11B8}, {0x11BA, 0x11BA}, {0x11BC, 0x11C2},
+ {0x11EB, 0x11EB}, {0x11F0, 0x11F0}, {0x11F9, 0x11F9}, {0x1E00, 0x1E9B}, {0x1EA0, 0x1EF9},
+ {0x1F00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57},
+ {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
+ {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3},
+ {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2126, 0x2126},
+ {0x212A, 0x212B}, {0x212E, 0x212E}, {0x2180, 0x2182}, {0x3041, 0x3094}, {0x30A1, 0x30FA},
+ {0x3105, 0x312C}, {0xAC00, 0xD7A3}
+};
+static const RangeIter g_base_end = g_base_begin + sizeof(g_base_begin) / sizeof(QXmlCharRange);
+
+static const QXmlCharRange g_ideographic_begin[] =
+{
+ {0x3007, 0x3007}, {0x3021, 0x3029}, {0x4E00, 0x9FA5}
+};
+static const RangeIter g_ideographic_end = g_ideographic_begin + sizeof(g_ideographic_begin) / sizeof(QXmlCharRange);
+
+bool QXmlUtils::isIdeographic(const QChar c)
+{
+ return rangeContains(g_ideographic_begin, g_ideographic_end, c);
+}
+
+static const QXmlCharRange g_combining_begin[] =
+{
+ {0x0300, 0x0345}, {0x0360, 0x0361}, {0x0483, 0x0486}, {0x0591, 0x05A1}, {0x05A3, 0x05B9},
+ {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C4}, {0x064B, 0x0652},
+ {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DD, 0x06DF}, {0x06E0, 0x06E4}, {0x06E7, 0x06E8},
+ {0x06EA, 0x06ED}, {0x0901, 0x0903}, {0x093C, 0x093C}, {0x093E, 0x094C}, {0x094D, 0x094D},
+ {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0983}, {0x09BC, 0x09BC}, {0x09BE, 0x09BE},
+ {0x09BF, 0x09BF}, {0x09C0, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CD}, {0x09D7, 0x09D7},
+ {0x09E2, 0x09E3}, {0x0A02, 0x0A02}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A3E}, {0x0A3F, 0x0A3F},
+ {0x0A40, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A70, 0x0A71}, {0x0A81, 0x0A83},
+ {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0B01, 0x0B03},
+ {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B43}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57},
+ {0x0B82, 0x0B83}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7},
+ {0x0C01, 0x0C03}, {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
+ {0x0C82, 0x0C83}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6},
+ {0x0D02, 0x0D03}, {0x0D3E, 0x0D43}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57},
+ {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9},
+ {0x0EBB, 0x0EBC}, {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37},
+ {0x0F39, 0x0F39}, {0x0F3E, 0x0F3E}, {0x0F3F, 0x0F3F}, {0x0F71, 0x0F84}, {0x0F86, 0x0F8B},
+ {0x0F90, 0x0F95}, {0x0F97, 0x0F97}, {0x0F99, 0x0FAD}, {0x0FB1, 0x0FB7}, {0x0FB9, 0x0FB9},
+ {0x20D0, 0x20DC}, {0x20E1, 0x20E1}, {0x302A, 0x302F}, {0x3099, 0x3099}, {0x309A, 0x309A}
+};
+static const RangeIter g_combining_end = g_combining_begin + sizeof(g_combining_begin) / sizeof(QXmlCharRange);
+
+bool QXmlUtils::isCombiningChar(const QChar c)
+{
+ return rangeContains(g_combining_begin, g_combining_end, c);
+}
+
+// [88] Digit ::= ...
+static const QXmlCharRange g_digit_begin[] =
+{
+ {0x0030, 0x0039}, {0x0660, 0x0669}, {0x06F0, 0x06F9}, {0x0966, 0x096F}, {0x09E6, 0x09EF},
+ {0x0A66, 0x0A6F}, {0x0AE6, 0x0AEF}, {0x0B66, 0x0B6F}, {0x0BE7, 0x0BEF}, {0x0C66, 0x0C6F},
+ {0x0CE6, 0x0CEF}, {0x0D66, 0x0D6F}, {0x0E50, 0x0E59}, {0x0ED0, 0x0ED9}, {0x0F20, 0x0F29}
+};
+static const RangeIter g_digit_end = g_digit_begin + sizeof(g_digit_begin) / sizeof(QXmlCharRange);
+
+bool QXmlUtils::isDigit(const QChar c)
+{
+ return rangeContains(g_digit_begin, g_digit_end, c);
+}
+
+// [89] Extender ::= ...
+static const QXmlCharRange g_extender_begin[] =
+{
+ {0x00B7, 0x00B7}, {0x02D0, 0x02D0}, {0x02D1, 0x02D1}, {0x0387, 0x0387}, {0x0640, 0x0640},
+ {0x0E46, 0x0E46}, {0x0EC6, 0x0EC6}, {0x3005, 0x3005}, {0x3031, 0x3035}, {0x309D, 0x309E},
+ {0x30FC, 0x30FE}
+};
+static const RangeIter g_extender_end = g_extender_begin + sizeof(g_extender_begin) / sizeof(QXmlCharRange);
+
+bool QXmlUtils::isExtender(const QChar c)
+{
+ return rangeContains(g_extender_begin, g_extender_end, c);
+}
+
+bool QXmlUtils::isBaseChar(const QChar c)
+{
+ return rangeContains(g_base_begin, g_base_end, c);
+}
+
+/*!
+ \internal
+
+ Determines whether \a encName is a valid instance of production [81]EncName in the XML 1.0
+ specification. If it is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml/#NT-EncName}
+ {Extensible Markup Language (XML) 1.0 (Fourth Edition), [81] EncName}
+ */
+bool QXmlUtils::isEncName(const QString &encName)
+{
+ /* Right, we here have a dependency on QRegExp. Writing a manual parser to
+ * replace that regexp is probably a 70 lines so I prioritize this to when
+ * the dependency is considered alarming, or when the rest of the bugs
+ * are fixed. */
+ const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
+ Q_ASSERT(encNameRegExp.isValid());
+
+ return encNameRegExp.exactMatch(encName);
+}
+
+/*!
+ \internal
+
+ Determines whether \a c is a valid instance of production [84]Letter in the XML 1.0
+ specification. If it is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml/#NT-Letter}
+ {Extensible Markup Language (XML) 1.0 (Fourth Edition), [84] Letter}
+ */
+bool QXmlUtils::isLetter(const QChar c)
+{
+ return isBaseChar(c) || isIdeographic(c);
+}
+
+/*!
+ \internal
+
+ Determines whether \a c is a valid instance of production [2]Char in the XML 1.0
+ specification. If it is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml/#NT-Char}
+ {Extensible Markup Language (XML) 1.0 (Fourth Edition), [2] Char}
+ */
+bool QXmlUtils::isChar(const QChar c)
+{
+ return (c.unicode() >= 0x0020 && c.unicode() <= 0xD7FF)
+ || c.unicode() == 0x0009
+ || c.unicode() == 0x000A
+ || c.unicode() == 0x000D
+ || (c.unicode() >= 0xE000 && c.unicode() <= 0xFFFD);
+}
+
+/*!
+ \internal
+
+ Determines whether \a c is a valid instance of
+ production [4]NameChar in the XML 1.0 specification. If it
+ is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml/#NT-NameChar}
+ {Extensible Markup Language (XML) 1.0 (Fourth Edition), [4] NameChar}
+ */
+bool QXmlUtils::isNameChar(const QChar c)
+{
+ return isBaseChar(c)
+ || isDigit(c)
+ || c.unicode() == '.'
+ || c.unicode() == '-'
+ || c.unicode() == '_'
+ || c.unicode() == ':'
+ || isCombiningChar(c)
+ || isIdeographic(c)
+ || isExtender(c);
+}
+
+/*!
+ \internal
+
+ Determines whether \a c is a valid instance of
+ production [12] PubidLiteral in the XML 1.0 specification. If it
+ is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml/#NT-PubidLiteral}
+ {Extensible Markup Language (XML) 1.0 (Fourth Edition), [12] PubidLiteral}
+ */
+bool QXmlUtils::isPublicID(const QString &candidate)
+{
+ const int len = candidate.length();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const ushort cp = candidate.at(i).unicode();
+
+ if ((cp >= 'a' && cp <= 'z')
+ || (cp >= 'A' && cp <= 'Z')
+ || (cp >= '0' && cp <= '9'))
+ {
+ continue;
+ }
+
+ switch (cp)
+ {
+ /* Fallthrough all these. */
+ case 0x20:
+ case 0x0D:
+ case 0x0A:
+ case '-':
+ case '\'':
+ case '(':
+ case ')':
+ case '+':
+ case ',':
+ case '.':
+ case '/':
+ case ':':
+ case '=':
+ case '?':
+ case ';':
+ case '!':
+ case '*':
+ case '#':
+ case '@':
+ case '$':
+ case '_':
+ case '%':
+ continue;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*!
+ \internal
+
+ Determines whether \a c is a valid instance of
+ production [4]NCName in the XML 1.0 Namespaces specification. If it
+ is, true is returned, otherwise false.
+
+ \sa \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName}
+ {W3CNamespaces in XML 1.0 (Second Edition), [4] NCName}
+ */
+bool QXmlUtils::isNCName(const QStringRef &ncName)
+{
+ if(ncName.isEmpty())
+ return false;
+
+ const QChar first(ncName.at(0));
+
+ if(!QXmlUtils::isLetter(first) && first.unicode() != '_' && first.unicode() != ':')
+ return false;
+
+ const int len = ncName.size();
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar &at = ncName.at(i);
+ if(!QXmlUtils::isNameChar(at) || at == QLatin1Char(':'))
+ return false;
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/xml/qxmlutils_p.h b/src/corelib/xml/qxmlutils_p.h
new file mode 100644
index 0000000000..c0de810574
--- /dev/null
+++ b/src/corelib/xml/qxmlutils_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QtCore module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXMLUTILS_P_H
+#define QXMLUTILS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QChar;
+class QXmlCharRange;
+
+/*!
+ \internal
+ \short This class contains helper functions related to XML, for validating character classes,
+ productions in the XML specification, and so on.
+ */
+class Q_CORE_EXPORT QXmlUtils
+{
+public:
+ static bool isEncName(const QString &encName);
+ static bool isChar(const QChar c);
+ static bool isNameChar(const QChar c);
+ static bool isLetter(const QChar c);
+ static bool isNCName(const QStringRef &ncName);
+ static inline bool isNCName(const QString &ncName) { return isNCName(&ncName); }
+ static bool isPublicID(const QString &candidate);
+
+private:
+ typedef const QXmlCharRange *RangeIter;
+ static bool rangeContains(RangeIter begin, RangeIter end, const QChar c);
+ static bool isBaseChar(const QChar c);
+ static bool isDigit(const QChar c);
+ static bool isExtender(const QChar c);
+ static bool isIdeographic(const QChar c);
+ static bool isCombiningChar(const QChar c);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/xml/xml.pri b/src/corelib/xml/xml.pri
new file mode 100644
index 0000000000..2401c09ab7
--- /dev/null
+++ b/src/corelib/xml/xml.pri
@@ -0,0 +1,10 @@
+# Qt xml core module
+
+HEADERS += \
+ xml/qxmlstream.h \
+ xml/qxmlstream_p.h \
+ xml/qxmlutils_p.h
+
+SOURCES += \
+ xml/qxmlstream.cpp \
+ xml/qxmlutils.cpp