summaryrefslogtreecommitdiffstats
path: root/src/corelib/xml
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/corelib/xml
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
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