/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the QtXml module of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
#include "qxml.h"+ −
#include "qtextcodec.h"+ −
#include "qbuffer.h"+ −
#include "qregexp.h"+ −
#include "qmap.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+ −
+ −
// 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;+ −
+ −
// Hack for letting QDom know where the skipped entity occurred+ −
// ### Qt5: the use of this variable means the code isn't reentrant.+ −
bool qt_xml_skipped_entity_in_content;+ −
+ −
// 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 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)+ −
{+ −
QString textDeclStart(QLatin1String("<?xml"));+ −
if (str.startsWith(textDeclStart)) {+ −
QRegExp 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;+ −
}+ −
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;+ −
#ifndef QT_NO_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 QXmlSimpleReaderPrivate+ −
{+ −
public:+ −
~QXmlSimpleReaderPrivate();+ −
private:+ −
// functions+ −
QXmlSimpleReaderPrivate(QXmlSimpleReader *reader);+ −
void initIncrementalParsing();+ −
+ −
// used to determine if elements are correctly nested+ −
QStack<QString> tags;+ −
+ −
// used by parseReference() and parsePEReference()+ −
enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };+ −
+ −
// used for entity declarations+ −
struct ExternParameterEntity+ −
{+ −
ExternParameterEntity() {}+ −
ExternParameterEntity(const QString &p, const QString &s)+ −
: publicId(p), systemId(s) {}+ −
QString publicId;+ −
QString systemId;+ −
+ −
Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity)+ −
};+ −
struct ExternEntity+ −
{+ −
ExternEntity() {}+ −
ExternEntity(const QString &p, const QString &s, const QString &n)+ −
: publicId(p), systemId(s), notation(n) {}+ −
QString publicId;+ −
QString systemId;+ −
QString notation;+ −
Q_DUMMY_COMPARISON_OPERATOR(ExternEntity)+ −
};+ −
QMap<QString,ExternParameterEntity> externParameterEntities;+ −
QMap<QString,QString> parameterEntities;+ −
QMap<QString,ExternEntity> externEntities;+ −
QMap<QString,QString> entities;+ −
+ −
// used for parsing of entity references+ −
struct XmlRef {+ −
XmlRef()+ −
: index(0) {}+ −
XmlRef(const QString &_name, const QString &_value)+ −
: name(_name), value(_value), index(0) {}+ −
bool isEmpty() const { return index == value.length(); }+ −
QChar next() { return value.at(index++); }+ −
QString name;+ −
QString value;+ −
int index;+ −
};+ −
QStack<XmlRef> xmlRefStack;+ −
+ −
// used for standalone declaration+ −
enum Standalone { Yes, No, Unknown };+ −
+ −
QString doctype; // only used for the doctype+ −
QString xmlVersion; // only used to store the version information+ −
QString encoding; // only used to store the encoding+ −
Standalone standalone; // used to store the value of the standalone declaration+ −
+ −
QString publicId; // used by parseExternalID() to store the public ID+ −
QString systemId; // used by parseExternalID() to store the system ID+ −
+ −
// Since publicId/systemId is used as temporary variables by parseExternalID(), it+ −
// might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would+ −
// possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration+ −
// instead of those of the current document.+ −
// Hence we have these two variables for storing the document's data.+ −
QString thisPublicId;+ −
QString thisSystemId;+ −
+ −
QString attDeclEName; // use by parseAttlistDecl()+ −
QString attDeclAName; // use by parseAttlistDecl()+ −
+ −
// flags for some features support+ −
bool useNamespaces;+ −
bool useNamespacePrefixes;+ −
bool reportWhitespaceCharData;+ −
bool reportEntities;+ −
+ −
// used to build the attribute list+ −
QXmlAttributes attList;+ −
+ −
// used in QXmlSimpleReader::parseContent() to decide whether character+ −
// data was read+ −
bool contentCharDataRead;+ −
+ −
// helper classes+ −
QScopedPointer<QXmlLocator> locator;+ −
QXmlNamespaceSupport namespaceSupport;+ −
+ −
// error string+ −
QString error;+ −
+ −
// arguments for parse functions (this is needed to allow incremental+ −
// parsing)+ −
bool parsePI_xmldecl;+ −
bool parseName_useRef;+ −
bool parseReference_charDataRead;+ −
EntityRecognitionContext parseReference_context;+ −
bool parseExternalID_allowPublicID;+ −
EntityRecognitionContext parsePEReference_context;+ −
QString parseString_s;+ −
+ −
// for incremental parsing+ −
struct ParseState {+ −
typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)();+ −
ParseFunction function;+ −
int state;+ −
};+ −
QStack<ParseState> *parseStack;+ −
+ −
// used in parseProlog()+ −
bool xmldecl_possible;+ −
bool doctype_read;+ −
+ −
// used in parseDoctype()+ −
bool startDTDwasReported;+ −
+ −
// used in parseString()+ −
signed char Done;+ −
+ −
+ −
// variables+ −
QXmlContentHandler *contentHnd;+ −
QXmlErrorHandler *errorHnd;+ −
QXmlDTDHandler *dtdHnd;+ −
QXmlEntityResolver *entityRes;+ −
QXmlLexicalHandler *lexicalHnd;+ −
QXmlDeclHandler *declHnd;+ −
+ −
QXmlInputSource *inputSource;+ −
+ −
QChar c; // the character at reading position+ −
int lineNr; // number of line+ −
int columnNr; // position in line+ −
+ −
QChar nameArray[256]; // only used for names+ −
QString nameValue; // only used for names+ −
int nameArrayPos;+ −
int nameValueLen;+ −
QChar refArray[256]; // only used for references+ −
QString refValue; // only used for references+ −
int refArrayPos;+ −
int refValueLen;+ −
QChar stringArray[256]; // used for any other strings that are parsed+ −
QString stringValue; // used for any other strings that are parsed+ −
int stringArrayPos;+ −
int stringValueLen;+ −
QString emptyStr;+ −
+ −
const QString &string();+ −
void stringClear();+ −
void stringAddC(QChar);+ −
inline void stringAddC() { stringAddC(c); }+ −
const QString &name();+ −
void nameClear();+ −
void nameAddC(QChar);+ −
inline void nameAddC() { nameAddC(c); }+ −
const QString &ref();+ −
void refClear();+ −
void refAddC(QChar);+ −
inline void refAddC() { refAddC(c); }+ −
+ −
// private functions+ −
bool eat_ws();+ −
bool next_eat_ws();+ −
+ −
void QT_FASTCALL next();+ −
bool atEnd();+ −
+ −
void init(const QXmlInputSource* i);+ −
void initData();+ −
+ −
bool entityExist(const QString&) const;+ −
+ −
bool parseBeginOrContinue(int state, bool incremental);+ −
+ −
bool parseProlog();+ −
bool parseElement();+ −
bool processElementEmptyTag();+ −
bool processElementETagBegin2();+ −
bool processElementAttribute();+ −
bool parseMisc();+ −
bool parseContent();+ −
+ −
bool parsePI();+ −
bool parseDoctype();+ −
bool parseComment();+ −
+ −
bool parseName();+ −
bool parseNmtoken();+ −
bool parseAttribute();+ −
bool parseReference();+ −
bool processReference();+ −
+ −
bool parseExternalID();+ −
bool parsePEReference();+ −
bool parseMarkupdecl();+ −
bool parseAttlistDecl();+ −
bool parseAttType();+ −
bool parseAttValue();+ −
bool parseElementDecl();+ −
bool parseNotationDecl();+ −
bool parseChoiceSeq();+ −
bool parseEntityDecl();+ −
bool parseEntityValue();+ −
+ −
bool parseString();+ −
+ −
bool insertXmlRef(const QString&, const QString&, bool);+ −
+ −
bool reportEndEntities();+ −
void reportParseError(const QString& error);+ −
+ −
typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) ();+ −
void unexpectedEof(ParseFunction where, int state);+ −
void parseFailed(ParseFunction where, int state);+ −
void pushParseState(ParseFunction function, int state);+ −
+ −
Q_DECLARE_PUBLIC(QXmlSimpleReader)+ −
QXmlSimpleReader *q_ptr;+ −
+ −
friend class QXmlSimpleReaderLocator;+ −
};+ −
+ −
/*!+ −
\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+ −
\o "no error occurred"+ −
\o "error triggered by consumer"+ −
\o "unexpected end of file"+ −
\o "more than one document type definition"+ −
\o "error occurred while parsing element"+ −
\o "tag mismatch"+ −
\o "error occurred while parsing content"+ −
\o "unexpected character"+ −
\o "invalid name for processing instruction"+ −
\o "version expected while reading the XML declaration"+ −
\o "wrong value for standalone declaration"+ −
\o "encoding declaration or standalone declaration expected while reading the XML declaration"+ −
\o "standalone declaration expected while reading the XML declaration"+ −
\o "error occurred while parsing document type definition"+ −
\o "letter is expected"+ −
\o "error occurred while parsing comment"+ −
\o "error occurred while parsing reference"+ −
\o "internal general entity reference not allowed in DTD"+ −
\o "external parsed general entity reference not allowed in attribute value"+ −
\o "external parsed general entity reference not allowed in DTD"+ −
\o "unparsed entity reference n wrong context"+ −
\o "recursive entities"+ −
\o "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+ −
{+ −
return (reader->d_ptr->columnNr == -1 ? -1 : reader->d_ptr->columnNr + 1);+ −
}+ −
int lineNumber() const+ −
{+ −
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.+ −
*/+ −
+ −
/*!+ −
\fn QXmlAttributes::~QXmlAttributes()+ −
+ −
Destroys the attributes object.+ −
*/+ −
+ −
/*!+ −
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(const 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(const 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 = 0;+ −
d->inputStream = 0;+ −
+ −
setData(QString());+ −
#ifndef QT_NO_TEXTCODEC+ −
d->encMapper = 0;+ −
#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;+ −
d->inputDevice->setTextModeEnabled(false);+ −
}+ −
+ −
#ifdef QT3_SUPPORT+ −
/*!+ −
Use the QXmlInputSource(QIODevice *) constructor instead, with+ −
the device used by \a stream.+ −
+ −
\sa QTextStream::device()+ −
*/+ −
QXmlInputSource::QXmlInputSource(QTextStream& stream)+ −
{+ −
init();+ −
d->inputStream = &stream;+ −
}+ −
+ −
/*!+ −
Use QXmlInputSource(&\a file) instead.+ −
*/+ −
QXmlInputSource::QXmlInputSource(QFile& file)+ −
{+ −
init();+ −
d->inputDevice = &file;+ −
}+ −
#endif+ −
+ −
/*!+ −
Destructor.+ −
*/+ −
QXmlInputSource::~QXmlInputSource()+ −
{+ −
// ### Qt 5: close the input device. See task 153111+ −
#ifndef QT_NO_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 EndOfDocument;+ −
}+ −
return next();+ −
}+ −
d->nextReturnedEndOfData = true;+ −
return 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 = 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 != -1) {+ −
// We don't want to give fromRawData() less than four bytes if we can avoid it.+ −
while (size < 4) {+ −
if (!device->waitForReadyRead(-1))+ −
break;+ −
int ret = device->read(rawData.data() + size, BufferSize - size);+ −
if (ret <= 0)+ −
break;+ −
size += ret;+ −
}+ −
}+ −
+ −
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));+ −
}+ −
}+ −
+ −
#ifndef QT_NO_TEXTCODEC+ −
static QString extractEncodingDecl(const QString &text, bool *needMoreText)+ −
{+ −
*needMoreText = false;+ −
+ −
int l = text.length();+ −
QString snip = QString::fromLatin1("<?xml").left(l);+ −
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) {+ −
ushort uc = text.at(pos).unicode();+ −
if (uc == '\'' || uc == '"')+ −
break;+ −
++pos;+ −
}+ −
+ −
if (pos == endPos)+ −
return QString();+ −
+ −
QString encoding;+ −
++pos;+ −
while (pos < endPos) {+ −
ushort uc = text.at(pos).unicode();+ −
if (uc == '\'' || uc == '"')+ −
break;+ −
encoding.append(uc);+ −
++pos;+ −
}+ −
+ −
return encoding;+ −
}+ −
#endif // QT_NO_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)+ −
{+ −
#ifdef QT_NO_TEXTCODEC+ −
Q_UNUSED(beginning);+ −
return QString::fromAscii(data.constData(), data.size());+ −
#else+ −
if (data.size() == 0)+ −
return QString();+ −
if (beginning) {+ −
delete d->encMapper;+ −
d->encMapper = 0;+ −
}+ −
+ −
int mib = 106; // UTF-8+ −
+ −
// This is the initial UTF codec we will read the encoding declaration with+ −
if (d->encMapper == 0) {+ −
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, data.size());+ −
+ −
if (d->lookingForEncodingDecl) {+ −
d->encodingDeclChars += input;+ −
+ −
bool needMoreText;+ −
QString encoding = extractEncodingDecl(d->encodingDeclChars, &needMoreText);+ −
+ −
if (!encoding.isEmpty()) {+ −
if (QTextCodec *codec = QTextCodec::codecForName(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, d->encodingDeclBytes.size());+ −
// now feed it the new data+ −
input = d->encMapper->toUnicode(data, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 doc/src/snippets/xml/rsslisting/rsslisting.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 doc/src/snippets/xml/rsslisting/handler.cpp 0+ −
+ −
The above function returns 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.+ −
*/+ −
/*!+ −
\fn QXmlDefaultHandler::~QXmlDefaultHandler()+ −
+ −
Destroys the handler.+ −
*/+ −
+ −
/*!+ −
\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 0, so that the reader uses the system identifier+ −
provided in the XML document.+ −
*/+ −
bool QXmlDefaultHandler::resolveEntity(const QString&, const QString&,+ −
QXmlInputSource*& ret)+ −
{+ −
ret = 0;+ −
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 = 0;+ −
+ −
locator.reset(new QXmlSimpleReaderLocator(reader));+ −
entityRes = 0;+ −
dtdHnd = 0;+ −
contentHnd = 0;+ −
errorHnd = 0;+ −
lexicalHnd = 0;+ −
declHnd = 0;+ −
+ −
// 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 \link+ −
http://www.saxproject.org/ SAX2 Java interface\endlink, 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 0: \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 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 0: 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 true if the reader has the property \a name; otherwise+ −
returns 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 0 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 0 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 0 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 0 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 0 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 0 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 true if+ −
the parsing was successful; otherwise returns 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 doc/src/snippets/xml/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 doc/src/snippets/xml/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 doc/src/snippets/xml/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 doc/src/snippets/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();+ −
+ −
// Qt5 ###: Change these strings to qt.nokia.com+ −
if (ok != 0)+ −
*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")) { // Shouldn't change in Qt 4+ −
return d->reportWhitespaceCharData;+ −
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4+ −
return d->reportEntities;+ −
} else {+ −
qWarning("Unknown feature %s", name.toLatin1().data());+ −
if (ok != 0)+ −
*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 \i Feature \i Default \i Notes+ −
\row \i \e http://xml.org/sax/features/namespaces+ −
\i true+ −
\i If enabled, namespaces are reported to the content handler.+ −
\row \i \e http://xml.org/sax/features/namespace-prefixes+ −
\i false+ −
\i If enabled, the original prefixed names+ −
and attributes used for namespace declarations are+ −
reported.+ −
\row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData+ −
\i true+ −
\i If enabled, CharData that consist of+ −
only whitespace characters are reported+ −
using QXmlContentHandler::characters(). If disabled, whitespace is silently+ −
discarded.+ −
\row \i \e http://trolltech.com/xml/features/report-start-end-entity+ −
\i false+ −
\i 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);+ −
// Qt5 ###: Change these strings to qt.nokia.com+ −
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")) { // Shouldn't change in Qt 4+ −
d->reportWhitespaceCharData = enable;+ −
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4+ −
d->reportEntities = enable;+ −
} else {+ −
qWarning("Unknown feature %s", name.toLatin1().data());+ −
}+ −
}+ −
+ −
/*! \reimp+ −
*/+ −
bool QXmlSimpleReader::hasFeature(const QString& name) const+ −
{+ −
// Qt5 ###: Change these strings to qt.nokia.com+ −
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") // Shouldn't change in Qt 4+ −
|| name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4+ −
return true;+ −
} else {+ −
return false;+ −
}+ −
}+ −
+ −
/*! \reimp+ −
*/+ −
void* QXmlSimpleReader::property(const QString&, bool *ok) const+ −
{+ −
if (ok != 0)+ −
*ok = false;+ −
return 0;+ −
}+ −
+ −
/*! \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 true if the parsing was successful; otherwise returns false.+ −
*/+ −
bool QXmlSimpleReader::parse(const QXmlInputSource* input)+ −
{+ −
return parse(input, false);+ −
}+ −
+ −
/*!+ −
Reads an XML document from \a input and parses it. Returns true+ −
if the parsing is completed successfully; otherwise returns 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);+ −
+ −
if (incremental) {+ −
d->initIncrementalParsing();+ −
} else {+ −
delete d->parseStack;+ −
d->parseStack = 0;+ −
}+ −
d->init(input);+ −
+ −
// call the handler+ −
if (d->contentHnd) {+ −
d->contentHnd->setDocumentLocator(d->locator.data());+ −
if (!d->contentHnd->startDocument()) {+ −
d->reportParseError(d->contentHnd->errorString());+ −
d->tags.clear();+ −
return false;+ −
}+ −
}+ −
qt_xml_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 false if a parsing error occurs; otherwise returns 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 == 0 || 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(0, 0);+ −
return true;+ −
} else {+ −
tags.clear();+ −
return false;+ −
}+ −
}+ −
state = 1;+ −
}+ −
if (state==1) {+ −
if (!parseElement()) {+ −
if (incremental && error.isNull()) {+ −
pushParseState(0, 1);+ −
return true;+ −
} else {+ −
tags.clear();+ −
return false;+ −
}+ −
}+ −
state = 2;+ −
}+ −
// parse Misc*+ −
while (!atEnd()) {+ −
if (!parseMisc()) {+ −
if (incremental && error.isNull()) {+ −
pushParseState(0, 2);+ −
return true;+ −
} else {+ −
tags.clear();+ −
return false;+ −
}+ −
}+ −
}+ −
if (!atEndOrig && incremental) {+ −
// we parsed something at all, so be prepared to come back later+ −
pushParseState(0, 2);+ −
return true;+ −
}+ −
// is stack empty?+ −
if (!tags.isEmpty() && !error.isNull()) {+ −
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));+ −
tags.clear();+ −
return false;+ −
}+ −
// call the handler+ −
if (contentHnd) {+ −
delete parseStack;+ −
parseStack = 0;+ −
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 == 0 || 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 == 0 || 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 == 0 || 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) {+ −
const QString &tagsTop = tags.top();+ −
if (useNamespaces) {+ −
QString uri, lname;+ −
namespaceSupport.processName(tagsTop, false, uri, lname);+ −
if (!contentHnd->startElement(uri, lname, tagsTop, attList)) {+ −
reportParseError(contentHnd->errorString());+ −
return false;+ −
}+ −
} else {+ −
if (!contentHnd->startElement(QString(), QString(), tagsTop, 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.isEmpty()) {+ −
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...+ −
if (!contentHnd->endElement(uri, lname, tags.pop())) {+ −
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+ −
if (!contentHnd->endElement(QString(), QString(), tags.pop())) {+ −
reportParseError(contentHnd->errorString());+ −
return false;+ −
}+ −
}+ −
} else {+ −
tags.pop_back();+ −
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+ −
if (tags.pop() != name) {+ −
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 == 0 || 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==0 || 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==0 || 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==0 || 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 (!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==0 || 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==0 || 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==0 || 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 = 0;+ −
if (it2 != externParameterEntities.end()) {+ −
if (!entityRes->resolveEntity((*it2).publicId, (*it2).systemId, ret)) {+ −
delete ret;+ −
reportParseError(entityRes->errorString());+ −
return false;+ −
}+ −
if (ret) {+ −
xmlRefString = 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==0 || 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==0 || 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==0 || 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==0 || 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==0 || 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==0 || 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;+ −
}+ −
+ −
/*+ −
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==0 || 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())) {+ −
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==0 || 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==0 || 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==0 || 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==0 || 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==0 || 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==0 || 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 != 0 && !contentHnd->characters(string())) {+ −
reportParseError(contentHnd->errorString());+ −
return false;+ −
}+ −
}+ −
stringClear();+ −
contentCharDataRead = false;+ −
}+ −
}+ −
+ −
if (contentHnd) {+ −
qt_xml_skipped_entity_in_content = parseReference_context == InContent;+ −
if (!contentHnd->skippedEntity(reference)) {+ −
qt_xml_skipped_entity_in_content = false;+ −
reportParseError(contentHnd->errorString());+ −
return false; // error+ −
}+ −
qt_xml_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 = 0;+ −
if (!entityRes->resolveEntity((*itExtern).publicId, (*itExtern).systemId, ret)) {+ −
delete ret;+ −
reportParseError(entityRes->errorString());+ −
return false;+ −
}+ −
if (ret) {+ −
QString xmlRefString = 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) {+ −
qt_xml_skipped_entity_in_content = true;+ −
if (!contentHnd->skippedEntity(reference)) {+ −
qt_xml_skipped_entity_in_content = false;+ −
reportParseError(contentHnd->errorString());+ −
return false; // error+ −
}+ −
qt_xml_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==0 || 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 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(""")).replace(QLatin1Char('\''), QLatin1String("'"))));+ −
} 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 == QXmlInputSource::EndOfData && parseStack == 0)+ −
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 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 != 0) {+ −
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();+ −
+ −
tags.clear();+ −
+ −
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 = QXmlInputSource::EndOfData;+ −
xmlRefStack.clear();+ −
next();+ −
}+ −
+ −
/*+ −
Returns true if a entity with the name \a e exists,+ −
otherwise returns 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 == 0) {+ −
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));+ −
} else {+ −
if (c == 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!=0 && 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+ −