/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qxml.h"
#include "qxml_p.h"
#if QT_CONFIG(textcodec)
#include "qtextcodec.h"
#endif
#include "qbuffer.h"
#if QT_CONFIG(regularexpression)
#include "qregularexpression.h"
#endif
#include "qmap.h"
#include "qhash.h"
#include "qstack.h"
#include <qdebug.h>


#ifdef Q_CC_BOR // borland 6 finds bogus warnings when building this file in uic3
#    pragma warn -8080
#endif

//#define QT_QXML_DEBUG

// Error strings for the XML reader
#define XMLERR_OK                         QT_TRANSLATE_NOOP("QXml", "no error occurred")
#define XMLERR_ERRORBYCONSUMER            QT_TRANSLATE_NOOP("QXml", "error triggered by consumer")
#define XMLERR_UNEXPECTEDEOF              QT_TRANSLATE_NOOP("QXml", "unexpected end of file")
#define XMLERR_MORETHANONEDOCTYPE         QT_TRANSLATE_NOOP("QXml", "more than one document type definition")
#define XMLERR_ERRORPARSINGELEMENT        QT_TRANSLATE_NOOP("QXml", "error occurred while parsing element")
#define XMLERR_TAGMISMATCH                QT_TRANSLATE_NOOP("QXml", "tag mismatch")
#define XMLERR_ERRORPARSINGCONTENT        QT_TRANSLATE_NOOP("QXml", "error occurred while parsing content")
#define XMLERR_UNEXPECTEDCHARACTER        QT_TRANSLATE_NOOP("QXml", "unexpected character")
#define XMLERR_INVALIDNAMEFORPI           QT_TRANSLATE_NOOP("QXml", "invalid name for processing instruction")
#define XMLERR_VERSIONEXPECTED            QT_TRANSLATE_NOOP("QXml", "version expected while reading the XML declaration")
#define XMLERR_WRONGVALUEFORSDECL         QT_TRANSLATE_NOOP("QXml", "wrong value for standalone declaration")
#define XMLERR_EDECLORSDDECLEXPECTED      QT_TRANSLATE_NOOP("QXml", "encoding declaration or standalone declaration expected while reading the XML declaration")
#define XMLERR_SDDECLEXPECTED             QT_TRANSLATE_NOOP("QXml", "standalone declaration expected while reading the XML declaration")
#define XMLERR_ERRORPARSINGDOCTYPE        QT_TRANSLATE_NOOP("QXml", "error occurred while parsing document type definition")
#define XMLERR_LETTEREXPECTED             QT_TRANSLATE_NOOP("QXml", "letter is expected")
#define XMLERR_ERRORPARSINGCOMMENT        QT_TRANSLATE_NOOP("QXml", "error occurred while parsing comment")
#define XMLERR_ERRORPARSINGREFERENCE      QT_TRANSLATE_NOOP("QXml", "error occurred while parsing reference")
#define XMLERR_INTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "internal general entity reference not allowed in DTD")
#define XMLERR_EXTERNALGENERALENTITYINAV  QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in attribute value")
#define XMLERR_EXTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in DTD")
#define XMLERR_UNPARSEDENTITYREFERENCE    QT_TRANSLATE_NOOP("QXml", "unparsed entity reference in wrong context")
#define XMLERR_RECURSIVEENTITIES          QT_TRANSLATE_NOOP("QXml", "recursive entities")
#define XMLERR_ERRORINTEXTDECL            QT_TRANSLATE_NOOP("QXml", "error in the text declaration of an external entity")

QT_BEGIN_NAMESPACE

namespace {

// work around missing std::stack::clear()
template <typename Container>
void clear(Container &c) { c = Container(); }

}

// the constants for the lookup table
static const signed char cltWS      =  0; // white space
static const signed char cltPer     =  1; // %
static const signed char cltAmp     =  2; // &
static const signed char cltGt      =  3; // >
static const signed char cltLt      =  4; // <
static const signed char cltSlash   =  5; // /
static const signed char cltQm      =  6; // ?
static const signed char cltEm      =  7; // !
static const signed char cltDash    =  8; // -
static const signed char cltCB      =  9; // ]
static const signed char cltOB      = 10; // [
static const signed char cltEq      = 11; // =
static const signed char cltDq      = 12; // "
static const signed char cltSq      = 13; // '
static const signed char cltUnknown = 14;

// character lookup table
static const signed char charLookupTable[256]={
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
    cltUnknown, // 0x08
    cltWS,      // 0x09 \t
    cltWS,      // 0x0A \n
    cltUnknown, // 0x0B
    cltUnknown, // 0x0C
    cltWS,      // 0x0D \r
    cltUnknown, // 0x0E
    cltUnknown, // 0x0F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
    cltWS,      // 0x20 Space
    cltEm,      // 0x21 !
    cltDq,      // 0x22 "
    cltUnknown, // 0x23
    cltUnknown, // 0x24
    cltPer,     // 0x25 %
    cltAmp,     // 0x26 &
    cltSq,      // 0x27 '
    cltUnknown, // 0x28
    cltUnknown, // 0x29
    cltUnknown, // 0x2A
    cltUnknown, // 0x2B
    cltUnknown, // 0x2C
    cltDash,    // 0x2D -
    cltUnknown, // 0x2E
    cltSlash,   // 0x2F /
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
    cltUnknown, // 0x38
    cltUnknown, // 0x39
    cltUnknown, // 0x3A
    cltUnknown, // 0x3B
    cltLt,      // 0x3C <
    cltEq,      // 0x3D =
    cltGt,      // 0x3E >
    cltQm,      // 0x3F ?
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
    cltUnknown, // 0x58
    cltUnknown, // 0x59
    cltUnknown, // 0x5A
    cltOB,      // 0x5B [
    cltUnknown, // 0x5C
    cltCB,      // 0x5D]
    cltUnknown, // 0x5E
    cltUnknown, // 0x5F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown  // 0xF8 - 0xFF
};

//
// local helper functions
//

/*
  This function strips the TextDecl [77] ("<?xml ...?>") from the string \a
  str. The stripped version is stored in \a str. If this function finds an
  invalid TextDecl, it returns \c false, otherwise true.

  This function is used for external entities since those can include an
  TextDecl that must be stripped before inserting the entity.
*/
static bool stripTextDecl(QString& str)
{
    QLatin1String textDeclStart("<?xml");
    if (str.startsWith(textDeclStart)) {
#if QT_CONFIG(regularexpression)
        QRegularExpression textDecl(QString::fromLatin1(
            "^<\\?xml\\s+"
            "(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
            "\\s*"
            "(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
            "\\s*\\?>"
        ));
        QString strTmp = str.replace(textDecl, QLatin1String(""));
        if (strTmp.length() != str.length())
            return false; // external entity has wrong TextDecl
        str = strTmp;
#else
        return false;
#endif
    }
    return true;
}


class QXmlAttributesPrivate
{
};

/* \class QXmlInputSourcePrivate
    \internal

  There's a slight misdesign in this class that can
  be worth to keep in mind: the `str' member is
  a buffer which QXmlInputSource::next() returns from,
  and which is populated from the input device or input
  stream. However, when the input is a QString(the user called
  QXmlInputSource::setData()), `str' has two roles: it's the
  buffer, but also the source. This /seems/ to be no problem
  because in the case of having no device or stream, the QString
  is read in one go.
 */
class QXmlInputSourcePrivate
{
public:
    QIODevice *inputDevice;
    QTextStream *inputStream;

    QString str;
    const QChar *unicode;
    int pos;
    int length;
    bool nextReturnedEndOfData;
#if QT_CONFIG(textcodec)
    QTextDecoder *encMapper;
#endif

    QByteArray encodingDeclBytes;
    QString encodingDeclChars;
    bool lookingForEncodingDecl;
};
class QXmlParseExceptionPrivate
{
public:
    QXmlParseExceptionPrivate()
        : column(-1), line(-1)
    {
    }
    QXmlParseExceptionPrivate(const QXmlParseExceptionPrivate &other)
        : msg(other.msg), column(other.column), line(other.line),
          pub(other.pub), sys(other.sys)
    {
    }

    QString msg;
    int column;
    int line;
    QString pub;
    QString sys;

};

class QXmlLocatorPrivate
{
};

class QXmlDefaultHandlerPrivate
{
};

/*!
    \class QXmlParseException
    \reentrant
    \brief The QXmlParseException class is used to report errors with
    the QXmlErrorHandler interface.

    \inmodule QtXml
    \ingroup xml-tools

    The XML subsystem constructs an instance of this class when it
    detects an error. You can retrieve the place where the error
    occurred using systemId(), publicId(), lineNumber() and
    columnNumber(), along with the error message(). The possible error
    messages are:


    \list
        \li "no error occurred"
        \li "error triggered by consumer"
        \li "unexpected end of file"
        \li "more than one document type definition"
        \li "error occurred while parsing element"
        \li "tag mismatch"
        \li "error occurred while parsing content"
        \li "unexpected character"
        \li "invalid name for processing instruction"
        \li "version expected while reading the XML declaration"
        \li "wrong value for standalone declaration"
        \li "encoding declaration or standalone declaration expected while reading the XML declaration"
        \li "standalone declaration expected while reading the XML declaration"
        \li "error occurred while parsing document type definition"
        \li "letter is expected"
        \li "error occurred while parsing comment"
        \li "error occurred while parsing reference"
        \li "internal general entity reference not allowed in DTD"
        \li "external parsed general entity reference not allowed in attribute value"
        \li "external parsed general entity reference not allowed in DTD"
        \li "unparsed entity reference n wrong context"
        \li "recursive entities"
        \li "error in the text declaration of an external entity"
    \endlist

    Note that, if you want to display these error messages to your
    application's users, they will be displayed in English unless
    they are explicitly translated.

    \sa QXmlErrorHandler, QXmlReader
*/

/*!
    Constructs a parse exception with the error string \a name for
    column \a c and line \a l for the public identifier \a p and the
    system identifier \a s.
*/

QXmlParseException::QXmlParseException(const QString& name, int c, int l,
                                       const QString& p, const QString& s)
    : d(new QXmlParseExceptionPrivate)
{
    d->msg = name;
    d->column = c;
    d->line = l;
    d->pub = p;
    d->sys = s;
}

/*!
    Creates a copy of \a other.
*/
QXmlParseException::QXmlParseException(const QXmlParseException& other) :
     d(new QXmlParseExceptionPrivate(*other.d))
{

}

/*!
    Destroys the QXmlParseException.
*/
QXmlParseException::~QXmlParseException()
{
}

/*!
    Returns the error message.
*/
QString QXmlParseException::message() const
{
    return d->msg;
}
/*!
    Returns the column number where the error occurred.
*/
int QXmlParseException::columnNumber() const
{
    return d->column;
}
/*!
    Returns the line number where the error occurred.
*/
int QXmlParseException::lineNumber() const
{
    return d->line;
}
/*!
    Returns the public identifier where the error occurred.
*/
QString QXmlParseException::publicId() const
{
    return d->pub;
}
/*!
    Returns the system identifier where the error occurred.
*/
QString QXmlParseException::systemId() const
{
    return d->sys;
}


/*!
    \class QXmlLocator
    \reentrant
    \brief The QXmlLocator class provides the XML handler classes with
    information about the parsing position within a file.

    \inmodule QtXml
    \ingroup xml-tools

    The reader reports a QXmlLocator to the content handler before it
    starts to parse the document. This is done with the
    QXmlContentHandler::setDocumentLocator() function. The handler
    classes can now use this locator to get the position (lineNumber()
    and columnNumber()) that the reader has reached.
*/

/*!
    Constructor.
*/
QXmlLocator::QXmlLocator()
{
}

/*!
    Destructor.
*/
QXmlLocator::~QXmlLocator()
{
}

/*!
    \fn int QXmlLocator::columnNumber() const

    Returns the column number (starting at 1) or -1 if there is no
    column number available.
*/

/*!
    \fn int QXmlLocator::lineNumber() const

    Returns the line number (starting at 1) or -1 if there is no line
    number available.
*/

class QXmlSimpleReaderLocator : public QXmlLocator
{
public:
    QXmlSimpleReaderLocator(QXmlSimpleReader* parent)
    {
        reader = parent;
    }
    ~QXmlSimpleReaderLocator()
    {
    }

    int columnNumber() const override
    {
        return (reader->d_ptr->columnNr == -1 ? -1 : reader->d_ptr->columnNr + 1);
    }
    int lineNumber() const override
    {
        return (reader->d_ptr->lineNr == -1 ? -1 : reader->d_ptr->lineNr + 1);
    }
//    QString getPublicId()
//    QString getSystemId()

private:
    QXmlSimpleReader *reader;
};

/*********************************************
 *
 * QXmlNamespaceSupport
 *
 *********************************************/

typedef QMap<QString, QString> NamespaceMap;

class QXmlNamespaceSupportPrivate
{
public:
    QXmlNamespaceSupportPrivate()
    {
        ns.insert(QLatin1String("xml"), QLatin1String("http://www.w3.org/XML/1998/namespace")); // the XML namespace
    }

    ~QXmlNamespaceSupportPrivate()
    {
    }

    QStack<NamespaceMap> nsStack;
    NamespaceMap ns;
};

/*!
    \class QXmlNamespaceSupport
    \since 4.4
    \reentrant
    \brief The QXmlNamespaceSupport class is a helper class for XML
    readers which want to include namespace support.

    \inmodule QtXml
    \ingroup xml-tools

    You can set the prefix for the current namespace with setPrefix(),
    and get the list of current prefixes (or those for a given URI)
    with prefixes(). The namespace URI is available from uri(). Use
    pushContext() to start a new namespace context, and popContext()
    to return to the previous namespace context. Use splitName() or
    processName() to split a name into its prefix and local name.

    \sa {Namespace Support via Features}
*/

/*!
    Constructs a QXmlNamespaceSupport.
*/
QXmlNamespaceSupport::QXmlNamespaceSupport()
{
    d = new QXmlNamespaceSupportPrivate;
}

/*!
    Destroys a QXmlNamespaceSupport.
*/
QXmlNamespaceSupport::~QXmlNamespaceSupport()
{
    delete d;
}

/*!
    This function declares a prefix \a pre in the current namespace
    context to be the namespace URI \a uri. The prefix remains in
    force until this context is popped, unless it is shadowed in a
    descendant context.

    Note that there is an asymmetry in this library. prefix() does not
    return the default "" prefix, even if you have declared one; to
    check for a default prefix, you must look it up explicitly using
    uri(). This asymmetry exists to make it easier to look up prefixes
    for attribute names, where the default prefix is not allowed.
*/
void QXmlNamespaceSupport::setPrefix(const QString& pre, const QString& uri)
{
    if(pre.isNull()) {
        d->ns.insert(QLatin1String(""), uri);
    } else {
        d->ns.insert(pre, uri);
    }
}

/*!
    Returns one of the prefixes mapped to the namespace URI \a uri.

    If more than one prefix is currently mapped to the same URI, this
    function makes an arbitrary selection; if you want all of the
    prefixes, use prefixes() instead.

    Note: to check for a default prefix, use the uri() function with
    an argument of "".
*/
QString QXmlNamespaceSupport::prefix(const QString& uri) const
{
    NamespaceMap::const_iterator itc, it = d->ns.constBegin();
    while ((itc=it) != d->ns.constEnd()) {
        ++it;
        if (*itc == uri && !itc.key().isEmpty())
            return itc.key();
    }
    return QLatin1String("");
}

/*!
    Looks up the prefix \a prefix in the current context and returns
    the currently-mapped namespace URI. Use the empty string ("") for
    the default namespace.
*/
QString QXmlNamespaceSupport::uri(const QString& prefix) const
{
    return d->ns[prefix];
}

/*!
    Splits the name \a qname at the ':' and returns the prefix in \a
    prefix and the local name in \a localname.

    \sa processName()
*/
void QXmlNamespaceSupport::splitName(const QString& qname, QString& prefix,
                                     QString& localname) const
{
    int pos = qname.indexOf(QLatin1Char(':'));
    if (pos == -1)
        pos = qname.size();

    prefix = qname.left(pos);
    localname = qname.mid(pos+1);
}

/*!
    Processes a raw XML 1.0 name in the current context by removing
    the prefix and looking it up among the prefixes currently
    declared.

    \a qname is the raw XML 1.0 name to be processed. \a isAttribute
    is true if the name is an attribute name.

    This function stores the namespace URI in \a nsuri (which will be
    set to an empty string if the raw name has an undeclared prefix),
    and stores the local name (without prefix) in \a localname (which
    will be set to an empty string if no namespace is in use).

    Note that attribute names are processed differently than element
    names: an unprefixed element name gets the default namespace (if
    any), while an unprefixed attribute name does not.
*/
void QXmlNamespaceSupport::processName(const QString& qname,
        bool isAttribute,
        QString& nsuri, QString& localname) const
{
    int len = qname.size();
    const QChar *data = qname.constData();
    for (int pos = 0; pos < len; ++pos) {
        if (data[pos] == QLatin1Char(':')) {
            nsuri = uri(qname.left(pos));
            localname = qname.mid(pos + 1);
            return;
        }
    }

    // there was no ':'
    nsuri.clear();
    // attributes don't take default namespace
    if (!isAttribute && !d->ns.isEmpty()) {
        /*
            We want to access d->ns.value(""), but as an optimization
            we use the fact that "" compares less than any other
            string, so it's either first in the map or not there.
        */
        NamespaceMap::const_iterator first = d->ns.constBegin();
        if (first.key().isEmpty())
            nsuri = first.value(); // get default namespace
    }
    localname = qname;
}

/*!
    Returns a list of all the prefixes currently declared.

    If there is a default prefix, this function does not return it in
    the list; check for the default prefix using uri() with an
    argument of "".
*/
QStringList QXmlNamespaceSupport::prefixes() const
{
    QStringList list;

    NamespaceMap::const_iterator itc, it = d->ns.constBegin();
    while ((itc=it) != d->ns.constEnd()) {
        ++it;
        if (!itc.key().isEmpty())
            list.append(itc.key());
    }
    return list;
}

/*!
    \overload

    Returns a list of all prefixes currently declared for the
    namespace URI \a uri.

    The "xml:" prefix is included. If you only want one prefix that is
    mapped to the namespace URI, and you don't care which one you get,
    use the prefix() function instead.

    Note: The empty (default) prefix is never included in this list;
    to check for the presence of a default namespace, call uri() with
    "" as the argument.
*/
QStringList QXmlNamespaceSupport::prefixes(const QString& uri) const
{
    QStringList list;

    NamespaceMap::const_iterator itc, it = d->ns.constBegin();
    while ((itc=it) != d->ns.constEnd()) {
        ++it;
        if (*itc == uri && !itc.key().isEmpty())
            list.append(itc.key());
    }
    return list;
}

/*!
    Starts a new namespace context.

    Normally, you should push a new context at the beginning of each
    XML element: the new context automatically inherits the
    declarations of its parent context, and it also keeps track of
    which declarations were made within this context.

    \sa popContext()
*/
void QXmlNamespaceSupport::pushContext()
{
    d->nsStack.push(d->ns);
}

/*!
    Reverts to the previous namespace context.

    Normally, you should pop the context at the end of each XML
    element. After popping the context, all namespace prefix mappings
    that were previously in force are restored.

    \sa pushContext()
*/
void QXmlNamespaceSupport::popContext()
{
    d->ns.clear();
    if(!d->nsStack.isEmpty())
        d->ns = d->nsStack.pop();
}

/*!
    Resets this namespace support object ready for reuse.
*/
void QXmlNamespaceSupport::reset()
{
    QXmlNamespaceSupportPrivate *newD = new QXmlNamespaceSupportPrivate;
    delete d;
    d = newD;
}



/*********************************************
 *
 * QXmlAttributes
 *
 *********************************************/

/*!
    \class QXmlAttributes
    \reentrant
    \brief The QXmlAttributes class provides XML attributes.

    \inmodule QtXml
    \ingroup xml-tools

    If attributes are reported by QXmlContentHandler::startElement()
    this class is used to pass the attribute values.

    Use index() to locate the position of an attribute in the list,
    count() to retrieve the number of attributes, and clear() to
    remove the attributes. New attributes can be added with append().
    Use type() to get an attribute's type and value() to get its
    value. The attribute's name is available from localName() or
    qName(), and its namespace URI from uri().

*/

/*!
    \fn QXmlAttributes::QXmlAttributes()

    Constructs an empty attribute list.
*/
QXmlAttributes::QXmlAttributes()
{
    // ### In Qt 5.0, this function was inlined and d was not initialized
    // The member cannot be used until Qt 6.0
    Q_UNUSED(d);
}

/*!
    \fn QXmlAttributes::~QXmlAttributes()

    Destroys the attributes object.
*/
QXmlAttributes::~QXmlAttributes()
{
}

/*!
  \fn void QXmlAttributes::swap(QXmlAttributes &other)

  Swaps \c this with \a other.
 */

/*!
    Looks up the index of an attribute by the qualified name \a qName.

    Returns the index of the attribute or -1 if it wasn't found.

    \sa {Namespace Support via Features}
*/
int QXmlAttributes::index(const QString& qName) const
{
    for (int i = 0; i < attList.size(); ++i) {
        if (attList.at(i).qname == qName)
            return i;
    }
    return -1;
}

/*! \overload
  */
int QXmlAttributes::index(QLatin1String qName) const
{
    for (int i = 0; i < attList.size(); ++i) {
        if (attList.at(i).qname == qName)
            return i;
    }
    return -1;
}

/*!
    \overload

    Looks up the index of an attribute by a namespace name.

    \a uri specifies the namespace URI, or an empty string if the name
    has no namespace URI. \a localPart specifies the attribute's local
    name.

    Returns the index of the attribute, or -1 if it wasn't found.

    \sa {Namespace Support via Features}
*/
int QXmlAttributes::index(const QString& uri, const QString& localPart) const
{
    for (int i = 0; i < attList.size(); ++i) {
        const Attribute &att = attList.at(i);
        if (att.uri == uri && att.localname == localPart)
            return i;
    }
    return -1;
}

/*!
    Returns the number of attributes in the list.

    \sa count()
*/
int QXmlAttributes::length() const
{
    return attList.count();
}

/*!
    \fn int QXmlAttributes::count() const

    Returns the number of attributes in the list. This function is
    equivalent to length().
*/

/*!
    Looks up an attribute's local name for the attribute at position
    \a index. If no namespace processing is done, the local name is
    an empty string.

    \sa {Namespace Support via Features}
*/
QString QXmlAttributes::localName(int index) const
{
    return attList.at(index).localname;
}

/*!
    Looks up an attribute's XML 1.0 qualified name for the attribute
    at position \a index.

    \sa {Namespace Support via Features}
*/
QString QXmlAttributes::qName(int index) const
{
    return attList.at(index).qname;
}

/*!
    Looks up an attribute's namespace URI for the attribute at
    position \a index. If no namespace processing is done or if the
    attribute has no namespace, the namespace URI is an empty string.

    \sa {Namespace Support via Features}
*/
QString QXmlAttributes::uri(int index) const
{
    return attList.at(index).uri;
}

/*!
    Looks up an attribute's type for the attribute at position \a
    index.

    Currently only "CDATA" is returned.
*/
QString QXmlAttributes::type(int) const
{
    return QLatin1String("CDATA");
}

/*!
    \overload

    Looks up an attribute's type for the qualified name \a qName.

    Currently only "CDATA" is returned.
*/
QString QXmlAttributes::type(const QString&) const
{
    return QLatin1String("CDATA");
}

/*!
    \overload

    Looks up an attribute's type by namespace name.

    \a uri specifies the namespace URI and \a localName specifies the
    local name. If the name has no namespace URI, use an empty string
    for \a uri.

    Currently only "CDATA" is returned.
*/
QString QXmlAttributes::type(const QString&, const QString&) const
{
    return QLatin1String("CDATA");
}

/*!
    Returns an attribute's value for the attribute at position \a
    index. The index must be a valid position
    (i.e., 0 <= \a index < count()).
*/
QString QXmlAttributes::value(int index) const
{
    return attList.at(index).value;
}

/*!
    \overload

    Returns an attribute's value for the qualified name \a qName, or an
    empty string if no attribute exists for the name given.

    \sa {Namespace Support via Features}
*/
QString QXmlAttributes::value(const QString& qName) const
{
    int i = index(qName);
    if (i == -1)
        return QString();
    return attList.at(i).value;
}

/*!
    \overload

    Returns an attribute's value for the qualified name \a qName, or an
    empty string if no attribute exists for the name given.

    \sa {Namespace Support via Features}
*/
QString QXmlAttributes::value(QLatin1String qName) const
{
    int i = index(qName);
    if (i == -1)
        return QString();
    return attList.at(i).value;
}

/*!
    \overload

    Returns an attribute's value by namespace name.

    \a uri specifies the namespace URI, or an empty string if the name
    has no namespace URI. \a localName specifies the attribute's local
    name.
*/
QString QXmlAttributes::value(const QString& uri, const QString& localName) const
{
    int i = index(uri, localName);
    if (i == -1)
        return QString();
    return attList.at(i).value;
}

/*!
    Clears the list of attributes.

    \sa append()
*/
void QXmlAttributes::clear()
{
    attList.clear();
}

/*!
    Appends a new attribute entry to the list of attributes. The
    qualified name of the attribute is \a qName, the namespace URI is
    \a uri and the local name is \a localPart. The value of the
    attribute is \a value.

    \sa qName(), uri(), localName(), value()
*/
void QXmlAttributes::append(const QString &qName, const QString &uri, const QString &localPart, const QString &value)
{
    Attribute att;
    att.qname = qName;
    att.uri = uri;
    att.localname = localPart;
    att.value = value;

    attList.append(att);
}


/*********************************************
 *
 * QXmlInputSource
 *
 *********************************************/

/*!
    \class QXmlInputSource
    \reentrant
    \brief The QXmlInputSource class provides the input data for the
    QXmlReader subclasses.

    \inmodule QtXml
    \ingroup xml-tools

    All subclasses of QXmlReader read the input XML document from this
    class.

    This class recognizes the encoding of the data by reading the
    encoding declaration in the XML file if it finds one, and reading
    the data using the corresponding encoding. If it does not find an
    encoding declaration, then it assumes that the data is either in
    UTF-8 or UTF-16, depending on whether it can find a byte-order
    mark.

    There are two ways to populate the input source with data: you can
    construct it with a QIODevice* so that the input source reads the
    data from that device. Or you can set the data explicitly with one
    of the setData() functions.

    Usually you either construct a QXmlInputSource that works on a
    QIODevice* or you construct an empty QXmlInputSource and set the
    data with setData(). There are only rare occasions where you would
    want to mix both methods.

    The QXmlReader subclasses use the next() function to read the
    input character by character. If you want to start from the
    beginning again, use reset().

    The functions data() and fetchData() are useful if you want to do
    something with the data other than parsing, e.g. displaying the
    raw XML file. The benefit of using the QXmlInputClass in such
    cases is that it tries to use the correct encoding.

    \sa QXmlReader, QXmlSimpleReader
*/

// the following two are guaranteed not to be a character
const ushort QXmlInputSource::EndOfData = 0xfffe;
const ushort QXmlInputSource::EndOfDocument = 0xffff;

/*
    Common part of the constructors.
*/
void QXmlInputSource::init()
{
    d = new QXmlInputSourcePrivate;

    QT_TRY {
        d->inputDevice = nullptr;
        d->inputStream = nullptr;

        setData(QString());
#if QT_CONFIG(textcodec)
        d->encMapper = nullptr;
#endif
        d->nextReturnedEndOfData = true; // first call to next() will call fetchData()

        d->encodingDeclBytes.clear();
        d->encodingDeclChars.clear();
        d->lookingForEncodingDecl = true;
    } QT_CATCH(...) {
        delete(d);
        QT_RETHROW;
    }
}

/*!
    Constructs an input source which contains no data.

    \sa setData()
*/
QXmlInputSource::QXmlInputSource()
{
    init();
}

/*!
    Constructs an input source and gets the data from device \a dev.
    If \a dev is not open, it is opened in read-only mode. If \a dev
    is 0 or it is not possible to read from the device, the input
    source will contain no data.

    \sa setData(), fetchData(), QIODevice
*/
QXmlInputSource::QXmlInputSource(QIODevice *dev)
{
    init();
    d->inputDevice = dev;
    if (dev->isOpen())
        d->inputDevice->setTextModeEnabled(false);
}

/*!
    Destructor.
*/
QXmlInputSource::~QXmlInputSource()
{
    // ### close the input device.
#if QT_CONFIG(textcodec)
    delete d->encMapper;
#endif
    delete d;
}

/*!
Returns the next character of the input source. If this function
reaches the end of available data, it returns
QXmlInputSource::EndOfData. If you call next() after that, it
tries to fetch more data by calling fetchData(). If the
fetchData() call results in new data, this function returns the
first character of that data; otherwise it returns
QXmlInputSource::EndOfDocument.

Readers, such as QXmlSimpleReader, will assume that the end of
the XML document has been reached if the this function returns
QXmlInputSource::EndOfDocument, and will check that the
supplied input is well-formed. Therefore, when reimplementing
this function, it is important to ensure that this behavior is
duplicated.

\sa reset(), fetchData(), QXmlSimpleReader::parse(),
    QXmlSimpleReader::parseContinue()
*/
QChar QXmlInputSource::next()
{
    if (d->pos >= d->length) {
        if (d->nextReturnedEndOfData) {
            d->nextReturnedEndOfData = false;
            fetchData();
            if (d->pos >= d->length) {
                return QChar(EndOfDocument);
            }
            return next();
        }
        d->nextReturnedEndOfData = true;
        return QChar(EndOfData);
    }

    // QXmlInputSource has no way to signal encoding errors. The best we can do
    // is return EndOfDocument. We do *not* return EndOfData, because the reader
    // will then just call this function again to get the next char.
    QChar c = d->unicode[d->pos++];
    if (c.unicode() == EndOfData)
        c = QChar(EndOfDocument);
    return c;
}

/*!
    This function sets the position used by next() to the beginning of
    the data returned by data(). This is useful if you want to use the
    input source for more than one parse.

    \note In the case that the underlying data source is a QIODevice,
    the current position in the device is not automatically set to the
    start of input. Call QIODevice::seek(0) on the device to do this.

    \sa next()
*/
void QXmlInputSource::reset()
{
    d->nextReturnedEndOfData = false;
    d->pos = 0;
}

/*!
    Returns the data the input source contains or an empty string if the
    input source does not contain any data.

    \sa setData(), QXmlInputSource(), fetchData()
*/
QString QXmlInputSource::data() const
{
    if (d->nextReturnedEndOfData) {
        QXmlInputSource *that = const_cast<QXmlInputSource*>(this);
        that->d->nextReturnedEndOfData = false;
        that->fetchData();
    }
    return d->str;
}

/*!
    Sets the data of the input source to \a dat.

    If the input source already contains data, this function deletes
    that data first.

    \sa data()
*/
void QXmlInputSource::setData(const QString& dat)
{
    d->str = dat;
    d->unicode = dat.unicode();
    d->pos = 0;
    d->length = d->str.length();
    d->nextReturnedEndOfData = false;
}

/*!
    \overload

    The data \a dat is passed through the correct text-codec, before
    it is set.
*/
void QXmlInputSource::setData(const QByteArray& dat)
{
    setData(fromRawData(dat));
}

/*!
    This function reads more data from the device that was set during
    construction. If the input source already contained data, this
    function deletes that data first.

    This object contains no data after a call to this function if the
    object was constructed without a device to read data from or if
    this function was not able to get more data from the device.

    There are two occasions where a fetch is done implicitly by
    another function call: during construction (so that the object
    starts out with some initial data where available), and during a
    call to next() (if the data had run out).

    You don't normally need to use this function if you use next().

    \sa data(), next(), QXmlInputSource()
*/

void QXmlInputSource::fetchData()
{
    enum
    {
        BufferSize = 1024
    };

    QByteArray rawData;

    if (d->inputDevice || d->inputStream) {
        QIODevice *device = d->inputDevice ? d->inputDevice : d->inputStream->device();

        if (!device) {
            if (d->inputStream && d->inputStream->string()) {
                QString *s = d->inputStream->string();
                rawData = QByteArray((const char *) s->constData(), s->size() * sizeof(QChar));
            }
        } else if (device->isOpen() || device->open(QIODevice::ReadOnly)) {
            rawData.resize(BufferSize);
            qint64 size = device->read(rawData.data(), BufferSize);
            if (size == 0 && device->waitForReadyRead(-1))
                size = device->read(rawData.data(), BufferSize);

            rawData.resize(qMax(qint64(0), size));
        }

        /* We do this inside the "if (d->inputDevice ..." scope
         * because if we're not using a stream or device, that is,
         * the user set a QString manually, we don't want to set
         * d->str. */
        setData(fromRawData(rawData));
    }
}

#if QT_CONFIG(textcodec)
static QString extractEncodingDecl(const QString &text, bool *needMoreText)
{
    *needMoreText = false;

    int l = text.length();
    const QLatin1String snip("<?xml", std::min(l, 5));
    if (l > 0 && !text.startsWith(snip))
        return QString();

    int endPos = text.indexOf(QLatin1Char('>'));
    if (endPos == -1) {
        *needMoreText = l < 255; // we won't look forever
        return QString();
    }

    int pos = text.indexOf(QLatin1String("encoding"));
    if (pos == -1 || pos >= endPos)
        return QString();

    while (pos < endPos) {
        QChar uc = text.at(pos);
        if (uc == u'\'' || uc == u'"')
            break;
        ++pos;
    }

    if (pos == endPos)
        return QString();

    QString encoding;
    ++pos;
    while (pos < endPos) {
        QChar uc = text.at(pos);
        if (uc == u'\'' || uc == u'"')
            break;
        encoding.append(uc);
        ++pos;
    }

    return encoding;
}
#endif // textcodec

/*!
    This function reads the XML file from \a data and tries to
    recognize the encoding. It converts the raw data \a data into a
    QString and returns it. It tries its best to get the correct
    encoding for the XML file.

    If \a beginning is true, this function assumes that the data
    starts at the beginning of a new XML document and looks for an
    encoding declaration. If \a beginning is false, it converts the
    raw data using the encoding determined from prior calls.
*/
QString QXmlInputSource::fromRawData(const QByteArray &data, bool beginning)
{
#if !QT_CONFIG(textcodec)
    Q_UNUSED(beginning);
    return QString::fromLatin1(data.constData(), data.size());
#else
    if (data.size() == 0)
        return QString();
    if (beginning) {
        delete d->encMapper;
        d->encMapper = nullptr;
    }

    int mib = 106; // UTF-8

    // This is the initial UTF codec we will read the encoding declaration with
    if (d->encMapper == nullptr) {
        d->encodingDeclBytes.clear();
        d->encodingDeclChars.clear();
        d->lookingForEncodingDecl = true;

        // look for byte order mark and read the first 5 characters
        if (data.size() >= 4) {
            uchar ch1 = data.at(0);
            uchar ch2 = data.at(1);
            uchar ch3 = data.at(2);
            uchar ch4 = data.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
        }
        if (mib == 106 && data.size() >= 2) {
            uchar ch1 = data.at(0);
            uchar ch2 = data.at(1);

            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
        }

        QTextCodec *codec = QTextCodec::codecForMib(mib);
        Q_ASSERT(codec);

        d->encMapper = codec->makeDecoder();
    }

    QString input = d->encMapper->toUnicode(data.constData(), data.size());

    if (d->lookingForEncodingDecl) {
        d->encodingDeclChars += input;

        bool needMoreText;
        QString encoding = extractEncodingDecl(d->encodingDeclChars, &needMoreText);

        if (!encoding.isEmpty()) {
            if (QTextCodec *codec = QTextCodec::codecForName(std::move(encoding).toLatin1())) {
                /* If the encoding is the same, we don't have to do toUnicode() all over again. */
                if(codec->mibEnum() != mib) {
                    delete d->encMapper;
                    d->encMapper = codec->makeDecoder();

                    /* The variable input can potentially be large, so we deallocate
                     * it before calling toUnicode() in order to avoid having two
                     * large QStrings in memory simultaneously. */
                    input.clear();

                    // prime the decoder with the data so far
                    d->encMapper->toUnicode(d->encodingDeclBytes.constData(), d->encodingDeclBytes.size());
                    // now feed it the new data
                    input = d->encMapper->toUnicode(data.constData(), data.size());
                }
            }
        }

        d->encodingDeclBytes += data;
        d->lookingForEncodingDecl = needMoreText;
    }

    return input;
#endif
}


/*********************************************
 *
 * QXmlDefaultHandler
 *
 *********************************************/

/*!
    \class QXmlContentHandler
    \reentrant
    \brief The QXmlContentHandler class provides an interface to
    report the logical content of XML data.

    \inmodule QtXml
    \ingroup xml-tools

    If the application needs to be informed of basic parsing events,
    it can implement this interface and activate it using
    QXmlReader::setContentHandler(). The reader can then report basic
    document-related events like the start and end of elements and
    character data through this interface.

    The order of events in this interface is very important, and
    mirrors the order of information in the document itself. For
    example, all of an element's content (character data, processing
    instructions, and sub-elements) appears, in order, between the
    startElement() event and the corresponding endElement() event.

    The class QXmlDefaultHandler provides a default implementation for
    this interface; subclassing from the QXmlDefaultHandler class is
    very convenient if you only want to be informed of some parsing
    events.

    The startDocument() function is called at the start of the
    document, and endDocument() is called at the end. Before parsing
    begins setDocumentLocator() is called. For each element
    startElement() is called, with endElement() being called at the
    end of each element. The characters() function is called with
    chunks of character data; ignorableWhitespace() is called with
    chunks of whitespace and processingInstruction() is called with
    processing instructions. If an entity is skipped skippedEntity()
    is called. At the beginning of prefix-URI scopes
    startPrefixMapping() is called.

    \sa QXmlDTDHandler, QXmlDeclHandler, QXmlEntityResolver, QXmlErrorHandler,
        QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlContentHandler::~QXmlContentHandler()

    Destroys the content handler.
*/

/*!
    \fn void QXmlContentHandler::setDocumentLocator(QXmlLocator* locator)

    The reader calls this function before it starts parsing the
    document. The argument \a locator is a pointer to a QXmlLocator
    which allows the application to get the parsing position within
    the document.

    Do not destroy the \a locator; it is destroyed when the reader is
    destroyed. (Do not use the \a locator after the reader is
    destroyed).
*/

/*!
    \fn bool QXmlContentHandler::startDocument()

    The reader calls this function when it starts parsing the
    document. The reader calls this function just once, after the call
    to setDocumentLocator(), and before any other functions in this
    class or in the QXmlDTDHandler class are called.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endDocument()
*/

/*!
    \fn bool QXmlContentHandler::endDocument()

    The reader calls this function after it has finished parsing. It
    is called just once, and is the last handler function called. It
    is called after the reader has read all input or has abandoned
    parsing because of a fatal error.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa startDocument()
*/

/*!
    \fn bool QXmlContentHandler::startPrefixMapping(const QString& prefix, const QString& uri)

    The reader calls this function to signal the begin of a prefix-URI
    namespace mapping scope. This information is not necessary for
    normal namespace processing since the reader automatically
    replaces prefixes for element and attribute names.

    Note that startPrefixMapping() and endPrefixMapping() calls are
    not guaranteed to be properly nested relative to each other: all
    startPrefixMapping() events occur before the corresponding
    startElement() event, and all endPrefixMapping() events occur
    after the corresponding endElement() event, but their order is not
    otherwise guaranteed.

    The argument \a prefix is the namespace prefix being declared and
    the argument \a uri is the namespace URI the prefix is mapped to.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endPrefixMapping(), {Namespace Support via Features}
*/

/*!
    \fn bool QXmlContentHandler::endPrefixMapping(const QString& prefix)

    The reader calls this function to signal the end of a prefix
    mapping for the prefix \a prefix.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa startPrefixMapping(), {Namespace Support via Features}
*/

/*!
    \fn bool QXmlContentHandler::startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts)

    The reader calls this function when it has parsed a start element
    tag.

    There is a corresponding endElement() call when the corresponding
    end element tag is read. The startElement() and endElement() calls
    are always nested correctly. Empty element tags (e.g. \c{<x/>})
    cause a startElement() call to be immediately followed by an
    endElement() call.

    The attribute list provided only contains attributes with explicit
    values. The attribute list contains attributes used for namespace
    declaration (i.e. attributes starting with xmlns) only if the
    namespace-prefix property of the reader is true.

    The argument \a namespaceURI is the namespace URI, or
    an empty string if the element has no namespace URI or if no
    namespace processing is done. \a localName is the local name
    (without prefix), or an empty string if no namespace processing is
    done, \a qName is the qualified name (with prefix) and \a atts are
    the attributes attached to the element. If there are no
    attributes, \a atts is an empty attributes object.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endElement(), {Namespace Support via Features}
*/

/*!
    \fn bool QXmlContentHandler::endElement(const QString& namespaceURI, const QString& localName, const QString& qName)

    The reader calls this function when it has parsed an end element
    tag with the qualified name \a qName, the local name \a localName
    and the namespace URI \a namespaceURI.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa startElement(), {Namespace Support via Features}
*/

/*!
    \fn bool QXmlContentHandler::characters(const QString& ch)

    The reader calls this function when it has parsed a chunk of
    character data (either normal character data or character data
    inside a CDATA section; if you need to distinguish between those
    two types you must use QXmlLexicalHandler::startCDATA() and
    QXmlLexicalHandler::endCDATA()). The character data is reported in
    \a ch.

    Some readers report whitespace in element content using the
    ignorableWhitespace() function rather than using this one.

    A reader may report the character data of an element in more than
    one chunk; e.g. a reader might want to report "a\<b" in three
    characters() events ("a ", "\<" and " b").

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlContentHandler::ignorableWhitespace(const QString& ch)

    Some readers may use this function to report each chunk of
    whitespace in element content. The whitespace is reported in \a ch.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlContentHandler::processingInstruction(const QString& target, const QString& data)

    The reader calls this function when it has parsed a processing
    instruction.

    \a target is the target name of the processing instruction and \a
    data is the data in the processing instruction.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlContentHandler::skippedEntity(const QString& name)

    Some readers may skip entities if they have not seen the
    declarations (e.g. because they are in an external DTD). If they
    do so they report that they skipped the entity called \a name by
    calling this function.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn QString QXmlContentHandler::errorString() const

    The reader calls this function to get an error string, e.g. if any
    of the handler functions returns \c false.
*/


/*!
    \class QXmlErrorHandler
    \reentrant
    \brief The QXmlErrorHandler class provides an interface to report
    errors in XML data.

    \inmodule QtXml
    \ingroup xml-tools

    If you want your application to report errors to the user or to
    perform customized error handling, you should subclass this class.

    You can set the error handler with QXmlReader::setErrorHandler().

    Errors can be reported using warning(), error() and fatalError(),
    with the error text being reported with errorString().

    \sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
        QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlErrorHandler::~QXmlErrorHandler()

    Destroys the error handler.
*/

/*!
    \fn bool QXmlErrorHandler::warning(const QXmlParseException& exception)

    A reader might use this function to report a warning. Warnings are
    conditions that are not errors or fatal errors as defined by the
    XML 1.0 specification. Details of the warning are stored in \a
    exception.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlErrorHandler::error(const QXmlParseException& exception)

    A reader might use this function to report a recoverable error. A
    recoverable error corresponds to the definiton of "error" in
    section 1.2 of the XML 1.0 specification. Details of the error are
    stored in \a exception.

    The reader must continue to provide normal parsing events after
    invoking this function.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
\fn bool QXmlErrorHandler::fatalError(const QXmlParseException& exception)

A reader must use this function to report a non-recoverable error.
Details of the error are stored in \a exception.

If this function returns \c true the reader might try to go on
parsing and reporting further errors, but no regular parsing
events are reported.
*/

/*!
    \fn QString QXmlErrorHandler::errorString() const

    The reader calls this function to get an error string if any of
    the handler functions returns \c false.
*/


/*!
    \class QXmlDTDHandler
    \reentrant
    \brief The QXmlDTDHandler class provides an interface to report
    DTD content of XML data.

    \inmodule QtXml
    \ingroup xml-tools

    If an application needs information about notations and unparsed
    entities, it can implement this interface and register an instance
    with QXmlReader::setDTDHandler().

    Note that this interface includes only those DTD events that the
    XML recommendation requires processors to report, i.e. notation
    and unparsed entity declarations using notationDecl() and
    unparsedEntityDecl() respectively.

    \sa QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler,
        QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlDTDHandler::~QXmlDTDHandler()

    Destroys the DTD handler.
*/

/*!
    \fn bool QXmlDTDHandler::notationDecl(const QString& name, const QString& publicId, const QString& systemId)

    The reader calls this function when it has parsed a notation
    declaration.

    The argument \a name is the notation name, \a publicId is the
    notation's public identifier and \a systemId is the notation's
    system identifier.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlDTDHandler::unparsedEntityDecl(const QString& name, const QString& publicId, const QString& systemId, const QString& notationName)

    The reader calls this function when it finds an unparsed entity
    declaration.

    The argument \a name is the unparsed entity's name, \a publicId is
    the entity's public identifier, \a systemId is the entity's system
    identifier and \a notationName is the name of the associated
    notation.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn QString QXmlDTDHandler::errorString() const

    The reader calls this function to get an error string if any of
    the handler functions returns \c false.
*/


/*!
    \class QXmlEntityResolver
    \reentrant
    \brief The QXmlEntityResolver class provides an interface to
    resolve external entities contained in XML data.

    \inmodule QtXml
    \ingroup xml-tools

    If an application needs to implement customized handling for
    external entities, it must implement this interface, i.e.
    resolveEntity(), and register it with
    QXmlReader::setEntityResolver().

    \sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlErrorHandler,
        QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlEntityResolver::~QXmlEntityResolver()

    Destroys the entity resolver.
*/

/*!
    \fn bool QXmlEntityResolver::resolveEntity(const QString& publicId, const QString& systemId, QXmlInputSource*& ret)

    The reader calls this function before it opens any external
    entity, except the top-level document entity. The application may
    request the reader to resolve the entity itself (\a ret is 0) or
    to use an entirely different input source (\a ret points to the
    input source).

    The reader deletes the input source \a ret when it no longer needs
    it, so you should allocate it on the heap with \c new.

    The argument \a publicId is the public identifier of the external
    entity, \a systemId is the system identifier of the external
    entity and \a ret is the return value of this function. If \a ret
    is 0 the reader should resolve the entity itself, if it is
    non-zero it must point to an input source which the reader uses
    instead.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn QString QXmlEntityResolver::errorString() const

    The reader calls this function to get an error string if any of
    the handler functions returns \c false.
*/


/*!
    \class QXmlLexicalHandler
    \reentrant
    \brief The QXmlLexicalHandler class provides an interface to
    report the lexical content of XML data.

    \inmodule QtXml
    \ingroup xml-tools

    The events in the lexical handler apply to the entire document,
    not just to the document element, and all lexical handler events
    appear between the content handler's startDocument and endDocument
    events.

    You can set the lexical handler with
    QXmlReader::setLexicalHandler().

    This interface's design is based on the SAX2 extension
    LexicalHandler.

    The interface provides the startDTD(), endDTD(), startEntity(),
    endEntity(), startCDATA(), endCDATA() and comment() functions.

    \sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
        QXmlErrorHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlLexicalHandler::~QXmlLexicalHandler()

    Destroys the lexical handler.
*/

/*!
    \fn bool QXmlLexicalHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId)

    The reader calls this function to report the start of a DTD
    declaration, if any. It reports the name of the document type in
    \a name, the public identifier in \a publicId and the system
    identifier in \a systemId.

    If the public identifier is missing, \a publicId is set to
    an empty string. If the system identifier is missing, \a systemId is
    set to an empty string. Note that it is not valid XML to have a
    public identifier but no system identifier; in such cases a parse
    error will occur.

    All declarations reported through QXmlDTDHandler or
    QXmlDeclHandler appear between the startDTD() and endDTD() calls.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endDTD()
*/

/*!
    \fn bool QXmlLexicalHandler::endDTD()

    The reader calls this function to report the end of a DTD
    declaration, if any.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa startDTD()
*/

/*!
    \fn bool QXmlLexicalHandler::startEntity(const QString& name)

    The reader calls this function to report the start of an entity
    called \a name.

    Note that if the entity is unknown, the reader reports it through
    QXmlContentHandler::skippedEntity() and not through this
    function.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endEntity(), QXmlSimpleReader::setFeature()
*/

/*!
    \fn bool QXmlLexicalHandler::endEntity(const QString& name)

    The reader calls this function to report the end of an entity
    called \a name.

    For every startEntity() call, there is a corresponding endEntity()
    call. The calls to startEntity() and endEntity() are properly
    nested.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa startEntity(), QXmlContentHandler::skippedEntity(), QXmlSimpleReader::setFeature()
*/

/*!
    \fn bool QXmlLexicalHandler::startCDATA()

    The reader calls this function to report the start of a CDATA
    section. The content of the CDATA section is reported through the
    QXmlContentHandler::characters() function. This function is
    intended only to report the boundary.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.

    \sa endCDATA()
*/

/*!
    \fn bool QXmlLexicalHandler::endCDATA()

    The reader calls this function to report the end of a CDATA
    section.

    If this function returns \c false the reader stops parsing and reports
    an error. The reader uses the function errorString() to get the error
    message.

    \sa startCDATA(), QXmlContentHandler::characters()
*/

/*!
    \fn bool QXmlLexicalHandler::comment(const QString& ch)

    The reader calls this function to report an XML comment anywhere
    in the document. It reports the text of the comment in \a ch.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn QString QXmlLexicalHandler::errorString() const

    The reader calls this function to get an error string if any of
    the handler functions returns \c false.
*/


/*!
    \class QXmlDeclHandler
    \reentrant
    \brief The QXmlDeclHandler class provides an interface to report declaration
    content of XML data.

    \inmodule QtXml
    \ingroup xml-tools

    You can set the declaration handler with
    QXmlReader::setDeclHandler().

    This interface is based on the SAX2 extension DeclHandler.

    The interface provides attributeDecl(), internalEntityDecl() and
    externalEntityDecl() functions.

    \sa QXmlDTDHandler, QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler,
        QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlDeclHandler::~QXmlDeclHandler()

    Destroys the declaration handler.
*/

/*!
    \fn bool QXmlDeclHandler::attributeDecl(const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value)

    The reader calls this function to report an attribute type
    declaration. Only the effective (first) declaration for an
    attribute is reported.

    The reader passes the name of the associated element in \a eName
    and the name of the attribute in \a aName. It passes a string that
    represents the attribute type in \a type and a string that
    represents the attribute default in \a valueDefault. This string
    is one of "#IMPLIED", "#REQUIRED", "#FIXED" or an empty string (if
    none of the others applies). The reader passes the attribute's
    default value in \a value. If no default value is specified in the
    XML file, \a value is an empty string.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlDeclHandler::internalEntityDecl(const QString& name, const QString& value)

    The reader calls this function to report an internal entity
    declaration. Only the effective (first) declaration is reported.

    The reader passes the name of the entity in \a name and the value
    of the entity in \a value.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn bool QXmlDeclHandler::externalEntityDecl(const QString& name, const QString& publicId, const QString& systemId)

    The reader calls this function to report a parsed external entity
    declaration. Only the effective (first) declaration for each
    entity is reported.

    The reader passes the name of the entity in \a name, the public
    identifier in \a publicId and the system identifier in \a
    systemId. If there is no public identifier specified, it passes
    an empty string in \a publicId.

    If this function returns \c false the reader stops parsing and
    reports an error. The reader uses the function errorString() to
    get the error message.
*/

/*!
    \fn QString QXmlDeclHandler::errorString() const

    The reader calls this function to get an error string if any of
    the handler functions returns \c false.
*/


/*!
    \class QXmlDefaultHandler
    \reentrant
    \brief The QXmlDefaultHandler class provides a default implementation of all
    the XML handler classes.

    \inmodule QtXml
    \ingroup xml-tools

    This class gathers together the features of
    the specialized handler classes, making it a convenient
    starting point when implementing custom handlers for
    subclasses of QXmlReader, particularly QXmlSimpleReader.
    The virtual functions from each of the base classes are
    reimplemented in this class, providing sensible default behavior
    for many common cases. By subclassing this class, and
    overriding these functions, you can concentrate
    on implementing the parts of the handler relevant to your
    application.

    The XML reader must be told which handler to use for different
    kinds of events during parsing. This means that, although
    QXmlDefaultHandler provides default implementations of functions
    inherited from all its base classes, we can still use specialized
    handlers for particular kinds of events.

    For example, QXmlDefaultHandler subclasses both
    QXmlContentHandler and QXmlErrorHandler, so by subclassing
    it we can use the same handler for both of the following
    reader functions:

    \snippet rsslisting/listing.cpp 0

    Since the reader will inform the handler of parsing errors, it is
    necessary to reimplement QXmlErrorHandler::fatalError() if, for
    example, we want to stop parsing when such an error occurs:

    \snippet rsslisting/handler.cpp 0

    The above function returns \c false, which tells the reader to stop
    parsing. To continue to use the same reader,
    it is necessary to create a new handler instance, and set up the
    reader to use it in the manner described above.

    It is useful to examine some of the functions inherited by
    QXmlDefaultHandler, and consider why they might be
    reimplemented in a custom handler.
    Custom handlers will typically reimplement
    QXmlContentHandler::startDocument() to prepare the handler for
    new content. Document elements and the text within them can be
    processed by reimplementing QXmlContentHandler::startElement(),
    QXmlContentHandler::endElement(), and
    QXmlContentHandler::characters().
    You may want to reimplement QXmlContentHandler::endDocument()
    to perform some finalization or validation on the content once the
    document has been read completely.

    \sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
        QXmlErrorHandler, QXmlLexicalHandler, {Introduction to SAX2}
*/

/*!
    \fn QXmlDefaultHandler::QXmlDefaultHandler()

    Constructs a handler for use with subclasses of QXmlReader.
*/
QXmlDefaultHandler::QXmlDefaultHandler()
{
    // ### In Qt 5.0, this function was inlined and d was not initialized
    // The member cannot be used until Qt 6.0
    Q_UNUSED(d);
}

/*!
    \fn QXmlDefaultHandler::~QXmlDefaultHandler()

    Destroys the handler.
*/
QXmlDefaultHandler::~QXmlDefaultHandler()
{
}

/*!
    \reimp

    This reimplementation does nothing.
*/
void QXmlDefaultHandler::setDocumentLocator(QXmlLocator*)
{
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startDocument()
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endDocument()
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startPrefixMapping(const QString&, const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endPrefixMapping(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startElement(const QString&, const QString&,
        const QString&, const QXmlAttributes&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endElement(const QString&, const QString&,
        const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::characters(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::ignorableWhitespace(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::processingInstruction(const QString&,
        const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::skippedEntity(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::warning(const QXmlParseException&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::error(const QXmlParseException&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::fatalError(const QXmlParseException&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::notationDecl(const QString&, const QString&,
        const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::unparsedEntityDecl(const QString&, const QString&,
        const QString&, const QString&)
{
    return true;
}

/*!
    \reimp

    Sets \a ret to \nullptr, so that the reader uses the system identifier
    provided in the XML document.
*/
bool QXmlDefaultHandler::resolveEntity(const QString&, const QString&,
        QXmlInputSource*& ret)
{
    ret = nullptr;
    return true;
}

/*!
    \reimp

    Returns the default error string.
*/
QString QXmlDefaultHandler::errorString() const
{
    return QString::fromLatin1(XMLERR_ERRORBYCONSUMER);
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startDTD(const QString&, const QString&, const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endDTD()
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startEntity(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endEntity(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::startCDATA()
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::endCDATA()
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::comment(const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QString&, const QString&, const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::internalEntityDecl(const QString&, const QString&)
{
    return true;
}

/*!
    \reimp

    This reimplementation does nothing.
*/
bool QXmlDefaultHandler::externalEntityDecl(const QString&, const QString&, const QString&)
{
    return true;
}


/*********************************************
 *
 * QXmlSimpleReaderPrivate
 *
 *********************************************/

inline bool QXmlSimpleReaderPrivate::atEnd()
{
    return (c.unicode()|0x0001) == 0xffff;
}

inline void QXmlSimpleReaderPrivate::stringClear()
{
    stringValueLen = 0; stringArrayPos = 0;
}
inline void QXmlSimpleReaderPrivate::nameClear()
{
    nameValueLen = 0; nameArrayPos = 0;
}

inline void QXmlSimpleReaderPrivate::refClear()
{
    refValueLen = 0; refArrayPos = 0;
}

QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate(QXmlSimpleReader *reader)
{
    q_ptr = reader;
    parseStack = nullptr;

    locator.reset(new QXmlSimpleReaderLocator(reader));
    entityRes  = nullptr;
    dtdHnd     = nullptr;
    contentHnd = nullptr;
    errorHnd   = nullptr;
    lexicalHnd = nullptr;
    declHnd    = nullptr;

    // default feature settings
    useNamespaces = true;
    useNamespacePrefixes = false;
    reportWhitespaceCharData = true;
    reportEntities = false;
}

QXmlSimpleReaderPrivate::~QXmlSimpleReaderPrivate()
{
    delete parseStack;
}

void QXmlSimpleReaderPrivate::initIncrementalParsing()
{
    if(parseStack)
        parseStack->clear();
    else
        parseStack = new QStack<ParseState>;
}

/*********************************************
 *
 * QXmlSimpleReader
 *
 *********************************************/

/*!
    \class QXmlReader
    \reentrant
    \brief The QXmlReader class provides an interface for XML readers (i.e.
    parsers).

    \inmodule QtXml
    \ingroup xml-tools

    This abstract class provides an interface for all of Qt's XML
    readers. Currently there is only one implementation of a reader
    included in Qt's XML module: QXmlSimpleReader. In future releases
    there might be more readers with different properties available
    (e.g. a validating parser).

    The design of the XML classes follows the \l{SAX2 Java interface}, with
    the names adapted to fit Qt naming conventions. It should be very
    easy for anybody who has worked with SAX2 to get started with the
    Qt XML classes.

    All readers use the class QXmlInputSource to read the input
    document. Since you are normally interested in particular content
    in the XML document, the reader reports the content through
    special handler classes (QXmlDTDHandler, QXmlDeclHandler,
    QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler and
    QXmlLexicalHandler), which you must subclass, if you want to
    process the contents.

    Since the handler classes only describe interfaces you must
    implement all the functions. We provide the QXmlDefaultHandler
    class to make this easier: it implements a default behavior (do
    nothing) for all functions, so you can subclass it and just
    implement the functions you are interested in.

    Features and properties of the reader can be set with setFeature()
    and setProperty() respectively. You can set the reader to use your
    own subclasses with setEntityResolver(), setDTDHandler(),
    setContentHandler(), setErrorHandler(), setLexicalHandler() and
    setDeclHandler(). The parse itself is started with a call to
    parse().

    \sa QXmlSimpleReader
*/

/*!
    \fn QXmlReader::~QXmlReader()

    Destroys the reader.
*/

/*!
    \fn bool QXmlReader::feature(const QString& name, bool *ok) const

    If the reader has the feature called \a name, the feature's value
    is returned. If no such feature exists the return value is
    undefined.

    If \a ok is not \nullptr: \c{*}\a{ok}  is set to true if the
    reader has the feature called \a name; otherwise \c{*}\a{ok} is
    set to false.

    \sa setFeature(), hasFeature()
*/

/*!
    \fn void QXmlReader::setFeature(const QString& name, bool value)

    Sets the feature called \a name to the given \a value. If the
    reader doesn't have the feature nothing happens.

    \sa feature(), hasFeature()
*/

/*!
    \fn bool QXmlReader::hasFeature(const QString& name) const

    Returns \c true if the reader has the feature called \a name;
    otherwise returns \c false.

    \sa feature(), setFeature()
*/

/*!
    \fn void* QXmlReader::property(const QString& name, bool *ok) const

    If the reader has the property \a name, this function returns the
    value of the property; otherwise the return value is undefined.

    If \a ok is not \nullptr: if the reader has the \a name property
    \c{*}\a{ok} is set to true; otherwise \c{*}\a{ok} is set to false.

    \sa setProperty(), hasProperty()
*/

/*!
    \fn void QXmlReader::setProperty(const QString& name, void* value)

    Sets the property \a name to \a value. If the reader doesn't have
    the property nothing happens.

    \sa property(), hasProperty()
*/

/*!
    \fn bool QXmlReader::hasProperty(const QString& name) const

    Returns \c true if the reader has the property \a name; otherwise
    returns \c false.

    \sa property(), setProperty()
*/

/*!
    \fn void QXmlReader::setEntityResolver(QXmlEntityResolver* handler)

    Sets the entity resolver to \a handler.

    \sa entityResolver()
*/

/*!
    \fn QXmlEntityResolver *QXmlReader::entityResolver() const

    Returns the entity resolver or \nullptr if none was set.

    \sa setEntityResolver()
*/

/*!
    \fn void QXmlReader::setDTDHandler(QXmlDTDHandler* handler)

    Sets the DTD handler to \a handler.

    \sa DTDHandler()
*/

/*!
    \fn QXmlDTDHandler *QXmlReader::DTDHandler() const

    Returns the DTD handler or \nullptr if none was set.

    \sa setDTDHandler()
*/

/*!
    \fn void QXmlReader::setContentHandler(QXmlContentHandler* handler)

    Sets the content handler to \a handler.

    \sa contentHandler()
*/

/*!
    \fn QXmlContentHandler *QXmlReader::contentHandler() const

    Returns the content handler or \nullptr if none was set.

    \sa setContentHandler()
*/

/*!
    \fn void QXmlReader::setErrorHandler(QXmlErrorHandler* handler)

    Sets the error handler to \a handler. Clears the error handler if
    \a handler is 0.

    \sa errorHandler()
*/

/*!
    \fn QXmlErrorHandler *QXmlReader::errorHandler() const

    Returns the error handler or \nullptr if none is set.

    \sa setErrorHandler()
*/

/*!
    \fn void QXmlReader::setLexicalHandler(QXmlLexicalHandler* handler)

    Sets the lexical handler to \a handler.

    \sa lexicalHandler()
*/

/*!
    \fn QXmlLexicalHandler *QXmlReader::lexicalHandler() const

    Returns the lexical handler or \nullptr if none was set.

    \sa setLexicalHandler()
*/

/*!
    \fn void QXmlReader::setDeclHandler(QXmlDeclHandler* handler)

    Sets the declaration handler to \a handler.

    \sa declHandler()
*/

/*!
    \fn QXmlDeclHandler *QXmlReader::declHandler() const

    Returns the declaration handler or \nullptr if none was set.

    \sa setDeclHandler()
*/

/*!
  \fn bool QXmlReader::parse(const QXmlInputSource &input)

  \obsolete

  Parses the given \a input.
*/

/*!
    \fn bool QXmlReader::parse(const QXmlInputSource *input)

    Reads an XML document from \a input and parses it. Returns \c true if
    the parsing was successful; otherwise returns \c false.
*/


/*!
    \class QXmlSimpleReader
    \nonreentrant
    \brief The QXmlSimpleReader class provides an implementation of a
    simple XML parser.

    \inmodule QtXml
    \ingroup xml-tools


    This XML reader is suitable for a wide range of applications. It
    is able to parse well-formed XML and can report the namespaces of
    elements to a content handler; however, it does not parse any
    external entities. For historical reasons, Attribute Value
    Normalization and End-of-Line Handling as described in the XML 1.0
    specification is not performed.

    The easiest pattern of use for this class is to create a reader
    instance, define an input source, specify the handlers to be used
    by the reader, and parse the data.

    For example, we could use a QFile to supply the input. Here, we
    create a reader, and define an input source to be used by the
    reader:

    \snippet simpleparse/main.cpp 0

    A handler lets us perform actions when the reader encounters
    certain types of content, or if errors in the input are found. The
    reader must be told which handler to use for each type of
    event. For many common applications, we can create a custom
    handler by subclassing QXmlDefaultHandler, and use this to handle
    both error and content events:

    \snippet simpleparse/main.cpp 1

    If you don't set at least the content and error handlers, the
    parser will fall back on its default behavior---and will do
    nothing.

    The most convenient way to handle the input is to read it in a
    single pass using the parse() function with an argument that
    specifies the input source:

    \snippet simpleparse/main.cpp 2

    If you can't parse the entire input in one go (for example, it is
    huge, or is being delivered over a network connection), data can
    be fed to the parser in pieces. This is achieved by telling
    parse() to work incrementally, and making subsequent calls to the
    parseContinue() function, until all the data has been processed.

    A common way to perform incremental parsing is to connect the \c
    readyRead() signal of a \l{QNetworkReply} {network reply} a slot,
    and handle the incoming data there. See QNetworkAccessManager.

    Aspects of the parsing behavior can be adapted using setFeature()
    and setProperty().

    \snippet code/src_xml_sax_qxml.cpp 0

    QXmlSimpleReader is not reentrant. If you want to use the class
    in threaded code, lock the code using QXmlSimpleReader with a
    locking mechanism, such as a QMutex.
*/

static inline bool is_S(QChar ch)
{
    ushort uc = ch.unicode();
    return (uc == ' ' || uc == '\t' || uc == '\n' || uc == '\r');
}

enum NameChar { NameBeginning, NameNotBeginning, NotName };

static const char Begi = (char)NameBeginning;
static const char NtBg = (char)NameNotBeginning;
static const char NotN = (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 (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;
}

static NameChar determineNameChar(QChar ch)
{
    return fastDetermineNameChar(ch);
}

/*!
    Constructs a simple XML reader.

*/
QXmlSimpleReader::QXmlSimpleReader()
    : d_ptr(new QXmlSimpleReaderPrivate(this))
{
}

/*!
    Destroys the simple XML reader.
*/
QXmlSimpleReader::~QXmlSimpleReader()
{
}

/*!
    \reimp
*/
bool QXmlSimpleReader::feature(const QString& name, bool *ok) const
{
    const QXmlSimpleReaderPrivate *d = d_func();

    if (ok)
        *ok = true;
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
        return d->useNamespaces;
    } else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
        return d->useNamespacePrefixes;
    } else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // For compat with Qt 4
               || name == QLatin1String("http://qt-project.org/xml/features/report-whitespace-only-CharData")) {
        return d->reportWhitespaceCharData;
    } else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity") // For compat with Qt 4
               || name == QLatin1String("http://qt-project.org/xml/features/report-start-end-entity")) {
        return d->reportEntities;
    } else {
        qWarning("Unknown feature %s", name.toLatin1().data());
        if (ok)
            *ok = false;
    }
    return false;
}

/*!
    Turns on the feature \a name if \a enable is true; otherwise turns it off.

    The \a name parameter must be one of the following strings:
    \table
    \header \li Feature \li Default \li Notes
    \row \li \e http://xml.org/sax/features/namespaces
         \li true
         \li If enabled, namespaces are reported to the content handler.
    \row \li \e http://xml.org/sax/features/namespace-prefixes
         \li false
         \li If enabled, the original prefixed names
            and attributes used for namespace declarations are
            reported.
    \row \li \e http://qt-project.org/xml/features/report-whitespace-only-CharData
         \li true
         \li If enabled, CharData that consist of
            only whitespace characters are reported
            using QXmlContentHandler::characters(). If disabled, whitespace is silently
            discarded.
    \row \li \e http://qt-project.org/xml/features/report-start-end-entity
         \li false
         \li If enabled, the parser reports
            QXmlContentHandler::startEntity() and
            QXmlContentHandler::endEntity() events, so character data
            might be reported in chunks.
            If disabled, the parser does not report these events, but
            silently substitutes the entities, and reports the character
            data in one chunk.
    \endtable

    \sa feature(), hasFeature(), {SAX2 Features}
*/
void QXmlSimpleReader::setFeature(const QString& name, bool enable)
{
    Q_D(QXmlSimpleReader);
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
        d->useNamespaces = enable;
    } else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
        d->useNamespacePrefixes = enable;
    } else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // For compat with Qt 4
               || name == QLatin1String("http://qt-project.org/xml/features/report-whitespace-only-CharData")) {
        d->reportWhitespaceCharData = enable;
    } else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity") // For compat with Qt 4
               || name == QLatin1String("http://qt-project.org/xml/features/report-start-end-entity")) {
        d->reportEntities = enable;
    } else {
        qWarning("Unknown feature %s", name.toLatin1().data());
    }
}

/*! \reimp
*/
bool QXmlSimpleReader::hasFeature(const QString& name) const
{
    if (name == QLatin1String("http://xml.org/sax/features/namespaces")
        || name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")
        || name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // For compat with Qt 4
        || name == QLatin1String("http://qt-project.org/xml/features/report-whitespace-only-CharData")
        || name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity") // For compat with Qt 4
        || name == QLatin1String("http://qt-project.org/xml/features/report-start-end-entity")) {
        return true;
    } else {
        return false;
    }
}

/*! \reimp
*/
void* QXmlSimpleReader::property(const QString&, bool *ok) const
{
    if (ok)
        *ok = false;
    return nullptr;
}

/*! \reimp
*/
void QXmlSimpleReader::setProperty(const QString&, void*)
{
}

/*!
    \reimp
*/
bool QXmlSimpleReader::hasProperty(const QString&) const
{
    return false;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setEntityResolver(QXmlEntityResolver* handler)
{
    Q_D(QXmlSimpleReader);
    d->entityRes = handler;
}

/*!
    \reimp
*/
QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->entityRes;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setDTDHandler(QXmlDTDHandler* handler)
{
    Q_D(QXmlSimpleReader);
    d->dtdHnd = handler;
}

/*!
    \reimp
*/
QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->dtdHnd;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setContentHandler(QXmlContentHandler* handler)
{
    Q_D(QXmlSimpleReader);
    d->contentHnd = handler;
}

/*!
    \reimp
*/
QXmlContentHandler* QXmlSimpleReader::contentHandler() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->contentHnd;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setErrorHandler(QXmlErrorHandler* handler)
{
    Q_D(QXmlSimpleReader);
    d->errorHnd = handler;
}

/*!
    \reimp
*/
QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->errorHnd;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setLexicalHandler(QXmlLexicalHandler* handler)
{
    Q_D(QXmlSimpleReader);
    d->lexicalHnd = handler;
}

/*!
    \reimp
*/
QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->lexicalHnd;
}

/*!
    \reimp
*/
void QXmlSimpleReader::setDeclHandler(QXmlDeclHandler* handler)
{
    Q_D(QXmlSimpleReader);
    d->declHnd = handler;
}

/*!
    \reimp
*/
QXmlDeclHandler* QXmlSimpleReader::declHandler() const
{
    const QXmlSimpleReaderPrivate *d = d_func();
    return d->declHnd;
}



/*!
    \reimp
*/
bool QXmlSimpleReader::parse(const QXmlInputSource& input)
{
    return parse(&input, false);
}

/*!
    Reads an XML document from \a input and parses it in one pass (non-incrementally).
    Returns \c true if the parsing was successful; otherwise returns \c false.
*/
bool QXmlSimpleReader::parse(const QXmlInputSource* input)
{
    return parse(input, false);
}

/*!
    Reads an XML document from \a input and parses it. Returns \c true
    if the parsing is completed successfully; otherwise returns \c false,
    indicating that an error occurred.

    If \a incremental is false, this function will return false if the XML
    file is not read completely. The parsing cannot be continued in this
    case.

    If \a incremental is true, the parser does not return false if
    it reaches the end of the \a input before reaching the end
    of the XML file. Instead, it stores the state of the parser so that
    parsing can be continued later when more data is available.
    In such a case, you can use the function parseContinue() to
    continue with parsing. This class stores a pointer to the input
    source \a input and the parseContinue() function tries to read from
    that input source. Therefore, you should not delete the input
    source \a input until you no longer need to call parseContinue().

    If this function is called with \a incremental set to true
    while an incremental parse is in progress, a new parsing
    session will be started, and the previous session will be lost.

    \sa parseContinue(), QTcpSocket
*/
bool QXmlSimpleReader::parse(const QXmlInputSource *input, bool incremental)
{
    Q_D(QXmlSimpleReader);

    d->literalEntitySizes.clear();
    d->referencesToOtherEntities.clear();
    d->expandedSizes.clear();

    if (incremental) {
        d->initIncrementalParsing();
    } else {
        delete d->parseStack;
        d->parseStack = nullptr;
    }
    d->init(input);

    // call the handler
    if (d->contentHnd) {
        d->contentHnd->setDocumentLocator(d->locator.data());
        if (!d->contentHnd->startDocument()) {
            d->reportParseError(d->contentHnd->errorString());
            clear(d->tags);
            return false;
        }
    }
    d->skipped_entity_in_content = false;
    return d->parseBeginOrContinue(0, incremental);
}

/*!
    Continues incremental parsing, taking input from the
    QXmlInputSource that was specified with the most recent
    call to parse(). To use this function, you \e must have called
    parse() with the incremental argument set to true.

    Returns \c false if a parsing error occurs; otherwise returns \c true,
    even if the end of the XML file has not been reached. You can
    continue parsing at a later stage by calling this function again
    when there is more data available to parse.

    Calling this function when there is no data available in the input
    source indicates to the reader that the end of the XML file has
    been reached. If the input supplied up to this point was
    not well-formed then a parsing error occurs, and false is returned.
    If the input supplied was well-formed, true is returned.
    It is important to end the input in this way because it allows you
    to reuse the reader to parse other XML files.

    Calling this function after the end of file has been reached, but
    without available data will cause false to be returned whether the
    previous input was well-formed or not.

    \sa parse(), QXmlInputSource::data(), QXmlInputSource::next()
*/
bool QXmlSimpleReader::parseContinue()
{
    Q_D(QXmlSimpleReader);
    if (d->parseStack == nullptr || d->parseStack->isEmpty())
        return false;
    d->initData();
    int state = d->parseStack->pop().state;
    return d->parseBeginOrContinue(state, true);
}

/*
  Common part of parse() and parseContinue()
*/
bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
{
    bool atEndOrig = atEnd();

    if (state==0) {
        if (!parseProlog()) {
            if (incremental && error.isNull()) {
                pushParseState(nullptr, 0);
                return true;
            } else {
                clear(tags);
                return false;
            }
        }
        state = 1;
    }
    if (state==1) {
        if (!parseElement()) {
            if (incremental && error.isNull()) {
                pushParseState(nullptr, 1);
                return true;
            } else {
                clear(tags);
                return false;
            }
        }
        state = 2;
    }
    // parse Misc*
    while (!atEnd()) {
        if (!parseMisc()) {
            if (incremental && error.isNull()) {
                pushParseState(nullptr, 2);
                return true;
            } else {
                clear(tags);
                return false;
            }
        }
    }
    if (!atEndOrig && incremental) {
        // we parsed something at all, so be prepared to come back later
        pushParseState(nullptr, 2);
        return true;
    }
    // is stack empty?
    if (!tags.empty() && !error.isNull()) {
        reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
        clear(tags);
        return false;
    }
    // call the handler
    if (contentHnd) {
        delete parseStack;
        parseStack = nullptr;
        if (!contentHnd->endDocument()) {
            reportParseError(contentHnd->errorString());
            return false;
        }
    }
    return true;
}

//
// The following private parse functions have another semantics for the return
// value: They return true iff parsing has finished successfully (i.e. the end
// of the XML file must be reached!). If one of these functions return false,
// there is only an error when d->error.isNULL() is also false.
//

/*
  For the incremental parsing, it is very important that the parse...()
  functions have a certain structure. Since it might be hard to understand how
  they work, here is a description of the layout of these functions:

    bool QXmlSimpleReader::parse...()
    {
(1)        const signed char Init             = 0;
        ...

(2)        const signed char Inp...           = 0;
        ...

(3)        static const signed char table[3][2] = {
        ...
        };
        signed char state;
        signed char input;

(4)        if (d->parseStack == nullptr || d->parseStack->isEmpty()) {
(4a)        ...
        } else {
(4b)        ...
        }

        for (; ;) {
(5)            switch (state) {
            ...
            }

(6)
(6a)            if (atEnd()) {
                unexpectedEof(&QXmlSimpleReader::parseNmtoken, state);
                return false;
            }
(6b)            if (determineNameChar(c) != NotName) {
            ...
            }
(7)            state = table[state][input];

(8)            switch (state) {
            ...
            }
        }
    }

  Explanation:
  ad 1: constants for the states (used in the transition table)
  ad 2: constants for the input (used in the transition table)
  ad 3: the transition table for the state machine
  ad 4: test if we are in a parseContinue() step
        a) if no, do inititalizations
        b) if yes, restore the state and call parse functions recursively
  ad 5: Do some actions according to the state; from the logical execution
        order, this code belongs after 8 (see there for an explanation)
  ad 6: Check the character that is at the actual "cursor" position:
        a) If we reached the EOF, report either error or push the state (in the
           case of incremental parsing).
        b) Otherwise, set the input character constant for the transition
           table.
  ad 7: Get the new state according to the input that was read.
  ad 8: Do some actions according to the state. The last line in every case
        statement reads new data (i.e. it move the cursor). This can also be
        done by calling another parse...() function. If you need processing for
        this state after that, you have to put it into the switch statement 5.
        This ensures that you have a well defined re-entry point, when you ran
        out of data.
*/

/*
  Parses the prolog [22].
*/

bool QXmlSimpleReaderPrivate::parseProlog()
{
    const signed char Init             = 0;
    const signed char EatWS            = 1; // eat white spaces
    const signed char Lt               = 2; // '<' read
    const signed char Em               = 3; // '!' read
    const signed char DocType          = 4; // read doctype
    const signed char Comment          = 5; // read comment
    const signed char CommentR         = 6; // same as Comment, but already reported
    const signed char PInstr           = 7; // read PI
    const signed char PInstrR          = 8; // same as PInstr, but already reported
    const signed char Done             = 9;

    const signed char InpWs            = 0;
    const signed char InpLt            = 1; // <
    const signed char InpQm            = 2; // ?
    const signed char InpEm            = 3; // !
    const signed char InpD             = 4; // D
    const signed char InpDash          = 5; // -
    const signed char InpUnknown       = 6;

    static const signed char table[9][7] = {
     /*  InpWs   InpLt  InpQm  InpEm  InpD      InpDash  InpUnknown */
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // Init
        { -1,     Lt,    -1,    -1,    -1,       -1,       -1      }, // EatWS
        { -1,     -1,    PInstr,Em,    Done,     -1,       Done    }, // Lt
        { -1,     -1,    -1,    -1,    DocType,  Comment,  -1      }, // Em
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // DocType
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // Comment
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // CommentR
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // PInstr
        { EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }  // PInstrR
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr|| parseStack->isEmpty()) {
        xmldecl_possible = true;
        doctype_read = false;
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseProlog (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case DocType:
                if (doctype_read) {
                    reportParseError(QLatin1String(XMLERR_MORETHANONEDOCTYPE));
                    return false;
                } else {
                    doctype_read = false;
                }
                break;
            case Comment:
                if (lexicalHnd) {
                    if (!lexicalHnd->comment(string())) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                state = CommentR;
                break;
            case PInstr:
                // call the handler
                if (contentHnd) {
                    if (xmldecl_possible && !xmlVersion.isEmpty()) {
                        QString value(QLatin1String("version='"));
                        value += xmlVersion;
                        value += QLatin1Char('\'');
                        if (!encoding.isEmpty()) {
                            value += QLatin1String(" encoding='");
                            value += encoding;
                            value += QLatin1Char('\'');
                        }
                        if (standalone == QXmlSimpleReaderPrivate::Yes) {
                            value += QLatin1String(" standalone='yes'");
                        } else if (standalone == QXmlSimpleReaderPrivate::No) {
                            value += QLatin1String(" standalone='no'");
                        }
                        if (!contentHnd->processingInstruction(QLatin1String("xml"), value)) {
                            reportParseError(contentHnd->errorString());
                            return false;
                        }
                    } else {
                        if (!contentHnd->processingInstruction(name(), string())) {
                            reportParseError(contentHnd->errorString());
                            return false;
                        }
                    }
                }
                // XML declaration only on first position possible
                xmldecl_possible = false;
                state = PInstrR;
                break;
            case Done:
                return true;
            case -1:
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseProlog, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('<')) {
            input = InpLt;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else if (c == QLatin1Char('!')) {
            input = InpEm;
        } else if (c == QLatin1Char('D')) {
            input = InpD;
        } else if (c == QLatin1Char('-')) {
            input = InpDash;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case EatWS:
                // XML declaration only on first position possible
                xmldecl_possible = false;
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
                    return false;
                }
                break;
            case Lt:
                next();
                break;
            case Em:
                // XML declaration only on first position possible
                xmldecl_possible = false;
                next();
                break;
            case DocType:
                if (!parseDoctype()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
                    return false;
                }
                break;
            case Comment:
            case CommentR:
                if (!parseComment()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
                    return false;
                }
                break;
            case PInstr:
            case PInstrR:
                parsePI_xmldecl = xmldecl_possible;
                if (!parsePI()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
                    return false;
                }
                break;
        }
    }
    return false;
}

/*
  Parse an element [39].

  Precondition: the opening '<' is already read.
*/
bool QXmlSimpleReaderPrivate::parseElement()
{
    const int Init             =  0;
    const int ReadName         =  1;
    const int Ws1              =  2;
    const int STagEnd          =  3;
    const int STagEnd2         =  4;
    const int ETagBegin        =  5;
    const int ETagBegin2       =  6;
    const int Ws2              =  7;
    const int EmptyTag         =  8;
    const int Attrib           =  9;
    const int AttribPro        = 10; // like Attrib, but processAttribute was already called
    const int Ws3              = 11;
    const int Done             = 12;

    const int InpWs            = 0; // whitespace
    const int InpNameBe        = 1; // NameBeginning
    const int InpGt            = 2; // >
    const int InpSlash         = 3; // /
    const int InpUnknown       = 4;

    static const int table[12][5] = {
     /*  InpWs      InpNameBe    InpGt        InpSlash     InpUnknown */
        { -1,        ReadName,    -1,          -1,          -1        }, // Init
        { Ws1,       Attrib,      STagEnd,     EmptyTag,    -1        }, // ReadName
        { -1,        Attrib,      STagEnd,     EmptyTag,    -1        }, // Ws1
        { STagEnd2,  STagEnd2,    STagEnd2,    STagEnd2,    STagEnd2  }, // STagEnd
        { -1,        -1,          -1,          ETagBegin,   -1        }, // STagEnd2
        { -1,        ETagBegin2,  -1,          -1,          -1        }, // ETagBegin
        { Ws2,       -1,          Done,        -1,          -1        }, // ETagBegin2
        { -1,        -1,          Done,        -1,          -1        }, // Ws2
        { -1,        -1,          Done,        -1,          -1        }, // EmptyTag
        { Ws3,       Attrib,      STagEnd,     EmptyTag,    -1        }, // Attrib
        { Ws3,       Attrib,      STagEnd,     EmptyTag,    -1        }, // AttribPro
        { -1,        Attrib,      STagEnd,     EmptyTag,    -1        }  // Ws3
    };
    int state;
    int input;

    if (parseStack == nullptr|| parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseElement (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case ReadName:
                // store it on the stack
                tags.push(name());
                // empty the attributes
                attList.clear();
                if (useNamespaces)
                    namespaceSupport.pushContext();
                break;
            case ETagBegin2:
                if (!processElementETagBegin2())
                    return false;
                break;
            case Attrib:
                if (!processElementAttribute())
                    return false;
                state = AttribPro;
                break;
            case Done:
                return true;
            case -1:
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseElement, state);
            return false;
        }
        if (fastDetermineNameChar(c) == NameBeginning) {
            input = InpNameBe;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('/')) {
            input = InpSlash;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case ReadName:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                    return false;
                }
                break;
            case Ws1:
            case Ws2:
            case Ws3:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                    return false;
                }
                break;
            case STagEnd:
                // call the handler
                if (contentHnd) {
                    if (useNamespaces) {
                        QString uri, lname;
                        namespaceSupport.processName(tags.top(), false, uri, lname);
                        if (!contentHnd->startElement(uri, lname, tags.top(), attList)) {
                            reportParseError(contentHnd->errorString());
                            return false;
                        }
                    } else {
                        if (!contentHnd->startElement(QString(), QString(), tags.top(), attList)) {
                            reportParseError(contentHnd->errorString());
                            return false;
                        }
                    }
                }
                next();
                break;
            case STagEnd2:
                if (!parseContent()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                    return false;
                }
                break;
            case ETagBegin:
                next();
                break;
            case ETagBegin2:
                // get the name of the tag
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                    return false;
                }
                break;
            case EmptyTag:
                if (tags.empty()) {
                    reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
                    return false;
                }
                if (!processElementEmptyTag())
                    return false;
                next();
                break;
            case Attrib:
            case AttribPro:
                // get name and value of attribute
                if (!parseAttribute()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Helper to break down the size of the code in the case statement.
  Return false on error, otherwise true.
*/
bool QXmlSimpleReaderPrivate::processElementEmptyTag()
{
    QString uri, lname;
    // pop the stack and call the handler
    if (contentHnd) {
        if (useNamespaces) {
            // report startElement first...
            namespaceSupport.processName(tags.top(), false, uri, lname);
            if (!contentHnd->startElement(uri, lname, tags.top(), attList)) {
                reportParseError(contentHnd->errorString());
                return false;
            }
            // ... followed by endElement...
            const bool endElementReturnedFalse = !contentHnd->endElement(uri, lname, tags.top());
            tags.pop();
            if (endElementReturnedFalse) {
                reportParseError(contentHnd->errorString());
                return false;
            }
            // ... followed by endPrefixMapping
            QStringList prefixesBefore, prefixesAfter;
            if (contentHnd) {
                prefixesBefore = namespaceSupport.prefixes();
            }
            namespaceSupport.popContext();
            // call the handler for prefix mapping
            prefixesAfter = namespaceSupport.prefixes();
            for (QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it) {
                if (!prefixesAfter.contains(*it)) {
                    if (!contentHnd->endPrefixMapping(*it)) {
                        reportParseError(contentHnd->errorString());
                        return false;
                    }
                }
            }
        } else {
            // report startElement first...
            if (!contentHnd->startElement(QString(), QString(), tags.top(), attList)) {
                reportParseError(contentHnd->errorString());
                return false;
            }
            // ... followed by endElement
            const bool endElementReturnedFalse = !contentHnd->endElement(QString(), QString(), tags.top());
            tags.pop();
            if (endElementReturnedFalse) {
                reportParseError(contentHnd->errorString());
                return false;
            }
        }
    } else {
        tags.pop();
        namespaceSupport.popContext();
    }
    return true;
}
/*
  Helper to break down the size of the code in the case statement.
  Return false on error, otherwise true.
*/
bool QXmlSimpleReaderPrivate::processElementETagBegin2()
{
    const QString &name = QXmlSimpleReaderPrivate::name();

    // pop the stack and compare it with the name
    const bool nameIsTagsTop = tags.top() == name;
    tags.pop();
    if (!nameIsTagsTop) {
        reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
        return false;
    }
    // call the handler
    if (contentHnd) {
        QString uri, lname;

        if (useNamespaces)
            namespaceSupport.processName(name, false, uri, lname);
        if (!contentHnd->endElement(uri, lname, name)) {
            reportParseError(contentHnd->errorString());
            return false;
        }
    }
    if (useNamespaces) {
        NamespaceMap prefixesBefore, prefixesAfter;
        if (contentHnd)
            prefixesBefore = namespaceSupport.d->ns;

        namespaceSupport.popContext();
        // call the handler for prefix mapping
        if (contentHnd) {
            prefixesAfter = namespaceSupport.d->ns;
            if (prefixesBefore.size() != prefixesAfter.size()) {
                for (NamespaceMap::const_iterator it = prefixesBefore.constBegin(); it != prefixesBefore.constEnd(); ++it) {
                    if (!it.key().isEmpty() && !prefixesAfter.contains(it.key())) {
                        if (!contentHnd->endPrefixMapping(it.key())) {
                            reportParseError(contentHnd->errorString());
                            return false;
                        }
                    }
                }
            }
        }
    }
    return true;
}
/*
  Helper to break down the size of the code in the case statement.
  Return false on error, otherwise true.
*/
bool QXmlSimpleReaderPrivate::processElementAttribute()
{
    QString uri, lname, prefix;
    const QString &name = QXmlSimpleReaderPrivate::name();
    const QString &string = QXmlSimpleReaderPrivate::string();

    // add the attribute to the list
    if (useNamespaces) {
        // is it a namespace declaration?
        namespaceSupport.splitName(name, prefix, lname);
        if (prefix == QLatin1String("xmlns")) {
            // namespace declaration
            namespaceSupport.setPrefix(lname, string);
            if (useNamespacePrefixes) {
                // according to http://www.w3.org/2000/xmlns/, the "prefix"
                // xmlns maps to the namespace name
                // http://www.w3.org/2000/xmlns/
                attList.append(name, QLatin1String("http://www.w3.org/2000/xmlns/"), lname, string);
            }
            // call the handler for prefix mapping
            if (contentHnd) {
                if (!contentHnd->startPrefixMapping(lname, string)) {
                    reportParseError(contentHnd->errorString());
                    return false;
                }
            }
        } else {
            // no namespace delcaration
            namespaceSupport.processName(name, true, uri, lname);
            attList.append(name, uri, lname, string);
        }
    } else {
        // no namespace support
        attList.append(name, uri, lname, string);
    }
    return true;
}

/*
  Parse a content [43].

  A content is only used between tags. If a end tag is found the < is already
  read and the head stand on the '/' of the end tag '</name>'.
*/
bool QXmlSimpleReaderPrivate::parseContent()
{
    const signed char Init             =  0;
    const signed char ChD              =  1; // CharData
    const signed char ChD1             =  2; // CharData help state
    const signed char ChD2             =  3; // CharData help state
    const signed char Ref              =  4; // Reference
    const signed char Lt               =  5; // '<' read
    const signed char PInstr           =  6; // PI
    const signed char PInstrR          =  7; // same as PInstr, but already reported
    const signed char Elem             =  8; // Element
    const signed char Em               =  9; // '!' read
    const signed char Com              = 10; // Comment
    const signed char ComR             = 11; // same as Com, but already reported
    const signed char CDS              = 12; // CDSect
    const signed char CDS1             = 13; // read a CDSect
    const signed char CDS2             = 14; // read a CDSect (help state)
    const signed char CDS3             = 15; // read a CDSect (help state)
    const signed char Done             = 16; // finished reading content

    const signed char InpLt            = 0; // <
    const signed char InpGt            = 1; // >
    const signed char InpSlash         = 2; // /
    const signed char InpQMark         = 3; // ?
    const signed char InpEMark         = 4; // !
    const signed char InpAmp           = 5; // &
    const signed char InpDash          = 6; // -
    const signed char InpOpenB         = 7; // [
    const signed char InpCloseB        = 8; //]
    const signed char InpUnknown       = 9;

    static const signed char mapCLT2FSMChar[] = {
        InpUnknown, // white space
        InpUnknown, // %
        InpAmp,     // &
        InpGt,      // >
        InpLt,      // <
        InpSlash,   // /
        InpQMark,   // ?
        InpEMark,   // !
        InpDash,    // -
        InpCloseB,  //]
        InpOpenB,   // [
        InpUnknown, // =
        InpUnknown, // "
        InpUnknown, // '
        InpUnknown  // unknown
    };

    static const signed char table[16][10] = {
     /*  InpLt  InpGt  InpSlash  InpQMark  InpEMark  InpAmp  InpDash  InpOpenB  InpCloseB  InpUnknown */
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD1,      ChD  }, // Init
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD1,      ChD  }, // ChD
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD2,      ChD  }, // ChD1
        { Lt,    -1,    ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD2,      ChD  }, // ChD2
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Ref (same as Init)
        { -1,    -1,    Done,     PInstr,   Em,       -1,     -1,      -1,       -1,        Elem }, // Lt
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // PInstr (same as Init)
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // PInstrR
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Elem (same as Init)
        { -1,    -1,    -1,       -1,       -1,       -1,     Com,     CDS,      -1,        -1   }, // Em
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Com (same as Init)
        { Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // ComR
        { CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS2,      CDS1 }, // CDS
        { CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS2,      CDS1 }, // CDS1
        { CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS3,      CDS1 }, // CDS2
        { CDS1,  Init,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS3,      CDS1 }  // CDS3
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        contentCharDataRead = false;
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseContent (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Ref:
                if (!contentCharDataRead)
                    contentCharDataRead = parseReference_charDataRead;
                break;
            case PInstr:
                if (contentHnd) {
                    if (!contentHnd->processingInstruction(name(),string())) {
                        reportParseError(contentHnd->errorString());
                        return false;
                    }
                }
                state = PInstrR;
                break;
            case Com:
                if (lexicalHnd) {
                    if (!lexicalHnd->comment(string())) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                state = ComR;
                break;
            case CDS:
                stringClear();
                break;
            case CDS2:
                if (!atEnd() && c != QLatin1Char(']'))
                    stringAddC(QLatin1Char(']'));
                break;
            case CDS3:
                // test if this skipping was legal
                if (!atEnd()) {
                    if (c == QLatin1Char('>')) {
                        // the end of the CDSect
                        if (lexicalHnd) {
                            if (!lexicalHnd->startCDATA()) {
                                reportParseError(lexicalHnd->errorString());
                                return false;
                            }
                        }
                        if (contentHnd) {
                            if (!contentHnd->characters(string())) {
                                reportParseError(contentHnd->errorString());
                                return false;
                            }
                        }
                        if (lexicalHnd) {
                            if (!lexicalHnd->endCDATA()) {
                                reportParseError(lexicalHnd->errorString());
                                return false;
                            }
                        }
                    } else if (c == QLatin1Char(']')) {
                        // three or more ']'
                        stringAddC(QLatin1Char(']'));
                    } else {
                        // after ']]' comes another character
                        stringAddC(QLatin1Char(']'));
                        stringAddC(QLatin1Char(']'));
                    }
                }
                break;
            case Done:
                // call the handler for CharData
                if (contentHnd) {
                    if (contentCharDataRead) {
                        if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
                            if (!contentHnd->characters(string())) {
                                reportParseError(contentHnd->errorString());
                                return false;
                            }
                        }
                    }
                }
                // Done
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGCONTENT));
                return false;
        }

        // get input (use lookup-table instead of nested ifs for performance
        // reasons)
        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseContent, state);
            return false;
        }
        if (c.row()) {
            input = InpUnknown;
        } else {
            input = mapCLT2FSMChar[charLookupTable[c.cell()]];
        }
        state = table[state][input];

        switch (state) {
            case Init:
                // skip the ending '>' of a CDATASection
                next();
                break;
            case ChD:
                // on first call: clear string
                if (!contentCharDataRead) {
                    contentCharDataRead = true;
                    stringClear();
                }
                stringAddC();
                if (reportEntities) {
                    if (!reportEndEntities())
                        return false;
                }
                next();
                break;
            case ChD1:
                // on first call: clear string
                if (!contentCharDataRead) {
                    contentCharDataRead = true;
                    stringClear();
                }
                stringAddC();
                if (reportEntities) {
                    if (!reportEndEntities())
                        return false;
                }
                next();
                break;
            case ChD2:
                stringAddC();
                if (reportEntities) {
                    if (!reportEndEntities())
                        return false;
                }
                next();
                break;
            case Ref:
                if (!contentCharDataRead) {
                    // reference may be CharData; so clear string to be safe
                    stringClear();
                    parseReference_context = InContent;
                    if (!parseReference()) {
                        parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                        return false;
                    }
                } else {
                    if (reportEntities) {
                        // report character data in chunks
                        if (contentHnd) {
                            if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
                                if (!contentHnd->characters(string())) {
                                    reportParseError(contentHnd->errorString());
                                    return false;
                                }
                            }
                        }
                        stringClear();
                    }
                    parseReference_context = InContent;
                    if (!parseReference()) {
                        parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                        return false;
                    }
                }
                break;
            case Lt:
                // call the handler for CharData
                if (contentHnd) {
                    if (contentCharDataRead) {
                        if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
                            if (!contentHnd->characters(string())) {
                                reportParseError(contentHnd->errorString());
                                return false;
                            }
                        }
                    }
                }
                contentCharDataRead = false;
                next();
                break;
            case PInstr:
            case PInstrR:
                parsePI_xmldecl = false;
                if (!parsePI()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                    return false;
                }
                break;
            case Elem:
                if (!parseElement()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                    return false;
                }
                break;
            case Em:
                next();
                break;
            case Com:
            case ComR:
                if (!parseComment()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                    return false;
                }
                break;
            case CDS:
                parseString_s = QLatin1String("[CDATA[");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
                    return false;
                }
                break;
            case CDS1:
                stringAddC();
                next();
                break;
            case CDS2:
                // skip ']'
                next();
                break;
            case CDS3:
                // skip ']'...
                next();
                break;
        }
    }
    return false;
}

bool QXmlSimpleReaderPrivate::reportEndEntities()
{
    int count = (int)xmlRefStack.count();
    while (count != 0 && xmlRefStack.top().isEmpty()) {
        if (contentHnd) {
            if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
                if (!contentHnd->characters(string())) {
                    reportParseError(contentHnd->errorString());
                    return false;
                }
            }
        }
        stringClear();
        if (lexicalHnd) {
            if (!lexicalHnd->endEntity(xmlRefStack.top().name)) {
                reportParseError(lexicalHnd->errorString());
                return false;
            }
        }
        xmlRefStack.pop_back();
        count--;
    }
    return true;
}

/*
  Parse Misc [27].
*/
bool QXmlSimpleReaderPrivate::parseMisc()
{
    const signed char Init             = 0;
    const signed char Lt               = 1; // '<' was read
    const signed char Comment          = 2; // read comment
    const signed char eatWS            = 3; // eat whitespaces
    const signed char PInstr           = 4; // read PI
    const signed char Comment2         = 5; // read comment

    const signed char InpWs            = 0; // S
    const signed char InpLt            = 1; // <
    const signed char InpQm            = 2; // ?
    const signed char InpEm            = 3; // !
    const signed char InpUnknown       = 4;

    static const signed char table[3][5] = {
     /*  InpWs   InpLt  InpQm  InpEm     InpUnknown */
        { eatWS,  Lt,    -1,    -1,       -1        }, // Init
        { -1,     -1,    PInstr,Comment,  -1        }, // Lt
        { -1,     -1,    -1,    -1,       Comment2  }  // Comment
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseMisc (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case eatWS:
                return true;
            case PInstr:
                if (contentHnd) {
                    if (!contentHnd->processingInstruction(name(),string())) {
                        reportParseError(contentHnd->errorString());
                        return false;
                    }
                }
                return true;
            case Comment2:
                if (lexicalHnd) {
                    if (!lexicalHnd->comment(string())) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseMisc, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('<')) {
            input = InpLt;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else if (c == QLatin1Char('!')) {
            input = InpEm;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case eatWS:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
                    return false;
                }
                break;
            case Lt:
                next();
                break;
            case PInstr:
                parsePI_xmldecl = false;
                if (!parsePI()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
                    return false;
                }
                break;
            case Comment:
                next();
                break;
            case Comment2:
                if (!parseComment()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
                    return false;
                }
                break;
        }
    }
    return false;
}

/*
  Parse a processing instruction [16].

  If xmldec is true, it tries to parse a PI or a XML declaration [23].

  Precondition: the beginning '<' of the PI is already read and the head stand
  on the '?' of '<?'.

  If this funktion was successful, the head-position is on the first
  character after the PI.
*/
bool QXmlSimpleReaderPrivate::parsePI()
{
    const signed char Init             =  0;
    const signed char QmI              =  1; // ? was read
    const signed char Name             =  2; // read Name
    const signed char XMLDecl          =  3; // read XMLDecl
    const signed char Ws1              =  4; // eat ws after "xml" of XMLDecl
    const signed char PInstr           =  5; // read PI
    const signed char Ws2              =  6; // eat ws after Name of PI
    const signed char Version          =  7; // read versionInfo
    const signed char Ws3              =  8; // eat ws after versionInfo
    const signed char EorSD            =  9; // read EDecl or SDDecl
    const signed char Ws4              = 10; // eat ws after EDecl or SDDecl
    const signed char SD               = 11; // read SDDecl
    const signed char Ws5              = 12; // eat ws after SDDecl
    const signed char ADone            = 13; // almost done
    const signed char Char             = 14; // Char was read
    const signed char Qm               = 15; // Qm was read
    const signed char Done             = 16; // finished reading content

    const signed char InpWs            = 0; // whitespace
    const signed char InpNameBe        = 1; // NameBeginning
    const signed char InpGt            = 2; // >
    const signed char InpQm            = 3; // ?
    const signed char InpUnknown       = 4;

    static const signed char table[16][5] = {
     /*  InpWs,  InpNameBe  InpGt  InpQm   InpUnknown  */
        { -1,     -1,        -1,    QmI,    -1     }, // Init
        { -1,     Name,      -1,    -1,     -1     }, // QmI
        { -1,     -1,        -1,    -1,     -1     }, // Name (this state is left not through input)
        { Ws1,    -1,        -1,    -1,     -1     }, // XMLDecl
        { -1,     Version,   -1,    -1,     -1     }, // Ws1
        { Ws2,    -1,        -1,    Qm,     -1     }, // PInstr
        { Char,   Char,      Char,  Qm,     Char   }, // Ws2
        { Ws3,    -1,        -1,    ADone,  -1     }, // Version
        { -1,     EorSD,     -1,    ADone,  -1     }, // Ws3
        { Ws4,    -1,        -1,    ADone,  -1     }, // EorSD
        { -1,     SD,        -1,    ADone,  -1     }, // Ws4
        { Ws5,    -1,        -1,    ADone,  -1     }, // SD
        { -1,     -1,        -1,    ADone,  -1     }, // Ws5
        { -1,     -1,        Done,  -1,     -1     }, // ADone
        { Char,   Char,      Char,  Qm,     Char   }, // Char
        { Char,   Char,      Done,  Qm,     Char   }, // Qm
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parsePI (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Name:
                // test what name was read and determine the next state
                // (not very beautiful, I admit)
                if (name().toLower() == QLatin1String("xml")) {
                    if (parsePI_xmldecl && name() == QLatin1String("xml")) {
                        state = XMLDecl;
                    } else {
                        reportParseError(QLatin1String(XMLERR_INVALIDNAMEFORPI));
                        return false;
                    }
                } else {
                    state = PInstr;
                    stringClear();
                }
                break;
            case Version:
                // get version (syntax like an attribute)
                if (name() != QLatin1String("version")) {
                    reportParseError(QLatin1String(XMLERR_VERSIONEXPECTED));
                    return false;
                }
                xmlVersion = string();
                break;
            case EorSD:
                // get the EDecl or SDDecl (syntax like an attribute)
                if (name() == QLatin1String("standalone")) {
                    if (string()== QLatin1String("yes")) {
                        standalone = QXmlSimpleReaderPrivate::Yes;
                    } else if (string() == QLatin1String("no")) {
                        standalone = QXmlSimpleReaderPrivate::No;
                    } else {
                        reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
                        return false;
                    }
                } else if (name() == QLatin1String("encoding")) {
                    encoding = string();
                } else {
                    reportParseError(QLatin1String(XMLERR_EDECLORSDDECLEXPECTED));
                    return false;
                }
                break;
            case SD:
                if (name() != QLatin1String("standalone")) {
                    reportParseError(QLatin1String(XMLERR_SDDECLEXPECTED));
                    return false;
                }
                if (string() == QLatin1String("yes")) {
                    standalone = QXmlSimpleReaderPrivate::Yes;
                } else if (string() == QLatin1String("no")) {
                    standalone = QXmlSimpleReaderPrivate::No;
                } else {
                    reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
                    return false;
                }
                break;
            case Qm:
                // test if the skipping was legal
                if (!atEnd() && c != QLatin1Char('>'))
                    stringAddC(QLatin1Char('?'));
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parsePI, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (determineNameChar(c) == NameBeginning) {
            input = InpNameBe;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case QmI:
                next();
                break;
            case Name:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                    return false;
                }
                break;
            case Ws1:
            case Ws2:
            case Ws3:
            case Ws4:
            case Ws5:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                    return false;
                }
                break;
            case Version:
                if (!parseAttribute()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                    return false;
                }
                break;
            case EorSD:
                if (!parseAttribute()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                    return false;
                }
                break;
            case SD:
                // get the SDDecl (syntax like an attribute)
                if (standalone != QXmlSimpleReaderPrivate::Unknown) {
                    // already parsed the standalone declaration
                    reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                    return false;
                }
                if (!parseAttribute()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
                    return false;
                }
                break;
            case ADone:
                next();
                break;
            case Char:
                stringAddC();
                next();
                break;
            case Qm:
                // skip the '?'
                next();
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a document type definition (doctypedecl [28]).

  Precondition: the beginning '<!' of the doctype is already read the head
  stands on the 'D' of '<!DOCTYPE'.

  If this function was successful, the head-position is on the first
  character after the document type definition.
*/
bool QXmlSimpleReaderPrivate::parseDoctype()
{
    const signed char Init             =  0;
    const signed char Doctype          =  1; // read the doctype
    const signed char Ws1              =  2; // eat_ws
    const signed char Doctype2         =  3; // read the doctype, part 2
    const signed char Ws2              =  4; // eat_ws
    const signed char Sys              =  5; // read SYSTEM or PUBLIC
    const signed char Ws3              =  6; // eat_ws
    const signed char MP               =  7; // markupdecl or PEReference
    const signed char MPR              =  8; // same as MP, but already reported
    const signed char PER              =  9; // PERReference
    const signed char Mup              = 10; // markupdecl
    const signed char Ws4              = 11; // eat_ws
    const signed char MPE              = 12; // end of markupdecl or PEReference
    const signed char Done             = 13;

    const signed char InpWs            = 0;
    const signed char InpD             = 1; // 'D'
    const signed char InpS             = 2; // 'S' or 'P'
    const signed char InpOB            = 3; // [
    const signed char InpCB            = 4; //]
    const signed char InpPer           = 5; // %
    const signed char InpGt            = 6; // >
    const signed char InpUnknown       = 7;

    static const signed char table[13][8] = {
     /*  InpWs,  InpD       InpS       InpOB  InpCB  InpPer InpGt  InpUnknown */
        { -1,     Doctype,   -1,        -1,    -1,    -1,    -1,    -1        }, // Init
        { Ws1,    -1,        -1,        -1,    -1,    -1,    -1,    -1        }, // Doctype
        { -1,     Doctype2,  Doctype2,  -1,    -1,    -1,    -1,    Doctype2  }, // Ws1
        { Ws2,    -1,        Sys,       MP,    -1,    -1,    Done,  -1        }, // Doctype2
        { -1,     -1,        Sys,       MP,    -1,    -1,    Done,  -1        }, // Ws2
        { Ws3,    -1,        -1,        MP,    -1,    -1,    Done,  -1        }, // Sys
        { -1,     -1,        -1,        MP,    -1,    -1,    Done,  -1        }, // Ws3
        { -1,     -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // MP
        { -1,     -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // MPR
        { Ws4,    -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // PER
        { Ws4,    -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // Mup
        { -1,     -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // Ws4
        { -1,     -1,        -1,        -1,    -1,    -1,    Done,  -1        }  // MPE
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        startDTDwasReported = false;
        systemId.clear();
        publicId.clear();
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseDoctype (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Doctype2:
                doctype = name();
                break;
            case MP:
                if (!startDTDwasReported && lexicalHnd ) {
                    startDTDwasReported = true;
                    if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                state = MPR;
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGDOCTYPE));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseDoctype, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('D')) {
            input = InpD;
        } else if (c == QLatin1Char('S')) {
            input = InpS;
        } else if (c == QLatin1Char('P')) {
            input = InpS;
        } else if (c == QLatin1Char('[')) {
            input = InpOB;
        } else if (c == QLatin1Char(']')) {
            input = InpCB;
        } else if (c == QLatin1Char('%')) {
            input = InpPer;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Doctype:
                parseString_s = QLatin1String("DOCTYPE");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case Ws1:
            case Ws2:
            case Ws3:
            case Ws4:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case Doctype2:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case Sys:
                parseExternalID_allowPublicID = false;
                if (!parseExternalID()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                thisPublicId = publicId;
                thisSystemId = systemId;
                break;
            case MP:
            case MPR:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case PER:
                parsePEReference_context = InDTD;
                if (!parsePEReference()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case Mup:
                if (dtdRecursionLimit > 0 && parameterEntities.size() > dtdRecursionLimit) {
                    reportParseError(QString::fromLatin1(
                        "DTD parsing exceeded recursion limit of %1.").arg(dtdRecursionLimit));
                    return false;
                }
                if (!parseMarkupdecl()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case MPE:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
                    return false;
                }
                break;
            case Done:
                if (lexicalHnd) {
                    if (!startDTDwasReported) {
                        startDTDwasReported = true;
                        if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
                            reportParseError(lexicalHnd->errorString());
                            return false;
                        }
                    }
                    if (!lexicalHnd->endDTD()) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a ExternalID [75].

  If allowPublicID is true parse ExternalID [75] or PublicID [83].
*/
bool QXmlSimpleReaderPrivate::parseExternalID()
{
    const signed char Init             =  0;
    const signed char Sys              =  1; // parse 'SYSTEM'
    const signed char SysWS            =  2; // parse the whitespace after 'SYSTEM'
    const signed char SysSQ            =  3; // parse SystemLiteral with '
    const signed char SysSQ2           =  4; // parse SystemLiteral with '
    const signed char SysDQ            =  5; // parse SystemLiteral with "
    const signed char SysDQ2           =  6; // parse SystemLiteral with "
    const signed char Pub              =  7; // parse 'PUBLIC'
    const signed char PubWS            =  8; // parse the whitespace after 'PUBLIC'
    const signed char PubSQ            =  9; // parse PubidLiteral with '
    const signed char PubSQ2           = 10; // parse PubidLiteral with '
    const signed char PubDQ            = 11; // parse PubidLiteral with "
    const signed char PubDQ2           = 12; // parse PubidLiteral with "
    const signed char PubE             = 13; // finished parsing the PubidLiteral
    const signed char PubWS2           = 14; // parse the whitespace after the PubidLiteral
    const signed char PDone            = 15; // done if allowPublicID is true
    const signed char Done             = 16;

    const signed char InpSQ            = 0; // '
    const signed char InpDQ            = 1; // "
    const signed char InpS             = 2; // S
    const signed char InpP             = 3; // P
    const signed char InpWs            = 4; // white space
    const signed char InpUnknown       = 5;

    static const signed char table[15][6] = {
     /*  InpSQ    InpDQ    InpS     InpP     InpWs     InpUnknown */
        { -1,      -1,      Sys,     Pub,     -1,       -1      }, // Init
        { -1,      -1,      -1,      -1,      SysWS,    -1      }, // Sys
        { SysSQ,   SysDQ,   -1,      -1,      -1,       -1      }, // SysWS
        { Done,    SysSQ2,  SysSQ2,  SysSQ2,  SysSQ2,   SysSQ2  }, // SysSQ
        { Done,    SysSQ2,  SysSQ2,  SysSQ2,  SysSQ2,   SysSQ2  }, // SysSQ2
        { SysDQ2,  Done,    SysDQ2,  SysDQ2,  SysDQ2,   SysDQ2  }, // SysDQ
        { SysDQ2,  Done,    SysDQ2,  SysDQ2,  SysDQ2,   SysDQ2  }, // SysDQ2
        { -1,      -1,      -1,      -1,      PubWS,    -1      }, // Pub
        { PubSQ,   PubDQ,   -1,      -1,      -1,       -1      }, // PubWS
        { PubE,    -1,      PubSQ2,  PubSQ2,  PubSQ2,   PubSQ2  }, // PubSQ
        { PubE,    -1,      PubSQ2,  PubSQ2,  PubSQ2,   PubSQ2  }, // PubSQ2
        { -1,      PubE,    PubDQ2,  PubDQ2,  PubDQ2,   PubDQ2  }, // PubDQ
        { -1,      PubE,    PubDQ2,  PubDQ2,  PubDQ2,   PubDQ2  }, // PubDQ2
        { PDone,   PDone,   PDone,   PDone,   PubWS2,   PDone   }, // PubE
        { SysSQ,   SysDQ,   PDone,   PDone,   PDone,    PDone   }  // PubWS2
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        systemId.clear();
        publicId.clear();
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseExternalID (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case PDone:
                if (parseExternalID_allowPublicID) {
                    publicId = string();
                    return true;
                } else {
                    reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                    return false;
                }
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseExternalID, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('\'')) {
            input = InpSQ;
        } else if (c == QLatin1Char('"')) {
            input = InpDQ;
        } else if (c == QLatin1Char('S')) {
            input = InpS;
        } else if (c == QLatin1Char('P')) {
            input = InpP;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Sys:
                parseString_s = QLatin1String("SYSTEM");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                    return false;
                }
                break;
            case SysWS:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                    return false;
                }
                break;
            case SysSQ:
            case SysDQ:
                stringClear();
                next();
                break;
            case SysSQ2:
            case SysDQ2:
                stringAddC();
                next();
                break;
            case Pub:
                parseString_s = QLatin1String("PUBLIC");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                    return false;
                }
                break;
            case PubWS:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                    return false;
                }
                break;
            case PubSQ:
            case PubDQ:
                stringClear();
                next();
                break;
            case PubSQ2:
            case PubDQ2:
                stringAddC();
                next();
                break;
            case PubE:
                next();
                break;
            case PubWS2:
                publicId = string();
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
                    return false;
                }
                break;
            case Done:
                systemId = string();
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a markupdecl [29].
*/
bool QXmlSimpleReaderPrivate::parseMarkupdecl()
{
    const signed char Init             = 0;
    const signed char Lt               = 1; // < was read
    const signed char Em               = 2; // ! was read
    const signed char CE               = 3; // E was read
    const signed char Qm               = 4; // ? was read
    const signed char Dash             = 5; // - was read
    const signed char CA               = 6; // A was read
    const signed char CEL              = 7; // EL was read
    const signed char CEN              = 8; // EN was read
    const signed char CN               = 9; // N was read
    const signed char Done             = 10;

    const signed char InpLt            = 0; // <
    const signed char InpQm            = 1; // ?
    const signed char InpEm            = 2; // !
    const signed char InpDash          = 3; // -
    const signed char InpA             = 4; // A
    const signed char InpE             = 5; // E
    const signed char InpL             = 6; // L
    const signed char InpN             = 7; // N
    const signed char InpUnknown       = 8;

    static const signed char table[4][9] = {
     /*  InpLt  InpQm  InpEm  InpDash  InpA   InpE   InpL   InpN   InpUnknown */
        { Lt,    -1,    -1,    -1,      -1,    -1,    -1,    -1,    -1     }, // Init
        { -1,    Qm,    Em,    -1,      -1,    -1,    -1,    -1,    -1     }, // Lt
        { -1,    -1,    -1,    Dash,    CA,    CE,    -1,    CN,    -1     }, // Em
        { -1,    -1,    -1,    -1,      -1,    -1,    CEL,   CEN,   -1     }  // CE
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseMarkupdecl (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Qm:
                if (contentHnd) {
                    if (!contentHnd->processingInstruction(name(),string())) {
                        reportParseError(contentHnd->errorString());
                        return false;
                    }
                }
                return true;
            case Dash:
                if (lexicalHnd) {
                    if (!lexicalHnd->comment(string())) {
                        reportParseError(lexicalHnd->errorString());
                        return false;
                    }
                }
                return true;
            case CA:
                return true;
            case CEL:
                return true;
            case CEN:
                return true;
            case CN:
                return true;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
            return false;
        }
        if        (c == QLatin1Char('<')) {
            input = InpLt;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else if (c == QLatin1Char('!')) {
            input = InpEm;
        } else if (c == QLatin1Char('-')) {
            input = InpDash;
        } else if (c == QLatin1Char('A')) {
            input = InpA;
        } else if (c == QLatin1Char('E')) {
            input = InpE;
        } else if (c == QLatin1Char('L')) {
            input = InpL;
        } else if (c == QLatin1Char('N')) {
            input = InpN;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Lt:
                next();
                break;
            case Em:
                next();
                break;
            case CE:
                next();
                break;
            case Qm:
                parsePI_xmldecl = false;
                if (!parsePI()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
            case Dash:
                if (!parseComment()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
            case CA:
                if (!parseAttlistDecl()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
            case CEL:
                if (!parseElementDecl()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
            case CEN:
                if (!parseEntityDecl()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
            case CN:
                if (!parseNotationDecl()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
                    return false;
                }
                break;
        }
    }
    return false;
}

/*
  Parse a PEReference [69]
*/
bool QXmlSimpleReaderPrivate::parsePEReference()
{
    const signed char Init             = 0;
    const signed char Next             = 1;
    const signed char Name             = 2;
    const signed char NameR            = 3; // same as Name, but already reported
    const signed char Done             = 4;

    const signed char InpSemi          = 0; // ;
    const signed char InpPer           = 1; // %
    const signed char InpUnknown       = 2;

    static const signed char table[4][3] = {
     /*  InpSemi  InpPer  InpUnknown */
        { -1,      Next,   -1    }, // Init
        { -1,      -1,     Name  }, // Next
        { Done,    -1,     -1    }, // Name
        { Done,    -1,     -1    }  // NameR
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parsePEReference (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Name:
                {
                    bool skipIt = true;
                    QString xmlRefString;

                    QMap<QString,QString>::Iterator it;
                    it = parameterEntities.find(ref());
                    if (it != parameterEntities.end()) {
                        skipIt = false;
                        xmlRefString = *it;
                    } else if (entityRes) {
                        QMap<QString,QXmlSimpleReaderPrivate::ExternParameterEntity>::Iterator it2;
                        it2 = externParameterEntities.find(ref());
                        QXmlInputSource *ret = nullptr;
                        if (it2 != externParameterEntities.end()) {
                            if (!entityRes->resolveEntity((*it2).publicId, (*it2).systemId, ret)) {
                                delete ret;
                                reportParseError(entityRes->errorString());
                                return false;
                            }
                            if (ret) {
                                QString buffer = ret->data();
                                while (!buffer.isEmpty()) {
                                    xmlRefString += buffer;
                                    ret->fetchData();
                                    buffer = ret->data();
                                }
                                delete ret;
                                if (!stripTextDecl(xmlRefString)) {
                                    reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
                                    return false;
                                }
                                skipIt = false;
                            }
                        }
                    }

                    if (skipIt) {
                        if (contentHnd) {
                            if (!contentHnd->skippedEntity(QLatin1Char('%') + ref())) {
                                reportParseError(contentHnd->errorString());
                                return false;
                            }
                        }
                    } else {
                        if (parsePEReference_context == InEntityValue) {
                            // Included in literal
                            if (!insertXmlRef(xmlRefString, ref(), true))
                                return false;
                        } else if (parsePEReference_context == InDTD) {
                            // Included as PE
                            if (!insertXmlRef(QLatin1Char(' ') + xmlRefString + QLatin1Char(' '), ref(), false))
                                return false;
                        }
                    }
                }
                state = NameR;
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parsePEReference, state);
            return false;
        }
        if        (c == QLatin1Char(';')) {
            input = InpSemi;
        } else if (c == QLatin1Char('%')) {
            input = InpPer;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Next:
                next();
                break;
            case Name:
            case NameR:
                parseName_useRef = true;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a AttlistDecl [52].

  Precondition: the beginning '<!' is already read and the head
  stands on the 'A' of '<!ATTLIST'
*/
bool QXmlSimpleReaderPrivate::parseAttlistDecl()
{
    const signed char Init             =  0;
    const signed char Attlist          =  1; // parse the string "ATTLIST"
    const signed char Ws               =  2; // whitespace read
    const signed char Name             =  3; // parse name
    const signed char Ws1              =  4; // whitespace read
    const signed char Attdef           =  5; // parse the AttDef
    const signed char Ws2              =  6; // whitespace read
    const signed char Atttype          =  7; // parse the AttType
    const signed char Ws3              =  8; // whitespace read
    const signed char DDecH            =  9; // DefaultDecl with #
    const signed char DefReq           = 10; // parse the string "REQUIRED"
    const signed char DefImp           = 11; // parse the string "IMPLIED"
    const signed char DefFix           = 12; // parse the string "FIXED"
    const signed char Attval           = 13; // parse the AttValue
    const signed char Ws4              = 14; // whitespace read
    const signed char Done             = 15;

    const signed char InpWs            = 0; // white space
    const signed char InpGt            = 1; // >
    const signed char InpHash          = 2; // #
    const signed char InpA             = 3; // A
    const signed char InpI             = 4; // I
    const signed char InpF             = 5; // F
    const signed char InpR             = 6; // R
    const signed char InpUnknown       = 7;

    static const signed char table[15][8] = {
     /*  InpWs    InpGt    InpHash  InpA      InpI     InpF     InpR     InpUnknown */
        { -1,      -1,      -1,      Attlist,  -1,      -1,      -1,      -1      }, // Init
        { Ws,      -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attlist
        { -1,      -1,      -1,      Name,     Name,    Name,    Name,    Name    }, // Ws
        { Ws1,     Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }, // Name
        { -1,      Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }, // Ws1
        { Ws2,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attdef
        { -1,      Atttype, Atttype, Atttype,  Atttype, Atttype, Atttype, Atttype }, // Ws2
        { Ws3,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attype
        { -1,      Attval,  DDecH,   Attval,   Attval,  Attval,  Attval,  Attval  }, // Ws3
        { -1,      -1,      -1,      -1,       DefImp,  DefFix,  DefReq,  -1      }, // DDecH
        { Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // DefReq
        { Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // DefImp
        { Ws3,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // DefFix
        { Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // Attval
        { -1,      Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }  // Ws4
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseAttlistDecl (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Name:
                attDeclEName = name();
                break;
            case Attdef:
                attDeclAName = name();
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (c == QLatin1Char('#')) {
            input = InpHash;
        } else if (c == QLatin1Char('A')) {
            input = InpA;
        } else if (c == QLatin1Char('I')) {
            input = InpI;
        } else if (c == QLatin1Char('F')) {
            input = InpF;
        } else if (c == QLatin1Char('R')) {
            input = InpR;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Attlist:
                parseString_s = QLatin1String("ATTLIST");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Ws:
            case Ws1:
            case Ws2:
            case Ws3:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Name:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Attdef:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Atttype:
                if (!parseAttType()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case DDecH:
                next();
                break;
            case DefReq:
                parseString_s = QLatin1String("REQUIRED");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case DefImp:
                parseString_s = QLatin1String("IMPLIED");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case DefFix:
                parseString_s = QLatin1String("FIXED");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Attval:
                if (!parseAttValue()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Ws4:
                if (declHnd) {
                    // ### not all values are computed yet...
                    if (!declHnd->attributeDecl(attDeclEName, attDeclAName, QLatin1String(""), QLatin1String(""), QLatin1String(""))) {
                        reportParseError(declHnd->errorString());
                        return false;
                    }
                }
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a AttType [54]
*/
bool QXmlSimpleReaderPrivate::parseAttType()
{
    const signed char Init             =  0;
    const signed char ST               =  1; // StringType
    const signed char TTI              =  2; // TokenizedType starting with 'I'
    const signed char TTI2             =  3; // TokenizedType helpstate
    const signed char TTI3             =  4; // TokenizedType helpstate
    const signed char TTE              =  5; // TokenizedType starting with 'E'
    const signed char TTEY             =  6; // TokenizedType starting with 'ENTITY'
    const signed char TTEI             =  7; // TokenizedType starting with 'ENTITI'
    const signed char N                =  8; // N read (TokenizedType or Notation)
    const signed char TTNM             =  9; // TokenizedType starting with 'NM'
    const signed char TTNM2            = 10; // TokenizedType helpstate
    const signed char NO               = 11; // Notation
    const signed char NO2              = 12; // Notation helpstate
    const signed char NO3              = 13; // Notation helpstate
    const signed char NOName           = 14; // Notation, read name
    const signed char NO4              = 15; // Notation helpstate
    const signed char EN               = 16; // Enumeration
    const signed char ENNmt            = 17; // Enumeration, read Nmtoken
    const signed char EN2              = 18; // Enumeration helpstate
    const signed char ADone            = 19; // almost done (make next and accept)
    const signed char Done             = 20;

    const signed char InpWs            =  0; // whitespace
    const signed char InpOp            =  1; // (
    const signed char InpCp            =  2; //)
    const signed char InpPipe          =  3; // |
    const signed char InpC             =  4; // C
    const signed char InpE             =  5; // E
    const signed char InpI             =  6; // I
    const signed char InpM             =  7; // M
    const signed char InpN             =  8; // N
    const signed char InpO             =  9; // O
    const signed char InpR             = 10; // R
    const signed char InpS             = 11; // S
    const signed char InpY             = 12; // Y
    const signed char InpUnknown       = 13;

    static const signed char table[19][14] = {
     /*  InpWs    InpOp    InpCp    InpPipe  InpC     InpE     InpI     InpM     InpN     InpO     InpR     InpS     InpY     InpUnknown */
        { -1,      EN,      -1,      -1,      ST,      TTE,     TTI,     -1,      N,       -1,      -1,      -1,      -1,      -1     }, // Init
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // ST
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTI2,    Done,    Done,    Done   }, // TTI
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTI3,    Done,    Done   }, // TTI2
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTI3
        { -1,      -1,      -1,      -1,      -1,      -1,      TTEI,    -1,      -1,      -1,      -1,      -1,      TTEY,    -1     }, // TTE
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTEY
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTEI
        { -1,      -1,      -1,      -1,      -1,      -1,      -1,      TTNM,    -1,      NO,      -1,      -1,      -1,      -1     }, // N
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTNM2,   Done,    Done   }, // TTNM
        { Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTNM2
        { NO2,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO
        { -1,      NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO2
        { NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName }, // NO3
        { NO4,     -1,      ADone,   NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NOName
        { -1,      -1,      ADone,   NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO4
        { -1,      -1,      ENNmt,   -1,      ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt  }, // EN
        { EN2,     -1,      ADone,   EN,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // ENNmt
        { -1,      -1,      ADone,   EN,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }  // EN2
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseAttType (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case ADone:
                return true;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseAttType, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('(')) {
            input = InpOp;
        } else if (c == QLatin1Char(')')) {
            input = InpCp;
        } else if (c == QLatin1Char('|')) {
            input = InpPipe;
        } else if (c == QLatin1Char('C')) {
            input = InpC;
        } else if (c == QLatin1Char('E')) {
            input = InpE;
        } else if (c == QLatin1Char('I')) {
            input = InpI;
        } else if (c == QLatin1Char('M')) {
            input = InpM;
        } else if (c == QLatin1Char('N')) {
            input = InpN;
        } else if (c == QLatin1Char('O')) {
            input = InpO;
        } else if (c == QLatin1Char('R')) {
            input = InpR;
        } else if (c == QLatin1Char('S')) {
            input = InpS;
        } else if (c == QLatin1Char('Y')) {
            input = InpY;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case ST:
                parseString_s = QLatin1String("CDATA");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case TTI:
                parseString_s = QLatin1String("ID");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case TTI2:
                parseString_s = QLatin1String("REF");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case TTI3:
                next(); // S
                break;
            case TTE:
                parseString_s = QLatin1String("ENTIT");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case TTEY:
                next(); // Y
                break;
            case TTEI:
                parseString_s = QLatin1String("IES");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case N:
                next(); // N
                break;
            case TTNM:
                parseString_s = QLatin1String("MTOKEN");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case TTNM2:
                next(); // S
                break;
            case NO:
                parseString_s = QLatin1String("OTATION");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case NO2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case NO3:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case NOName:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case NO4:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case EN:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case ENNmt:
                if (!parseNmtoken()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case EN2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
                    return false;
                }
                break;
            case ADone:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a AttValue [10]

  Precondition: the head stands on the beginning " or '

  If this function was successful, the head stands on the first
  character after the closing " or ' and the value of the attribute
  is in string().
*/
bool QXmlSimpleReaderPrivate::parseAttValue()
{
    const signed char Init             = 0;
    const signed char Dq               = 1; // double quotes were read
    const signed char DqRef            = 2; // read references in double quotes
    const signed char DqC              = 3; // signed character read in double quotes
    const signed char Sq               = 4; // single quotes were read
    const signed char SqRef            = 5; // read references in single quotes
    const signed char SqC              = 6; // signed character read in single quotes
    const signed char Done             = 7;

    const signed char InpDq            = 0; // "
    const signed char InpSq            = 1; // '
    const signed char InpAmp           = 2; // &
    const signed char InpLt            = 3; // <
    const signed char InpUnknown       = 4;

    static const signed char table[7][5] = {
     /*  InpDq  InpSq  InpAmp  InpLt InpUnknown */
        { Dq,    Sq,    -1,     -1,   -1    }, // Init
        { Done,  DqC,   DqRef,  -1,   DqC   }, // Dq
        { Done,  DqC,   DqRef,  -1,   DqC   }, // DqRef
        { Done,  DqC,   DqRef,  -1,   DqC   }, // DqC
        { SqC,   Done,  SqRef,  -1,   SqC   }, // Sq
        { SqC,   Done,  SqRef,  -1,   SqC   }, // SqRef
        { SqC,   Done,  SqRef,  -1,   SqC   }  // SqRef
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseAttValue (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseAttValue, state);
            return false;
        }
        if        (c == QLatin1Char('"')) {
            input = InpDq;
        } else if (c == QLatin1Char('\'')) {
            input = InpSq;
        } else if (c == QLatin1Char('&')) {
            input = InpAmp;
        } else if (c == QLatin1Char('<')) {
            input = InpLt;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Dq:
            case Sq:
                stringClear();
                next();
                break;
            case DqRef:
            case SqRef:
                parseReference_context = InAttributeValue;
                if (!parseReference()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
                    return false;
                }
                break;
            case DqC:
            case SqC:
                stringAddC();
                next();
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a elementdecl [45].

  Precondition: the beginning '<!E' is already read and the head
  stands on the 'L' of '<!ELEMENT'
*/
bool QXmlSimpleReaderPrivate::parseElementDecl()
{
    const signed char Init             =  0;
    const signed char Elem             =  1; // parse the beginning string
    const signed char Ws1              =  2; // whitespace required
    const signed char Nam              =  3; // parse Name
    const signed char Ws2              =  4; // whitespace required
    const signed char Empty            =  5; // read EMPTY
    const signed char Any              =  6; // read ANY
    const signed char Cont             =  7; // read contentspec (except ANY or EMPTY)
    const signed char Mix              =  8; // read Mixed
    const signed char Mix2             =  9; //
    const signed char Mix3             = 10; //
    const signed char MixN1            = 11; //
    const signed char MixN2            = 12; //
    const signed char MixN3            = 13; //
    const signed char MixN4            = 14; //
    const signed char Cp               = 15; // parse cp
    const signed char Cp2              = 16; //
    const signed char WsD              = 17; // eat whitespace before Done
    const signed char Done             = 18;

    const signed char InpWs            =  0;
    const signed char InpGt            =  1; // >
    const signed char InpPipe          =  2; // |
    const signed char InpOp            =  3; // (
    const signed char InpCp            =  4; //)
    const signed char InpHash          =  5; // #
    const signed char InpQm            =  6; // ?
    const signed char InpAst           =  7; // *
    const signed char InpPlus          =  8; // +
    const signed char InpA             =  9; // A
    const signed char InpE             = 10; // E
    const signed char InpL             = 11; // L
    const signed char InpUnknown       = 12;

    static const signed char table[18][13] = {
     /*  InpWs   InpGt  InpPipe  InpOp  InpCp   InpHash  InpQm  InpAst  InpPlus  InpA    InpE    InpL    InpUnknown */
        { -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     Elem,   -1     }, // Init
        { Ws1,    -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Elem
        { -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      Nam,    Nam,    Nam,    Nam    }, // Ws1
        { Ws2,    -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Nam
        { -1,     -1,    -1,      Cont,  -1,     -1,      -1,    -1,     -1,      Any,    Empty,  -1,     -1     }, // Ws2
        { WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Empty
        { WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Any
        { -1,     -1,    -1,      Cp,    Cp,     Mix,     -1,    -1,     -1,      Cp,     Cp,     Cp,     Cp     }, // Cont
        { Mix2,   -1,    MixN1,   -1,    Mix3,   -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Mix
        { -1,     -1,    MixN1,   -1,    Mix3,   -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Mix2
        { WsD,    Done,  -1,      -1,    -1,     -1,      -1,    WsD,    -1,      -1,     -1,     -1,     -1     }, // Mix3
        { -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      MixN2,  MixN2,  MixN2,  MixN2  }, // MixN1
        { MixN3,  -1,    MixN1,   -1,    MixN4,  -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // MixN2
        { -1,     -1,    MixN1,   -1,    MixN4,  -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // MixN3
        { -1,     -1,    -1,      -1,    -1,     -1,      -1,    WsD,    -1,      -1,     -1,     -1,     -1     }, // MixN4
        { WsD,    Done,  -1,      -1,    -1,     -1,      Cp2,   Cp2,    Cp2,     -1,     -1,     -1,     -1     }, // Cp
        { WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Cp2
        { -1,     Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }  // WsD
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseElementDecl (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseElementDecl, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (c == QLatin1Char('|')) {
            input = InpPipe;
        } else if (c == QLatin1Char('(')) {
            input = InpOp;
        } else if (c == QLatin1Char(')')) {
            input = InpCp;
        } else if (c == QLatin1Char('#')) {
            input = InpHash;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else if (c == QLatin1Char('*')) {
            input = InpAst;
        } else if (c == QLatin1Char('+')) {
            input = InpPlus;
        } else if (c == QLatin1Char('A')) {
            input = InpA;
        } else if (c == QLatin1Char('E')) {
            input = InpE;
        } else if (c == QLatin1Char('L')) {
            input = InpL;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Elem:
                parseString_s = QLatin1String("LEMENT");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Ws1:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Nam:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Ws2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Empty:
                parseString_s = QLatin1String("EMPTY");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Any:
                parseString_s = QLatin1String("ANY");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Cont:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Mix:
                parseString_s = QLatin1String("#PCDATA");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Mix2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Mix3:
                next();
                break;
            case MixN1:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case MixN2:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case MixN3:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case MixN4:
                next();
                break;
            case Cp:
                if (!parseChoiceSeq()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Cp2:
                next();
                break;
            case WsD:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a NotationDecl [82].

  Precondition: the beginning '<!' is already read and the head
  stands on the 'N' of '<!NOTATION'
*/
bool QXmlSimpleReaderPrivate::parseNotationDecl()
{
    const signed char Init             = 0;
    const signed char Not              = 1; // read NOTATION
    const signed char Ws1              = 2; // eat whitespaces
    const signed char Nam              = 3; // read Name
    const signed char Ws2              = 4; // eat whitespaces
    const signed char ExtID            = 5; // parse ExternalID
    const signed char ExtIDR           = 6; // same as ExtID, but already reported
    const signed char Ws3              = 7; // eat whitespaces
    const signed char Done             = 8;

    const signed char InpWs            = 0;
    const signed char InpGt            = 1; // >
    const signed char InpN             = 2; // N
    const signed char InpUnknown       = 3;

    static const signed char table[8][4] = {
     /*  InpWs   InpGt  InpN    InpUnknown */
        { -1,     -1,    Not,    -1     }, // Init
        { Ws1,    -1,    -1,     -1     }, // Not
        { -1,     -1,    Nam,    Nam    }, // Ws1
        { Ws2,    Done,  -1,     -1     }, // Nam
        { -1,     Done,  ExtID,  ExtID  }, // Ws2
        { Ws3,    Done,  -1,     -1     }, // ExtID
        { Ws3,    Done,  -1,     -1     }, // ExtIDR
        { -1,     Done,  -1,     -1     }  // Ws3
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseNotationDecl (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case ExtID:
                // call the handler
                if (dtdHnd) {
                    if (!dtdHnd->notationDecl(name(), publicId, systemId)) {
                        reportParseError(dtdHnd->errorString());
                        return false;
                    }
                }
                state = ExtIDR;
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (c == QLatin1Char('N')) {
            input = InpN;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Not:
                parseString_s = QLatin1String("NOTATION");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case Ws1:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case Nam:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case Ws2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case ExtID:
            case ExtIDR:
                parseExternalID_allowPublicID = true;
                if (!parseExternalID()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case Ws3:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse choice [49] or seq [50].

  Precondition: the beginning '('S? is already read and the head
  stands on the first non-whitespace character after it.
*/
bool QXmlSimpleReaderPrivate::parseChoiceSeq()
{
    const signed char Init             = 0;
    const signed char Ws1              = 1; // eat whitespace
    const signed char CoS              = 2; // choice or set
    const signed char Ws2              = 3; // eat whitespace
    const signed char More             = 4; // more cp to read
    const signed char Name             = 5; // read name
    const signed char Done             = 6; //

    const signed char InpWs            = 0; // S
    const signed char InpOp            = 1; // (
    const signed char InpCp            = 2; //)
    const signed char InpQm            = 3; // ?
    const signed char InpAst           = 4; // *
    const signed char InpPlus          = 5; // +
    const signed char InpPipe          = 6; // |
    const signed char InpComm          = 7; // ,
    const signed char InpUnknown       = 8;

    static const signed char table[6][9] = {
     /*  InpWs   InpOp  InpCp  InpQm  InpAst  InpPlus  InpPipe  InpComm  InpUnknown */
        { -1,     Ws1,   -1,    -1,    -1,     -1,      -1,      -1,      Name  }, // Init
        { -1,     CoS,   -1,    -1,    -1,     -1,      -1,      -1,      CoS   }, // Ws1
        { Ws2,    -1,    Done,  Ws2,   Ws2,    Ws2,     More,    More,    -1    }, // CS
        { -1,     -1,    Done,  -1,    -1,     -1,      More,    More,    -1    }, // Ws2
        { -1,     Ws1,   -1,    -1,    -1,     -1,      -1,      -1,      Name  }, // More (same as Init)
        { Ws2,    -1,    Done,  Ws2,   Ws2,    Ws2,     More,    More,    -1    }  // Name (same as CS)
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseChoiceSeq (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('(')) {
            input = InpOp;
        } else if (c == QLatin1Char(')')) {
            input = InpCp;
        } else if (c == QLatin1Char('?')) {
            input = InpQm;
        } else if (c == QLatin1Char('*')) {
            input = InpAst;
        } else if (c == QLatin1Char('+')) {
            input = InpPlus;
        } else if (c == QLatin1Char('|')) {
            input = InpPipe;
        } else if (c == QLatin1Char(',')) {
            input = InpComm;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Ws1:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                    return false;
                }
                break;
            case CoS:
                if (!parseChoiceSeq()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                    return false;
                }
                break;
            case Ws2:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                    return false;
                }
                break;
            case More:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                    return false;
                }
                break;
            case Name:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

bool QXmlSimpleReaderPrivate::isExpandedEntityValueTooLarge(QString *errorMessage)
{
    QString entityNameBuffer;

    // For every entity, check how many times all entity names were referenced in its value.
    for (QMap<QString,QString>::const_iterator toSearchIt = entities.constBegin();
         toSearchIt != entities.constEnd();
         ++toSearchIt) {
        const QString &toSearch = toSearchIt.key();

        // Don't check the same entities twice.
        if (!literalEntitySizes.contains(toSearch)) {
            // The amount of characters that weren't entity names, but literals, like 'X'.
            QString leftOvers = entities.value(toSearch);
            // How many times was entityName referenced by toSearch?
            for (QMap<QString,QString>::const_iterator referencedIt = entities.constBegin();
                 referencedIt != entities.constEnd();
                 ++referencedIt) {
                const QString &entityName = referencedIt.key();

                for (int i = 0; i < leftOvers.size() && i != -1; ) {
                    entityNameBuffer = QLatin1Char('&') + entityName + QLatin1Char(';');

                    i = leftOvers.indexOf(entityNameBuffer, i);
                    if (i != -1) {
                        leftOvers.remove(i, entityName.size() + 2);
                        // The entityName we're currently trying to find was matched in this string; increase our count.
                        ++referencesToOtherEntities[toSearch][entityName];
                    }
                }
            }
            literalEntitySizes[toSearch] = leftOvers.size();
        }
    }

    for (QHash<QString, QHash<QString, int> >::const_iterator entityIt = referencesToOtherEntities.constBegin();
         entityIt != referencesToOtherEntities.constEnd();
         ++entityIt) {
        const QString &entity = entityIt.key();

        QHash<QString, int>::iterator expandedIt = expandedSizes.find(entity);
        if (expandedIt == expandedSizes.end()) {
            expandedIt = expandedSizes.insert(entity, literalEntitySizes.value(entity));
            for (QHash<QString, int>::const_iterator referenceIt = entityIt->constBegin();
                 referenceIt != entityIt->constEnd();
                 ++referenceIt) {
                const QString &referenceTo = referenceIt.key();
                const int references = referencesToOtherEntities.value(entity).value(referenceTo);
                // The total size of an entity's value is the expanded size of all of its referenced entities, plus its literal size.
                *expandedIt += expandedSizes.value(referenceTo) * references + literalEntitySizes.value(referenceTo) * references;
            }

            if (*expandedIt > entityCharacterLimit) {
                if (errorMessage) {
                    *errorMessage = QString::fromLatin1("The XML entity \"%1\" expands to a string that is too large to process (%2 characters > %3).")
                        .arg(entity, QString::number(*expandedIt), QString::number(entityCharacterLimit));
                }
                return true;
            }
        }
    }
    return false;
}

/*
  Parse a EntityDecl [70].

  Precondition: the beginning '<!E' is already read and the head
  stand on the 'N' of '<!ENTITY'
*/
bool QXmlSimpleReaderPrivate::parseEntityDecl()
{
    const signed char Init             =  0;
    const signed char Ent              =  1; // parse "ENTITY"
    const signed char Ws1              =  2; // white space read
    const signed char Name             =  3; // parse name
    const signed char Ws2              =  4; // white space read
    const signed char EValue           =  5; // parse entity value
    const signed char EValueR          =  6; // same as EValue, but already reported
    const signed char ExtID            =  7; // parse ExternalID
    const signed char Ws3              =  8; // white space read
    const signed char Ndata            =  9; // parse "NDATA"
    const signed char Ws4              = 10; // white space read
    const signed char NNam             = 11; // parse name
    const signed char NNamR            = 12; // same as NNam, but already reported
    const signed char PEDec            = 13; // parse PEDecl
    const signed char Ws6              = 14; // white space read
    const signed char PENam            = 15; // parse name
    const signed char Ws7              = 16; // white space read
    const signed char PEVal            = 17; // parse entity value
    const signed char PEValR           = 18; // same as PEVal, but already reported
    const signed char PEEID            = 19; // parse ExternalID
    const signed char PEEIDR           = 20; // same as PEEID, but already reported
    const signed char WsE              = 21; // white space read
    const signed char Done             = 22;
    const signed char EDDone           = 23; // done, but also report an external, unparsed entity decl

    const signed char InpWs            = 0; // white space
    const signed char InpPer           = 1; // %
    const signed char InpQuot          = 2; // " or '
    const signed char InpGt            = 3; // >
    const signed char InpN             = 4; // N
    const signed char InpUnknown       = 5;

    static const signed char table[22][6] = {
     /*  InpWs  InpPer  InpQuot  InpGt  InpN    InpUnknown */
        { -1,    -1,     -1,      -1,    Ent,    -1      }, // Init
        { Ws1,   -1,     -1,      -1,    -1,     -1      }, // Ent
        { -1,    PEDec,  -1,      -1,    Name,   Name    }, // Ws1
        { Ws2,   -1,     -1,      -1,    -1,     -1      }, // Name
        { -1,    -1,     EValue,  -1,    -1,     ExtID   }, // Ws2
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // EValue
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // EValueR
        { Ws3,   -1,     -1,      EDDone,-1,     -1      }, // ExtID
        { -1,    -1,     -1,      EDDone,Ndata,  -1      }, // Ws3
        { Ws4,   -1,     -1,      -1,    -1,     -1      }, // Ndata
        { -1,    -1,     -1,      -1,    NNam,   NNam    }, // Ws4
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // NNam
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // NNamR
        { Ws6,   -1,     -1,      -1,    -1,     -1      }, // PEDec
        { -1,    -1,     -1,      -1,    PENam,  PENam   }, // Ws6
        { Ws7,   -1,     -1,      -1,    -1,     -1      }, // PENam
        { -1,    -1,     PEVal,   -1,    -1,     PEEID   }, // Ws7
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // PEVal
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // PEValR
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // PEEID
        { WsE,   -1,     -1,      Done,  -1,     -1      }, // PEEIDR
        { -1,    -1,     -1,      Done,  -1,     -1      }  // WsE
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseEntityDecl (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case EValue:
                if ( !entityExist(name())) {
                    QString errorMessage;
                    if (isExpandedEntityValueTooLarge(&errorMessage)) {
                        reportParseError(errorMessage);
                        return false;
                    }

                    entities.insert(name(), string());
                    if (declHnd) {
                        if (!declHnd->internalEntityDecl(name(), string())) {
                            reportParseError(declHnd->errorString());
                            return false;
                        }
                    }
                }
                state = EValueR;
                break;
            case NNam:
                if ( !entityExist(name())) {
                    externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, ref()));
                    if (dtdHnd) {
                        if (!dtdHnd->unparsedEntityDecl(name(), publicId, systemId, ref())) {
                            reportParseError(declHnd->errorString());
                            return false;
                        }
                    }
                }
                state = NNamR;
                break;
            case PEVal:
                if ( !entityExist(name())) {
                    parameterEntities.insert(name(), string());
                    if (declHnd) {
                        if (!declHnd->internalEntityDecl(QLatin1Char('%') + name(), string())) {
                            reportParseError(declHnd->errorString());
                            return false;
                        }
                    }
                }
                state = PEValR;
                break;
            case PEEID:
                if ( !entityExist(name())) {
                    externParameterEntities.insert(name(), QXmlSimpleReaderPrivate::ExternParameterEntity(publicId, systemId));
                    if (declHnd) {
                        if (!declHnd->externalEntityDecl(QLatin1Char('%') + name(), publicId, systemId)) {
                            reportParseError(declHnd->errorString());
                            return false;
                        }
                    }
                }
                state = PEEIDR;
                break;
            case EDDone:
                if ( !entityExist(name())) {
                    externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, QString()));
                    if (declHnd) {
                        if (!declHnd->externalEntityDecl(name(), publicId, systemId)) {
                            reportParseError(declHnd->errorString());
                            return false;
                        }
                    }
                }
                return true;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
            return false;
        }
        if (is_S(c)) {
            input = InpWs;
        } else if (c == QLatin1Char('%')) {
            input = InpPer;
        } else if (c == QLatin1Char('"') || c == QLatin1Char('\'')) {
            input = InpQuot;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else if (c == QLatin1Char('N')) {
            input = InpN;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Ent:
                parseString_s = QLatin1String("NTITY");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ws1:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Name:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ws2:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case EValue:
            case EValueR:
                if (!parseEntityValue()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case ExtID:
                parseExternalID_allowPublicID = false;
                if (!parseExternalID()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ws3:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ndata:
                parseString_s = QLatin1String("NDATA");
                if (!parseString()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ws4:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case NNam:
            case NNamR:
                parseName_useRef = true;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case PEDec:
                next();
                break;
            case Ws6:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case PENam:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case Ws7:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case PEVal:
            case PEValR:
                if (!parseEntityValue()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case PEEID:
            case PEEIDR:
                parseExternalID_allowPublicID = false;
                if (!parseExternalID()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case WsE:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
                    return false;
                }
                break;
            case EDDone:
                next();
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a EntityValue [9]
*/
bool QXmlSimpleReaderPrivate::parseEntityValue()
{
    const signed char Init             = 0;
    const signed char Dq               = 1; // EntityValue is double quoted
    const signed char DqC              = 2; // signed character
    const signed char DqPER            = 3; // PERefence
    const signed char DqRef            = 4; // Reference
    const signed char Sq               = 5; // EntityValue is double quoted
    const signed char SqC              = 6; // signed character
    const signed char SqPER            = 7; // PERefence
    const signed char SqRef            = 8; // Reference
    const signed char Done             = 9;

    const signed char InpDq            = 0; // "
    const signed char InpSq            = 1; // '
    const signed char InpAmp           = 2; // &
    const signed char InpPer           = 3; // %
    const signed char InpUnknown       = 4;

    static const signed char table[9][5] = {
     /*  InpDq  InpSq  InpAmp  InpPer  InpUnknown */
        { Dq,    Sq,    -1,     -1,     -1    }, // Init
        { Done,  DqC,   DqRef,  DqPER,  DqC   }, // Dq
        { Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqC
        { Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqPER
        { Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqRef
        { SqC,   Done,  SqRef,  SqPER,  SqC   }, // Sq
        { SqC,   Done,  SqRef,  SqPER,  SqC   }, // SqC
        { SqC,   Done,  SqRef,  SqPER,  SqC   }, // SqPER
        { SqC,   Done,  SqRef,  SqPER,  SqC   }  // SqRef
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseEntityValue (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityValue, state);
            return false;
        }
        if        (c == QLatin1Char('"')) {
            input = InpDq;
        } else if (c == QLatin1Char('\'')) {
            input = InpSq;
        } else if (c == QLatin1Char('&')) {
            input = InpAmp;
        } else if (c == QLatin1Char('%')) {
            input = InpPer;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Dq:
            case Sq:
                stringClear();
                next();
                break;
            case DqC:
            case SqC:
                stringAddC();
                next();
                break;
            case DqPER:
            case SqPER:
                parsePEReference_context = InEntityValue;
                if (!parsePEReference()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
                    return false;
                }
                break;
            case DqRef:
            case SqRef:
                parseReference_context = InEntityValue;
                if (!parseReference()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
                    return false;
                }
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a comment [15].

  Precondition: the beginning '<!' of the comment is already read and the head
  stands on the first '-' of '<!--'.

  If this funktion was successful, the head-position is on the first
  character after the comment.
*/
bool QXmlSimpleReaderPrivate::parseComment()
{
    const signed char Init             = 0;
    const signed char Dash1            = 1; // the first dash was read
    const signed char Dash2            = 2; // the second dash was read
    const signed char Com              = 3; // read comment
    const signed char Com2             = 4; // read comment (help state)
    const signed char ComE             = 5; // finished reading comment
    const signed char Done             = 6;

    const signed char InpDash          = 0; // -
    const signed char InpGt            = 1; // >
    const signed char InpUnknown       = 2;

    static const signed char table[6][3] = {
     /*  InpDash  InpGt  InpUnknown */
        { Dash1,   -1,    -1  }, // Init
        { Dash2,   -1,    -1  }, // Dash1
        { Com2,    Com,   Com }, // Dash2
        { Com2,    Com,   Com }, // Com
        { ComE,    Com,   Com }, // Com2
        { -1,      Done,  -1  }  // ComE
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseComment (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseComment, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Dash2:
                stringClear();
                break;
            case Com2:
                // if next character is not a dash than don't skip it
                if (!atEnd() && c != QLatin1Char('-'))
                    stringAddC(QLatin1Char('-'));
                break;
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGCOMMENT));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseComment, state);
            return false;
        }
        if (c == QLatin1Char('-')) {
            input = InpDash;
        } else if (c == QLatin1Char('>')) {
            input = InpGt;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case Dash1:
                next();
                break;
            case Dash2:
                next();
                break;
            case Com:
                stringAddC();
                next();
                break;
            case Com2:
                next();
                break;
            case ComE:
                next();
                break;
            case Done:
                next();
                break;
        }
    }
    return false;
}

/*
    Parse an Attribute [41].

    Precondition: the head stands on the first character of the name
    of the attribute (i.e. all whitespaces are already parsed).

    The head stand on the next character after the end quotes. The
    variable name contains the name of the attribute and the variable
    string contains the value of the attribute.
*/
bool QXmlSimpleReaderPrivate::parseAttribute()
{
    const int Init             = 0;
    const int PName            = 1; // parse name
    const int Ws               = 2; // eat ws
    const int Eq               = 3; // the '=' was read
    const int Quotes           = 4; // " or ' were read

    const int InpNameBe        = 0;
    const int InpEq            = 1; // =
    const int InpDq            = 2; // "
    const int InpSq            = 3; // '
    const int InpUnknown       = 4;

    static const int table[4][5] = {
     /*  InpNameBe  InpEq  InpDq    InpSq    InpUnknown */
        { PName,     -1,    -1,      -1,      -1    }, // Init
        { -1,        Eq,    -1,      -1,      Ws    }, // PName
        { -1,        Eq,    -1,      -1,      -1    }, // Ws
        { -1,        -1,    Quotes,  Quotes,  -1    }  // Eq
    };
    int state;
    int input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseAttribute (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Quotes:
                // Done
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseAttribute, state);
            return false;
        }
        if (determineNameChar(c) == NameBeginning) {
            input = InpNameBe;
        } else if (c == QLatin1Char('=')) {
            input = InpEq;
        } else if (c == QLatin1Char('"')) {
            input = InpDq;
        } else if (c == QLatin1Char('\'')) {
            input = InpSq;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case PName:
                parseName_useRef = false;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
                    return false;
                }
                break;
            case Ws:
                if (!eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
                    return false;
                }
                break;
            case Eq:
                if (!next_eat_ws()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
                    return false;
                }
                break;
            case Quotes:
                if (!parseAttValue()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
                    return false;
                }
                break;
        }
    }
    return false;
}

/*
  Parse a Name [5] and store the name in name or ref (if useRef is true).
*/
bool QXmlSimpleReaderPrivate::parseName()
{
    const int Init             = 0;
    const int Name1            = 1; // parse first character of the name
    const int Name             = 2; // parse name
    const int Done             = 3;

    static const int table[3][3] = {
     /*  InpNameBe  InpNameCh  InpUnknown */
        { Name1,     -1,        -1    }, // Init
        { Name,      Name,      Done  }, // Name1
        { Name,      Name,      Done  }  // Name
    };
    int state;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseName (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseName, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseName, state);
            return false;
        }

        // we can safely do the (int) cast thanks to the Q_ASSERTs earlier in this function
        state = table[state][(int)fastDetermineNameChar(c)];

        switch (state) {
            case Name1:
                if (parseName_useRef) {
                    refClear();
                    refAddC();
                } else {
                    nameClear();
                    nameAddC();
                }
                next();
                break;
            case Name:
                if (parseName_useRef) {
                    refAddC();
                } else {
                    nameAddC();
                }
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a Nmtoken [7] and store the name in name.
*/
bool QXmlSimpleReaderPrivate::parseNmtoken()
{
    const signed char Init             = 0;
    const signed char NameF            = 1;
    const signed char Name             = 2;
    const signed char Done             = 3;

    const signed char InpNameCh        = 0; // NameChar without InpNameBe
    const signed char InpUnknown       = 1;

    static const signed char table[3][2] = {
     /*  InpNameCh  InpUnknown */
        { NameF,     -1    }, // Init
        { Name,      Done  }, // NameF
        { Name,      Done  }  // Name
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseNmtoken (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseNmtoken, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case Done:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseNmtoken, state);
            return false;
        }
        if (determineNameChar(c) == NotName) {
            input = InpUnknown;
        } else {
            input = InpNameCh;
        }
        state = table[state][input];

        switch (state) {
            case NameF:
                nameClear();
                nameAddC();
                next();
                break;
            case Name:
                nameAddC();
                next();
                break;
        }
    }
    return false;
}

/*
  Parse a Reference [67].

  parseReference_charDataRead is set to true if the reference must not be
  parsed. The character(s) which the reference mapped to are appended to
  string. The head stands on the first character after the reference.

  parseReference_charDataRead is set to false if the reference must be parsed.
  The charachter(s) which the reference mapped to are inserted at the reference
  position. The head stands on the first character of the replacement).
*/
bool QXmlSimpleReaderPrivate::parseReference()
{
    // temporary variables (only used in very local context, so they don't
    // interfere with incremental parsing)
    uint tmp;
    bool ok;

    const signed char Init             =  0;
    const signed char SRef             =  1; // start of a reference
    const signed char ChRef            =  2; // parse CharRef
    const signed char ChDec            =  3; // parse CharRef decimal
    const signed char ChHexS           =  4; // start CharRef hexadecimal
    const signed char ChHex            =  5; // parse CharRef hexadecimal
    const signed char Name             =  6; // parse name
    const signed char DoneD            =  7; // done CharRef decimal
    const signed char DoneH            =  8; // done CharRef hexadecimal
    const signed char DoneN            =  9; // done EntityRef

    const signed char InpAmp           = 0; // &
    const signed char InpSemi          = 1; // ;
    const signed char InpHash          = 2; // #
    const signed char InpX             = 3; // x
    const signed char InpNum           = 4; // 0-9
    const signed char InpHex           = 5; // a-f A-F
    const signed char InpUnknown       = 6;

    static const signed char table[8][7] = {
     /*  InpAmp  InpSemi  InpHash  InpX     InpNum  InpHex  InpUnknown */
        { SRef,   -1,      -1,      -1,      -1,     -1,     -1    }, // Init
        { -1,     -1,      ChRef,   Name,    Name,   Name,   Name  }, // SRef
        { -1,     -1,      -1,      ChHexS,  ChDec,  -1,     -1    }, // ChRef
        { -1,     DoneD,   -1,      -1,      ChDec,  -1,     -1    }, // ChDec
        { -1,     -1,      -1,      -1,      ChHex,  ChHex,  -1    }, // ChHexS
        { -1,     DoneH,   -1,      -1,      ChHex,  ChHex,  -1    }, // ChHex
        { -1,     DoneN,   -1,      -1,      -1,     -1,     -1    }  // Name
    };
    signed char state;
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        parseReference_charDataRead = false;
        state = Init;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseReference (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
                return false;
            }
        }
    }

    for (;;) {
        switch (state) {
            case DoneD:
                return true;
            case DoneH:
                return true;
            case DoneN:
                return true;
            case -1:
                // Error
                reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
                return false;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseReference, state);
            return false;
        }
        if        (c.row()) {
            input = InpUnknown;
        } else if (c.cell() == '&') {
            input = InpAmp;
        } else if (c.cell() == ';') {
            input = InpSemi;
        } else if (c.cell() == '#') {
            input = InpHash;
        } else if (c.cell() == 'x') {
            input = InpX;
        } else if ('0' <= c.cell() && c.cell() <= '9') {
            input = InpNum;
        } else if ('a' <= c.cell() && c.cell() <= 'f') {
            input = InpHex;
        } else if ('A' <= c.cell() && c.cell() <= 'F') {
            input = InpHex;
        } else {
            input = InpUnknown;
        }
        state = table[state][input];

        switch (state) {
            case SRef:
                refClear();
                next();
                break;
            case ChRef:
                next();
                break;
            case ChDec:
                refAddC();
                next();
                break;
            case ChHexS:
                next();
                break;
            case ChHex:
                refAddC();
                next();
                break;
            case Name:
                // read the name into the ref
                parseName_useRef = true;
                if (!parseName()) {
                    parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
                    return false;
                }
                break;
            case DoneD:
                tmp = ref().toUInt(&ok, 10);
                if (ok) {
                    stringAddC(QChar(tmp));
                } else {
                    reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
                    return false;
                }
                parseReference_charDataRead = true;
                next();
                break;
            case DoneH:
                tmp = ref().toUInt(&ok, 16);
                if (ok) {
                    stringAddC(QChar(tmp));
                } else {
                    reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
                    return false;
                }
                parseReference_charDataRead = true;
                next();
                break;
            case DoneN:
                if (!processReference())
                    return false;
                next();
                break;
        }
    }
    return false;
}

/*
  Helper function for parseReference()
*/
bool QXmlSimpleReaderPrivate::processReference()
{
    QString reference = ref();
    if (reference == QLatin1String("amp")) {
        if (parseReference_context == InEntityValue) {
            // Bypassed
            stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('m')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char(';'));
        } else {
            // Included or Included in literal
            stringAddC(QLatin1Char('&'));
        }
        parseReference_charDataRead = true;
    } else if (reference == QLatin1String("lt")) {
        if (parseReference_context == InEntityValue) {
            // Bypassed
            stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('l')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
        } else {
            // Included or Included in literal
            stringAddC(QLatin1Char('<'));
        }
        parseReference_charDataRead = true;
    } else if (reference == QLatin1String("gt")) {
        if (parseReference_context == InEntityValue) {
            // Bypassed
            stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('g')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
        } else {
            // Included or Included in literal
            stringAddC(QLatin1Char('>'));
        }
        parseReference_charDataRead = true;
    } else if (reference == QLatin1String("apos")) {
        if (parseReference_context == InEntityValue) {
            // Bypassed
            stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('s')); stringAddC(QLatin1Char(';'));
        } else {
            // Included or Included in literal
            stringAddC(QLatin1Char('\''));
        }
        parseReference_charDataRead = true;
    } else if (reference == QLatin1String("quot")) {
        if (parseReference_context == InEntityValue) {
            // Bypassed
            stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('q')); stringAddC(QLatin1Char('u')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
        } else {
            // Included or Included in literal
            stringAddC(QLatin1Char('"'));
        }
        parseReference_charDataRead = true;
    } else {
        QMap<QString,QString>::Iterator it;
        it = entities.find(reference);
        if (it != entities.end()) {
            // "Internal General"
            switch (parseReference_context) {
                case InContent:
                    // Included
                    if (!insertXmlRef(*it, reference, false))
                        return false;
                    parseReference_charDataRead = false;
                    break;
                case InAttributeValue:
                    // Included in literal
                    if (!insertXmlRef(*it, reference, true))
                        return false;
                    parseReference_charDataRead = false;
                    break;
                case InEntityValue:
                    {
                        // Bypassed
                        stringAddC(QLatin1Char('&'));
                        for (int i=0; i<(int)reference.length(); i++) {
                            stringAddC(reference[i]);
                        }
                        stringAddC(QLatin1Char(';'));
                        parseReference_charDataRead = true;
                    }
                    break;
                case InDTD:
                    // Forbidden
                    parseReference_charDataRead = false;
                    reportParseError(QLatin1String(XMLERR_INTERNALGENERALENTITYINDTD));
                    return false;
            }
        } else {
            QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
            itExtern = externEntities.find(reference);
            if (itExtern == externEntities.end()) {
                // entity not declared
                // ### check this case for conformance
                if (parseReference_context == InEntityValue) {
                    // Bypassed
                    stringAddC(QLatin1Char('&'));
                    for (int i=0; i<(int)reference.length(); i++) {
                        stringAddC(reference[i]);
                    }
                    stringAddC(QLatin1Char(';'));
                    parseReference_charDataRead = true;
                } else {
                    // if we have some char data read, report it now
                    if (parseReference_context == InContent) {
                        if (contentCharDataRead) {
                            if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
                                if (contentHnd != nullptr && !contentHnd->characters(string())) {
                                    reportParseError(contentHnd->errorString());
                                    return false;
                                }
                            }
                            stringClear();
                            contentCharDataRead = false;
                        }
                    }

                    if (contentHnd) {
                        skipped_entity_in_content = parseReference_context == InContent;
                        if (!contentHnd->skippedEntity(reference)) {
                            skipped_entity_in_content = false;
                            reportParseError(contentHnd->errorString());
                            return false; // error
                        }
                        skipped_entity_in_content = false;
                    }
                }
            } else if ((*itExtern).notation.isNull()) {
                // "External Parsed General"
                switch (parseReference_context) {
                    case InContent:
                        {
                            // Included if validating
                            bool skipIt = true;
                            if (entityRes) {
                                QXmlInputSource *ret = nullptr;
                                if (!entityRes->resolveEntity((*itExtern).publicId, (*itExtern).systemId, ret)) {
                                    delete ret;
                                    reportParseError(entityRes->errorString());
                                    return false;
                                }
                                if (ret) {
                                    QString xmlRefString;
                                    QString buffer = ret->data();
                                    while (!buffer.isEmpty()) {
                                        xmlRefString += buffer;
                                        ret->fetchData();
                                        buffer = ret->data();
                                    }

                                    delete ret;
                                    if (!stripTextDecl(xmlRefString)) {
                                        reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
                                        return false;
                                    }
                                    if (!insertXmlRef(xmlRefString, reference, false))
                                        return false;
                                    skipIt = false;
                                }
                            }
                            if (skipIt && contentHnd) {
                                skipped_entity_in_content = true;
                                if (!contentHnd->skippedEntity(reference)) {
                                    skipped_entity_in_content = false;
                                    reportParseError(contentHnd->errorString());
                                    return false; // error
                                }
                                skipped_entity_in_content = false;
                            }
                            parseReference_charDataRead = false;
                        } break;
                    case InAttributeValue:
                        // Forbidden
                        parseReference_charDataRead = false;
                        reportParseError(QLatin1String(XMLERR_EXTERNALGENERALENTITYINAV));
                        return false;
                    case InEntityValue:
                        {
                            // Bypassed
                            stringAddC(QLatin1Char('&'));
                            for (int i=0; i<(int)reference.length(); i++) {
                                stringAddC(reference[i]);
                            }
                            stringAddC(QLatin1Char(';'));
                            parseReference_charDataRead = true;
                        }
                        break;
                    case InDTD:
                        // Forbidden
                        parseReference_charDataRead = false;
                        reportParseError(QLatin1String(XMLERR_EXTERNALGENERALENTITYINDTD));
                        return false;
                }
            } else {
                // "Unparsed"
                // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
                // Forbidden
                parseReference_charDataRead = false;
                reportParseError(QLatin1String(XMLERR_UNPARSEDENTITYREFERENCE));
                return false; // error
            }
        }
    }
    return true; // no error
}


/*
  Parses over a simple string.

  After the string was successfully parsed, the head is on the first
  character after the string.
*/
bool QXmlSimpleReaderPrivate::parseString()
{
    const signed char InpCharExpected  = 0; // the character that was expected
    const signed char InpUnknown       = 1;

    signed char state; // state in this function is the position in the string s
    signed char input;

    if (parseStack == nullptr || parseStack->isEmpty()) {
        Done = parseString_s.length();
        state = 0;
    } else {
        state = parseStack->pop().state;
#if defined(QT_QXML_DEBUG)
        qDebug("QXmlSimpleReader: parseString (cont) in state %d", state);
#endif
        if (!parseStack->isEmpty()) {
            ParseFunction function = parseStack->top().function;
            if (function == &QXmlSimpleReaderPrivate::eat_ws) {
                parseStack->pop();
#if defined(QT_QXML_DEBUG)
                qDebug("QXmlSimpleReader: eat_ws (cont)");
#endif
            }
            if (!(this->*function)()) {
                parseFailed(&QXmlSimpleReaderPrivate::parseString, state);
                return false;
            }
        }
    }

    for (;;) {
        if (state == Done) {
            return true;
        }

        if (atEnd()) {
            unexpectedEof(&QXmlSimpleReaderPrivate::parseString, state);
            return false;
        }
        if (c == parseString_s[(int)state]) {
            input = InpCharExpected;
        } else {
            input = InpUnknown;
        }
        if (input == InpCharExpected) {
            state++;
        } else {
            // Error
            reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
            return false;
        }

        next();
    }
    return false;
}

/*
  This private function inserts and reports an entity substitution. The
  substituted string is \a data and the name of the entity reference is \a
  name. If \a inLiteral is true, the entity is IncludedInLiteral (i.e., " and '
  must be quoted. Otherwise they are not quoted.

  This function returns \c false on error.
*/
bool QXmlSimpleReaderPrivate::insertXmlRef(const QString &data, const QString &name, bool inLiteral)
{
    if (inLiteral) {
        QString tmp = data;
        xmlRefStack.push(XmlRef(name, tmp.replace(QLatin1Char('\"'),
                            QLatin1String("&quot;")).replace(QLatin1Char('\''), QLatin1String("&apos;"))));
    } else {
        xmlRefStack.push(XmlRef(name, data));
    }
    int n = qMax(parameterEntities.count(), entities.count());
    if (xmlRefStack.count() > n+1) {
        // recursive entities
        reportParseError(QLatin1String(XMLERR_RECURSIVEENTITIES));
        return false;
    }
    if (reportEntities && lexicalHnd) {
        if (!lexicalHnd->startEntity(name)) {
            reportParseError(lexicalHnd->errorString());
            return false;
        }
    }
    return true;
}

/*
  This private function moves the cursor to the next character.
*/
void QXmlSimpleReaderPrivate::next()
{
    int count = xmlRefStack.size();
    while (count != 0) {
        if (xmlRefStack.top().isEmpty()) {
            xmlRefStack.pop_back();
            count--;
        } else {
            c = xmlRefStack.top().next();
            return;
        }
    }

    // the following could be written nicer, but since it is a time-critical
    // function, rather optimize for speed
    ushort uc = c.unicode();
    c = inputSource->next();
    // If we are not incremental parsing, we just skip over EndOfData chars to give the
    // parser an uninterrupted stream of document chars.
    if (c == QChar(QXmlInputSource::EndOfData) && parseStack == nullptr)
        c = inputSource->next();
    if (uc == '\n') {
        lineNr++;
        columnNr = -1;
    } else if (uc == '\r') {
        if (c != QLatin1Char('\n')) {
            lineNr++;
            columnNr = -1;
        }
    }
    ++columnNr;
}

/*
  This private function moves the cursor to the next non-whitespace character.
  This function does not move the cursor if the actual cursor position is a
  non-whitespace charcter.

  Returns \c false when you use incremental parsing and this function reaches EOF
  with reading only whitespace characters. In this case it also poplulates the
  parseStack with useful information. In all other cases, this function returns
  true.
*/
bool QXmlSimpleReaderPrivate::eat_ws()
{
    while (!atEnd()) {
        if (!is_S(c)) {
            return true;
        }
        next();
    }
    if (parseStack != nullptr) {
        unexpectedEof(&QXmlSimpleReaderPrivate::eat_ws, 0);
        return false;
    }
    return true;
}

bool QXmlSimpleReaderPrivate::next_eat_ws()
{
    next();
    return eat_ws();
}


/*
  This private function initializes the reader. \a i is the input source to
  read the data from.
*/
void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i)
{
    lineNr = 0;
    columnNr = -1;
    inputSource = const_cast<QXmlInputSource *>(i);
    initData();

    externParameterEntities.clear();
    parameterEntities.clear();
    externEntities.clear();
    entities.clear();

    clear(tags);

    doctype.clear();
    xmlVersion.clear();
    encoding.clear();
    standalone = QXmlSimpleReaderPrivate::Unknown;
    error.clear();
}

/*
  This private function initializes the XML data related variables. Especially,
  it reads the data from the input source.
*/
void QXmlSimpleReaderPrivate::initData()
{
    c = QChar(QXmlInputSource::EndOfData);
    xmlRefStack.clear();
    next();
}

/*
  Returns \c true if a entity with the name \a e exists,
  otherwise returns \c false.
*/
bool QXmlSimpleReaderPrivate::entityExist(const QString& e) const
{
    if ( parameterEntities.find(e) == parameterEntities.end() &&
          externParameterEntities.find(e) == externParameterEntities.end() &&
          externEntities.find(e) == externEntities.end() &&
          entities.find(e) == entities.end()) {
        return false;
    } else {
        return true;
    }
}

void QXmlSimpleReaderPrivate::reportParseError(const QString& error)
{
    this->error = error;
    if (errorHnd) {
        if (this->error.isNull()) {
            const QXmlParseException ex(QLatin1String(XMLERR_OK), columnNr+1, lineNr+1,
                                        thisPublicId, thisSystemId);
            errorHnd->fatalError(ex);
        } else {
            const QXmlParseException ex(this->error, columnNr+1, lineNr+1,
                                        thisPublicId, thisSystemId);
            errorHnd->fatalError(ex);
        }
    }
}

/*
  This private function is called when a parsing function encounters an
  unexpected EOF. It decides what to do (depending on incremental parsing or
  not). \a where is a pointer to the function where the error occurred and \a
  state is the parsing state in this function.
*/
void QXmlSimpleReaderPrivate::unexpectedEof(ParseFunction where, int state)
{
    if (parseStack == nullptr) {
        reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
    } else {
        if (c == QChar(QXmlInputSource::EndOfDocument)) {
            reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
        } else {
            pushParseState(where, state);
        }
    }
}

/*
  This private function is called when a parse...() function returned false. It
  determines if there was an error or if incremental parsing simply went out of
  data and does the right thing for the case. \a where is a pointer to the
  function where the error occurred and \a state is the parsing state in this
  function.
*/
void QXmlSimpleReaderPrivate::parseFailed(ParseFunction where, int state)
{
    if (parseStack != nullptr && error.isNull()) {
        pushParseState(where, state);
    }
}

/*
  This private function pushes the function pointer \a function and state \a
  state to the parse stack. This is used when you are doing an incremental
  parsing and reach the end of file too early.

  Only call this function when d->parseStack!=0.
*/
void QXmlSimpleReaderPrivate::pushParseState(ParseFunction function, int state)
{
    QXmlSimpleReaderPrivate::ParseState ps;
    ps.function = function;
    ps.state = state;
    parseStack->push(ps);
}

inline static void updateValue(QString &value, const QChar *array, int &arrayPos, int &valueLen)
{
    value.resize(valueLen + arrayPos);
    memcpy(value.data() + valueLen, array, arrayPos * sizeof(QChar));
    valueLen += arrayPos;
    arrayPos = 0;
}

// use buffers instead of QString::operator+= when single characters are read
const QString& QXmlSimpleReaderPrivate::string()
{
    updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
    return stringValue;
}
const QString& QXmlSimpleReaderPrivate::name()
{
    updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
    return nameValue;
}
const QString& QXmlSimpleReaderPrivate::ref()
{
    updateValue(refValue, refArray, refArrayPos, refValueLen);
    return refValue;
}

void QXmlSimpleReaderPrivate::stringAddC(QChar ch)
{
    if (stringArrayPos == 256)
        updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
    stringArray[stringArrayPos++] = ch;
}
void QXmlSimpleReaderPrivate::nameAddC(QChar ch)
{
    if (nameArrayPos == 256)
        updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
    nameArray[nameArrayPos++] = ch;
}
void QXmlSimpleReaderPrivate::refAddC(QChar ch)
{
    if (refArrayPos == 256)
        updateValue(refValue, refArray, refArrayPos, refValueLen);
    refArray[refArrayPos++] = ch;
}
QT_END_NAMESPACE
