0
+ − 1
/****************************************************************************
+ − 2
**
+ − 3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ − 4
** All rights reserved.
+ − 5
** Contact: Nokia Corporation (qt-info@nokia.com)
+ − 6
**
+ − 7
** This file is part of the QtXml module of the Qt Toolkit.
+ − 8
**
+ − 9
** $QT_BEGIN_LICENSE:LGPL$
+ − 10
** No Commercial Usage
+ − 11
** This file contains pre-release code and may not be distributed.
+ − 12
** You may use this file in accordance with the terms and conditions
+ − 13
** contained in the Technology Preview License Agreement accompanying
+ − 14
** this package.
+ − 15
**
+ − 16
** GNU Lesser General Public License Usage
+ − 17
** Alternatively, this file may be used under the terms of the GNU Lesser
+ − 18
** General Public License version 2.1 as published by the Free Software
+ − 19
** Foundation and appearing in the file LICENSE.LGPL included in the
+ − 20
** packaging of this file. Please review the following information to
+ − 21
** ensure the GNU Lesser General Public License version 2.1 requirements
+ − 22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ − 23
**
+ − 24
** In addition, as a special exception, Nokia gives you certain additional
+ − 25
** rights. These rights are described in the Nokia Qt LGPL Exception
+ − 26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ − 27
**
+ − 28
** If you have questions regarding the use of this file, please contact
+ − 29
** Nokia at qt-info@nokia.com.
+ − 30
**
+ − 31
**
+ − 32
**
+ − 33
**
+ − 34
**
+ − 35
**
+ − 36
**
+ − 37
**
+ − 38
** $QT_END_LICENSE$
+ − 39
**
+ − 40
****************************************************************************/
+ − 41
+ − 42
#include "qxml.h"
+ − 43
#include "qtextcodec.h"
+ − 44
#include "qbuffer.h"
+ − 45
#include "qregexp.h"
+ − 46
#include "qmap.h"
+ − 47
#include "qstack.h"
+ − 48
#include <qdebug.h>
+ − 49
+ − 50
+ − 51
#ifdef Q_CC_BOR // borland 6 finds bogus warnings when building this file in uic3
+ − 52
# pragma warn -8080
+ − 53
#endif
+ − 54
+ − 55
//#define QT_QXML_DEBUG
+ − 56
+ − 57
// Error strings for the XML reader
+ − 58
#define XMLERR_OK QT_TRANSLATE_NOOP("QXml", "no error occurred")
+ − 59
#define XMLERR_ERRORBYCONSUMER QT_TRANSLATE_NOOP("QXml", "error triggered by consumer")
+ − 60
#define XMLERR_UNEXPECTEDEOF QT_TRANSLATE_NOOP("QXml", "unexpected end of file")
+ − 61
#define XMLERR_MORETHANONEDOCTYPE QT_TRANSLATE_NOOP("QXml", "more than one document type definition")
+ − 62
#define XMLERR_ERRORPARSINGELEMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing element")
+ − 63
#define XMLERR_TAGMISMATCH QT_TRANSLATE_NOOP("QXml", "tag mismatch")
+ − 64
#define XMLERR_ERRORPARSINGCONTENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing content")
+ − 65
#define XMLERR_UNEXPECTEDCHARACTER QT_TRANSLATE_NOOP("QXml", "unexpected character")
+ − 66
#define XMLERR_INVALIDNAMEFORPI QT_TRANSLATE_NOOP("QXml", "invalid name for processing instruction")
+ − 67
#define XMLERR_VERSIONEXPECTED QT_TRANSLATE_NOOP("QXml", "version expected while reading the XML declaration")
+ − 68
#define XMLERR_WRONGVALUEFORSDECL QT_TRANSLATE_NOOP("QXml", "wrong value for standalone declaration")
+ − 69
#define XMLERR_EDECLORSDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "encoding declaration or standalone declaration expected while reading the XML declaration")
+ − 70
#define XMLERR_SDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "standalone declaration expected while reading the XML declaration")
+ − 71
#define XMLERR_ERRORPARSINGDOCTYPE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing document type definition")
+ − 72
#define XMLERR_LETTEREXPECTED QT_TRANSLATE_NOOP("QXml", "letter is expected")
+ − 73
#define XMLERR_ERRORPARSINGCOMMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing comment")
+ − 74
#define XMLERR_ERRORPARSINGREFERENCE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing reference")
+ − 75
#define XMLERR_INTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "internal general entity reference not allowed in DTD")
+ − 76
#define XMLERR_EXTERNALGENERALENTITYINAV QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in attribute value")
+ − 77
#define XMLERR_EXTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in DTD")
+ − 78
#define XMLERR_UNPARSEDENTITYREFERENCE QT_TRANSLATE_NOOP("QXml", "unparsed entity reference in wrong context")
+ − 79
#define XMLERR_RECURSIVEENTITIES QT_TRANSLATE_NOOP("QXml", "recursive entities")
+ − 80
#define XMLERR_ERRORINTEXTDECL QT_TRANSLATE_NOOP("QXml", "error in the text declaration of an external entity")
+ − 81
+ − 82
QT_BEGIN_NAMESPACE
+ − 83
+ − 84
// the constants for the lookup table
+ − 85
static const signed char cltWS = 0; // white space
+ − 86
static const signed char cltPer = 1; // %
+ − 87
static const signed char cltAmp = 2; // &
+ − 88
static const signed char cltGt = 3; // >
+ − 89
static const signed char cltLt = 4; // <
+ − 90
static const signed char cltSlash = 5; // /
+ − 91
static const signed char cltQm = 6; // ?
+ − 92
static const signed char cltEm = 7; // !
+ − 93
static const signed char cltDash = 8; // -
+ − 94
static const signed char cltCB = 9; // ]
+ − 95
static const signed char cltOB = 10; // [
+ − 96
static const signed char cltEq = 11; // =
+ − 97
static const signed char cltDq = 12; // "
+ − 98
static const signed char cltSq = 13; // '
+ − 99
static const signed char cltUnknown = 14;
+ − 100
+ − 101
// Hack for letting QDom know where the skipped entity occurred
+ − 102
// ### Qt5: the use of this variable means the code isn't reentrant.
+ − 103
bool qt_xml_skipped_entity_in_content;
+ − 104
+ − 105
// character lookup table
+ − 106
static const signed char charLookupTable[256]={
+ − 107
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+ − 108
cltUnknown, // 0x08
+ − 109
cltWS, // 0x09 \t
+ − 110
cltWS, // 0x0A \n
+ − 111
cltUnknown, // 0x0B
+ − 112
cltUnknown, // 0x0C
+ − 113
cltWS, // 0x0D \r
+ − 114
cltUnknown, // 0x0E
+ − 115
cltUnknown, // 0x0F
+ − 116
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+ − 117
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+ − 118
cltWS, // 0x20 Space
+ − 119
cltEm, // 0x21 !
+ − 120
cltDq, // 0x22 "
+ − 121
cltUnknown, // 0x23
+ − 122
cltUnknown, // 0x24
+ − 123
cltPer, // 0x25 %
+ − 124
cltAmp, // 0x26 &
+ − 125
cltSq, // 0x27 '
+ − 126
cltUnknown, // 0x28
+ − 127
cltUnknown, // 0x29
+ − 128
cltUnknown, // 0x2A
+ − 129
cltUnknown, // 0x2B
+ − 130
cltUnknown, // 0x2C
+ − 131
cltDash, // 0x2D -
+ − 132
cltUnknown, // 0x2E
+ − 133
cltSlash, // 0x2F /
+ − 134
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+ − 135
cltUnknown, // 0x38
+ − 136
cltUnknown, // 0x39
+ − 137
cltUnknown, // 0x3A
+ − 138
cltUnknown, // 0x3B
+ − 139
cltLt, // 0x3C <
+ − 140
cltEq, // 0x3D =
+ − 141
cltGt, // 0x3E >
+ − 142
cltQm, // 0x3F ?
+ − 143
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+ − 144
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+ − 145
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+ − 146
cltUnknown, // 0x58
+ − 147
cltUnknown, // 0x59
+ − 148
cltUnknown, // 0x5A
+ − 149
cltOB, // 0x5B [
+ − 150
cltUnknown, // 0x5C
+ − 151
cltCB, // 0x5D]
+ − 152
cltUnknown, // 0x5E
+ − 153
cltUnknown, // 0x5F
+ − 154
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+ − 155
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+ − 156
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+ − 157
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+ − 158
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+ − 159
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+ − 160
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+ − 161
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+ − 162
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+ − 163
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+ − 164
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+ − 165
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+ − 166
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+ − 167
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+ − 168
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+ − 169
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+ − 170
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+ − 171
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+ − 172
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+ − 173
cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
+ − 174
};
+ − 175
+ − 176
//
+ − 177
// local helper functions
+ − 178
//
+ − 179
+ − 180
/*
+ − 181
This function strips the TextDecl [77] ("<?xml ...?>") from the string \a
+ − 182
str. The stripped version is stored in \a str. If this function finds an
+ − 183
invalid TextDecl, it returns false, otherwise true.
+ − 184
+ − 185
This function is used for external entities since those can include an
+ − 186
TextDecl that must be stripped before inserting the entity.
+ − 187
*/
+ − 188
static bool stripTextDecl(QString& str)
+ − 189
{
+ − 190
QString textDeclStart(QLatin1String("<?xml"));
+ − 191
if (str.startsWith(textDeclStart)) {
+ − 192
QRegExp textDecl(QString::fromLatin1(
+ − 193
"^<\\?xml\\s+"
+ − 194
"(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
+ − 195
"\\s*"
+ − 196
"(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
+ − 197
"\\s*\\?>"
+ − 198
));
+ − 199
QString strTmp = str.replace(textDecl, QLatin1String(""));
+ − 200
if (strTmp.length() != str.length())
+ − 201
return false; // external entity has wrong TextDecl
+ − 202
str = strTmp;
+ − 203
}
+ − 204
return true;
+ − 205
}
+ − 206
+ − 207
+ − 208
class QXmlAttributesPrivate
+ − 209
{
+ − 210
};
+ − 211
+ − 212
/* \class QXmlInputSourcePrivate
+ − 213
\internal
+ − 214
+ − 215
There's a slight misdesign in this class that can
+ − 216
be worth to keep in mind: the `str' member is
+ − 217
a buffer which QXmlInputSource::next() returns from,
+ − 218
and which is populated from the input device or input
+ − 219
stream. However, when the input is a QString(the user called
+ − 220
QXmlInputSource::setData()), `str' has two roles: it's the
+ − 221
buffer, but also the source. This /seems/ to be no problem
+ − 222
because in the case of having no device or stream, the QString
+ − 223
is read in one go.
+ − 224
*/
+ − 225
class QXmlInputSourcePrivate
+ − 226
{
+ − 227
public:
+ − 228
QIODevice *inputDevice;
+ − 229
QTextStream *inputStream;
+ − 230
+ − 231
QString str;
+ − 232
const QChar *unicode;
+ − 233
int pos;
+ − 234
int length;
+ − 235
bool nextReturnedEndOfData;
+ − 236
#ifndef QT_NO_TEXTCODEC
+ − 237
QTextDecoder *encMapper;
+ − 238
#endif
+ − 239
+ − 240
QByteArray encodingDeclBytes;
+ − 241
QString encodingDeclChars;
+ − 242
bool lookingForEncodingDecl;
+ − 243
};
+ − 244
class QXmlParseExceptionPrivate
+ − 245
{
+ − 246
public:
+ − 247
QXmlParseExceptionPrivate()
+ − 248
: column(-1), line(-1)
+ − 249
{
+ − 250
}
+ − 251
QXmlParseExceptionPrivate(const QXmlParseExceptionPrivate &other)
+ − 252
: msg(other.msg), column(other.column), line(other.line),
+ − 253
pub(other.pub), sys(other.sys)
+ − 254
{
+ − 255
}
+ − 256
+ − 257
QString msg;
+ − 258
int column;
+ − 259
int line;
+ − 260
QString pub;
+ − 261
QString sys;
+ − 262
+ − 263
};
+ − 264
+ − 265
class QXmlLocatorPrivate
+ − 266
{
+ − 267
};
+ − 268
+ − 269
class QXmlDefaultHandlerPrivate
+ − 270
{
+ − 271
};
+ − 272
+ − 273
class QXmlSimpleReaderPrivate
+ − 274
{
+ − 275
public:
+ − 276
~QXmlSimpleReaderPrivate();
+ − 277
private:
+ − 278
// functions
+ − 279
QXmlSimpleReaderPrivate(QXmlSimpleReader *reader);
+ − 280
void initIncrementalParsing();
+ − 281
+ − 282
// used to determine if elements are correctly nested
+ − 283
QStack<QString> tags;
+ − 284
+ − 285
// used by parseReference() and parsePEReference()
+ − 286
enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+ − 287
+ − 288
// used for entity declarations
+ − 289
struct ExternParameterEntity
+ − 290
{
+ − 291
ExternParameterEntity() {}
+ − 292
ExternParameterEntity(const QString &p, const QString &s)
+ − 293
: publicId(p), systemId(s) {}
+ − 294
QString publicId;
+ − 295
QString systemId;
+ − 296
+ − 297
Q_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity)
+ − 298
};
+ − 299
struct ExternEntity
+ − 300
{
+ − 301
ExternEntity() {}
+ − 302
ExternEntity(const QString &p, const QString &s, const QString &n)
+ − 303
: publicId(p), systemId(s), notation(n) {}
+ − 304
QString publicId;
+ − 305
QString systemId;
+ − 306
QString notation;
+ − 307
Q_DUMMY_COMPARISON_OPERATOR(ExternEntity)
+ − 308
};
+ − 309
QMap<QString,ExternParameterEntity> externParameterEntities;
+ − 310
QMap<QString,QString> parameterEntities;
+ − 311
QMap<QString,ExternEntity> externEntities;
+ − 312
QMap<QString,QString> entities;
+ − 313
+ − 314
// used for parsing of entity references
+ − 315
struct XmlRef {
+ − 316
XmlRef()
+ − 317
: index(0) {}
+ − 318
XmlRef(const QString &_name, const QString &_value)
+ − 319
: name(_name), value(_value), index(0) {}
+ − 320
bool isEmpty() const { return index == value.length(); }
+ − 321
QChar next() { return value.at(index++); }
+ − 322
QString name;
+ − 323
QString value;
+ − 324
int index;
+ − 325
};
+ − 326
QStack<XmlRef> xmlRefStack;
+ − 327
+ − 328
// used for standalone declaration
+ − 329
enum Standalone { Yes, No, Unknown };
+ − 330
+ − 331
QString doctype; // only used for the doctype
+ − 332
QString xmlVersion; // only used to store the version information
+ − 333
QString encoding; // only used to store the encoding
+ − 334
Standalone standalone; // used to store the value of the standalone declaration
+ − 335
+ − 336
QString publicId; // used by parseExternalID() to store the public ID
+ − 337
QString systemId; // used by parseExternalID() to store the system ID
+ − 338
+ − 339
// Since publicId/systemId is used as temporary variables by parseExternalID(), it
+ − 340
// might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would
+ − 341
// possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration
+ − 342
// instead of those of the current document.
+ − 343
// Hence we have these two variables for storing the document's data.
+ − 344
QString thisPublicId;
+ − 345
QString thisSystemId;
+ − 346
+ − 347
QString attDeclEName; // use by parseAttlistDecl()
+ − 348
QString attDeclAName; // use by parseAttlistDecl()
+ − 349
+ − 350
// flags for some features support
+ − 351
bool useNamespaces;
+ − 352
bool useNamespacePrefixes;
+ − 353
bool reportWhitespaceCharData;
+ − 354
bool reportEntities;
+ − 355
+ − 356
// used to build the attribute list
+ − 357
QXmlAttributes attList;
+ − 358
+ − 359
// used in QXmlSimpleReader::parseContent() to decide whether character
+ − 360
// data was read
+ − 361
bool contentCharDataRead;
+ − 362
+ − 363
// helper classes
+ − 364
QScopedPointer<QXmlLocator> locator;
+ − 365
QXmlNamespaceSupport namespaceSupport;
+ − 366
+ − 367
// error string
+ − 368
QString error;
+ − 369
+ − 370
// arguments for parse functions (this is needed to allow incremental
+ − 371
// parsing)
+ − 372
bool parsePI_xmldecl;
+ − 373
bool parseName_useRef;
+ − 374
bool parseReference_charDataRead;
+ − 375
EntityRecognitionContext parseReference_context;
+ − 376
bool parseExternalID_allowPublicID;
+ − 377
EntityRecognitionContext parsePEReference_context;
+ − 378
QString parseString_s;
+ − 379
+ − 380
// for incremental parsing
+ − 381
struct ParseState {
+ − 382
typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)();
+ − 383
ParseFunction function;
+ − 384
int state;
+ − 385
};
+ − 386
QStack<ParseState> *parseStack;
+ − 387
+ − 388
// used in parseProlog()
+ − 389
bool xmldecl_possible;
+ − 390
bool doctype_read;
+ − 391
+ − 392
// used in parseDoctype()
+ − 393
bool startDTDwasReported;
+ − 394
+ − 395
// used in parseString()
+ − 396
signed char Done;
+ − 397
+ − 398
+ − 399
// variables
+ − 400
QXmlContentHandler *contentHnd;
+ − 401
QXmlErrorHandler *errorHnd;
+ − 402
QXmlDTDHandler *dtdHnd;
+ − 403
QXmlEntityResolver *entityRes;
+ − 404
QXmlLexicalHandler *lexicalHnd;
+ − 405
QXmlDeclHandler *declHnd;
+ − 406
+ − 407
QXmlInputSource *inputSource;
+ − 408
+ − 409
QChar c; // the character at reading position
+ − 410
int lineNr; // number of line
+ − 411
int columnNr; // position in line
+ − 412
+ − 413
QChar nameArray[256]; // only used for names
+ − 414
QString nameValue; // only used for names
+ − 415
int nameArrayPos;
+ − 416
int nameValueLen;
+ − 417
QChar refArray[256]; // only used for references
+ − 418
QString refValue; // only used for references
+ − 419
int refArrayPos;
+ − 420
int refValueLen;
+ − 421
QChar stringArray[256]; // used for any other strings that are parsed
+ − 422
QString stringValue; // used for any other strings that are parsed
+ − 423
int stringArrayPos;
+ − 424
int stringValueLen;
+ − 425
QString emptyStr;
+ − 426
+ − 427
const QString &string();
+ − 428
void stringClear();
+ − 429
void stringAddC(QChar);
+ − 430
inline void stringAddC() { stringAddC(c); }
+ − 431
const QString &name();
+ − 432
void nameClear();
+ − 433
void nameAddC(QChar);
+ − 434
inline void nameAddC() { nameAddC(c); }
+ − 435
const QString &ref();
+ − 436
void refClear();
+ − 437
void refAddC(QChar);
+ − 438
inline void refAddC() { refAddC(c); }
+ − 439
+ − 440
// private functions
+ − 441
bool eat_ws();
+ − 442
bool next_eat_ws();
+ − 443
+ − 444
void QT_FASTCALL next();
+ − 445
bool atEnd();
+ − 446
+ − 447
void init(const QXmlInputSource* i);
+ − 448
void initData();
+ − 449
+ − 450
bool entityExist(const QString&) const;
+ − 451
+ − 452
bool parseBeginOrContinue(int state, bool incremental);
+ − 453
+ − 454
bool parseProlog();
+ − 455
bool parseElement();
+ − 456
bool processElementEmptyTag();
+ − 457
bool processElementETagBegin2();
+ − 458
bool processElementAttribute();
+ − 459
bool parseMisc();
+ − 460
bool parseContent();
+ − 461
+ − 462
bool parsePI();
+ − 463
bool parseDoctype();
+ − 464
bool parseComment();
+ − 465
+ − 466
bool parseName();
+ − 467
bool parseNmtoken();
+ − 468
bool parseAttribute();
+ − 469
bool parseReference();
+ − 470
bool processReference();
+ − 471
+ − 472
bool parseExternalID();
+ − 473
bool parsePEReference();
+ − 474
bool parseMarkupdecl();
+ − 475
bool parseAttlistDecl();
+ − 476
bool parseAttType();
+ − 477
bool parseAttValue();
+ − 478
bool parseElementDecl();
+ − 479
bool parseNotationDecl();
+ − 480
bool parseChoiceSeq();
+ − 481
bool parseEntityDecl();
+ − 482
bool parseEntityValue();
+ − 483
+ − 484
bool parseString();
+ − 485
+ − 486
bool insertXmlRef(const QString&, const QString&, bool);
+ − 487
+ − 488
bool reportEndEntities();
+ − 489
void reportParseError(const QString& error);
+ − 490
+ − 491
typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) ();
+ − 492
void unexpectedEof(ParseFunction where, int state);
+ − 493
void parseFailed(ParseFunction where, int state);
+ − 494
void pushParseState(ParseFunction function, int state);
+ − 495
+ − 496
Q_DECLARE_PUBLIC(QXmlSimpleReader)
+ − 497
QXmlSimpleReader *q_ptr;
+ − 498
+ − 499
friend class QXmlSimpleReaderLocator;
+ − 500
};
+ − 501
+ − 502
/*!
+ − 503
\class QXmlParseException
+ − 504
\reentrant
+ − 505
\brief The QXmlParseException class is used to report errors with
+ − 506
the QXmlErrorHandler interface.
+ − 507
+ − 508
\inmodule QtXml
+ − 509
\ingroup xml-tools
+ − 510
+ − 511
The XML subsystem constructs an instance of this class when it
+ − 512
detects an error. You can retrieve the place where the error
+ − 513
occurred using systemId(), publicId(), lineNumber() and
+ − 514
columnNumber(), along with the error message(). The possible error
+ − 515
messages are:
+ − 516
+ − 517
+ − 518
\list
+ − 519
\o "no error occurred"
+ − 520
\o "error triggered by consumer"
+ − 521
\o "unexpected end of file"
+ − 522
\o "more than one document type definition"
+ − 523
\o "error occurred while parsing element"
+ − 524
\o "tag mismatch"
+ − 525
\o "error occurred while parsing content"
+ − 526
\o "unexpected character"
+ − 527
\o "invalid name for processing instruction"
+ − 528
\o "version expected while reading the XML declaration"
+ − 529
\o "wrong value for standalone declaration"
+ − 530
\o "encoding declaration or standalone declaration expected while reading the XML declaration"
+ − 531
\o "standalone declaration expected while reading the XML declaration"
+ − 532
\o "error occurred while parsing document type definition"
+ − 533
\o "letter is expected"
+ − 534
\o "error occurred while parsing comment"
+ − 535
\o "error occurred while parsing reference"
+ − 536
\o "internal general entity reference not allowed in DTD"
+ − 537
\o "external parsed general entity reference not allowed in attribute value"
+ − 538
\o "external parsed general entity reference not allowed in DTD"
+ − 539
\o "unparsed entity reference n wrong context"
+ − 540
\o "recursive entities"
+ − 541
\o "error in the text declaration of an external entity"
+ − 542
\endlist
+ − 543
+ − 544
Note that, if you want to display these error messages to your
+ − 545
application's users, they will be displayed in English unless
+ − 546
they are explicitly translated.
+ − 547
+ − 548
\sa QXmlErrorHandler, QXmlReader
+ − 549
*/
+ − 550
+ − 551
/*!
+ − 552
Constructs a parse exception with the error string \a name for
+ − 553
column \a c and line \a l for the public identifier \a p and the
+ − 554
system identifier \a s.
+ − 555
*/
+ − 556
+ − 557
QXmlParseException::QXmlParseException(const QString& name, int c, int l,
+ − 558
const QString& p, const QString& s)
+ − 559
: d(new QXmlParseExceptionPrivate)
+ − 560
{
+ − 561
d->msg = name;
+ − 562
d->column = c;
+ − 563
d->line = l;
+ − 564
d->pub = p;
+ − 565
d->sys = s;
+ − 566
}
+ − 567
+ − 568
/*!
+ − 569
Creates a copy of \a other.
+ − 570
*/
+ − 571
QXmlParseException::QXmlParseException(const QXmlParseException& other) :
+ − 572
d(new QXmlParseExceptionPrivate(*other.d))
+ − 573
{
+ − 574
+ − 575
}
+ − 576
+ − 577
/*!
+ − 578
Destroys the QXmlParseException.
+ − 579
*/
+ − 580
QXmlParseException::~QXmlParseException()
+ − 581
{
+ − 582
}
+ − 583
+ − 584
/*!
+ − 585
Returns the error message.
+ − 586
*/
+ − 587
QString QXmlParseException::message() const
+ − 588
{
+ − 589
return d->msg;
+ − 590
}
+ − 591
/*!
+ − 592
Returns the column number where the error occurred.
+ − 593
*/
+ − 594
int QXmlParseException::columnNumber() const
+ − 595
{
+ − 596
return d->column;
+ − 597
}
+ − 598
/*!
+ − 599
Returns the line number where the error occurred.
+ − 600
*/
+ − 601
int QXmlParseException::lineNumber() const
+ − 602
{
+ − 603
return d->line;
+ − 604
}
+ − 605
/*!
+ − 606
Returns the public identifier where the error occurred.
+ − 607
*/
+ − 608
QString QXmlParseException::publicId() const
+ − 609
{
+ − 610
return d->pub;
+ − 611
}
+ − 612
/*!
+ − 613
Returns the system identifier where the error occurred.
+ − 614
*/
+ − 615
QString QXmlParseException::systemId() const
+ − 616
{
+ − 617
return d->sys;
+ − 618
}
+ − 619
+ − 620
+ − 621
/*!
+ − 622
\class QXmlLocator
+ − 623
\reentrant
+ − 624
\brief The QXmlLocator class provides the XML handler classes with
+ − 625
information about the parsing position within a file.
+ − 626
+ − 627
\inmodule QtXml
+ − 628
\ingroup xml-tools
+ − 629
+ − 630
The reader reports a QXmlLocator to the content handler before it
+ − 631
starts to parse the document. This is done with the
+ − 632
QXmlContentHandler::setDocumentLocator() function. The handler
+ − 633
classes can now use this locator to get the position (lineNumber()
+ − 634
and columnNumber()) that the reader has reached.
+ − 635
*/
+ − 636
+ − 637
/*!
+ − 638
Constructor.
+ − 639
*/
+ − 640
QXmlLocator::QXmlLocator()
+ − 641
{
+ − 642
}
+ − 643
+ − 644
/*!
+ − 645
Destructor.
+ − 646
*/
+ − 647
QXmlLocator::~QXmlLocator()
+ − 648
{
+ − 649
}
+ − 650
+ − 651
/*!
+ − 652
\fn int QXmlLocator::columnNumber() const
+ − 653
+ − 654
Returns the column number (starting at 1) or -1 if there is no
+ − 655
column number available.
+ − 656
*/
+ − 657
+ − 658
/*!
+ − 659
\fn int QXmlLocator::lineNumber() const
+ − 660
+ − 661
Returns the line number (starting at 1) or -1 if there is no line
+ − 662
number available.
+ − 663
*/
+ − 664
+ − 665
class QXmlSimpleReaderLocator : public QXmlLocator
+ − 666
{
+ − 667
public:
+ − 668
QXmlSimpleReaderLocator(QXmlSimpleReader* parent)
+ − 669
{
+ − 670
reader = parent;
+ − 671
}
+ − 672
~QXmlSimpleReaderLocator()
+ − 673
{
+ − 674
}
+ − 675
+ − 676
int columnNumber() const
+ − 677
{
+ − 678
return (reader->d_ptr->columnNr == -1 ? -1 : reader->d_ptr->columnNr + 1);
+ − 679
}
+ − 680
int lineNumber() const
+ − 681
{
+ − 682
return (reader->d_ptr->lineNr == -1 ? -1 : reader->d_ptr->lineNr + 1);
+ − 683
}
+ − 684
// QString getPublicId()
+ − 685
// QString getSystemId()
+ − 686
+ − 687
private:
+ − 688
QXmlSimpleReader *reader;
+ − 689
};
+ − 690
+ − 691
/*********************************************
+ − 692
*
+ − 693
* QXmlNamespaceSupport
+ − 694
*
+ − 695
*********************************************/
+ − 696
+ − 697
typedef QMap<QString, QString> NamespaceMap;
+ − 698
+ − 699
class QXmlNamespaceSupportPrivate
+ − 700
{
+ − 701
public:
+ − 702
QXmlNamespaceSupportPrivate()
+ − 703
{
+ − 704
ns.insert(QLatin1String("xml"), QLatin1String("http://www.w3.org/XML/1998/namespace")); // the XML namespace
+ − 705
}
+ − 706
+ − 707
~QXmlNamespaceSupportPrivate()
+ − 708
{
+ − 709
}
+ − 710
+ − 711
QStack<NamespaceMap> nsStack;
+ − 712
NamespaceMap ns;
+ − 713
};
+ − 714
+ − 715
/*!
+ − 716
\class QXmlNamespaceSupport
+ − 717
\since 4.4
+ − 718
\reentrant
+ − 719
\brief The QXmlNamespaceSupport class is a helper class for XML
+ − 720
readers which want to include namespace support.
+ − 721
+ − 722
\inmodule QtXml
+ − 723
\ingroup xml-tools
+ − 724
+ − 725
You can set the prefix for the current namespace with setPrefix(),
+ − 726
and get the list of current prefixes (or those for a given URI)
+ − 727
with prefixes(). The namespace URI is available from uri(). Use
+ − 728
pushContext() to start a new namespace context, and popContext()
+ − 729
to return to the previous namespace context. Use splitName() or
+ − 730
processName() to split a name into its prefix and local name.
+ − 731
+ − 732
\sa {Namespace Support via Features}
+ − 733
*/
+ − 734
+ − 735
/*!
+ − 736
Constructs a QXmlNamespaceSupport.
+ − 737
*/
+ − 738
QXmlNamespaceSupport::QXmlNamespaceSupport()
+ − 739
{
+ − 740
d = new QXmlNamespaceSupportPrivate;
+ − 741
}
+ − 742
+ − 743
/*!
+ − 744
Destroys a QXmlNamespaceSupport.
+ − 745
*/
+ − 746
QXmlNamespaceSupport::~QXmlNamespaceSupport()
+ − 747
{
+ − 748
delete d;
+ − 749
}
+ − 750
+ − 751
/*!
+ − 752
This function declares a prefix \a pre in the current namespace
+ − 753
context to be the namespace URI \a uri. The prefix remains in
+ − 754
force until this context is popped, unless it is shadowed in a
+ − 755
descendant context.
+ − 756
+ − 757
Note that there is an asymmetry in this library. prefix() does not
+ − 758
return the default "" prefix, even if you have declared one; to
+ − 759
check for a default prefix, you must look it up explicitly using
+ − 760
uri(). This asymmetry exists to make it easier to look up prefixes
+ − 761
for attribute names, where the default prefix is not allowed.
+ − 762
*/
+ − 763
void QXmlNamespaceSupport::setPrefix(const QString& pre, const QString& uri)
+ − 764
{
+ − 765
if(pre.isNull()) {
+ − 766
d->ns.insert(QLatin1String(""), uri);
+ − 767
} else {
+ − 768
d->ns.insert(pre, uri);
+ − 769
}
+ − 770
}
+ − 771
+ − 772
/*!
+ − 773
Returns one of the prefixes mapped to the namespace URI \a uri.
+ − 774
+ − 775
If more than one prefix is currently mapped to the same URI, this
+ − 776
function makes an arbitrary selection; if you want all of the
+ − 777
prefixes, use prefixes() instead.
+ − 778
+ − 779
Note: to check for a default prefix, use the uri() function with
+ − 780
an argument of "".
+ − 781
*/
+ − 782
QString QXmlNamespaceSupport::prefix(const QString& uri) const
+ − 783
{
+ − 784
NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ − 785
while ((itc=it) != d->ns.constEnd()) {
+ − 786
++it;
+ − 787
if (*itc == uri && !itc.key().isEmpty())
+ − 788
return itc.key();
+ − 789
}
+ − 790
return QLatin1String("");
+ − 791
}
+ − 792
+ − 793
/*!
+ − 794
Looks up the prefix \a prefix in the current context and returns
+ − 795
the currently-mapped namespace URI. Use the empty string ("") for
+ − 796
the default namespace.
+ − 797
*/
+ − 798
QString QXmlNamespaceSupport::uri(const QString& prefix) const
+ − 799
{
+ − 800
return d->ns[prefix];
+ − 801
}
+ − 802
+ − 803
/*!
+ − 804
Splits the name \a qname at the ':' and returns the prefix in \a
+ − 805
prefix and the local name in \a localname.
+ − 806
+ − 807
\sa processName()
+ − 808
*/
+ − 809
void QXmlNamespaceSupport::splitName(const QString& qname, QString& prefix,
+ − 810
QString& localname) const
+ − 811
{
+ − 812
int pos = qname.indexOf(QLatin1Char(':'));
+ − 813
if (pos == -1)
+ − 814
pos = qname.size();
+ − 815
+ − 816
prefix = qname.left(pos);
+ − 817
localname = qname.mid(pos+1);
+ − 818
}
+ − 819
+ − 820
/*!
+ − 821
Processes a raw XML 1.0 name in the current context by removing
+ − 822
the prefix and looking it up among the prefixes currently
+ − 823
declared.
+ − 824
+ − 825
\a qname is the raw XML 1.0 name to be processed. \a isAttribute
+ − 826
is true if the name is an attribute name.
+ − 827
+ − 828
This function stores the namespace URI in \a nsuri (which will be
+ − 829
set to an empty string if the raw name has an undeclared prefix),
+ − 830
and stores the local name (without prefix) in \a localname (which
+ − 831
will be set to an empty string if no namespace is in use).
+ − 832
+ − 833
Note that attribute names are processed differently than element
+ − 834
names: an unprefixed element name gets the default namespace (if
+ − 835
any), while an unprefixed attribute name does not.
+ − 836
*/
+ − 837
void QXmlNamespaceSupport::processName(const QString& qname,
+ − 838
bool isAttribute,
+ − 839
QString& nsuri, QString& localname) const
+ − 840
{
+ − 841
int len = qname.size();
+ − 842
const QChar *data = qname.constData();
+ − 843
for (int pos = 0; pos < len; ++pos) {
+ − 844
if (data[pos] == QLatin1Char(':')) {
+ − 845
nsuri = uri(qname.left(pos));
+ − 846
localname = qname.mid(pos + 1);
+ − 847
return;
+ − 848
}
+ − 849
}
+ − 850
+ − 851
// there was no ':'
+ − 852
nsuri.clear();
+ − 853
// attributes don't take default namespace
+ − 854
if (!isAttribute && !d->ns.isEmpty()) {
+ − 855
/*
+ − 856
We want to access d->ns.value(""), but as an optimization
+ − 857
we use the fact that "" compares less than any other
+ − 858
string, so it's either first in the map or not there.
+ − 859
*/
+ − 860
NamespaceMap::const_iterator first = d->ns.constBegin();
+ − 861
if (first.key().isEmpty())
+ − 862
nsuri = first.value(); // get default namespace
+ − 863
}
+ − 864
localname = qname;
+ − 865
}
+ − 866
+ − 867
/*!
+ − 868
Returns a list of all the prefixes currently declared.
+ − 869
+ − 870
If there is a default prefix, this function does not return it in
+ − 871
the list; check for the default prefix using uri() with an
+ − 872
argument of "".
+ − 873
*/
+ − 874
QStringList QXmlNamespaceSupport::prefixes() const
+ − 875
{
+ − 876
QStringList list;
+ − 877
+ − 878
NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ − 879
while ((itc=it) != d->ns.constEnd()) {
+ − 880
++it;
+ − 881
if (!itc.key().isEmpty())
+ − 882
list.append(itc.key());
+ − 883
}
+ − 884
return list;
+ − 885
}
+ − 886
+ − 887
/*!
+ − 888
\overload
+ − 889
+ − 890
Returns a list of all prefixes currently declared for the
+ − 891
namespace URI \a uri.
+ − 892
+ − 893
The "xml:" prefix is included. If you only want one prefix that is
+ − 894
mapped to the namespace URI, and you don't care which one you get,
+ − 895
use the prefix() function instead.
+ − 896
+ − 897
Note: The empty (default) prefix is never included in this list;
+ − 898
to check for the presence of a default namespace, call uri() with
+ − 899
"" as the argument.
+ − 900
*/
+ − 901
QStringList QXmlNamespaceSupport::prefixes(const QString& uri) const
+ − 902
{
+ − 903
QStringList list;
+ − 904
+ − 905
NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ − 906
while ((itc=it) != d->ns.constEnd()) {
+ − 907
++it;
+ − 908
if (*itc == uri && !itc.key().isEmpty())
+ − 909
list.append(itc.key());
+ − 910
}
+ − 911
return list;
+ − 912
}
+ − 913
+ − 914
/*!
+ − 915
Starts a new namespace context.
+ − 916
+ − 917
Normally, you should push a new context at the beginning of each
+ − 918
XML element: the new context automatically inherits the
+ − 919
declarations of its parent context, and it also keeps track of
+ − 920
which declarations were made within this context.
+ − 921
+ − 922
\sa popContext()
+ − 923
*/
+ − 924
void QXmlNamespaceSupport::pushContext()
+ − 925
{
+ − 926
d->nsStack.push(d->ns);
+ − 927
}
+ − 928
+ − 929
/*!
+ − 930
Reverts to the previous namespace context.
+ − 931
+ − 932
Normally, you should pop the context at the end of each XML
+ − 933
element. After popping the context, all namespace prefix mappings
+ − 934
that were previously in force are restored.
+ − 935
+ − 936
\sa pushContext()
+ − 937
*/
+ − 938
void QXmlNamespaceSupport::popContext()
+ − 939
{
+ − 940
d->ns.clear();
+ − 941
if(!d->nsStack.isEmpty())
+ − 942
d->ns = d->nsStack.pop();
+ − 943
}
+ − 944
+ − 945
/*!
+ − 946
Resets this namespace support object ready for reuse.
+ − 947
*/
+ − 948
void QXmlNamespaceSupport::reset()
+ − 949
{
+ − 950
QXmlNamespaceSupportPrivate *newD = new QXmlNamespaceSupportPrivate;
+ − 951
delete d;
+ − 952
d = newD;
+ − 953
}
+ − 954
+ − 955
+ − 956
+ − 957
/*********************************************
+ − 958
*
+ − 959
* QXmlAttributes
+ − 960
*
+ − 961
*********************************************/
+ − 962
+ − 963
/*!
+ − 964
\class QXmlAttributes
+ − 965
\reentrant
+ − 966
\brief The QXmlAttributes class provides XML attributes.
+ − 967
+ − 968
\inmodule QtXml
+ − 969
\ingroup xml-tools
+ − 970
+ − 971
If attributes are reported by QXmlContentHandler::startElement()
+ − 972
this class is used to pass the attribute values.
+ − 973
+ − 974
Use index() to locate the position of an attribute in the list,
+ − 975
count() to retrieve the number of attributes, and clear() to
+ − 976
remove the attributes. New attributes can be added with append().
+ − 977
Use type() to get an attribute's type and value() to get its
+ − 978
value. The attribute's name is available from localName() or
+ − 979
qName(), and its namespace URI from uri().
+ − 980
+ − 981
*/
+ − 982
+ − 983
/*!
+ − 984
\fn QXmlAttributes::QXmlAttributes()
+ − 985
+ − 986
Constructs an empty attribute list.
+ − 987
*/
+ − 988
+ − 989
/*!
+ − 990
\fn QXmlAttributes::~QXmlAttributes()
+ − 991
+ − 992
Destroys the attributes object.
+ − 993
*/
+ − 994
+ − 995
/*!
+ − 996
Looks up the index of an attribute by the qualified name \a qName.
+ − 997
+ − 998
Returns the index of the attribute or -1 if it wasn't found.
+ − 999
+ − 1000
\sa {Namespace Support via Features}
+ − 1001
*/
+ − 1002
int QXmlAttributes::index(const QString& qName) const
+ − 1003
{
+ − 1004
for (int i = 0; i < attList.size(); ++i) {
+ − 1005
if (attList.at(i).qname == qName)
+ − 1006
return i;
+ − 1007
}
+ − 1008
return -1;
+ − 1009
}
+ − 1010
+ − 1011
/*! \overload
+ − 1012
*/
+ − 1013
int QXmlAttributes::index(const QLatin1String& qName) const
+ − 1014
{
+ − 1015
for (int i = 0; i < attList.size(); ++i) {
+ − 1016
if (attList.at(i).qname == qName)
+ − 1017
return i;
+ − 1018
}
+ − 1019
return -1;
+ − 1020
}
+ − 1021
+ − 1022
/*!
+ − 1023
\overload
+ − 1024
+ − 1025
Looks up the index of an attribute by a namespace name.
+ − 1026
+ − 1027
\a uri specifies the namespace URI, or an empty string if the name
+ − 1028
has no namespace URI. \a localPart specifies the attribute's local
+ − 1029
name.
+ − 1030
+ − 1031
Returns the index of the attribute, or -1 if it wasn't found.
+ − 1032
+ − 1033
\sa {Namespace Support via Features}
+ − 1034
*/
+ − 1035
int QXmlAttributes::index(const QString& uri, const QString& localPart) const
+ − 1036
{
+ − 1037
for (int i = 0; i < attList.size(); ++i) {
+ − 1038
const Attribute &att = attList.at(i);
+ − 1039
if (att.uri == uri && att.localname == localPart)
+ − 1040
return i;
+ − 1041
}
+ − 1042
return -1;
+ − 1043
}
+ − 1044
+ − 1045
/*!
+ − 1046
Returns the number of attributes in the list.
+ − 1047
+ − 1048
\sa count()
+ − 1049
*/
+ − 1050
int QXmlAttributes::length() const
+ − 1051
{
+ − 1052
return attList.count();
+ − 1053
}
+ − 1054
+ − 1055
/*!
+ − 1056
\fn int QXmlAttributes::count() const
+ − 1057
+ − 1058
Returns the number of attributes in the list. This function is
+ − 1059
equivalent to length().
+ − 1060
*/
+ − 1061
+ − 1062
/*!
+ − 1063
Looks up an attribute's local name for the attribute at position
+ − 1064
\a index. If no namespace processing is done, the local name is
+ − 1065
an empty string.
+ − 1066
+ − 1067
\sa {Namespace Support via Features}
+ − 1068
*/
+ − 1069
QString QXmlAttributes::localName(int index) const
+ − 1070
{
+ − 1071
return attList.at(index).localname;
+ − 1072
}
+ − 1073
+ − 1074
/*!
+ − 1075
Looks up an attribute's XML 1.0 qualified name for the attribute
+ − 1076
at position \a index.
+ − 1077
+ − 1078
\sa {Namespace Support via Features}
+ − 1079
*/
+ − 1080
QString QXmlAttributes::qName(int index) const
+ − 1081
{
+ − 1082
return attList.at(index).qname;
+ − 1083
}
+ − 1084
+ − 1085
/*!
+ − 1086
Looks up an attribute's namespace URI for the attribute at
+ − 1087
position \a index. If no namespace processing is done or if the
+ − 1088
attribute has no namespace, the namespace URI is an empty string.
+ − 1089
+ − 1090
\sa {Namespace Support via Features}
+ − 1091
*/
+ − 1092
QString QXmlAttributes::uri(int index) const
+ − 1093
{
+ − 1094
return attList.at(index).uri;
+ − 1095
}
+ − 1096
+ − 1097
/*!
+ − 1098
Looks up an attribute's type for the attribute at position \a
+ − 1099
index.
+ − 1100
+ − 1101
Currently only "CDATA" is returned.
+ − 1102
*/
+ − 1103
QString QXmlAttributes::type(int) const
+ − 1104
{
+ − 1105
return QLatin1String("CDATA");
+ − 1106
}
+ − 1107
+ − 1108
/*!
+ − 1109
\overload
+ − 1110
+ − 1111
Looks up an attribute's type for the qualified name \a qName.
+ − 1112
+ − 1113
Currently only "CDATA" is returned.
+ − 1114
*/
+ − 1115
QString QXmlAttributes::type(const QString&) const
+ − 1116
{
+ − 1117
return QLatin1String("CDATA");
+ − 1118
}
+ − 1119
+ − 1120
/*!
+ − 1121
\overload
+ − 1122
+ − 1123
Looks up an attribute's type by namespace name.
+ − 1124
+ − 1125
\a uri specifies the namespace URI and \a localName specifies the
+ − 1126
local name. If the name has no namespace URI, use an empty string
+ − 1127
for \a uri.
+ − 1128
+ − 1129
Currently only "CDATA" is returned.
+ − 1130
*/
+ − 1131
QString QXmlAttributes::type(const QString&, const QString&) const
+ − 1132
{
+ − 1133
return QLatin1String("CDATA");
+ − 1134
}
+ − 1135
+ − 1136
/*!
+ − 1137
Returns an attribute's value for the attribute at position \a
+ − 1138
index. The index must be a valid position
+ − 1139
(i.e., 0 <= \a index < count()).
+ − 1140
*/
+ − 1141
QString QXmlAttributes::value(int index) const
+ − 1142
{
+ − 1143
return attList.at(index).value;
+ − 1144
}
+ − 1145
+ − 1146
/*!
+ − 1147
\overload
+ − 1148
+ − 1149
Returns an attribute's value for the qualified name \a qName, or an
+ − 1150
empty string if no attribute exists for the name given.
+ − 1151
+ − 1152
\sa {Namespace Support via Features}
+ − 1153
*/
+ − 1154
QString QXmlAttributes::value(const QString& qName) const
+ − 1155
{
+ − 1156
int i = index(qName);
+ − 1157
if (i == -1)
+ − 1158
return QString();
+ − 1159
return attList.at(i).value;
+ − 1160
}
+ − 1161
+ − 1162
/*!
+ − 1163
\overload
+ − 1164
+ − 1165
Returns an attribute's value for the qualified name \a qName, or an
+ − 1166
empty string if no attribute exists for the name given.
+ − 1167
+ − 1168
\sa {Namespace Support via Features}
+ − 1169
*/
+ − 1170
QString QXmlAttributes::value(const QLatin1String& qName) const
+ − 1171
{
+ − 1172
int i = index(qName);
+ − 1173
if (i == -1)
+ − 1174
return QString();
+ − 1175
return attList.at(i).value;
+ − 1176
}
+ − 1177
+ − 1178
/*!
+ − 1179
\overload
+ − 1180
+ − 1181
Returns an attribute's value by namespace name.
+ − 1182
+ − 1183
\a uri specifies the namespace URI, or an empty string if the name
+ − 1184
has no namespace URI. \a localName specifies the attribute's local
+ − 1185
name.
+ − 1186
*/
+ − 1187
QString QXmlAttributes::value(const QString& uri, const QString& localName) const
+ − 1188
{
+ − 1189
int i = index(uri, localName);
+ − 1190
if (i == -1)
+ − 1191
return QString();
+ − 1192
return attList.at(i).value;
+ − 1193
}
+ − 1194
+ − 1195
/*!
+ − 1196
Clears the list of attributes.
+ − 1197
+ − 1198
\sa append()
+ − 1199
*/
+ − 1200
void QXmlAttributes::clear()
+ − 1201
{
+ − 1202
attList.clear();
+ − 1203
}
+ − 1204
+ − 1205
/*!
+ − 1206
Appends a new attribute entry to the list of attributes. The
+ − 1207
qualified name of the attribute is \a qName, the namespace URI is
+ − 1208
\a uri and the local name is \a localPart. The value of the
+ − 1209
attribute is \a value.
+ − 1210
+ − 1211
\sa qName() uri() localName() value()
+ − 1212
*/
+ − 1213
void QXmlAttributes::append(const QString &qName, const QString &uri, const QString &localPart, const QString &value)
+ − 1214
{
+ − 1215
Attribute att;
+ − 1216
att.qname = qName;
+ − 1217
att.uri = uri;
+ − 1218
att.localname = localPart;
+ − 1219
att.value = value;
+ − 1220
+ − 1221
attList.append(att);
+ − 1222
}
+ − 1223
+ − 1224
+ − 1225
/*********************************************
+ − 1226
*
+ − 1227
* QXmlInputSource
+ − 1228
*
+ − 1229
*********************************************/
+ − 1230
+ − 1231
/*!
+ − 1232
\class QXmlInputSource
+ − 1233
\reentrant
+ − 1234
\brief The QXmlInputSource class provides the input data for the
+ − 1235
QXmlReader subclasses.
+ − 1236
+ − 1237
\inmodule QtXml
+ − 1238
\ingroup xml-tools
+ − 1239
+ − 1240
All subclasses of QXmlReader read the input XML document from this
+ − 1241
class.
+ − 1242
+ − 1243
This class recognizes the encoding of the data by reading the
+ − 1244
encoding declaration in the XML file if it finds one, and reading
+ − 1245
the data using the corresponding encoding. If it does not find an
+ − 1246
encoding declaration, then it assumes that the data is either in
+ − 1247
UTF-8 or UTF-16, depending on whether it can find a byte-order
+ − 1248
mark.
+ − 1249
+ − 1250
There are two ways to populate the input source with data: you can
+ − 1251
construct it with a QIODevice* so that the input source reads the
+ − 1252
data from that device. Or you can set the data explicitly with one
+ − 1253
of the setData() functions.
+ − 1254
+ − 1255
Usually you either construct a QXmlInputSource that works on a
+ − 1256
QIODevice* or you construct an empty QXmlInputSource and set the
+ − 1257
data with setData(). There are only rare occasions where you would
+ − 1258
want to mix both methods.
+ − 1259
+ − 1260
The QXmlReader subclasses use the next() function to read the
+ − 1261
input character by character. If you want to start from the
+ − 1262
beginning again, use reset().
+ − 1263
+ − 1264
The functions data() and fetchData() are useful if you want to do
+ − 1265
something with the data other than parsing, e.g. displaying the
+ − 1266
raw XML file. The benefit of using the QXmlInputClass in such
+ − 1267
cases is that it tries to use the correct encoding.
+ − 1268
+ − 1269
\sa QXmlReader QXmlSimpleReader
+ − 1270
*/
+ − 1271
+ − 1272
// the following two are guaranteed not to be a character
+ − 1273
const ushort QXmlInputSource::EndOfData = 0xfffe;
+ − 1274
const ushort QXmlInputSource::EndOfDocument = 0xffff;
+ − 1275
+ − 1276
/*
+ − 1277
Common part of the constructors.
+ − 1278
*/
+ − 1279
void QXmlInputSource::init()
+ − 1280
{
+ − 1281
d = new QXmlInputSourcePrivate;
+ − 1282
+ − 1283
QT_TRY {
+ − 1284
d->inputDevice = 0;
+ − 1285
d->inputStream = 0;
+ − 1286
+ − 1287
setData(QString());
+ − 1288
#ifndef QT_NO_TEXTCODEC
+ − 1289
d->encMapper = 0;
+ − 1290
#endif
+ − 1291
d->nextReturnedEndOfData = true; // first call to next() will call fetchData()
+ − 1292
+ − 1293
d->encodingDeclBytes.clear();
+ − 1294
d->encodingDeclChars.clear();
+ − 1295
d->lookingForEncodingDecl = true;
+ − 1296
} QT_CATCH(...) {
+ − 1297
delete(d);
+ − 1298
QT_RETHROW;
+ − 1299
}
+ − 1300
}
+ − 1301
+ − 1302
/*!
+ − 1303
Constructs an input source which contains no data.
+ − 1304
+ − 1305
\sa setData()
+ − 1306
*/
+ − 1307
QXmlInputSource::QXmlInputSource()
+ − 1308
{
+ − 1309
init();
+ − 1310
}
+ − 1311
+ − 1312
/*!
+ − 1313
Constructs an input source and gets the data from device \a dev.
+ − 1314
If \a dev is not open, it is opened in read-only mode. If \a dev
+ − 1315
is 0 or it is not possible to read from the device, the input
+ − 1316
source will contain no data.
+ − 1317
+ − 1318
\sa setData() fetchData() QIODevice
+ − 1319
*/
+ − 1320
QXmlInputSource::QXmlInputSource(QIODevice *dev)
+ − 1321
{
+ − 1322
init();
+ − 1323
d->inputDevice = dev;
+ − 1324
d->inputDevice->setTextModeEnabled(false);
+ − 1325
}
+ − 1326
+ − 1327
#ifdef QT3_SUPPORT
+ − 1328
/*!
+ − 1329
Use the QXmlInputSource(QIODevice *) constructor instead, with
+ − 1330
the device used by \a stream.
+ − 1331
+ − 1332
\sa QTextStream::device()
+ − 1333
*/
+ − 1334
QXmlInputSource::QXmlInputSource(QTextStream& stream)
+ − 1335
{
+ − 1336
init();
+ − 1337
d->inputStream = &stream;
+ − 1338
}
+ − 1339
+ − 1340
/*!
+ − 1341
Use QXmlInputSource(&\a file) instead.
+ − 1342
*/
+ − 1343
QXmlInputSource::QXmlInputSource(QFile& file)
+ − 1344
{
+ − 1345
init();
+ − 1346
d->inputDevice = &file;
+ − 1347
}
+ − 1348
#endif
+ − 1349
+ − 1350
/*!
+ − 1351
Destructor.
+ − 1352
*/
+ − 1353
QXmlInputSource::~QXmlInputSource()
+ − 1354
{
+ − 1355
// ### Qt 5: close the input device. See task 153111
+ − 1356
#ifndef QT_NO_TEXTCODEC
+ − 1357
delete d->encMapper;
+ − 1358
#endif
+ − 1359
delete d;
+ − 1360
}
+ − 1361
+ − 1362
/*!
+ − 1363
Returns the next character of the input source. If this function
+ − 1364
reaches the end of available data, it returns
+ − 1365
QXmlInputSource::EndOfData. If you call next() after that, it
+ − 1366
tries to fetch more data by calling fetchData(). If the
+ − 1367
fetchData() call results in new data, this function returns the
+ − 1368
first character of that data; otherwise it returns
+ − 1369
QXmlInputSource::EndOfDocument.
+ − 1370
+ − 1371
Readers, such as QXmlSimpleReader, will assume that the end of
+ − 1372
the XML document has been reached if the this function returns
+ − 1373
QXmlInputSource::EndOfDocument, and will check that the
+ − 1374
supplied input is well-formed. Therefore, when reimplementing
+ − 1375
this function, it is important to ensure that this behavior is
+ − 1376
duplicated.
+ − 1377
+ − 1378
\sa reset() fetchData() QXmlSimpleReader::parse() QXmlSimpleReader::parseContinue()
+ − 1379
*/
+ − 1380
QChar QXmlInputSource::next()
+ − 1381
{
+ − 1382
if (d->pos >= d->length) {
+ − 1383
if (d->nextReturnedEndOfData) {
+ − 1384
d->nextReturnedEndOfData = false;
+ − 1385
fetchData();
+ − 1386
if (d->pos >= d->length) {
+ − 1387
return EndOfDocument;
+ − 1388
}
+ − 1389
return next();
+ − 1390
}
+ − 1391
d->nextReturnedEndOfData = true;
+ − 1392
return EndOfData;
+ − 1393
}
+ − 1394
+ − 1395
// QXmlInputSource has no way to signal encoding errors. The best we can do
+ − 1396
// is return EndOfDocument. We do *not* return EndOfData, because the reader
+ − 1397
// will then just call this function again to get the next char.
+ − 1398
QChar c = d->unicode[d->pos++];
+ − 1399
if (c.unicode() == EndOfData)
+ − 1400
c = EndOfDocument;
+ − 1401
return c;
+ − 1402
}
+ − 1403
+ − 1404
/*!
+ − 1405
This function sets the position used by next() to the beginning of
+ − 1406
the data returned by data(). This is useful if you want to use the
+ − 1407
input source for more than one parse.
+ − 1408
+ − 1409
\note In the case that the underlying data source is a QIODevice,
+ − 1410
the current position in the device is not automatically set to the
+ − 1411
start of input. Call QIODevice::seek(0) on the device to do this.
+ − 1412
+ − 1413
\sa next()
+ − 1414
*/
+ − 1415
void QXmlInputSource::reset()
+ − 1416
{
+ − 1417
d->nextReturnedEndOfData = false;
+ − 1418
d->pos = 0;
+ − 1419
}
+ − 1420
+ − 1421
/*!
+ − 1422
Returns the data the input source contains or an empty string if the
+ − 1423
input source does not contain any data.
+ − 1424
+ − 1425
\sa setData() QXmlInputSource() fetchData()
+ − 1426
*/
+ − 1427
QString QXmlInputSource::data() const
+ − 1428
{
+ − 1429
if (d->nextReturnedEndOfData) {
+ − 1430
QXmlInputSource *that = const_cast<QXmlInputSource*>(this);
+ − 1431
that->d->nextReturnedEndOfData = false;
+ − 1432
that->fetchData();
+ − 1433
}
+ − 1434
return d->str;
+ − 1435
}
+ − 1436
+ − 1437
/*!
+ − 1438
Sets the data of the input source to \a dat.
+ − 1439
+ − 1440
If the input source already contains data, this function deletes
+ − 1441
that data first.
+ − 1442
+ − 1443
\sa data()
+ − 1444
*/
+ − 1445
void QXmlInputSource::setData(const QString& dat)
+ − 1446
{
+ − 1447
d->str = dat;
+ − 1448
d->unicode = dat.unicode();
+ − 1449
d->pos = 0;
+ − 1450
d->length = d->str.length();
+ − 1451
d->nextReturnedEndOfData = false;
+ − 1452
}
+ − 1453
+ − 1454
/*!
+ − 1455
\overload
+ − 1456
+ − 1457
The data \a dat is passed through the correct text-codec, before
+ − 1458
it is set.
+ − 1459
*/
+ − 1460
void QXmlInputSource::setData(const QByteArray& dat)
+ − 1461
{
+ − 1462
setData(fromRawData(dat));
+ − 1463
}
+ − 1464
+ − 1465
/*!
+ − 1466
This function reads more data from the device that was set during
+ − 1467
construction. If the input source already contained data, this
+ − 1468
function deletes that data first.
+ − 1469
+ − 1470
This object contains no data after a call to this function if the
+ − 1471
object was constructed without a device to read data from or if
+ − 1472
this function was not able to get more data from the device.
+ − 1473
+ − 1474
There are two occasions where a fetch is done implicitly by
+ − 1475
another function call: during construction (so that the object
+ − 1476
starts out with some initial data where available), and during a
+ − 1477
call to next() (if the data had run out).
+ − 1478
+ − 1479
You don't normally need to use this function if you use next().
+ − 1480
+ − 1481
\sa data() next() QXmlInputSource()
+ − 1482
*/
+ − 1483
+ − 1484
void QXmlInputSource::fetchData()
+ − 1485
{
+ − 1486
enum
+ − 1487
{
+ − 1488
BufferSize = 1024
+ − 1489
};
+ − 1490
+ − 1491
QByteArray rawData;
+ − 1492
+ − 1493
if (d->inputDevice || d->inputStream) {
+ − 1494
QIODevice *device = d->inputDevice ? d->inputDevice : d->inputStream->device();
+ − 1495
+ − 1496
if (!device) {
+ − 1497
if (d->inputStream && d->inputStream->string()) {
+ − 1498
QString *s = d->inputStream->string();
+ − 1499
rawData = QByteArray((const char *) s->constData(), s->size() * sizeof(QChar));
+ − 1500
}
+ − 1501
} else if (device->isOpen() || device->open(QIODevice::ReadOnly)) {
+ − 1502
rawData.resize(BufferSize);
+ − 1503
qint64 size = device->read(rawData.data(), BufferSize);
+ − 1504
+ − 1505
if (size != -1) {
+ − 1506
// We don't want to give fromRawData() less than four bytes if we can avoid it.
+ − 1507
while (size < 4) {
+ − 1508
if (!device->waitForReadyRead(-1))
+ − 1509
break;
+ − 1510
int ret = device->read(rawData.data() + size, BufferSize - size);
+ − 1511
if (ret <= 0)
+ − 1512
break;
+ − 1513
size += ret;
+ − 1514
}
+ − 1515
}
+ − 1516
+ − 1517
rawData.resize(qMax(qint64(0), size));
+ − 1518
}
+ − 1519
+ − 1520
/* We do this inside the "if (d->inputDevice ..." scope
+ − 1521
* because if we're not using a stream or device, that is,
+ − 1522
* the user set a QString manually, we don't want to set
+ − 1523
* d->str. */
+ − 1524
setData(fromRawData(rawData));
+ − 1525
}
+ − 1526
}
+ − 1527
+ − 1528
#ifndef QT_NO_TEXTCODEC
+ − 1529
static QString extractEncodingDecl(const QString &text, bool *needMoreText)
+ − 1530
{
+ − 1531
*needMoreText = false;
+ − 1532
+ − 1533
int l = text.length();
+ − 1534
QString snip = QString::fromLatin1("<?xml").left(l);
+ − 1535
if (l > 0 && !text.startsWith(snip))
+ − 1536
return QString();
+ − 1537
+ − 1538
int endPos = text.indexOf(QLatin1Char('>'));
+ − 1539
if (endPos == -1) {
+ − 1540
*needMoreText = l < 255; // we won't look forever
+ − 1541
return QString();
+ − 1542
}
+ − 1543
+ − 1544
int pos = text.indexOf(QLatin1String("encoding"));
+ − 1545
if (pos == -1 || pos >= endPos)
+ − 1546
return QString();
+ − 1547
+ − 1548
while (pos < endPos) {
+ − 1549
ushort uc = text.at(pos).unicode();
+ − 1550
if (uc == '\'' || uc == '"')
+ − 1551
break;
+ − 1552
++pos;
+ − 1553
}
+ − 1554
+ − 1555
if (pos == endPos)
+ − 1556
return QString();
+ − 1557
+ − 1558
QString encoding;
+ − 1559
++pos;
+ − 1560
while (pos < endPos) {
+ − 1561
ushort uc = text.at(pos).unicode();
+ − 1562
if (uc == '\'' || uc == '"')
+ − 1563
break;
+ − 1564
encoding.append(uc);
+ − 1565
++pos;
+ − 1566
}
+ − 1567
+ − 1568
return encoding;
+ − 1569
}
+ − 1570
#endif // QT_NO_TEXTCODEC
+ − 1571
+ − 1572
/*!
+ − 1573
This function reads the XML file from \a data and tries to
+ − 1574
recognize the encoding. It converts the raw data \a data into a
+ − 1575
QString and returns it. It tries its best to get the correct
+ − 1576
encoding for the XML file.
+ − 1577
+ − 1578
If \a beginning is true, this function assumes that the data
+ − 1579
starts at the beginning of a new XML document and looks for an
+ − 1580
encoding declaration. If \a beginning is false, it converts the
+ − 1581
raw data using the encoding determined from prior calls.
+ − 1582
*/
+ − 1583
QString QXmlInputSource::fromRawData(const QByteArray &data, bool beginning)
+ − 1584
{
+ − 1585
#ifdef QT_NO_TEXTCODEC
+ − 1586
Q_UNUSED(beginning);
+ − 1587
return QString::fromAscii(data.constData(), data.size());
+ − 1588
#else
+ − 1589
if (data.size() == 0)
+ − 1590
return QString();
+ − 1591
if (beginning) {
+ − 1592
delete d->encMapper;
+ − 1593
d->encMapper = 0;
+ − 1594
}
+ − 1595
+ − 1596
int mib = 106; // UTF-8
+ − 1597
+ − 1598
// This is the initial UTF codec we will read the encoding declaration with
+ − 1599
if (d->encMapper == 0) {
+ − 1600
d->encodingDeclBytes.clear();
+ − 1601
d->encodingDeclChars.clear();
+ − 1602
d->lookingForEncodingDecl = true;
+ − 1603
+ − 1604
// look for byte order mark and read the first 5 characters
+ − 1605
if (data.size() >= 4) {
+ − 1606
uchar ch1 = data.at(0);
+ − 1607
uchar ch2 = data.at(1);
+ − 1608
uchar ch3 = data.at(2);
+ − 1609
uchar ch4 = data.at(3);
+ − 1610
+ − 1611
if ((ch1 == 0 && ch2 == 0 && ch3 == 0xfe && ch4 == 0xff) ||
+ − 1612
(ch1 == 0xff && ch2 == 0xfe && ch3 == 0 && ch4 == 0))
+ − 1613
mib = 1017; // UTF-32 with byte order mark
+ − 1614
else if (ch1 == 0x3c && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x00)
+ − 1615
mib = 1019; // UTF-32LE
+ − 1616
else if (ch1 == 0x00 && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x3c)
+ − 1617
mib = 1018; // UTF-32BE
+ − 1618
}
+ − 1619
if (mib == 106 && data.size() >= 2) {
+ − 1620
uchar ch1 = data.at(0);
+ − 1621
uchar ch2 = data.at(1);
+ − 1622
+ − 1623
if ((ch1 == 0xfe && ch2 == 0xff) || (ch1 == 0xff && ch2 == 0xfe))
+ − 1624
mib = 1015; // UTF-16 with byte order mark
+ − 1625
else if (ch1 == 0x3c && ch2 == 0x00)
+ − 1626
mib = 1014; // UTF-16LE
+ − 1627
else if (ch1 == 0x00 && ch2 == 0x3c)
+ − 1628
mib = 1013; // UTF-16BE
+ − 1629
}
+ − 1630
+ − 1631
QTextCodec *codec = QTextCodec::codecForMib(mib);
+ − 1632
Q_ASSERT(codec);
+ − 1633
+ − 1634
d->encMapper = codec->makeDecoder();
+ − 1635
}
+ − 1636
+ − 1637
QString input = d->encMapper->toUnicode(data, data.size());
+ − 1638
+ − 1639
if (d->lookingForEncodingDecl) {
+ − 1640
d->encodingDeclChars += input;
+ − 1641
+ − 1642
bool needMoreText;
+ − 1643
QString encoding = extractEncodingDecl(d->encodingDeclChars, &needMoreText);
+ − 1644
+ − 1645
if (!encoding.isEmpty()) {
+ − 1646
if (QTextCodec *codec = QTextCodec::codecForName(encoding.toLatin1())) {
+ − 1647
/* If the encoding is the same, we don't have to do toUnicode() all over again. */
+ − 1648
if(codec->mibEnum() != mib) {
+ − 1649
delete d->encMapper;
+ − 1650
d->encMapper = codec->makeDecoder();
+ − 1651
+ − 1652
/* The variable input can potentially be large, so we deallocate
+ − 1653
* it before calling toUnicode() in order to avoid having two
+ − 1654
* large QStrings in memory simultaneously. */
+ − 1655
input.clear();
+ − 1656
+ − 1657
// prime the decoder with the data so far
+ − 1658
d->encMapper->toUnicode(d->encodingDeclBytes, d->encodingDeclBytes.size());
+ − 1659
// now feed it the new data
+ − 1660
input = d->encMapper->toUnicode(data, data.size());
+ − 1661
}
+ − 1662
}
+ − 1663
}
+ − 1664
+ − 1665
d->encodingDeclBytes += data;
+ − 1666
d->lookingForEncodingDecl = needMoreText;
+ − 1667
}
+ − 1668
+ − 1669
return input;
+ − 1670
#endif
+ − 1671
}
+ − 1672
+ − 1673
+ − 1674
/*********************************************
+ − 1675
*
+ − 1676
* QXmlDefaultHandler
+ − 1677
*
+ − 1678
*********************************************/
+ − 1679
+ − 1680
/*!
+ − 1681
\class QXmlContentHandler
+ − 1682
\reentrant
+ − 1683
\brief The QXmlContentHandler class provides an interface to
+ − 1684
report the logical content of XML data.
+ − 1685
+ − 1686
\inmodule QtXml
+ − 1687
\ingroup xml-tools
+ − 1688
+ − 1689
If the application needs to be informed of basic parsing events,
+ − 1690
it can implement this interface and activate it using
+ − 1691
QXmlReader::setContentHandler(). The reader can then report basic
+ − 1692
document-related events like the start and end of elements and
+ − 1693
character data through this interface.
+ − 1694
+ − 1695
The order of events in this interface is very important, and
+ − 1696
mirrors the order of information in the document itself. For
+ − 1697
example, all of an element's content (character data, processing
+ − 1698
instructions, and sub-elements) appears, in order, between the
+ − 1699
startElement() event and the corresponding endElement() event.
+ − 1700
+ − 1701
The class QXmlDefaultHandler provides a default implementation for
+ − 1702
this interface; subclassing from the QXmlDefaultHandler class is
+ − 1703
very convenient if you only want to be informed of some parsing
+ − 1704
events.
+ − 1705
+ − 1706
The startDocument() function is called at the start of the
+ − 1707
document, and endDocument() is called at the end. Before parsing
+ − 1708
begins setDocumentLocator() is called. For each element
+ − 1709
startElement() is called, with endElement() being called at the
+ − 1710
end of each element. The characters() function is called with
+ − 1711
chunks of character data; ignorableWhitespace() is called with
+ − 1712
chunks of whitespace and processingInstruction() is called with
+ − 1713
processing instructions. If an entity is skipped skippedEntity()
+ − 1714
is called. At the beginning of prefix-URI scopes
+ − 1715
startPrefixMapping() is called.
+ − 1716
+ − 1717
\sa QXmlDTDHandler, QXmlDeclHandler, QXmlEntityResolver, QXmlErrorHandler,
+ − 1718
QXmlLexicalHandler, {Introduction to SAX2}
+ − 1719
*/
+ − 1720
+ − 1721
/*!
+ − 1722
\fn QXmlContentHandler::~QXmlContentHandler()
+ − 1723
+ − 1724
Destroys the content handler.
+ − 1725
*/
+ − 1726
+ − 1727
/*!
+ − 1728
\fn void QXmlContentHandler::setDocumentLocator(QXmlLocator* locator)
+ − 1729
+ − 1730
The reader calls this function before it starts parsing the
+ − 1731
document. The argument \a locator is a pointer to a QXmlLocator
+ − 1732
which allows the application to get the parsing position within
+ − 1733
the document.
+ − 1734
+ − 1735
Do not destroy the \a locator; it is destroyed when the reader is
+ − 1736
destroyed. (Do not use the \a locator after the reader is
+ − 1737
destroyed).
+ − 1738
*/
+ − 1739
+ − 1740
/*!
+ − 1741
\fn bool QXmlContentHandler::startDocument()
+ − 1742
+ − 1743
The reader calls this function when it starts parsing the
+ − 1744
document. The reader calls this function just once, after the call
+ − 1745
to setDocumentLocator(), and before any other functions in this
+ − 1746
class or in the QXmlDTDHandler class are called.
+ − 1747
+ − 1748
If this function returns false the reader stops parsing and
+ − 1749
reports an error. The reader uses the function errorString() to
+ − 1750
get the error message.
+ − 1751
+ − 1752
\sa endDocument()
+ − 1753
*/
+ − 1754
+ − 1755
/*!
+ − 1756
\fn bool QXmlContentHandler::endDocument()
+ − 1757
+ − 1758
The reader calls this function after it has finished parsing. It
+ − 1759
is called just once, and is the last handler function called. It
+ − 1760
is called after the reader has read all input or has abandoned
+ − 1761
parsing because of a fatal error.
+ − 1762
+ − 1763
If this function returns false the reader stops parsing and
+ − 1764
reports an error. The reader uses the function errorString() to
+ − 1765
get the error message.
+ − 1766
+ − 1767
\sa startDocument()
+ − 1768
*/
+ − 1769
+ − 1770
/*!
+ − 1771
\fn bool QXmlContentHandler::startPrefixMapping(const QString& prefix, const QString& uri)
+ − 1772
+ − 1773
The reader calls this function to signal the begin of a prefix-URI
+ − 1774
namespace mapping scope. This information is not necessary for
+ − 1775
normal namespace processing since the reader automatically
+ − 1776
replaces prefixes for element and attribute names.
+ − 1777
+ − 1778
Note that startPrefixMapping() and endPrefixMapping() calls are
+ − 1779
not guaranteed to be properly nested relative to each other: all
+ − 1780
startPrefixMapping() events occur before the corresponding
+ − 1781
startElement() event, and all endPrefixMapping() events occur
+ − 1782
after the corresponding endElement() event, but their order is not
+ − 1783
otherwise guaranteed.
+ − 1784
+ − 1785
The argument \a prefix is the namespace prefix being declared and
+ − 1786
the argument \a uri is the namespace URI the prefix is mapped to.
+ − 1787
+ − 1788
If this function returns false the reader stops parsing and
+ − 1789
reports an error. The reader uses the function errorString() to
+ − 1790
get the error message.
+ − 1791
+ − 1792
\sa endPrefixMapping(), {Namespace Support via Features}
+ − 1793
*/
+ − 1794
+ − 1795
/*!
+ − 1796
\fn bool QXmlContentHandler::endPrefixMapping(const QString& prefix)
+ − 1797
+ − 1798
The reader calls this function to signal the end of a prefix
+ − 1799
mapping for the prefix \a prefix.
+ − 1800
+ − 1801
If this function returns false the reader stops parsing and
+ − 1802
reports an error. The reader uses the function errorString() to
+ − 1803
get the error message.
+ − 1804
+ − 1805
\sa startPrefixMapping(), {Namespace Support via Features}
+ − 1806
*/
+ − 1807
+ − 1808
/*!
+ − 1809
\fn bool QXmlContentHandler::startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts)
+ − 1810
+ − 1811
The reader calls this function when it has parsed a start element
+ − 1812
tag.
+ − 1813
+ − 1814
There is a corresponding endElement() call when the corresponding
+ − 1815
end element tag is read. The startElement() and endElement() calls
+ − 1816
are always nested correctly. Empty element tags (e.g. \c{<x/>})
+ − 1817
cause a startElement() call to be immediately followed by an
+ − 1818
endElement() call.
+ − 1819
+ − 1820
The attribute list provided only contains attributes with explicit
+ − 1821
values. The attribute list contains attributes used for namespace
+ − 1822
declaration (i.e. attributes starting with xmlns) only if the
+ − 1823
namespace-prefix property of the reader is true.
+ − 1824
+ − 1825
The argument \a namespaceURI is the namespace URI, or
+ − 1826
an empty string if the element has no namespace URI or if no
+ − 1827
namespace processing is done. \a localName is the local name
+ − 1828
(without prefix), or an empty string if no namespace processing is
+ − 1829
done, \a qName is the qualified name (with prefix) and \a atts are
+ − 1830
the attributes attached to the element. If there are no
+ − 1831
attributes, \a atts is an empty attributes object.
+ − 1832
+ − 1833
If this function returns false the reader stops parsing and
+ − 1834
reports an error. The reader uses the function errorString() to
+ − 1835
get the error message.
+ − 1836
+ − 1837
\sa endElement(), {Namespace Support via Features}
+ − 1838
*/
+ − 1839
+ − 1840
/*!
+ − 1841
\fn bool QXmlContentHandler::endElement(const QString& namespaceURI, const QString& localName, const QString& qName)
+ − 1842
+ − 1843
The reader calls this function when it has parsed an end element
+ − 1844
tag with the qualified name \a qName, the local name \a localName
+ − 1845
and the namespace URI \a namespaceURI.
+ − 1846
+ − 1847
If this function returns false the reader stops parsing and
+ − 1848
reports an error. The reader uses the function errorString() to
+ − 1849
get the error message.
+ − 1850
+ − 1851
\sa startElement(), {Namespace Support via Features}
+ − 1852
*/
+ − 1853
+ − 1854
/*!
+ − 1855
\fn bool QXmlContentHandler::characters(const QString& ch)
+ − 1856
+ − 1857
The reader calls this function when it has parsed a chunk of
+ − 1858
character data (either normal character data or character data
+ − 1859
inside a CDATA section; if you need to distinguish between those
+ − 1860
two types you must use QXmlLexicalHandler::startCDATA() and
+ − 1861
QXmlLexicalHandler::endCDATA()). The character data is reported in
+ − 1862
\a ch.
+ − 1863
+ − 1864
Some readers report whitespace in element content using the
+ − 1865
ignorableWhitespace() function rather than using this one.
+ − 1866
+ − 1867
A reader may report the character data of an element in more than
+ − 1868
one chunk; e.g. a reader might want to report "a\<b" in three
+ − 1869
characters() events ("a ", "\<" and " b").
+ − 1870
+ − 1871
If this function returns false the reader stops parsing and
+ − 1872
reports an error. The reader uses the function errorString() to
+ − 1873
get the error message.
+ − 1874
*/
+ − 1875
+ − 1876
/*!
+ − 1877
\fn bool QXmlContentHandler::ignorableWhitespace(const QString& ch)
+ − 1878
+ − 1879
Some readers may use this function to report each chunk of
+ − 1880
whitespace in element content. The whitespace is reported in \a ch.
+ − 1881
+ − 1882
If this function returns false the reader stops parsing and
+ − 1883
reports an error. The reader uses the function errorString() to
+ − 1884
get the error message.
+ − 1885
*/
+ − 1886
+ − 1887
/*!
+ − 1888
\fn bool QXmlContentHandler::processingInstruction(const QString& target, const QString& data)
+ − 1889
+ − 1890
The reader calls this function when it has parsed a processing
+ − 1891
instruction.
+ − 1892
+ − 1893
\a target is the target name of the processing instruction and \a
+ − 1894
data is the data in the processing instruction.
+ − 1895
+ − 1896
If this function returns false the reader stops parsing and
+ − 1897
reports an error. The reader uses the function errorString() to
+ − 1898
get the error message.
+ − 1899
*/
+ − 1900
+ − 1901
/*!
+ − 1902
\fn bool QXmlContentHandler::skippedEntity(const QString& name)
+ − 1903
+ − 1904
Some readers may skip entities if they have not seen the
+ − 1905
declarations (e.g. because they are in an external DTD). If they
+ − 1906
do so they report that they skipped the entity called \a name by
+ − 1907
calling this function.
+ − 1908
+ − 1909
If this function returns false the reader stops parsing and
+ − 1910
reports an error. The reader uses the function errorString() to
+ − 1911
get the error message.
+ − 1912
*/
+ − 1913
+ − 1914
/*!
+ − 1915
\fn QString QXmlContentHandler::errorString() const
+ − 1916
+ − 1917
The reader calls this function to get an error string, e.g. if any
+ − 1918
of the handler functions returns false.
+ − 1919
*/
+ − 1920
+ − 1921
+ − 1922
/*!
+ − 1923
\class QXmlErrorHandler
+ − 1924
\reentrant
+ − 1925
\brief The QXmlErrorHandler class provides an interface to report
+ − 1926
errors in XML data.
+ − 1927
+ − 1928
\inmodule QtXml
+ − 1929
\ingroup xml-tools
+ − 1930
+ − 1931
If you want your application to report errors to the user or to
+ − 1932
perform customized error handling, you should subclass this class.
+ − 1933
+ − 1934
You can set the error handler with QXmlReader::setErrorHandler().
+ − 1935
+ − 1936
Errors can be reported using warning(), error() and fatalError(),
+ − 1937
with the error text being reported with errorString().
+ − 1938
+ − 1939
\sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ − 1940
QXmlLexicalHandler, {Introduction to SAX2}
+ − 1941
*/
+ − 1942
+ − 1943
/*!
+ − 1944
\fn QXmlErrorHandler::~QXmlErrorHandler()
+ − 1945
+ − 1946
Destroys the error handler.
+ − 1947
*/
+ − 1948
+ − 1949
/*!
+ − 1950
\fn bool QXmlErrorHandler::warning(const QXmlParseException& exception)
+ − 1951
+ − 1952
A reader might use this function to report a warning. Warnings are
+ − 1953
conditions that are not errors or fatal errors as defined by the
+ − 1954
XML 1.0 specification. Details of the warning are stored in \a
+ − 1955
exception.
+ − 1956
+ − 1957
If this function returns false the reader stops parsing and
+ − 1958
reports an error. The reader uses the function errorString() to
+ − 1959
get the error message.
+ − 1960
*/
+ − 1961
+ − 1962
/*!
+ − 1963
\fn bool QXmlErrorHandler::error(const QXmlParseException& exception)
+ − 1964
+ − 1965
A reader might use this function to report a recoverable error. A
+ − 1966
recoverable error corresponds to the definiton of "error" in
+ − 1967
section 1.2 of the XML 1.0 specification. Details of the error are
+ − 1968
stored in \a exception.
+ − 1969
+ − 1970
The reader must continue to provide normal parsing events after
+ − 1971
invoking this function.
+ − 1972
+ − 1973
If this function returns false the reader stops parsing and
+ − 1974
reports an error. The reader uses the function errorString() to
+ − 1975
get the error message.
+ − 1976
*/
+ − 1977
+ − 1978
/*!
+ − 1979
\fn bool QXmlErrorHandler::fatalError(const QXmlParseException& exception)
+ − 1980
+ − 1981
A reader must use this function to report a non-recoverable error.
+ − 1982
Details of the error are stored in \a exception.
+ − 1983
+ − 1984
If this function returns true the reader might try to go on
+ − 1985
parsing and reporting further errors, but no regular parsing
+ − 1986
events are reported.
+ − 1987
*/
+ − 1988
+ − 1989
/*!
+ − 1990
\fn QString QXmlErrorHandler::errorString() const
+ − 1991
+ − 1992
The reader calls this function to get an error string if any of
+ − 1993
the handler functions returns false.
+ − 1994
*/
+ − 1995
+ − 1996
+ − 1997
/*!
+ − 1998
\class QXmlDTDHandler
+ − 1999
\reentrant
+ − 2000
\brief The QXmlDTDHandler class provides an interface to report
+ − 2001
DTD content of XML data.
+ − 2002
+ − 2003
\inmodule QtXml
+ − 2004
\ingroup xml-tools
+ − 2005
+ − 2006
If an application needs information about notations and unparsed
+ − 2007
entities, it can implement this interface and register an instance
+ − 2008
with QXmlReader::setDTDHandler().
+ − 2009
+ − 2010
Note that this interface includes only those DTD events that the
+ − 2011
XML recommendation requires processors to report, i.e. notation
+ − 2012
and unparsed entity declarations using notationDecl() and
+ − 2013
unparsedEntityDecl() respectively.
+ − 2014
+ − 2015
\sa QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler,
+ − 2016
QXmlLexicalHandler, {Introduction to SAX2}
+ − 2017
*/
+ − 2018
+ − 2019
/*!
+ − 2020
\fn QXmlDTDHandler::~QXmlDTDHandler()
+ − 2021
+ − 2022
Destroys the DTD handler.
+ − 2023
*/
+ − 2024
+ − 2025
/*!
+ − 2026
\fn bool QXmlDTDHandler::notationDecl(const QString& name, const QString& publicId, const QString& systemId)
+ − 2027
+ − 2028
The reader calls this function when it has parsed a notation
+ − 2029
declaration.
+ − 2030
+ − 2031
The argument \a name is the notation name, \a publicId is the
+ − 2032
notation's public identifier and \a systemId is the notation's
+ − 2033
system identifier.
+ − 2034
+ − 2035
If this function returns false the reader stops parsing and
+ − 2036
reports an error. The reader uses the function errorString() to
+ − 2037
get the error message.
+ − 2038
*/
+ − 2039
+ − 2040
/*!
+ − 2041
\fn bool QXmlDTDHandler::unparsedEntityDecl(const QString& name, const QString& publicId, const QString& systemId, const QString& notationName)
+ − 2042
+ − 2043
The reader calls this function when it finds an unparsed entity
+ − 2044
declaration.
+ − 2045
+ − 2046
The argument \a name is the unparsed entity's name, \a publicId is
+ − 2047
the entity's public identifier, \a systemId is the entity's system
+ − 2048
identifier and \a notationName is the name of the associated
+ − 2049
notation.
+ − 2050
+ − 2051
If this function returns false the reader stops parsing and
+ − 2052
reports an error. The reader uses the function errorString() to
+ − 2053
get the error message.
+ − 2054
*/
+ − 2055
+ − 2056
/*!
+ − 2057
\fn QString QXmlDTDHandler::errorString() const
+ − 2058
+ − 2059
The reader calls this function to get an error string if any of
+ − 2060
the handler functions returns false.
+ − 2061
*/
+ − 2062
+ − 2063
+ − 2064
/*!
+ − 2065
\class QXmlEntityResolver
+ − 2066
\reentrant
+ − 2067
\brief The QXmlEntityResolver class provides an interface to
+ − 2068
resolve external entities contained in XML data.
+ − 2069
+ − 2070
\inmodule QtXml
+ − 2071
\ingroup xml-tools
+ − 2072
+ − 2073
If an application needs to implement customized handling for
+ − 2074
external entities, it must implement this interface, i.e.
+ − 2075
resolveEntity(), and register it with
+ − 2076
QXmlReader::setEntityResolver().
+ − 2077
+ − 2078
\sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlErrorHandler,
+ − 2079
QXmlLexicalHandler, {Introduction to SAX2}
+ − 2080
*/
+ − 2081
+ − 2082
/*!
+ − 2083
\fn QXmlEntityResolver::~QXmlEntityResolver()
+ − 2084
+ − 2085
Destroys the entity resolver.
+ − 2086
*/
+ − 2087
+ − 2088
/*!
+ − 2089
\fn bool QXmlEntityResolver::resolveEntity(const QString& publicId, const QString& systemId, QXmlInputSource*& ret)
+ − 2090
+ − 2091
The reader calls this function before it opens any external
+ − 2092
entity, except the top-level document entity. The application may
+ − 2093
request the reader to resolve the entity itself (\a ret is 0) or
+ − 2094
to use an entirely different input source (\a ret points to the
+ − 2095
input source).
+ − 2096
+ − 2097
The reader deletes the input source \a ret when it no longer needs
+ − 2098
it, so you should allocate it on the heap with \c new.
+ − 2099
+ − 2100
The argument \a publicId is the public identifier of the external
+ − 2101
entity, \a systemId is the system identifier of the external
+ − 2102
entity and \a ret is the return value of this function. If \a ret
+ − 2103
is 0 the reader should resolve the entity itself, if it is
+ − 2104
non-zero it must point to an input source which the reader uses
+ − 2105
instead.
+ − 2106
+ − 2107
If this function returns false the reader stops parsing and
+ − 2108
reports an error. The reader uses the function errorString() to
+ − 2109
get the error message.
+ − 2110
*/
+ − 2111
+ − 2112
/*!
+ − 2113
\fn QString QXmlEntityResolver::errorString() const
+ − 2114
+ − 2115
The reader calls this function to get an error string if any of
+ − 2116
the handler functions returns false.
+ − 2117
*/
+ − 2118
+ − 2119
+ − 2120
/*!
+ − 2121
\class QXmlLexicalHandler
+ − 2122
\reentrant
+ − 2123
\brief The QXmlLexicalHandler class provides an interface to
+ − 2124
report the lexical content of XML data.
+ − 2125
+ − 2126
\inmodule QtXml
+ − 2127
\ingroup xml-tools
+ − 2128
+ − 2129
The events in the lexical handler apply to the entire document,
+ − 2130
not just to the document element, and all lexical handler events
+ − 2131
appear between the content handler's startDocument and endDocument
+ − 2132
events.
+ − 2133
+ − 2134
You can set the lexical handler with
+ − 2135
QXmlReader::setLexicalHandler().
+ − 2136
+ − 2137
This interface's design is based on the SAX2 extension
+ − 2138
LexicalHandler.
+ − 2139
+ − 2140
The interface provides the startDTD(), endDTD(), startEntity(),
+ − 2141
endEntity(), startCDATA(), endCDATA() and comment() functions.
+ − 2142
+ − 2143
\sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ − 2144
QXmlErrorHandler, {Introduction to SAX2}
+ − 2145
*/
+ − 2146
+ − 2147
/*!
+ − 2148
\fn QXmlLexicalHandler::~QXmlLexicalHandler()
+ − 2149
+ − 2150
Destroys the lexical handler.
+ − 2151
*/
+ − 2152
+ − 2153
/*!
+ − 2154
\fn bool QXmlLexicalHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId)
+ − 2155
+ − 2156
The reader calls this function to report the start of a DTD
+ − 2157
declaration, if any. It reports the name of the document type in
+ − 2158
\a name, the public identifier in \a publicId and the system
+ − 2159
identifier in \a systemId.
+ − 2160
+ − 2161
If the public identifier is missing, \a publicId is set to
+ − 2162
an empty string. If the system identifier is missing, \a systemId is
+ − 2163
set to an empty string. Note that it is not valid XML to have a
+ − 2164
public identifier but no system identifier; in such cases a parse
+ − 2165
error will occur.
+ − 2166
+ − 2167
All declarations reported through QXmlDTDHandler or
+ − 2168
QXmlDeclHandler appear between the startDTD() and endDTD() calls.
+ − 2169
+ − 2170
If this function returns false the reader stops parsing and
+ − 2171
reports an error. The reader uses the function errorString() to
+ − 2172
get the error message.
+ − 2173
+ − 2174
\sa endDTD()
+ − 2175
*/
+ − 2176
+ − 2177
/*!
+ − 2178
\fn bool QXmlLexicalHandler::endDTD()
+ − 2179
+ − 2180
The reader calls this function to report the end of a DTD
+ − 2181
declaration, if any.
+ − 2182
+ − 2183
If this function returns false the reader stops parsing and
+ − 2184
reports an error. The reader uses the function errorString() to
+ − 2185
get the error message.
+ − 2186
+ − 2187
\sa startDTD()
+ − 2188
*/
+ − 2189
+ − 2190
/*!
+ − 2191
\fn bool QXmlLexicalHandler::startEntity(const QString& name)
+ − 2192
+ − 2193
The reader calls this function to report the start of an entity
+ − 2194
called \a name.
+ − 2195
+ − 2196
Note that if the entity is unknown, the reader reports it through
+ − 2197
QXmlContentHandler::skippedEntity() and not through this
+ − 2198
function.
+ − 2199
+ − 2200
If this function returns false the reader stops parsing and
+ − 2201
reports an error. The reader uses the function errorString() to
+ − 2202
get the error message.
+ − 2203
+ − 2204
\sa endEntity(), QXmlSimpleReader::setFeature()
+ − 2205
*/
+ − 2206
+ − 2207
/*!
+ − 2208
\fn bool QXmlLexicalHandler::endEntity(const QString& name)
+ − 2209
+ − 2210
The reader calls this function to report the end of an entity
+ − 2211
called \a name.
+ − 2212
+ − 2213
For every startEntity() call, there is a corresponding endEntity()
+ − 2214
call. The calls to startEntity() and endEntity() are properly
+ − 2215
nested.
+ − 2216
+ − 2217
If this function returns false the reader stops parsing and
+ − 2218
reports an error. The reader uses the function errorString() to
+ − 2219
get the error message.
+ − 2220
+ − 2221
\sa startEntity(), QXmlContentHandler::skippedEntity(), QXmlSimpleReader::setFeature()
+ − 2222
*/
+ − 2223
+ − 2224
/*!
+ − 2225
\fn bool QXmlLexicalHandler::startCDATA()
+ − 2226
+ − 2227
The reader calls this function to report the start of a CDATA
+ − 2228
section. The content of the CDATA section is reported through the
+ − 2229
QXmlContentHandler::characters() function. This function is
+ − 2230
intended only to report the boundary.
+ − 2231
+ − 2232
If this function returns false the reader stops parsing and
+ − 2233
reports an error. The reader uses the function errorString() to
+ − 2234
get the error message.
+ − 2235
+ − 2236
\sa endCDATA()
+ − 2237
*/
+ − 2238
+ − 2239
/*!
+ − 2240
\fn bool QXmlLexicalHandler::endCDATA()
+ − 2241
+ − 2242
The reader calls this function to report the end of a CDATA
+ − 2243
section.
+ − 2244
+ − 2245
If this function returns false the reader stops parsing and reports
+ − 2246
an error. The reader uses the function errorString() to get the error
+ − 2247
message.
+ − 2248
+ − 2249
\sa startCDATA(), QXmlContentHandler::characters()
+ − 2250
*/
+ − 2251
+ − 2252
/*!
+ − 2253
\fn bool QXmlLexicalHandler::comment(const QString& ch)
+ − 2254
+ − 2255
The reader calls this function to report an XML comment anywhere
+ − 2256
in the document. It reports the text of the comment in \a ch.
+ − 2257
+ − 2258
If this function returns false the reader stops parsing and
+ − 2259
reports an error. The reader uses the function errorString() to
+ − 2260
get the error message.
+ − 2261
*/
+ − 2262
+ − 2263
/*!
+ − 2264
\fn QString QXmlLexicalHandler::errorString() const
+ − 2265
+ − 2266
The reader calls this function to get an error string if any of
+ − 2267
the handler functions returns false.
+ − 2268
*/
+ − 2269
+ − 2270
+ − 2271
/*!
+ − 2272
\class QXmlDeclHandler
+ − 2273
\reentrant
+ − 2274
\brief The QXmlDeclHandler class provides an interface to report declaration
+ − 2275
content of XML data.
+ − 2276
+ − 2277
\inmodule QtXml
+ − 2278
\ingroup xml-tools
+ − 2279
+ − 2280
You can set the declaration handler with
+ − 2281
QXmlReader::setDeclHandler().
+ − 2282
+ − 2283
This interface is based on the SAX2 extension DeclHandler.
+ − 2284
+ − 2285
The interface provides attributeDecl(), internalEntityDecl() and
+ − 2286
externalEntityDecl() functions.
+ − 2287
+ − 2288
\sa QXmlDTDHandler, QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler,
+ − 2289
QXmlLexicalHandler, {Introduction to SAX2}
+ − 2290
*/
+ − 2291
+ − 2292
/*!
+ − 2293
\fn QXmlDeclHandler::~QXmlDeclHandler()
+ − 2294
+ − 2295
Destroys the declaration handler.
+ − 2296
*/
+ − 2297
+ − 2298
/*!
+ − 2299
\fn bool QXmlDeclHandler::attributeDecl(const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value)
+ − 2300
+ − 2301
The reader calls this function to report an attribute type
+ − 2302
declaration. Only the effective (first) declaration for an
+ − 2303
attribute is reported.
+ − 2304
+ − 2305
The reader passes the name of the associated element in \a eName
+ − 2306
and the name of the attribute in \a aName. It passes a string that
+ − 2307
represents the attribute type in \a type and a string that
+ − 2308
represents the attribute default in \a valueDefault. This string
+ − 2309
is one of "#IMPLIED", "#REQUIRED", "#FIXED" or an empty string (if
+ − 2310
none of the others applies). The reader passes the attribute's
+ − 2311
default value in \a value. If no default value is specified in the
+ − 2312
XML file, \a value is an empty string.
+ − 2313
+ − 2314
If this function returns false the reader stops parsing and
+ − 2315
reports an error. The reader uses the function errorString() to
+ − 2316
get the error message.
+ − 2317
*/
+ − 2318
+ − 2319
/*!
+ − 2320
\fn bool QXmlDeclHandler::internalEntityDecl(const QString& name, const QString& value)
+ − 2321
+ − 2322
The reader calls this function to report an internal entity
+ − 2323
declaration. Only the effective (first) declaration is reported.
+ − 2324
+ − 2325
The reader passes the name of the entity in \a name and the value
+ − 2326
of the entity in \a value.
+ − 2327
+ − 2328
If this function returns false the reader stops parsing and
+ − 2329
reports an error. The reader uses the function errorString() to
+ − 2330
get the error message.
+ − 2331
*/
+ − 2332
+ − 2333
/*!
+ − 2334
\fn bool QXmlDeclHandler::externalEntityDecl(const QString& name, const QString& publicId, const QString& systemId)
+ − 2335
+ − 2336
The reader calls this function to report a parsed external entity
+ − 2337
declaration. Only the effective (first) declaration for each
+ − 2338
entity is reported.
+ − 2339
+ − 2340
The reader passes the name of the entity in \a name, the public
+ − 2341
identifier in \a publicId and the system identifier in \a
+ − 2342
systemId. If there is no public identifier specified, it passes
+ − 2343
an empty string in \a publicId.
+ − 2344
+ − 2345
If this function returns false the reader stops parsing and
+ − 2346
reports an error. The reader uses the function errorString() to
+ − 2347
get the error message.
+ − 2348
*/
+ − 2349
+ − 2350
/*!
+ − 2351
\fn QString QXmlDeclHandler::errorString() const
+ − 2352
+ − 2353
The reader calls this function to get an error string if any of
+ − 2354
the handler functions returns false.
+ − 2355
*/
+ − 2356
+ − 2357
+ − 2358
/*!
+ − 2359
\class QXmlDefaultHandler
+ − 2360
\reentrant
+ − 2361
\brief The QXmlDefaultHandler class provides a default implementation of all
+ − 2362
the XML handler classes.
+ − 2363
+ − 2364
\inmodule QtXml
+ − 2365
\ingroup xml-tools
+ − 2366
+ − 2367
This class gathers together the features of
+ − 2368
the specialized handler classes, making it a convenient
+ − 2369
starting point when implementing custom handlers for
+ − 2370
subclasses of QXmlReader, particularly QXmlSimpleReader.
+ − 2371
The virtual functions from each of the base classes are
+ − 2372
reimplemented in this class, providing sensible default behavior
+ − 2373
for many common cases. By subclassing this class, and
+ − 2374
overriding these functions, you can concentrate
+ − 2375
on implementing the parts of the handler relevant to your
+ − 2376
application.
+ − 2377
+ − 2378
The XML reader must be told which handler to use for different
+ − 2379
kinds of events during parsing. This means that, although
+ − 2380
QXmlDefaultHandler provides default implementations of functions
+ − 2381
inherited from all its base classes, we can still use specialized
+ − 2382
handlers for particular kinds of events.
+ − 2383
+ − 2384
For example, QXmlDefaultHandler subclasses both
+ − 2385
QXmlContentHandler and QXmlErrorHandler, so by subclassing
+ − 2386
it we can use the same handler for both of the following
+ − 2387
reader functions:
+ − 2388
+ − 2389
\snippet doc/src/snippets/xml/rsslisting/rsslisting.cpp 0
+ − 2390
+ − 2391
Since the reader will inform the handler of parsing errors, it is
+ − 2392
necessary to reimplement QXmlErrorHandler::fatalError() if, for
+ − 2393
example, we want to stop parsing when such an error occurs:
+ − 2394
+ − 2395
\snippet doc/src/snippets/xml/rsslisting/handler.cpp 0
+ − 2396
+ − 2397
The above function returns false, which tells the reader to stop
+ − 2398
parsing. To continue to use the same reader,
+ − 2399
it is necessary to create a new handler instance, and set up the
+ − 2400
reader to use it in the manner described above.
+ − 2401
+ − 2402
It is useful to examine some of the functions inherited by
+ − 2403
QXmlDefaultHandler, and consider why they might be
+ − 2404
reimplemented in a custom handler.
+ − 2405
Custom handlers will typically reimplement
+ − 2406
QXmlContentHandler::startDocument() to prepare the handler for
+ − 2407
new content. Document elements and the text within them can be
+ − 2408
processed by reimplementing QXmlContentHandler::startElement(),
+ − 2409
QXmlContentHandler::endElement(), and
+ − 2410
QXmlContentHandler::characters().
+ − 2411
You may want to reimplement QXmlContentHandler::endDocument()
+ − 2412
to perform some finalization or validation on the content once the
+ − 2413
document has been read completely.
+ − 2414
+ − 2415
\sa QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ − 2416
QXmlErrorHandler, QXmlLexicalHandler, {Introduction to SAX2}
+ − 2417
*/
+ − 2418
+ − 2419
/*!
+ − 2420
\fn QXmlDefaultHandler::QXmlDefaultHandler()
+ − 2421
+ − 2422
Constructs a handler for use with subclasses of QXmlReader.
+ − 2423
*/
+ − 2424
/*!
+ − 2425
\fn QXmlDefaultHandler::~QXmlDefaultHandler()
+ − 2426
+ − 2427
Destroys the handler.
+ − 2428
*/
+ − 2429
+ − 2430
/*!
+ − 2431
\reimp
+ − 2432
+ − 2433
This reimplementation does nothing.
+ − 2434
*/
+ − 2435
void QXmlDefaultHandler::setDocumentLocator(QXmlLocator*)
+ − 2436
{
+ − 2437
}
+ − 2438
+ − 2439
/*!
+ − 2440
\reimp
+ − 2441
+ − 2442
This reimplementation does nothing.
+ − 2443
*/
+ − 2444
bool QXmlDefaultHandler::startDocument()
+ − 2445
{
+ − 2446
return true;
+ − 2447
}
+ − 2448
+ − 2449
/*!
+ − 2450
\reimp
+ − 2451
+ − 2452
This reimplementation does nothing.
+ − 2453
*/
+ − 2454
bool QXmlDefaultHandler::endDocument()
+ − 2455
{
+ − 2456
return true;
+ − 2457
}
+ − 2458
+ − 2459
/*!
+ − 2460
\reimp
+ − 2461
+ − 2462
This reimplementation does nothing.
+ − 2463
*/
+ − 2464
bool QXmlDefaultHandler::startPrefixMapping(const QString&, const QString&)
+ − 2465
{
+ − 2466
return true;
+ − 2467
}
+ − 2468
+ − 2469
/*!
+ − 2470
\reimp
+ − 2471
+ − 2472
This reimplementation does nothing.
+ − 2473
*/
+ − 2474
bool QXmlDefaultHandler::endPrefixMapping(const QString&)
+ − 2475
{
+ − 2476
return true;
+ − 2477
}
+ − 2478
+ − 2479
/*!
+ − 2480
\reimp
+ − 2481
+ − 2482
This reimplementation does nothing.
+ − 2483
*/
+ − 2484
bool QXmlDefaultHandler::startElement(const QString&, const QString&,
+ − 2485
const QString&, const QXmlAttributes&)
+ − 2486
{
+ − 2487
return true;
+ − 2488
}
+ − 2489
+ − 2490
/*!
+ − 2491
\reimp
+ − 2492
+ − 2493
This reimplementation does nothing.
+ − 2494
*/
+ − 2495
bool QXmlDefaultHandler::endElement(const QString&, const QString&,
+ − 2496
const QString&)
+ − 2497
{
+ − 2498
return true;
+ − 2499
}
+ − 2500
+ − 2501
/*!
+ − 2502
\reimp
+ − 2503
+ − 2504
This reimplementation does nothing.
+ − 2505
*/
+ − 2506
bool QXmlDefaultHandler::characters(const QString&)
+ − 2507
{
+ − 2508
return true;
+ − 2509
}
+ − 2510
+ − 2511
/*!
+ − 2512
\reimp
+ − 2513
+ − 2514
This reimplementation does nothing.
+ − 2515
*/
+ − 2516
bool QXmlDefaultHandler::ignorableWhitespace(const QString&)
+ − 2517
{
+ − 2518
return true;
+ − 2519
}
+ − 2520
+ − 2521
/*!
+ − 2522
\reimp
+ − 2523
+ − 2524
This reimplementation does nothing.
+ − 2525
*/
+ − 2526
bool QXmlDefaultHandler::processingInstruction(const QString&,
+ − 2527
const QString&)
+ − 2528
{
+ − 2529
return true;
+ − 2530
}
+ − 2531
+ − 2532
/*!
+ − 2533
\reimp
+ − 2534
+ − 2535
This reimplementation does nothing.
+ − 2536
*/
+ − 2537
bool QXmlDefaultHandler::skippedEntity(const QString&)
+ − 2538
{
+ − 2539
return true;
+ − 2540
}
+ − 2541
+ − 2542
/*!
+ − 2543
\reimp
+ − 2544
+ − 2545
This reimplementation does nothing.
+ − 2546
*/
+ − 2547
bool QXmlDefaultHandler::warning(const QXmlParseException&)
+ − 2548
{
+ − 2549
return true;
+ − 2550
}
+ − 2551
+ − 2552
/*!
+ − 2553
\reimp
+ − 2554
+ − 2555
This reimplementation does nothing.
+ − 2556
*/
+ − 2557
bool QXmlDefaultHandler::error(const QXmlParseException&)
+ − 2558
{
+ − 2559
return true;
+ − 2560
}
+ − 2561
+ − 2562
/*!
+ − 2563
\reimp
+ − 2564
+ − 2565
This reimplementation does nothing.
+ − 2566
*/
+ − 2567
bool QXmlDefaultHandler::fatalError(const QXmlParseException&)
+ − 2568
{
+ − 2569
return true;
+ − 2570
}
+ − 2571
+ − 2572
/*!
+ − 2573
\reimp
+ − 2574
+ − 2575
This reimplementation does nothing.
+ − 2576
*/
+ − 2577
bool QXmlDefaultHandler::notationDecl(const QString&, const QString&,
+ − 2578
const QString&)
+ − 2579
{
+ − 2580
return true;
+ − 2581
}
+ − 2582
+ − 2583
/*!
+ − 2584
\reimp
+ − 2585
+ − 2586
This reimplementation does nothing.
+ − 2587
*/
+ − 2588
bool QXmlDefaultHandler::unparsedEntityDecl(const QString&, const QString&,
+ − 2589
const QString&, const QString&)
+ − 2590
{
+ − 2591
return true;
+ − 2592
}
+ − 2593
+ − 2594
/*!
+ − 2595
\reimp
+ − 2596
+ − 2597
Sets \a ret to 0, so that the reader uses the system identifier
+ − 2598
provided in the XML document.
+ − 2599
*/
+ − 2600
bool QXmlDefaultHandler::resolveEntity(const QString&, const QString&,
+ − 2601
QXmlInputSource*& ret)
+ − 2602
{
+ − 2603
ret = 0;
+ − 2604
return true;
+ − 2605
}
+ − 2606
+ − 2607
/*!
+ − 2608
\reimp
+ − 2609
+ − 2610
Returns the default error string.
+ − 2611
*/
+ − 2612
QString QXmlDefaultHandler::errorString() const
+ − 2613
{
+ − 2614
return QString::fromLatin1(XMLERR_ERRORBYCONSUMER);
+ − 2615
}
+ − 2616
+ − 2617
/*!
+ − 2618
\reimp
+ − 2619
+ − 2620
This reimplementation does nothing.
+ − 2621
*/
+ − 2622
bool QXmlDefaultHandler::startDTD(const QString&, const QString&, const QString&)
+ − 2623
{
+ − 2624
return true;
+ − 2625
}
+ − 2626
+ − 2627
/*!
+ − 2628
\reimp
+ − 2629
+ − 2630
This reimplementation does nothing.
+ − 2631
*/
+ − 2632
bool QXmlDefaultHandler::endDTD()
+ − 2633
{
+ − 2634
return true;
+ − 2635
}
+ − 2636
+ − 2637
/*!
+ − 2638
\reimp
+ − 2639
+ − 2640
This reimplementation does nothing.
+ − 2641
*/
+ − 2642
bool QXmlDefaultHandler::startEntity(const QString&)
+ − 2643
{
+ − 2644
return true;
+ − 2645
}
+ − 2646
+ − 2647
/*!
+ − 2648
\reimp
+ − 2649
+ − 2650
This reimplementation does nothing.
+ − 2651
*/
+ − 2652
bool QXmlDefaultHandler::endEntity(const QString&)
+ − 2653
{
+ − 2654
return true;
+ − 2655
}
+ − 2656
+ − 2657
/*!
+ − 2658
\reimp
+ − 2659
+ − 2660
This reimplementation does nothing.
+ − 2661
*/
+ − 2662
bool QXmlDefaultHandler::startCDATA()
+ − 2663
{
+ − 2664
return true;
+ − 2665
}
+ − 2666
+ − 2667
/*!
+ − 2668
\reimp
+ − 2669
+ − 2670
This reimplementation does nothing.
+ − 2671
*/
+ − 2672
bool QXmlDefaultHandler::endCDATA()
+ − 2673
{
+ − 2674
return true;
+ − 2675
}
+ − 2676
+ − 2677
/*!
+ − 2678
\reimp
+ − 2679
+ − 2680
This reimplementation does nothing.
+ − 2681
*/
+ − 2682
bool QXmlDefaultHandler::comment(const QString&)
+ − 2683
{
+ − 2684
return true;
+ − 2685
}
+ − 2686
+ − 2687
/*!
+ − 2688
\reimp
+ − 2689
+ − 2690
This reimplementation does nothing.
+ − 2691
*/
+ − 2692
bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QString&, const QString&, const QString&)
+ − 2693
{
+ − 2694
return true;
+ − 2695
}
+ − 2696
+ − 2697
/*!
+ − 2698
\reimp
+ − 2699
+ − 2700
This reimplementation does nothing.
+ − 2701
*/
+ − 2702
bool QXmlDefaultHandler::internalEntityDecl(const QString&, const QString&)
+ − 2703
{
+ − 2704
return true;
+ − 2705
}
+ − 2706
+ − 2707
/*!
+ − 2708
\reimp
+ − 2709
+ − 2710
This reimplementation does nothing.
+ − 2711
*/
+ − 2712
bool QXmlDefaultHandler::externalEntityDecl(const QString&, const QString&, const QString&)
+ − 2713
{
+ − 2714
return true;
+ − 2715
}
+ − 2716
+ − 2717
+ − 2718
/*********************************************
+ − 2719
*
+ − 2720
* QXmlSimpleReaderPrivate
+ − 2721
*
+ − 2722
*********************************************/
+ − 2723
+ − 2724
inline bool QXmlSimpleReaderPrivate::atEnd()
+ − 2725
{
+ − 2726
return (c.unicode()|0x0001) == 0xffff;
+ − 2727
}
+ − 2728
+ − 2729
inline void QXmlSimpleReaderPrivate::stringClear()
+ − 2730
{
+ − 2731
stringValueLen = 0; stringArrayPos = 0;
+ − 2732
}
+ − 2733
inline void QXmlSimpleReaderPrivate::nameClear()
+ − 2734
{
+ − 2735
nameValueLen = 0; nameArrayPos = 0;
+ − 2736
}
+ − 2737
+ − 2738
inline void QXmlSimpleReaderPrivate::refClear()
+ − 2739
{
+ − 2740
refValueLen = 0; refArrayPos = 0;
+ − 2741
}
+ − 2742
+ − 2743
QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate(QXmlSimpleReader *reader)
+ − 2744
{
+ − 2745
q_ptr = reader;
+ − 2746
parseStack = 0;
+ − 2747
+ − 2748
locator.reset(new QXmlSimpleReaderLocator(reader));
+ − 2749
entityRes = 0;
+ − 2750
dtdHnd = 0;
+ − 2751
contentHnd = 0;
+ − 2752
errorHnd = 0;
+ − 2753
lexicalHnd = 0;
+ − 2754
declHnd = 0;
+ − 2755
+ − 2756
// default feature settings
+ − 2757
useNamespaces = true;
+ − 2758
useNamespacePrefixes = false;
+ − 2759
reportWhitespaceCharData = true;
+ − 2760
reportEntities = false;
+ − 2761
}
+ − 2762
+ − 2763
QXmlSimpleReaderPrivate::~QXmlSimpleReaderPrivate()
+ − 2764
{
+ − 2765
delete parseStack;
+ − 2766
}
+ − 2767
+ − 2768
void QXmlSimpleReaderPrivate::initIncrementalParsing()
+ − 2769
{
+ − 2770
if(parseStack)
+ − 2771
parseStack->clear();
+ − 2772
else
+ − 2773
parseStack = new QStack<ParseState>;
+ − 2774
}
+ − 2775
+ − 2776
/*********************************************
+ − 2777
*
+ − 2778
* QXmlSimpleReader
+ − 2779
*
+ − 2780
*********************************************/
+ − 2781
+ − 2782
/*!
+ − 2783
\class QXmlReader
+ − 2784
\reentrant
+ − 2785
\brief The QXmlReader class provides an interface for XML readers (i.e.
+ − 2786
parsers).
+ − 2787
+ − 2788
\inmodule QtXml
+ − 2789
\ingroup xml-tools
+ − 2790
+ − 2791
This abstract class provides an interface for all of Qt's XML
+ − 2792
readers. Currently there is only one implementation of a reader
+ − 2793
included in Qt's XML module: QXmlSimpleReader. In future releases
+ − 2794
there might be more readers with different properties available
+ − 2795
(e.g. a validating parser).
+ − 2796
+ − 2797
The design of the XML classes follows the \link
+ − 2798
http://www.saxproject.org/ SAX2 Java interface\endlink, with
+ − 2799
the names adapted to fit Qt naming conventions. It should be very
+ − 2800
easy for anybody who has worked with SAX2 to get started with the
+ − 2801
Qt XML classes.
+ − 2802
+ − 2803
All readers use the class QXmlInputSource to read the input
+ − 2804
document. Since you are normally interested in particular content
+ − 2805
in the XML document, the reader reports the content through
+ − 2806
special handler classes (QXmlDTDHandler, QXmlDeclHandler,
+ − 2807
QXmlContentHandler, QXmlEntityResolver, QXmlErrorHandler and
+ − 2808
QXmlLexicalHandler), which you must subclass, if you want to
+ − 2809
process the contents.
+ − 2810
+ − 2811
Since the handler classes only describe interfaces you must
+ − 2812
implement all the functions. We provide the QXmlDefaultHandler
+ − 2813
class to make this easier: it implements a default behavior (do
+ − 2814
nothing) for all functions, so you can subclass it and just
+ − 2815
implement the functions you are interested in.
+ − 2816
+ − 2817
Features and properties of the reader can be set with setFeature()
+ − 2818
and setProperty() respectively. You can set the reader to use your
+ − 2819
own subclasses with setEntityResolver(), setDTDHandler(),
+ − 2820
setContentHandler(), setErrorHandler(), setLexicalHandler() and
+ − 2821
setDeclHandler(). The parse itself is started with a call to
+ − 2822
parse().
+ − 2823
+ − 2824
\sa QXmlSimpleReader
+ − 2825
*/
+ − 2826
+ − 2827
/*!
+ − 2828
\fn QXmlReader::~QXmlReader()
+ − 2829
+ − 2830
Destroys the reader.
+ − 2831
*/
+ − 2832
+ − 2833
/*!
+ − 2834
\fn bool QXmlReader::feature(const QString& name, bool *ok) const
+ − 2835
+ − 2836
If the reader has the feature called \a name, the feature's value
+ − 2837
is returned. If no such feature exists the return value is
+ − 2838
undefined.
+ − 2839
+ − 2840
If \a ok is not 0: \c{*}\a{ok} is set to true if the reader has the
+ − 2841
feature called \a name; otherwise \c{*}\a{ok} is set to false.
+ − 2842
+ − 2843
\sa setFeature(), hasFeature()
+ − 2844
*/
+ − 2845
+ − 2846
/*!
+ − 2847
\fn void QXmlReader::setFeature(const QString& name, bool value)
+ − 2848
+ − 2849
Sets the feature called \a name to the given \a value. If the
+ − 2850
reader doesn't have the feature nothing happens.
+ − 2851
+ − 2852
\sa feature(), hasFeature()
+ − 2853
*/
+ − 2854
+ − 2855
/*!
+ − 2856
\fn bool QXmlReader::hasFeature(const QString& name) const
+ − 2857
+ − 2858
Returns \c true if the reader has the feature called \a name;
+ − 2859
otherwise returns false.
+ − 2860
+ − 2861
\sa feature(), setFeature()
+ − 2862
*/
+ − 2863
+ − 2864
/*!
+ − 2865
\fn void* QXmlReader::property(const QString& name, bool *ok) const
+ − 2866
+ − 2867
If the reader has the property \a name, this function returns the
+ − 2868
value of the property; otherwise the return value is undefined.
+ − 2869
+ − 2870
If \a ok is not 0: if the reader has the \a name property
+ − 2871
\c{*}\a{ok} is set to true; otherwise \c{*}\a{ok} is set to false.
+ − 2872
+ − 2873
\sa setProperty(), hasProperty()
+ − 2874
*/
+ − 2875
+ − 2876
/*!
+ − 2877
\fn void QXmlReader::setProperty(const QString& name, void* value)
+ − 2878
+ − 2879
Sets the property \a name to \a value. If the reader doesn't have
+ − 2880
the property nothing happens.
+ − 2881
+ − 2882
\sa property(), hasProperty()
+ − 2883
*/
+ − 2884
+ − 2885
/*!
+ − 2886
\fn bool QXmlReader::hasProperty(const QString& name) const
+ − 2887
+ − 2888
Returns true if the reader has the property \a name; otherwise
+ − 2889
returns false.
+ − 2890
+ − 2891
\sa property(), setProperty()
+ − 2892
*/
+ − 2893
+ − 2894
/*!
+ − 2895
\fn void QXmlReader::setEntityResolver(QXmlEntityResolver* handler)
+ − 2896
+ − 2897
Sets the entity resolver to \a handler.
+ − 2898
+ − 2899
\sa entityResolver()
+ − 2900
*/
+ − 2901
+ − 2902
/*!
+ − 2903
\fn QXmlEntityResolver* QXmlReader::entityResolver() const
+ − 2904
+ − 2905
Returns the entity resolver or 0 if none was set.
+ − 2906
+ − 2907
\sa setEntityResolver()
+ − 2908
*/
+ − 2909
+ − 2910
/*!
+ − 2911
\fn void QXmlReader::setDTDHandler(QXmlDTDHandler* handler)
+ − 2912
+ − 2913
Sets the DTD handler to \a handler.
+ − 2914
+ − 2915
\sa DTDHandler()
+ − 2916
*/
+ − 2917
+ − 2918
/*!
+ − 2919
\fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+ − 2920
+ − 2921
Returns the DTD handler or 0 if none was set.
+ − 2922
+ − 2923
\sa setDTDHandler()
+ − 2924
*/
+ − 2925
+ − 2926
/*!
+ − 2927
\fn void QXmlReader::setContentHandler(QXmlContentHandler* handler)
+ − 2928
+ − 2929
Sets the content handler to \a handler.
+ − 2930
+ − 2931
\sa contentHandler()
+ − 2932
*/
+ − 2933
+ − 2934
/*!
+ − 2935
\fn QXmlContentHandler* QXmlReader::contentHandler() const
+ − 2936
+ − 2937
Returns the content handler or 0 if none was set.
+ − 2938
+ − 2939
\sa setContentHandler()
+ − 2940
*/
+ − 2941
+ − 2942
/*!
+ − 2943
\fn void QXmlReader::setErrorHandler(QXmlErrorHandler* handler)
+ − 2944
+ − 2945
Sets the error handler to \a handler. Clears the error handler if
+ − 2946
\a handler is 0.
+ − 2947
+ − 2948
\sa errorHandler()
+ − 2949
*/
+ − 2950
+ − 2951
/*!
+ − 2952
\fn QXmlErrorHandler* QXmlReader::errorHandler() const
+ − 2953
+ − 2954
Returns the error handler or 0 if none is set.
+ − 2955
+ − 2956
\sa setErrorHandler()
+ − 2957
*/
+ − 2958
+ − 2959
/*!
+ − 2960
\fn void QXmlReader::setLexicalHandler(QXmlLexicalHandler* handler)
+ − 2961
+ − 2962
Sets the lexical handler to \a handler.
+ − 2963
+ − 2964
\sa lexicalHandler()
+ − 2965
*/
+ − 2966
+ − 2967
/*!
+ − 2968
\fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+ − 2969
+ − 2970
Returns the lexical handler or 0 if none was set.
+ − 2971
+ − 2972
\sa setLexicalHandler()
+ − 2973
*/
+ − 2974
+ − 2975
/*!
+ − 2976
\fn void QXmlReader::setDeclHandler(QXmlDeclHandler* handler)
+ − 2977
+ − 2978
Sets the declaration handler to \a handler.
+ − 2979
+ − 2980
\sa declHandler()
+ − 2981
*/
+ − 2982
+ − 2983
/*!
+ − 2984
\fn QXmlDeclHandler* QXmlReader::declHandler() const
+ − 2985
+ − 2986
Returns the declaration handler or 0 if none was set.
+ − 2987
+ − 2988
\sa setDeclHandler()
+ − 2989
*/
+ − 2990
+ − 2991
/*!
+ − 2992
\fn bool QXmlReader::parse(const QXmlInputSource &input)
+ − 2993
+ − 2994
\obsolete
+ − 2995
+ − 2996
Parses the given \a input.
+ − 2997
*/
+ − 2998
+ − 2999
/*!
+ − 3000
\fn bool QXmlReader::parse(const QXmlInputSource *input)
+ − 3001
+ − 3002
Reads an XML document from \a input and parses it. Returns true if
+ − 3003
the parsing was successful; otherwise returns false.
+ − 3004
*/
+ − 3005
+ − 3006
+ − 3007
/*!
+ − 3008
\class QXmlSimpleReader
+ − 3009
\nonreentrant
+ − 3010
\brief The QXmlSimpleReader class provides an implementation of a
+ − 3011
simple XML parser.
+ − 3012
+ − 3013
\inmodule QtXml
+ − 3014
\ingroup xml-tools
+ − 3015
+ − 3016
+ − 3017
This XML reader is suitable for a wide range of applications. It
+ − 3018
is able to parse well-formed XML and can report the namespaces of
+ − 3019
elements to a content handler; however, it does not parse any
+ − 3020
external entities. For historical reasons, Attribute Value
+ − 3021
Normalization and End-of-Line Handling as described in the XML 1.0
+ − 3022
specification is not performed.
+ − 3023
+ − 3024
The easiest pattern of use for this class is to create a reader
+ − 3025
instance, define an input source, specify the handlers to be used
+ − 3026
by the reader, and parse the data.
+ − 3027
+ − 3028
For example, we could use a QFile to supply the input. Here, we
+ − 3029
create a reader, and define an input source to be used by the
+ − 3030
reader:
+ − 3031
+ − 3032
\snippet doc/src/snippets/xml/simpleparse/main.cpp 0
+ − 3033
+ − 3034
A handler lets us perform actions when the reader encounters
+ − 3035
certain types of content, or if errors in the input are found. The
+ − 3036
reader must be told which handler to use for each type of
+ − 3037
event. For many common applications, we can create a custom
+ − 3038
handler by subclassing QXmlDefaultHandler, and use this to handle
+ − 3039
both error and content events:
+ − 3040
+ − 3041
\snippet doc/src/snippets/xml/simpleparse/main.cpp 1
+ − 3042
+ − 3043
If you don't set at least the content and error handlers, the
+ − 3044
parser will fall back on its default behavior---and will do
+ − 3045
nothing.
+ − 3046
+ − 3047
The most convenient way to handle the input is to read it in a
+ − 3048
single pass using the parse() function with an argument that
+ − 3049
specifies the input source:
+ − 3050
+ − 3051
\snippet doc/src/snippets/xml/simpleparse/main.cpp 2
+ − 3052
+ − 3053
If you can't parse the entire input in one go (for example, it is
+ − 3054
huge, or is being delivered over a network connection), data can
+ − 3055
be fed to the parser in pieces. This is achieved by telling
+ − 3056
parse() to work incrementally, and making subsequent calls to the
+ − 3057
parseContinue() function, until all the data has been processed.
+ − 3058
+ − 3059
A common way to perform incremental parsing is to connect the \c
+ − 3060
readyRead() signal of a \l{QNetworkReply} {network reply} a slot,
+ − 3061
and handle the incoming data there. See QNetworkAccessManager.
+ − 3062
+ − 3063
Aspects of the parsing behavior can be adapted using setFeature()
+ − 3064
and setProperty().
+ − 3065
+ − 3066
QXmlSimpleReader is not reentrant. If you want to use the class
+ − 3067
in threaded code, lock the code using QXmlSimpleReader with a
+ − 3068
locking mechanism, such as a QMutex.
+ − 3069
+ − 3070
\snippet doc/src/snippets/code/src_xml_sax_qxml.cpp 0
+ − 3071
*/
+ − 3072
+ − 3073
static inline bool is_S(QChar ch)
+ − 3074
{
+ − 3075
ushort uc = ch.unicode();
+ − 3076
return (uc == ' ' || uc == '\t' || uc == '\n' || uc == '\r');
+ − 3077
}
+ − 3078
+ − 3079
enum NameChar { NameBeginning, NameNotBeginning, NotName };
+ − 3080
+ − 3081
static const char Begi = (char)NameBeginning;
+ − 3082
static const char NtBg = (char)NameNotBeginning;
+ − 3083
static const char NotN = (char)NotName;
+ − 3084
+ − 3085
static const char nameCharTable[128] =
+ − 3086
{
+ − 3087
// 0x00
+ − 3088
NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ − 3089
NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ − 3090
// 0x10
+ − 3091
NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ − 3092
NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ − 3093
// 0x20 (0x2D is '-', 0x2E is '.')
+ − 3094
NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ − 3095
NotN, NotN, NotN, NotN, NotN, NtBg, NtBg, NotN,
+ − 3096
// 0x30 (0x30..0x39 are '0'..'9', 0x3A is ':')
+ − 3097
NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg,
+ − 3098
NtBg, NtBg, Begi, NotN, NotN, NotN, NotN, NotN,
+ − 3099
// 0x40 (0x41..0x5A are 'A'..'Z')
+ − 3100
NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3101
Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3102
// 0x50 (0x5F is '_')
+ − 3103
Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3104
Begi, Begi, Begi, NotN, NotN, NotN, NotN, Begi,
+ − 3105
// 0x60 (0x61..0x7A are 'a'..'z')
+ − 3106
NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3107
Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3108
// 0x70
+ − 3109
Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ − 3110
Begi, Begi, Begi, NotN, NotN, NotN, NotN, NotN
+ − 3111
};
+ − 3112
+ − 3113
static inline NameChar fastDetermineNameChar(QChar ch)
+ − 3114
{
+ − 3115
ushort uc = ch.unicode();
+ − 3116
if (!(uc & ~0x7f)) // uc < 128
+ − 3117
return (NameChar)nameCharTable[uc];
+ − 3118
+ − 3119
QChar::Category cat = ch.category();
+ − 3120
// ### some these categories might be slightly wrong
+ − 3121
if ((cat >= QChar::Letter_Uppercase && cat <= QChar::Letter_Other)
+ − 3122
|| cat == QChar::Number_Letter)
+ − 3123
return NameBeginning;
+ − 3124
if ((cat >= QChar::Number_DecimalDigit && cat <= QChar::Number_Other)
+ − 3125
|| (cat >= QChar::Mark_NonSpacing && cat <= QChar::Mark_Enclosing))
+ − 3126
return NameNotBeginning;
+ − 3127
return NotName;
+ − 3128
}
+ − 3129
+ − 3130
static NameChar determineNameChar(QChar ch)
+ − 3131
{
+ − 3132
return fastDetermineNameChar(ch);
+ − 3133
}
+ − 3134
+ − 3135
/*!
+ − 3136
Constructs a simple XML reader.
+ − 3137
+ − 3138
*/
+ − 3139
QXmlSimpleReader::QXmlSimpleReader()
+ − 3140
: d_ptr(new QXmlSimpleReaderPrivate(this))
+ − 3141
{
+ − 3142
}
+ − 3143
+ − 3144
/*!
+ − 3145
Destroys the simple XML reader.
+ − 3146
*/
+ − 3147
QXmlSimpleReader::~QXmlSimpleReader()
+ − 3148
{
+ − 3149
}
+ − 3150
+ − 3151
/*!
+ − 3152
\reimp
+ − 3153
*/
+ − 3154
bool QXmlSimpleReader::feature(const QString& name, bool *ok) const
+ − 3155
{
+ − 3156
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3157
+ − 3158
// Qt5 ###: Change these strings to qt.nokia.com
+ − 3159
if (ok != 0)
+ − 3160
*ok = true;
+ − 3161
if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
+ − 3162
return d->useNamespaces;
+ − 3163
} else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
+ − 3164
return d->useNamespacePrefixes;
+ − 3165
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData")) { // Shouldn't change in Qt 4
+ − 3166
return d->reportWhitespaceCharData;
+ − 3167
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
+ − 3168
return d->reportEntities;
+ − 3169
} else {
+ − 3170
qWarning("Unknown feature %s", name.toLatin1().data());
+ − 3171
if (ok != 0)
+ − 3172
*ok = false;
+ − 3173
}
+ − 3174
return false;
+ − 3175
}
+ − 3176
+ − 3177
/*!
+ − 3178
Turns on the feature \a name if \a enable is true; otherwise turns it off.
+ − 3179
+ − 3180
The \a name parameter must be one of the following strings:
+ − 3181
\table
+ − 3182
\header \i Feature \i Default \i Notes
+ − 3183
\row \i \e http://xml.org/sax/features/namespaces
+ − 3184
\i true
+ − 3185
\i If enabled, namespaces are reported to the content handler.
+ − 3186
\row \i \e http://xml.org/sax/features/namespace-prefixes
+ − 3187
\i false
+ − 3188
\i If enabled, the original prefixed names
+ − 3189
and attributes used for namespace declarations are
+ − 3190
reported.
+ − 3191
\row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
+ − 3192
\i true
+ − 3193
\i If enabled, CharData that consist of
+ − 3194
only whitespace characters are reported
+ − 3195
using QXmlContentHandler::characters(). If disabled, whitespace is silently
+ − 3196
discarded.
+ − 3197
\row \i \e http://trolltech.com/xml/features/report-start-end-entity
+ − 3198
\i false
+ − 3199
\i If enabled, the parser reports
+ − 3200
QXmlContentHandler::startEntity() and
+ − 3201
QXmlContentHandler::endEntity() events, so character data
+ − 3202
might be reported in chunks.
+ − 3203
If disabled, the parser does not report these events, but
+ − 3204
silently substitutes the entities, and reports the character
+ − 3205
data in one chunk.
+ − 3206
\endtable
+ − 3207
+ − 3208
\sa feature(), hasFeature(), {SAX2 Features}
+ − 3209
*/
+ − 3210
void QXmlSimpleReader::setFeature(const QString& name, bool enable)
+ − 3211
{
+ − 3212
Q_D(QXmlSimpleReader);
+ − 3213
// Qt5 ###: Change these strings to qt.nokia.com
+ − 3214
if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
+ − 3215
d->useNamespaces = enable;
+ − 3216
} else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
+ − 3217
d->useNamespacePrefixes = enable;
+ − 3218
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData")) { // Shouldn't change in Qt 4
+ − 3219
d->reportWhitespaceCharData = enable;
+ − 3220
} else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
+ − 3221
d->reportEntities = enable;
+ − 3222
} else {
+ − 3223
qWarning("Unknown feature %s", name.toLatin1().data());
+ − 3224
}
+ − 3225
}
+ − 3226
+ − 3227
/*! \reimp
+ − 3228
*/
+ − 3229
bool QXmlSimpleReader::hasFeature(const QString& name) const
+ − 3230
{
+ − 3231
// Qt5 ###: Change these strings to qt.nokia.com
+ − 3232
if (name == QLatin1String("http://xml.org/sax/features/namespaces")
+ − 3233
|| name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")
+ − 3234
|| name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // Shouldn't change in Qt 4
+ − 3235
|| name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
+ − 3236
return true;
+ − 3237
} else {
+ − 3238
return false;
+ − 3239
}
+ − 3240
}
+ − 3241
+ − 3242
/*! \reimp
+ − 3243
*/
+ − 3244
void* QXmlSimpleReader::property(const QString&, bool *ok) const
+ − 3245
{
+ − 3246
if (ok != 0)
+ − 3247
*ok = false;
+ − 3248
return 0;
+ − 3249
}
+ − 3250
+ − 3251
/*! \reimp
+ − 3252
*/
+ − 3253
void QXmlSimpleReader::setProperty(const QString&, void*)
+ − 3254
{
+ − 3255
}
+ − 3256
+ − 3257
/*!
+ − 3258
\reimp
+ − 3259
*/
+ − 3260
bool QXmlSimpleReader::hasProperty(const QString&) const
+ − 3261
{
+ − 3262
return false;
+ − 3263
}
+ − 3264
+ − 3265
/*!
+ − 3266
\reimp
+ − 3267
*/
+ − 3268
void QXmlSimpleReader::setEntityResolver(QXmlEntityResolver* handler)
+ − 3269
{
+ − 3270
Q_D(QXmlSimpleReader);
+ − 3271
d->entityRes = handler;
+ − 3272
}
+ − 3273
+ − 3274
/*!
+ − 3275
\reimp
+ − 3276
*/
+ − 3277
QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
+ − 3278
{
+ − 3279
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3280
return d->entityRes;
+ − 3281
}
+ − 3282
+ − 3283
/*!
+ − 3284
\reimp
+ − 3285
*/
+ − 3286
void QXmlSimpleReader::setDTDHandler(QXmlDTDHandler* handler)
+ − 3287
{
+ − 3288
Q_D(QXmlSimpleReader);
+ − 3289
d->dtdHnd = handler;
+ − 3290
}
+ − 3291
+ − 3292
/*!
+ − 3293
\reimp
+ − 3294
*/
+ − 3295
QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
+ − 3296
{
+ − 3297
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3298
return d->dtdHnd;
+ − 3299
}
+ − 3300
+ − 3301
/*!
+ − 3302
\reimp
+ − 3303
*/
+ − 3304
void QXmlSimpleReader::setContentHandler(QXmlContentHandler* handler)
+ − 3305
{
+ − 3306
Q_D(QXmlSimpleReader);
+ − 3307
d->contentHnd = handler;
+ − 3308
}
+ − 3309
+ − 3310
/*!
+ − 3311
\reimp
+ − 3312
*/
+ − 3313
QXmlContentHandler* QXmlSimpleReader::contentHandler() const
+ − 3314
{
+ − 3315
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3316
return d->contentHnd;
+ − 3317
}
+ − 3318
+ − 3319
/*!
+ − 3320
\reimp
+ − 3321
*/
+ − 3322
void QXmlSimpleReader::setErrorHandler(QXmlErrorHandler* handler)
+ − 3323
{
+ − 3324
Q_D(QXmlSimpleReader);
+ − 3325
d->errorHnd = handler;
+ − 3326
}
+ − 3327
+ − 3328
/*!
+ − 3329
\reimp
+ − 3330
*/
+ − 3331
QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
+ − 3332
{
+ − 3333
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3334
return d->errorHnd;
+ − 3335
}
+ − 3336
+ − 3337
/*!
+ − 3338
\reimp
+ − 3339
*/
+ − 3340
void QXmlSimpleReader::setLexicalHandler(QXmlLexicalHandler* handler)
+ − 3341
{
+ − 3342
Q_D(QXmlSimpleReader);
+ − 3343
d->lexicalHnd = handler;
+ − 3344
}
+ − 3345
+ − 3346
/*!
+ − 3347
\reimp
+ − 3348
*/
+ − 3349
QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
+ − 3350
{
+ − 3351
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3352
return d->lexicalHnd;
+ − 3353
}
+ − 3354
+ − 3355
/*!
+ − 3356
\reimp
+ − 3357
*/
+ − 3358
void QXmlSimpleReader::setDeclHandler(QXmlDeclHandler* handler)
+ − 3359
{
+ − 3360
Q_D(QXmlSimpleReader);
+ − 3361
d->declHnd = handler;
+ − 3362
}
+ − 3363
+ − 3364
/*!
+ − 3365
\reimp
+ − 3366
*/
+ − 3367
QXmlDeclHandler* QXmlSimpleReader::declHandler() const
+ − 3368
{
+ − 3369
const QXmlSimpleReaderPrivate *d = d_func();
+ − 3370
return d->declHnd;
+ − 3371
}
+ − 3372
+ − 3373
+ − 3374
+ − 3375
/*!
+ − 3376
\reimp
+ − 3377
*/
+ − 3378
bool QXmlSimpleReader::parse(const QXmlInputSource& input)
+ − 3379
{
+ − 3380
return parse(&input, false);
+ − 3381
}
+ − 3382
+ − 3383
/*!
+ − 3384
Reads an XML document from \a input and parses it in one pass (non-incrementally).
+ − 3385
Returns true if the parsing was successful; otherwise returns false.
+ − 3386
*/
+ − 3387
bool QXmlSimpleReader::parse(const QXmlInputSource* input)
+ − 3388
{
+ − 3389
return parse(input, false);
+ − 3390
}
+ − 3391
+ − 3392
/*!
+ − 3393
Reads an XML document from \a input and parses it. Returns true
+ − 3394
if the parsing is completed successfully; otherwise returns false,
+ − 3395
indicating that an error occurred.
+ − 3396
+ − 3397
If \a incremental is false, this function will return false if the XML
+ − 3398
file is not read completely. The parsing cannot be continued in this
+ − 3399
case.
+ − 3400
+ − 3401
If \a incremental is true, the parser does not return false if
+ − 3402
it reaches the end of the \a input before reaching the end
+ − 3403
of the XML file. Instead, it stores the state of the parser so that
+ − 3404
parsing can be continued later when more data is available.
+ − 3405
In such a case, you can use the function parseContinue() to
+ − 3406
continue with parsing. This class stores a pointer to the input
+ − 3407
source \a input and the parseContinue() function tries to read from
+ − 3408
that input source. Therefore, you should not delete the input
+ − 3409
source \a input until you no longer need to call parseContinue().
+ − 3410
+ − 3411
If this function is called with \a incremental set to true
+ − 3412
while an incremental parse is in progress, a new parsing
+ − 3413
session will be started, and the previous session will be lost.
+ − 3414
+ − 3415
\sa parseContinue(), QTcpSocket
+ − 3416
*/
+ − 3417
bool QXmlSimpleReader::parse(const QXmlInputSource *input, bool incremental)
+ − 3418
{
+ − 3419
Q_D(QXmlSimpleReader);
+ − 3420
+ − 3421
if (incremental) {
+ − 3422
d->initIncrementalParsing();
+ − 3423
} else {
+ − 3424
delete d->parseStack;
+ − 3425
d->parseStack = 0;
+ − 3426
}
+ − 3427
d->init(input);
+ − 3428
+ − 3429
// call the handler
+ − 3430
if (d->contentHnd) {
+ − 3431
d->contentHnd->setDocumentLocator(d->locator.data());
+ − 3432
if (!d->contentHnd->startDocument()) {
+ − 3433
d->reportParseError(d->contentHnd->errorString());
+ − 3434
d->tags.clear();
+ − 3435
return false;
+ − 3436
}
+ − 3437
}
+ − 3438
qt_xml_skipped_entity_in_content = false;
+ − 3439
return d->parseBeginOrContinue(0, incremental);
+ − 3440
}
+ − 3441
+ − 3442
/*!
+ − 3443
Continues incremental parsing, taking input from the
+ − 3444
QXmlInputSource that was specified with the most recent
+ − 3445
call to parse(). To use this function, you \e must have called
+ − 3446
parse() with the incremental argument set to true.
+ − 3447
+ − 3448
Returns false if a parsing error occurs; otherwise returns true,
+ − 3449
even if the end of the XML file has not been reached. You can
+ − 3450
continue parsing at a later stage by calling this function again
+ − 3451
when there is more data available to parse.
+ − 3452
+ − 3453
Calling this function when there is no data available in the input
+ − 3454
source indicates to the reader that the end of the XML file has
+ − 3455
been reached. If the input supplied up to this point was
+ − 3456
not well-formed then a parsing error occurs, and false is returned.
+ − 3457
If the input supplied was well-formed, true is returned.
+ − 3458
It is important to end the input in this way because it allows you
+ − 3459
to reuse the reader to parse other XML files.
+ − 3460
+ − 3461
Calling this function after the end of file has been reached, but
+ − 3462
without available data will cause false to be returned whether the
+ − 3463
previous input was well-formed or not.
+ − 3464
+ − 3465
\sa parse(), QXmlInputSource::data(), QXmlInputSource::next()
+ − 3466
*/
+ − 3467
bool QXmlSimpleReader::parseContinue()
+ − 3468
{
+ − 3469
Q_D(QXmlSimpleReader);
+ − 3470
if (d->parseStack == 0 || d->parseStack->isEmpty())
+ − 3471
return false;
+ − 3472
d->initData();
+ − 3473
int state = d->parseStack->pop().state;
+ − 3474
return d->parseBeginOrContinue(state, true);
+ − 3475
}
+ − 3476
+ − 3477
/*
+ − 3478
Common part of parse() and parseContinue()
+ − 3479
*/
+ − 3480
bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
+ − 3481
{
+ − 3482
bool atEndOrig = atEnd();
+ − 3483
+ − 3484
if (state==0) {
+ − 3485
if (!parseProlog()) {
+ − 3486
if (incremental && error.isNull()) {
+ − 3487
pushParseState(0, 0);
+ − 3488
return true;
+ − 3489
} else {
+ − 3490
tags.clear();
+ − 3491
return false;
+ − 3492
}
+ − 3493
}
+ − 3494
state = 1;
+ − 3495
}
+ − 3496
if (state==1) {
+ − 3497
if (!parseElement()) {
+ − 3498
if (incremental && error.isNull()) {
+ − 3499
pushParseState(0, 1);
+ − 3500
return true;
+ − 3501
} else {
+ − 3502
tags.clear();
+ − 3503
return false;
+ − 3504
}
+ − 3505
}
+ − 3506
state = 2;
+ − 3507
}
+ − 3508
// parse Misc*
+ − 3509
while (!atEnd()) {
+ − 3510
if (!parseMisc()) {
+ − 3511
if (incremental && error.isNull()) {
+ − 3512
pushParseState(0, 2);
+ − 3513
return true;
+ − 3514
} else {
+ − 3515
tags.clear();
+ − 3516
return false;
+ − 3517
}
+ − 3518
}
+ − 3519
}
+ − 3520
if (!atEndOrig && incremental) {
+ − 3521
// we parsed something at all, so be prepared to come back later
+ − 3522
pushParseState(0, 2);
+ − 3523
return true;
+ − 3524
}
+ − 3525
// is stack empty?
+ − 3526
if (!tags.isEmpty() && !error.isNull()) {
+ − 3527
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
+ − 3528
tags.clear();
+ − 3529
return false;
+ − 3530
}
+ − 3531
// call the handler
+ − 3532
if (contentHnd) {
+ − 3533
delete parseStack;
+ − 3534
parseStack = 0;
+ − 3535
if (!contentHnd->endDocument()) {
+ − 3536
reportParseError(contentHnd->errorString());
+ − 3537
return false;
+ − 3538
}
+ − 3539
}
+ − 3540
return true;
+ − 3541
}
+ − 3542
+ − 3543
//
+ − 3544
// The following private parse functions have another semantics for the return
+ − 3545
// value: They return true iff parsing has finished successfully (i.e. the end
+ − 3546
// of the XML file must be reached!). If one of these functions return false,
+ − 3547
// there is only an error when d->error.isNULL() is also false.
+ − 3548
//
+ − 3549
+ − 3550
/*
+ − 3551
For the incremental parsing, it is very important that the parse...()
+ − 3552
functions have a certain structure. Since it might be hard to understand how
+ − 3553
they work, here is a description of the layout of these functions:
+ − 3554
+ − 3555
bool QXmlSimpleReader::parse...()
+ − 3556
{
+ − 3557
(1) const signed char Init = 0;
+ − 3558
...
+ − 3559
+ − 3560
(2) const signed char Inp... = 0;
+ − 3561
...
+ − 3562
+ − 3563
(3) static const signed char table[3][2] = {
+ − 3564
...
+ − 3565
};
+ − 3566
signed char state;
+ − 3567
signed char input;
+ − 3568
+ − 3569
(4) if (d->parseStack == 0 || d->parseStack->isEmpty()) {
+ − 3570
(4a) ...
+ − 3571
} else {
+ − 3572
(4b) ...
+ − 3573
}
+ − 3574
+ − 3575
for (; ;) {
+ − 3576
(5) switch (state) {
+ − 3577
...
+ − 3578
}
+ − 3579
+ − 3580
(6)
+ − 3581
(6a) if (atEnd()) {
+ − 3582
unexpectedEof(&QXmlSimpleReader::parseNmtoken, state);
+ − 3583
return false;
+ − 3584
}
+ − 3585
(6b) if (determineNameChar(c) != NotName) {
+ − 3586
...
+ − 3587
}
+ − 3588
(7) state = table[state][input];
+ − 3589
+ − 3590
(8) switch (state) {
+ − 3591
...
+ − 3592
}
+ − 3593
}
+ − 3594
}
+ − 3595
+ − 3596
Explanation:
+ − 3597
ad 1: constants for the states (used in the transition table)
+ − 3598
ad 2: constants for the input (used in the transition table)
+ − 3599
ad 3: the transition table for the state machine
+ − 3600
ad 4: test if we are in a parseContinue() step
+ − 3601
a) if no, do inititalizations
+ − 3602
b) if yes, restore the state and call parse functions recursively
+ − 3603
ad 5: Do some actions according to the state; from the logical execution
+ − 3604
order, this code belongs after 8 (see there for an explanation)
+ − 3605
ad 6: Check the character that is at the actual "cursor" position:
+ − 3606
a) If we reached the EOF, report either error or push the state (in the
+ − 3607
case of incremental parsing).
+ − 3608
b) Otherwise, set the input character constant for the transition
+ − 3609
table.
+ − 3610
ad 7: Get the new state according to the input that was read.
+ − 3611
ad 8: Do some actions according to the state. The last line in every case
+ − 3612
statement reads new data (i.e. it move the cursor). This can also be
+ − 3613
done by calling another parse...() function. If you need processing for
+ − 3614
this state after that, you have to put it into the switch statement 5.
+ − 3615
This ensures that you have a well defined re-entry point, when you ran
+ − 3616
out of data.
+ − 3617
*/
+ − 3618
+ − 3619
/*
+ − 3620
Parses the prolog [22].
+ − 3621
*/
+ − 3622
+ − 3623
bool QXmlSimpleReaderPrivate::parseProlog()
+ − 3624
{
+ − 3625
const signed char Init = 0;
+ − 3626
const signed char EatWS = 1; // eat white spaces
+ − 3627
const signed char Lt = 2; // '<' read
+ − 3628
const signed char Em = 3; // '!' read
+ − 3629
const signed char DocType = 4; // read doctype
+ − 3630
const signed char Comment = 5; // read comment
+ − 3631
const signed char CommentR = 6; // same as Comment, but already reported
+ − 3632
const signed char PInstr = 7; // read PI
+ − 3633
const signed char PInstrR = 8; // same as PInstr, but already reported
+ − 3634
const signed char Done = 9;
+ − 3635
+ − 3636
const signed char InpWs = 0;
+ − 3637
const signed char InpLt = 1; // <
+ − 3638
const signed char InpQm = 2; // ?
+ − 3639
const signed char InpEm = 3; // !
+ − 3640
const signed char InpD = 4; // D
+ − 3641
const signed char InpDash = 5; // -
+ − 3642
const signed char InpUnknown = 6;
+ − 3643
+ − 3644
static const signed char table[9][7] = {
+ − 3645
/* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
+ − 3646
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
+ − 3647
{ -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
+ − 3648
{ -1, -1, PInstr,Em, Done, -1, Done }, // Lt
+ − 3649
{ -1, -1, -1, -1, DocType, Comment, -1 }, // Em
+ − 3650
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
+ − 3651
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
+ − 3652
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // CommentR
+ − 3653
{ EatWS, Lt, -1, -1, -1, -1, -1 }, // PInstr
+ − 3654
{ EatWS, Lt, -1, -1, -1, -1, -1 } // PInstrR
+ − 3655
};
+ − 3656
signed char state;
+ − 3657
signed char input;
+ − 3658
+ − 3659
if (parseStack == 0 || parseStack->isEmpty()) {
+ − 3660
xmldecl_possible = true;
+ − 3661
doctype_read = false;
+ − 3662
state = Init;
+ − 3663
} else {
+ − 3664
state = parseStack->pop().state;
+ − 3665
#if defined(QT_QXML_DEBUG)
+ − 3666
qDebug("QXmlSimpleReader: parseProlog (cont) in state %d", state);
+ − 3667
#endif
+ − 3668
if (!parseStack->isEmpty()) {
+ − 3669
ParseFunction function = parseStack->top().function;
+ − 3670
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 3671
parseStack->pop();
+ − 3672
#if defined(QT_QXML_DEBUG)
+ − 3673
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 3674
#endif
+ − 3675
}
+ − 3676
if (!(this->*function)()) {
+ − 3677
parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3678
return false;
+ − 3679
}
+ − 3680
}
+ − 3681
}
+ − 3682
+ − 3683
for (;;) {
+ − 3684
switch (state) {
+ − 3685
case DocType:
+ − 3686
if (doctype_read) {
+ − 3687
reportParseError(QLatin1String(XMLERR_MORETHANONEDOCTYPE));
+ − 3688
return false;
+ − 3689
} else {
+ − 3690
doctype_read = false;
+ − 3691
}
+ − 3692
break;
+ − 3693
case Comment:
+ − 3694
if (lexicalHnd) {
+ − 3695
if (!lexicalHnd->comment(string())) {
+ − 3696
reportParseError(lexicalHnd->errorString());
+ − 3697
return false;
+ − 3698
}
+ − 3699
}
+ − 3700
state = CommentR;
+ − 3701
break;
+ − 3702
case PInstr:
+ − 3703
// call the handler
+ − 3704
if (contentHnd) {
+ − 3705
if (xmldecl_possible && !xmlVersion.isEmpty()) {
+ − 3706
QString value(QLatin1String("version='"));
+ − 3707
value += xmlVersion;
+ − 3708
value += QLatin1Char('\'');
+ − 3709
if (!encoding.isEmpty()) {
+ − 3710
value += QLatin1String(" encoding='");
+ − 3711
value += encoding;
+ − 3712
value += QLatin1Char('\'');
+ − 3713
}
+ − 3714
if (standalone == QXmlSimpleReaderPrivate::Yes) {
+ − 3715
value += QLatin1String(" standalone='yes'");
+ − 3716
} else if (standalone == QXmlSimpleReaderPrivate::No) {
+ − 3717
value += QLatin1String(" standalone='no'");
+ − 3718
}
+ − 3719
if (!contentHnd->processingInstruction(QLatin1String("xml"), value)) {
+ − 3720
reportParseError(contentHnd->errorString());
+ − 3721
return false;
+ − 3722
}
+ − 3723
} else {
+ − 3724
if (!contentHnd->processingInstruction(name(), string())) {
+ − 3725
reportParseError(contentHnd->errorString());
+ − 3726
return false;
+ − 3727
}
+ − 3728
}
+ − 3729
}
+ − 3730
// XML declaration only on first position possible
+ − 3731
xmldecl_possible = false;
+ − 3732
state = PInstrR;
+ − 3733
break;
+ − 3734
case Done:
+ − 3735
return true;
+ − 3736
case -1:
+ − 3737
reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
+ − 3738
return false;
+ − 3739
}
+ − 3740
+ − 3741
if (atEnd()) {
+ − 3742
unexpectedEof(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3743
return false;
+ − 3744
}
+ − 3745
if (is_S(c)) {
+ − 3746
input = InpWs;
+ − 3747
} else if (c == QLatin1Char('<')) {
+ − 3748
input = InpLt;
+ − 3749
} else if (c == QLatin1Char('?')) {
+ − 3750
input = InpQm;
+ − 3751
} else if (c == QLatin1Char('!')) {
+ − 3752
input = InpEm;
+ − 3753
} else if (c == QLatin1Char('D')) {
+ − 3754
input = InpD;
+ − 3755
} else if (c == QLatin1Char('-')) {
+ − 3756
input = InpDash;
+ − 3757
} else {
+ − 3758
input = InpUnknown;
+ − 3759
}
+ − 3760
state = table[state][input];
+ − 3761
+ − 3762
switch (state) {
+ − 3763
case EatWS:
+ − 3764
// XML declaration only on first position possible
+ − 3765
xmldecl_possible = false;
+ − 3766
if (!eat_ws()) {
+ − 3767
parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3768
return false;
+ − 3769
}
+ − 3770
break;
+ − 3771
case Lt:
+ − 3772
next();
+ − 3773
break;
+ − 3774
case Em:
+ − 3775
// XML declaration only on first position possible
+ − 3776
xmldecl_possible = false;
+ − 3777
next();
+ − 3778
break;
+ − 3779
case DocType:
+ − 3780
if (!parseDoctype()) {
+ − 3781
parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3782
return false;
+ − 3783
}
+ − 3784
break;
+ − 3785
case Comment:
+ − 3786
case CommentR:
+ − 3787
if (!parseComment()) {
+ − 3788
parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3789
return false;
+ − 3790
}
+ − 3791
break;
+ − 3792
case PInstr:
+ − 3793
case PInstrR:
+ − 3794
parsePI_xmldecl = xmldecl_possible;
+ − 3795
if (!parsePI()) {
+ − 3796
parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
+ − 3797
return false;
+ − 3798
}
+ − 3799
break;
+ − 3800
}
+ − 3801
}
+ − 3802
return false;
+ − 3803
}
+ − 3804
+ − 3805
/*
+ − 3806
Parse an element [39].
+ − 3807
+ − 3808
Precondition: the opening '<' is already read.
+ − 3809
*/
+ − 3810
bool QXmlSimpleReaderPrivate::parseElement()
+ − 3811
{
+ − 3812
const int Init = 0;
+ − 3813
const int ReadName = 1;
+ − 3814
const int Ws1 = 2;
+ − 3815
const int STagEnd = 3;
+ − 3816
const int STagEnd2 = 4;
+ − 3817
const int ETagBegin = 5;
+ − 3818
const int ETagBegin2 = 6;
+ − 3819
const int Ws2 = 7;
+ − 3820
const int EmptyTag = 8;
+ − 3821
const int Attrib = 9;
+ − 3822
const int AttribPro = 10; // like Attrib, but processAttribute was already called
+ − 3823
const int Ws3 = 11;
+ − 3824
const int Done = 12;
+ − 3825
+ − 3826
const int InpWs = 0; // whitespace
+ − 3827
const int InpNameBe = 1; // NameBeginning
+ − 3828
const int InpGt = 2; // >
+ − 3829
const int InpSlash = 3; // /
+ − 3830
const int InpUnknown = 4;
+ − 3831
+ − 3832
static const int table[12][5] = {
+ − 3833
/* InpWs InpNameBe InpGt InpSlash InpUnknown */
+ − 3834
{ -1, ReadName, -1, -1, -1 }, // Init
+ − 3835
{ Ws1, Attrib, STagEnd, EmptyTag, -1 }, // ReadName
+ − 3836
{ -1, Attrib, STagEnd, EmptyTag, -1 }, // Ws1
+ − 3837
{ STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
+ − 3838
{ -1, -1, -1, ETagBegin, -1 }, // STagEnd2
+ − 3839
{ -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
+ − 3840
{ Ws2, -1, Done, -1, -1 }, // ETagBegin2
+ − 3841
{ -1, -1, Done, -1, -1 }, // Ws2
+ − 3842
{ -1, -1, Done, -1, -1 }, // EmptyTag
+ − 3843
{ Ws3, Attrib, STagEnd, EmptyTag, -1 }, // Attrib
+ − 3844
{ Ws3, Attrib, STagEnd, EmptyTag, -1 }, // AttribPro
+ − 3845
{ -1, Attrib, STagEnd, EmptyTag, -1 } // Ws3
+ − 3846
};
+ − 3847
int state;
+ − 3848
int input;
+ − 3849
+ − 3850
if (parseStack == 0 || parseStack->isEmpty()) {
+ − 3851
state = Init;
+ − 3852
} else {
+ − 3853
state = parseStack->pop().state;
+ − 3854
#if defined(QT_QXML_DEBUG)
+ − 3855
qDebug("QXmlSimpleReader: parseElement (cont) in state %d", state);
+ − 3856
#endif
+ − 3857
if (!parseStack->isEmpty()) {
+ − 3858
ParseFunction function = parseStack->top().function;
+ − 3859
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 3860
parseStack->pop();
+ − 3861
#if defined(QT_QXML_DEBUG)
+ − 3862
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 3863
#endif
+ − 3864
}
+ − 3865
if (!(this->*function)()) {
+ − 3866
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3867
return false;
+ − 3868
}
+ − 3869
}
+ − 3870
}
+ − 3871
+ − 3872
for (;;) {
+ − 3873
switch (state) {
+ − 3874
case ReadName:
+ − 3875
// store it on the stack
+ − 3876
tags.push(name());
+ − 3877
// empty the attributes
+ − 3878
attList.clear();
+ − 3879
if (useNamespaces)
+ − 3880
namespaceSupport.pushContext();
+ − 3881
break;
+ − 3882
case ETagBegin2:
+ − 3883
if (!processElementETagBegin2())
+ − 3884
return false;
+ − 3885
break;
+ − 3886
case Attrib:
+ − 3887
if (!processElementAttribute())
+ − 3888
return false;
+ − 3889
state = AttribPro;
+ − 3890
break;
+ − 3891
case Done:
+ − 3892
return true;
+ − 3893
case -1:
+ − 3894
reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
+ − 3895
return false;
+ − 3896
}
+ − 3897
+ − 3898
if (atEnd()) {
+ − 3899
unexpectedEof(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3900
return false;
+ − 3901
}
+ − 3902
if (fastDetermineNameChar(c) == NameBeginning) {
+ − 3903
input = InpNameBe;
+ − 3904
} else if (c == QLatin1Char('>')) {
+ − 3905
input = InpGt;
+ − 3906
} else if (is_S(c)) {
+ − 3907
input = InpWs;
+ − 3908
} else if (c == QLatin1Char('/')) {
+ − 3909
input = InpSlash;
+ − 3910
} else {
+ − 3911
input = InpUnknown;
+ − 3912
}
+ − 3913
state = table[state][input];
+ − 3914
+ − 3915
switch (state) {
+ − 3916
case ReadName:
+ − 3917
parseName_useRef = false;
+ − 3918
if (!parseName()) {
+ − 3919
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3920
return false;
+ − 3921
}
+ − 3922
break;
+ − 3923
case Ws1:
+ − 3924
case Ws2:
+ − 3925
case Ws3:
+ − 3926
if (!eat_ws()) {
+ − 3927
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3928
return false;
+ − 3929
}
+ − 3930
break;
+ − 3931
case STagEnd:
+ − 3932
// call the handler
+ − 3933
if (contentHnd) {
+ − 3934
const QString &tagsTop = tags.top();
+ − 3935
if (useNamespaces) {
+ − 3936
QString uri, lname;
+ − 3937
namespaceSupport.processName(tagsTop, false, uri, lname);
+ − 3938
if (!contentHnd->startElement(uri, lname, tagsTop, attList)) {
+ − 3939
reportParseError(contentHnd->errorString());
+ − 3940
return false;
+ − 3941
}
+ − 3942
} else {
+ − 3943
if (!contentHnd->startElement(QString(), QString(), tagsTop, attList)) {
+ − 3944
reportParseError(contentHnd->errorString());
+ − 3945
return false;
+ − 3946
}
+ − 3947
}
+ − 3948
}
+ − 3949
next();
+ − 3950
break;
+ − 3951
case STagEnd2:
+ − 3952
if (!parseContent()) {
+ − 3953
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3954
return false;
+ − 3955
}
+ − 3956
break;
+ − 3957
case ETagBegin:
+ − 3958
next();
+ − 3959
break;
+ − 3960
case ETagBegin2:
+ − 3961
// get the name of the tag
+ − 3962
parseName_useRef = false;
+ − 3963
if (!parseName()) {
+ − 3964
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3965
return false;
+ − 3966
}
+ − 3967
break;
+ − 3968
case EmptyTag:
+ − 3969
if (tags.isEmpty()) {
+ − 3970
reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
+ − 3971
return false;
+ − 3972
}
+ − 3973
if (!processElementEmptyTag())
+ − 3974
return false;
+ − 3975
next();
+ − 3976
break;
+ − 3977
case Attrib:
+ − 3978
case AttribPro:
+ − 3979
// get name and value of attribute
+ − 3980
if (!parseAttribute()) {
+ − 3981
parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
+ − 3982
return false;
+ − 3983
}
+ − 3984
break;
+ − 3985
case Done:
+ − 3986
next();
+ − 3987
break;
+ − 3988
}
+ − 3989
}
+ − 3990
return false;
+ − 3991
}
+ − 3992
+ − 3993
/*
+ − 3994
Helper to break down the size of the code in the case statement.
+ − 3995
Return false on error, otherwise true.
+ − 3996
*/
+ − 3997
bool QXmlSimpleReaderPrivate::processElementEmptyTag()
+ − 3998
{
+ − 3999
QString uri, lname;
+ − 4000
// pop the stack and call the handler
+ − 4001
if (contentHnd) {
+ − 4002
if (useNamespaces) {
+ − 4003
// report startElement first...
+ − 4004
namespaceSupport.processName(tags.top(), false, uri, lname);
+ − 4005
if (!contentHnd->startElement(uri, lname, tags.top(), attList)) {
+ − 4006
reportParseError(contentHnd->errorString());
+ − 4007
return false;
+ − 4008
}
+ − 4009
// ... followed by endElement...
+ − 4010
if (!contentHnd->endElement(uri, lname, tags.pop())) {
+ − 4011
reportParseError(contentHnd->errorString());
+ − 4012
return false;
+ − 4013
}
+ − 4014
// ... followed by endPrefixMapping
+ − 4015
QStringList prefixesBefore, prefixesAfter;
+ − 4016
if (contentHnd) {
+ − 4017
prefixesBefore = namespaceSupport.prefixes();
+ − 4018
}
+ − 4019
namespaceSupport.popContext();
+ − 4020
// call the handler for prefix mapping
+ − 4021
prefixesAfter = namespaceSupport.prefixes();
+ − 4022
for (QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it) {
+ − 4023
if (!prefixesAfter.contains(*it)) {
+ − 4024
if (!contentHnd->endPrefixMapping(*it)) {
+ − 4025
reportParseError(contentHnd->errorString());
+ − 4026
return false;
+ − 4027
}
+ − 4028
}
+ − 4029
}
+ − 4030
} else {
+ − 4031
// report startElement first...
+ − 4032
if (!contentHnd->startElement(QString(), QString(), tags.top(), attList)) {
+ − 4033
reportParseError(contentHnd->errorString());
+ − 4034
return false;
+ − 4035
}
+ − 4036
// ... followed by endElement
+ − 4037
if (!contentHnd->endElement(QString(), QString(), tags.pop())) {
+ − 4038
reportParseError(contentHnd->errorString());
+ − 4039
return false;
+ − 4040
}
+ − 4041
}
+ − 4042
} else {
+ − 4043
tags.pop_back();
+ − 4044
namespaceSupport.popContext();
+ − 4045
}
+ − 4046
return true;
+ − 4047
}
+ − 4048
/*
+ − 4049
Helper to break down the size of the code in the case statement.
+ − 4050
Return false on error, otherwise true.
+ − 4051
*/
+ − 4052
bool QXmlSimpleReaderPrivate::processElementETagBegin2()
+ − 4053
{
+ − 4054
const QString &name = QXmlSimpleReaderPrivate::name();
+ − 4055
+ − 4056
// pop the stack and compare it with the name
+ − 4057
if (tags.pop() != name) {
+ − 4058
reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
+ − 4059
return false;
+ − 4060
}
+ − 4061
// call the handler
+ − 4062
if (contentHnd) {
+ − 4063
QString uri, lname;
+ − 4064
+ − 4065
if (useNamespaces)
+ − 4066
namespaceSupport.processName(name, false, uri, lname);
+ − 4067
if (!contentHnd->endElement(uri, lname, name)) {
+ − 4068
reportParseError(contentHnd->errorString());
+ − 4069
return false;
+ − 4070
}
+ − 4071
}
+ − 4072
if (useNamespaces) {
+ − 4073
NamespaceMap prefixesBefore, prefixesAfter;
+ − 4074
if (contentHnd)
+ − 4075
prefixesBefore = namespaceSupport.d->ns;
+ − 4076
+ − 4077
namespaceSupport.popContext();
+ − 4078
// call the handler for prefix mapping
+ − 4079
if (contentHnd) {
+ − 4080
prefixesAfter = namespaceSupport.d->ns;
+ − 4081
if (prefixesBefore.size() != prefixesAfter.size()) {
+ − 4082
for (NamespaceMap::const_iterator it = prefixesBefore.constBegin(); it != prefixesBefore.constEnd(); ++it) {
+ − 4083
if (!it.key().isEmpty() && !prefixesAfter.contains(it.key())) {
+ − 4084
if (!contentHnd->endPrefixMapping(it.key())) {
+ − 4085
reportParseError(contentHnd->errorString());
+ − 4086
return false;
+ − 4087
}
+ − 4088
}
+ − 4089
}
+ − 4090
}
+ − 4091
}
+ − 4092
}
+ − 4093
return true;
+ − 4094
}
+ − 4095
/*
+ − 4096
Helper to break down the size of the code in the case statement.
+ − 4097
Return false on error, otherwise true.
+ − 4098
*/
+ − 4099
bool QXmlSimpleReaderPrivate::processElementAttribute()
+ − 4100
{
+ − 4101
QString uri, lname, prefix;
+ − 4102
const QString &name = QXmlSimpleReaderPrivate::name();
+ − 4103
const QString &string = QXmlSimpleReaderPrivate::string();
+ − 4104
+ − 4105
// add the attribute to the list
+ − 4106
if (useNamespaces) {
+ − 4107
// is it a namespace declaration?
+ − 4108
namespaceSupport.splitName(name, prefix, lname);
+ − 4109
if (prefix == QLatin1String("xmlns")) {
+ − 4110
// namespace declaration
+ − 4111
namespaceSupport.setPrefix(lname, string);
+ − 4112
if (useNamespacePrefixes) {
+ − 4113
// according to http://www.w3.org/2000/xmlns/, the "prefix"
+ − 4114
// xmlns maps to the namespace name
+ − 4115
// http://www.w3.org/2000/xmlns/
+ − 4116
attList.append(name, QLatin1String("http://www.w3.org/2000/xmlns/"), lname, string);
+ − 4117
}
+ − 4118
// call the handler for prefix mapping
+ − 4119
if (contentHnd) {
+ − 4120
if (!contentHnd->startPrefixMapping(lname, string)) {
+ − 4121
reportParseError(contentHnd->errorString());
+ − 4122
return false;
+ − 4123
}
+ − 4124
}
+ − 4125
} else {
+ − 4126
// no namespace delcaration
+ − 4127
namespaceSupport.processName(name, true, uri, lname);
+ − 4128
attList.append(name, uri, lname, string);
+ − 4129
}
+ − 4130
} else {
+ − 4131
// no namespace support
+ − 4132
attList.append(name, uri, lname, string);
+ − 4133
}
+ − 4134
return true;
+ − 4135
}
+ − 4136
+ − 4137
/*
+ − 4138
Parse a content [43].
+ − 4139
+ − 4140
A content is only used between tags. If a end tag is found the < is already
+ − 4141
read and the head stand on the '/' of the end tag '</name>'.
+ − 4142
*/
+ − 4143
bool QXmlSimpleReaderPrivate::parseContent()
+ − 4144
{
+ − 4145
const signed char Init = 0;
+ − 4146
const signed char ChD = 1; // CharData
+ − 4147
const signed char ChD1 = 2; // CharData help state
+ − 4148
const signed char ChD2 = 3; // CharData help state
+ − 4149
const signed char Ref = 4; // Reference
+ − 4150
const signed char Lt = 5; // '<' read
+ − 4151
const signed char PInstr = 6; // PI
+ − 4152
const signed char PInstrR = 7; // same as PInstr, but already reported
+ − 4153
const signed char Elem = 8; // Element
+ − 4154
const signed char Em = 9; // '!' read
+ − 4155
const signed char Com = 10; // Comment
+ − 4156
const signed char ComR = 11; // same as Com, but already reported
+ − 4157
const signed char CDS = 12; // CDSect
+ − 4158
const signed char CDS1 = 13; // read a CDSect
+ − 4159
const signed char CDS2 = 14; // read a CDSect (help state)
+ − 4160
const signed char CDS3 = 15; // read a CDSect (help state)
+ − 4161
const signed char Done = 16; // finished reading content
+ − 4162
+ − 4163
const signed char InpLt = 0; // <
+ − 4164
const signed char InpGt = 1; // >
+ − 4165
const signed char InpSlash = 2; // /
+ − 4166
const signed char InpQMark = 3; // ?
+ − 4167
const signed char InpEMark = 4; // !
+ − 4168
const signed char InpAmp = 5; // &
+ − 4169
const signed char InpDash = 6; // -
+ − 4170
const signed char InpOpenB = 7; // [
+ − 4171
const signed char InpCloseB = 8; //]
+ − 4172
const signed char InpUnknown = 9;
+ − 4173
+ − 4174
static const signed char mapCLT2FSMChar[] = {
+ − 4175
InpUnknown, // white space
+ − 4176
InpUnknown, // %
+ − 4177
InpAmp, // &
+ − 4178
InpGt, // >
+ − 4179
InpLt, // <
+ − 4180
InpSlash, // /
+ − 4181
InpQMark, // ?
+ − 4182
InpEMark, // !
+ − 4183
InpDash, // -
+ − 4184
InpCloseB, //]
+ − 4185
InpOpenB, // [
+ − 4186
InpUnknown, // =
+ − 4187
InpUnknown, // "
+ − 4188
InpUnknown, // '
+ − 4189
InpUnknown // unknown
+ − 4190
};
+ − 4191
+ − 4192
static const signed char table[16][10] = {
+ − 4193
/* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
+ − 4194
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
+ − 4195
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
+ − 4196
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
+ − 4197
{ Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
+ − 4198
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
+ − 4199
{ -1, -1, Done, PInstr, Em, -1, -1, -1, -1, Elem }, // Lt
+ − 4200
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstr (same as Init)
+ − 4201
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstrR
+ − 4202
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
+ − 4203
{ -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
+ − 4204
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
+ − 4205
{ Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // ComR
+ − 4206
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
+ − 4207
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
+ − 4208
{ CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
+ − 4209
{ CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
+ − 4210
};
+ − 4211
signed char state;
+ − 4212
signed char input;
+ − 4213
+ − 4214
if (parseStack == 0 || parseStack->isEmpty()) {
+ − 4215
contentCharDataRead = false;
+ − 4216
state = Init;
+ − 4217
} else {
+ − 4218
state = parseStack->pop().state;
+ − 4219
#if defined(QT_QXML_DEBUG)
+ − 4220
qDebug("QXmlSimpleReader: parseContent (cont) in state %d", state);
+ − 4221
#endif
+ − 4222
if (!parseStack->isEmpty()) {
+ − 4223
ParseFunction function = parseStack->top().function;
+ − 4224
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 4225
parseStack->pop();
+ − 4226
#if defined(QT_QXML_DEBUG)
+ − 4227
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 4228
#endif
+ − 4229
}
+ − 4230
if (!(this->*function)()) {
+ − 4231
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4232
return false;
+ − 4233
}
+ − 4234
}
+ − 4235
}
+ − 4236
+ − 4237
for (;;) {
+ − 4238
switch (state) {
+ − 4239
case Ref:
+ − 4240
if (!contentCharDataRead)
+ − 4241
contentCharDataRead = parseReference_charDataRead;
+ − 4242
break;
+ − 4243
case PInstr:
+ − 4244
if (contentHnd) {
+ − 4245
if (!contentHnd->processingInstruction(name(),string())) {
+ − 4246
reportParseError(contentHnd->errorString());
+ − 4247
return false;
+ − 4248
}
+ − 4249
}
+ − 4250
state = PInstrR;
+ − 4251
break;
+ − 4252
case Com:
+ − 4253
if (lexicalHnd) {
+ − 4254
if (!lexicalHnd->comment(string())) {
+ − 4255
reportParseError(lexicalHnd->errorString());
+ − 4256
return false;
+ − 4257
}
+ − 4258
}
+ − 4259
state = ComR;
+ − 4260
break;
+ − 4261
case CDS:
+ − 4262
stringClear();
+ − 4263
break;
+ − 4264
case CDS2:
+ − 4265
if (!atEnd() && c != QLatin1Char(']'))
+ − 4266
stringAddC(QLatin1Char(']'));
+ − 4267
break;
+ − 4268
case CDS3:
+ − 4269
// test if this skipping was legal
+ − 4270
if (!atEnd()) {
+ − 4271
if (c == QLatin1Char('>')) {
+ − 4272
// the end of the CDSect
+ − 4273
if (lexicalHnd) {
+ − 4274
if (!lexicalHnd->startCDATA()) {
+ − 4275
reportParseError(lexicalHnd->errorString());
+ − 4276
return false;
+ − 4277
}
+ − 4278
}
+ − 4279
if (contentHnd) {
+ − 4280
if (!contentHnd->characters(string())) {
+ − 4281
reportParseError(contentHnd->errorString());
+ − 4282
return false;
+ − 4283
}
+ − 4284
}
+ − 4285
if (lexicalHnd) {
+ − 4286
if (!lexicalHnd->endCDATA()) {
+ − 4287
reportParseError(lexicalHnd->errorString());
+ − 4288
return false;
+ − 4289
}
+ − 4290
}
+ − 4291
} else if (c == QLatin1Char(']')) {
+ − 4292
// three or more ']'
+ − 4293
stringAddC(QLatin1Char(']'));
+ − 4294
} else {
+ − 4295
// after ']]' comes another character
+ − 4296
stringAddC(QLatin1Char(']'));
+ − 4297
stringAddC(QLatin1Char(']'));
+ − 4298
}
+ − 4299
}
+ − 4300
break;
+ − 4301
case Done:
+ − 4302
// call the handler for CharData
+ − 4303
if (contentHnd) {
+ − 4304
if (contentCharDataRead) {
+ − 4305
if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
+ − 4306
if (!contentHnd->characters(string())) {
+ − 4307
reportParseError(contentHnd->errorString());
+ − 4308
return false;
+ − 4309
}
+ − 4310
}
+ − 4311
}
+ − 4312
}
+ − 4313
// Done
+ − 4314
return true;
+ − 4315
case -1:
+ − 4316
// Error
+ − 4317
reportParseError(QLatin1String(XMLERR_ERRORPARSINGCONTENT));
+ − 4318
return false;
+ − 4319
}
+ − 4320
+ − 4321
// get input (use lookup-table instead of nested ifs for performance
+ − 4322
// reasons)
+ − 4323
if (atEnd()) {
+ − 4324
unexpectedEof(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4325
return false;
+ − 4326
}
+ − 4327
if (c.row()) {
+ − 4328
input = InpUnknown;
+ − 4329
} else {
+ − 4330
input = mapCLT2FSMChar[charLookupTable[c.cell()]];
+ − 4331
}
+ − 4332
state = table[state][input];
+ − 4333
+ − 4334
switch (state) {
+ − 4335
case Init:
+ − 4336
// skip the ending '>' of a CDATASection
+ − 4337
next();
+ − 4338
break;
+ − 4339
case ChD:
+ − 4340
// on first call: clear string
+ − 4341
if (!contentCharDataRead) {
+ − 4342
contentCharDataRead = true;
+ − 4343
stringClear();
+ − 4344
}
+ − 4345
stringAddC();
+ − 4346
if (reportEntities) {
+ − 4347
if (!reportEndEntities())
+ − 4348
return false;
+ − 4349
}
+ − 4350
next();
+ − 4351
break;
+ − 4352
case ChD1:
+ − 4353
// on first call: clear string
+ − 4354
if (!contentCharDataRead) {
+ − 4355
contentCharDataRead = true;
+ − 4356
stringClear();
+ − 4357
}
+ − 4358
stringAddC();
+ − 4359
if (reportEntities) {
+ − 4360
if (!reportEndEntities())
+ − 4361
return false;
+ − 4362
}
+ − 4363
next();
+ − 4364
break;
+ − 4365
case ChD2:
+ − 4366
stringAddC();
+ − 4367
if (reportEntities) {
+ − 4368
if (!reportEndEntities())
+ − 4369
return false;
+ − 4370
}
+ − 4371
next();
+ − 4372
break;
+ − 4373
case Ref:
+ − 4374
if (!contentCharDataRead) {
+ − 4375
// reference may be CharData; so clear string to be safe
+ − 4376
stringClear();
+ − 4377
parseReference_context = InContent;
+ − 4378
if (!parseReference()) {
+ − 4379
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4380
return false;
+ − 4381
}
+ − 4382
} else {
+ − 4383
if (reportEntities) {
+ − 4384
// report character data in chunks
+ − 4385
if (contentHnd) {
+ − 4386
if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
+ − 4387
if (!contentHnd->characters(string())) {
+ − 4388
reportParseError(contentHnd->errorString());
+ − 4389
return false;
+ − 4390
}
+ − 4391
}
+ − 4392
}
+ − 4393
stringClear();
+ − 4394
}
+ − 4395
parseReference_context = InContent;
+ − 4396
if (!parseReference()) {
+ − 4397
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4398
return false;
+ − 4399
}
+ − 4400
}
+ − 4401
break;
+ − 4402
case Lt:
+ − 4403
// call the handler for CharData
+ − 4404
if (contentHnd) {
+ − 4405
if (contentCharDataRead) {
+ − 4406
if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
+ − 4407
if (!contentHnd->characters(string())) {
+ − 4408
reportParseError(contentHnd->errorString());
+ − 4409
return false;
+ − 4410
}
+ − 4411
}
+ − 4412
}
+ − 4413
}
+ − 4414
contentCharDataRead = false;
+ − 4415
next();
+ − 4416
break;
+ − 4417
case PInstr:
+ − 4418
case PInstrR:
+ − 4419
parsePI_xmldecl = false;
+ − 4420
if (!parsePI()) {
+ − 4421
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4422
return false;
+ − 4423
}
+ − 4424
break;
+ − 4425
case Elem:
+ − 4426
if (!parseElement()) {
+ − 4427
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4428
return false;
+ − 4429
}
+ − 4430
break;
+ − 4431
case Em:
+ − 4432
next();
+ − 4433
break;
+ − 4434
case Com:
+ − 4435
case ComR:
+ − 4436
if (!parseComment()) {
+ − 4437
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4438
return false;
+ − 4439
}
+ − 4440
break;
+ − 4441
case CDS:
+ − 4442
parseString_s = QLatin1String("[CDATA[");
+ − 4443
if (!parseString()) {
+ − 4444
parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
+ − 4445
return false;
+ − 4446
}
+ − 4447
break;
+ − 4448
case CDS1:
+ − 4449
stringAddC();
+ − 4450
next();
+ − 4451
break;
+ − 4452
case CDS2:
+ − 4453
// skip ']'
+ − 4454
next();
+ − 4455
break;
+ − 4456
case CDS3:
+ − 4457
// skip ']'...
+ − 4458
next();
+ − 4459
break;
+ − 4460
}
+ − 4461
}
+ − 4462
return false;
+ − 4463
}
+ − 4464
+ − 4465
bool QXmlSimpleReaderPrivate::reportEndEntities()
+ − 4466
{
+ − 4467
int count = (int)xmlRefStack.count();
+ − 4468
while (count != 0 && xmlRefStack.top().isEmpty()) {
+ − 4469
if (contentHnd) {
+ − 4470
if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
+ − 4471
if (!contentHnd->characters(string())) {
+ − 4472
reportParseError(contentHnd->errorString());
+ − 4473
return false;
+ − 4474
}
+ − 4475
}
+ − 4476
}
+ − 4477
stringClear();
+ − 4478
if (lexicalHnd) {
+ − 4479
if (!lexicalHnd->endEntity(xmlRefStack.top().name)) {
+ − 4480
reportParseError(lexicalHnd->errorString());
+ − 4481
return false;
+ − 4482
}
+ − 4483
}
+ − 4484
xmlRefStack.pop_back();
+ − 4485
count--;
+ − 4486
}
+ − 4487
return true;
+ − 4488
}
+ − 4489
+ − 4490
/*
+ − 4491
Parse Misc [27].
+ − 4492
*/
+ − 4493
bool QXmlSimpleReaderPrivate::parseMisc()
+ − 4494
{
+ − 4495
const signed char Init = 0;
+ − 4496
const signed char Lt = 1; // '<' was read
+ − 4497
const signed char Comment = 2; // read comment
+ − 4498
const signed char eatWS = 3; // eat whitespaces
+ − 4499
const signed char PInstr = 4; // read PI
+ − 4500
const signed char Comment2 = 5; // read comment
+ − 4501
+ − 4502
const signed char InpWs = 0; // S
+ − 4503
const signed char InpLt = 1; // <
+ − 4504
const signed char InpQm = 2; // ?
+ − 4505
const signed char InpEm = 3; // !
+ − 4506
const signed char InpUnknown = 4;
+ − 4507
+ − 4508
static const signed char table[3][5] = {
+ − 4509
/* InpWs InpLt InpQm InpEm InpUnknown */
+ − 4510
{ eatWS, Lt, -1, -1, -1 }, // Init
+ − 4511
{ -1, -1, PInstr,Comment, -1 }, // Lt
+ − 4512
{ -1, -1, -1, -1, Comment2 } // Comment
+ − 4513
};
+ − 4514
signed char state;
+ − 4515
signed char input;
+ − 4516
+ − 4517
if (parseStack==0 || parseStack->isEmpty()) {
+ − 4518
state = Init;
+ − 4519
} else {
+ − 4520
state = parseStack->pop().state;
+ − 4521
#if defined(QT_QXML_DEBUG)
+ − 4522
qDebug("QXmlSimpleReader: parseMisc (cont) in state %d", state);
+ − 4523
#endif
+ − 4524
if (!parseStack->isEmpty()) {
+ − 4525
ParseFunction function = parseStack->top().function;
+ − 4526
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 4527
parseStack->pop();
+ − 4528
#if defined(QT_QXML_DEBUG)
+ − 4529
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 4530
#endif
+ − 4531
}
+ − 4532
if (!(this->*function)()) {
+ − 4533
parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
+ − 4534
return false;
+ − 4535
}
+ − 4536
}
+ − 4537
}
+ − 4538
+ − 4539
for (;;) {
+ − 4540
switch (state) {
+ − 4541
case eatWS:
+ − 4542
return true;
+ − 4543
case PInstr:
+ − 4544
if (contentHnd) {
+ − 4545
if (!contentHnd->processingInstruction(name(),string())) {
+ − 4546
reportParseError(contentHnd->errorString());
+ − 4547
return false;
+ − 4548
}
+ − 4549
}
+ − 4550
return true;
+ − 4551
case Comment2:
+ − 4552
if (lexicalHnd) {
+ − 4553
if (!lexicalHnd->comment(string())) {
+ − 4554
reportParseError(lexicalHnd->errorString());
+ − 4555
return false;
+ − 4556
}
+ − 4557
}
+ − 4558
return true;
+ − 4559
case -1:
+ − 4560
// Error
+ − 4561
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 4562
return false;
+ − 4563
}
+ − 4564
+ − 4565
if (atEnd()) {
+ − 4566
unexpectedEof(&QXmlSimpleReaderPrivate::parseMisc, state);
+ − 4567
return false;
+ − 4568
}
+ − 4569
if (is_S(c)) {
+ − 4570
input = InpWs;
+ − 4571
} else if (c == QLatin1Char('<')) {
+ − 4572
input = InpLt;
+ − 4573
} else if (c == QLatin1Char('?')) {
+ − 4574
input = InpQm;
+ − 4575
} else if (c == QLatin1Char('!')) {
+ − 4576
input = InpEm;
+ − 4577
} else {
+ − 4578
input = InpUnknown;
+ − 4579
}
+ − 4580
state = table[state][input];
+ − 4581
+ − 4582
switch (state) {
+ − 4583
case eatWS:
+ − 4584
if (!eat_ws()) {
+ − 4585
parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
+ − 4586
return false;
+ − 4587
}
+ − 4588
break;
+ − 4589
case Lt:
+ − 4590
next();
+ − 4591
break;
+ − 4592
case PInstr:
+ − 4593
parsePI_xmldecl = false;
+ − 4594
if (!parsePI()) {
+ − 4595
parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
+ − 4596
return false;
+ − 4597
}
+ − 4598
break;
+ − 4599
case Comment:
+ − 4600
next();
+ − 4601
break;
+ − 4602
case Comment2:
+ − 4603
if (!parseComment()) {
+ − 4604
parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
+ − 4605
return false;
+ − 4606
}
+ − 4607
break;
+ − 4608
}
+ − 4609
}
+ − 4610
return false;
+ − 4611
}
+ − 4612
+ − 4613
/*
+ − 4614
Parse a processing instruction [16].
+ − 4615
+ − 4616
If xmldec is true, it tries to parse a PI or a XML declaration [23].
+ − 4617
+ − 4618
Precondition: the beginning '<' of the PI is already read and the head stand
+ − 4619
on the '?' of '<?'.
+ − 4620
+ − 4621
If this funktion was successful, the head-position is on the first
+ − 4622
character after the PI.
+ − 4623
*/
+ − 4624
bool QXmlSimpleReaderPrivate::parsePI()
+ − 4625
{
+ − 4626
const signed char Init = 0;
+ − 4627
const signed char QmI = 1; // ? was read
+ − 4628
const signed char Name = 2; // read Name
+ − 4629
const signed char XMLDecl = 3; // read XMLDecl
+ − 4630
const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
+ − 4631
const signed char PInstr = 5; // read PI
+ − 4632
const signed char Ws2 = 6; // eat ws after Name of PI
+ − 4633
const signed char Version = 7; // read versionInfo
+ − 4634
const signed char Ws3 = 8; // eat ws after versionInfo
+ − 4635
const signed char EorSD = 9; // read EDecl or SDDecl
+ − 4636
const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
+ − 4637
const signed char SD = 11; // read SDDecl
+ − 4638
const signed char Ws5 = 12; // eat ws after SDDecl
+ − 4639
const signed char ADone = 13; // almost done
+ − 4640
const signed char Char = 14; // Char was read
+ − 4641
const signed char Qm = 15; // Qm was read
+ − 4642
const signed char Done = 16; // finished reading content
+ − 4643
+ − 4644
const signed char InpWs = 0; // whitespace
+ − 4645
const signed char InpNameBe = 1; // NameBeginning
+ − 4646
const signed char InpGt = 2; // >
+ − 4647
const signed char InpQm = 3; // ?
+ − 4648
const signed char InpUnknown = 4;
+ − 4649
+ − 4650
static const signed char table[16][5] = {
+ − 4651
/* InpWs, InpNameBe InpGt InpQm InpUnknown */
+ − 4652
{ -1, -1, -1, QmI, -1 }, // Init
+ − 4653
{ -1, Name, -1, -1, -1 }, // QmI
+ − 4654
{ -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
+ − 4655
{ Ws1, -1, -1, -1, -1 }, // XMLDecl
+ − 4656
{ -1, Version, -1, -1, -1 }, // Ws1
+ − 4657
{ Ws2, -1, -1, Qm, -1 }, // PInstr
+ − 4658
{ Char, Char, Char, Qm, Char }, // Ws2
+ − 4659
{ Ws3, -1, -1, ADone, -1 }, // Version
+ − 4660
{ -1, EorSD, -1, ADone, -1 }, // Ws3
+ − 4661
{ Ws4, -1, -1, ADone, -1 }, // EorSD
+ − 4662
{ -1, SD, -1, ADone, -1 }, // Ws4
+ − 4663
{ Ws5, -1, -1, ADone, -1 }, // SD
+ − 4664
{ -1, -1, -1, ADone, -1 }, // Ws5
+ − 4665
{ -1, -1, Done, -1, -1 }, // ADone
+ − 4666
{ Char, Char, Char, Qm, Char }, // Char
+ − 4667
{ Char, Char, Done, Qm, Char }, // Qm
+ − 4668
};
+ − 4669
signed char state;
+ − 4670
signed char input;
+ − 4671
+ − 4672
if (parseStack==0 || parseStack->isEmpty()) {
+ − 4673
state = Init;
+ − 4674
} else {
+ − 4675
state = parseStack->pop().state;
+ − 4676
#if defined(QT_QXML_DEBUG)
+ − 4677
qDebug("QXmlSimpleReader: parsePI (cont) in state %d", state);
+ − 4678
#endif
+ − 4679
if (!parseStack->isEmpty()) {
+ − 4680
ParseFunction function = parseStack->top().function;
+ − 4681
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 4682
parseStack->pop();
+ − 4683
#if defined(QT_QXML_DEBUG)
+ − 4684
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 4685
#endif
+ − 4686
}
+ − 4687
if (!(this->*function)()) {
+ − 4688
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4689
return false;
+ − 4690
}
+ − 4691
}
+ − 4692
}
+ − 4693
+ − 4694
for (;;) {
+ − 4695
switch (state) {
+ − 4696
case Name:
+ − 4697
// test what name was read and determine the next state
+ − 4698
// (not very beautiful, I admit)
+ − 4699
if (name().toLower() == QLatin1String("xml")) {
+ − 4700
if (parsePI_xmldecl && name() == QLatin1String("xml")) {
+ − 4701
state = XMLDecl;
+ − 4702
} else {
+ − 4703
reportParseError(QLatin1String(XMLERR_INVALIDNAMEFORPI));
+ − 4704
return false;
+ − 4705
}
+ − 4706
} else {
+ − 4707
state = PInstr;
+ − 4708
stringClear();
+ − 4709
}
+ − 4710
break;
+ − 4711
case Version:
+ − 4712
// get version (syntax like an attribute)
+ − 4713
if (name() != QLatin1String("version")) {
+ − 4714
reportParseError(QLatin1String(XMLERR_VERSIONEXPECTED));
+ − 4715
return false;
+ − 4716
}
+ − 4717
xmlVersion = string();
+ − 4718
break;
+ − 4719
case EorSD:
+ − 4720
// get the EDecl or SDDecl (syntax like an attribute)
+ − 4721
if (name() == QLatin1String("standalone")) {
+ − 4722
if (string()== QLatin1String("yes")) {
+ − 4723
standalone = QXmlSimpleReaderPrivate::Yes;
+ − 4724
} else if (string() == QLatin1String("no")) {
+ − 4725
standalone = QXmlSimpleReaderPrivate::No;
+ − 4726
} else {
+ − 4727
reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
+ − 4728
return false;
+ − 4729
}
+ − 4730
} else if (name() == QLatin1String("encoding")) {
+ − 4731
encoding = string();
+ − 4732
} else {
+ − 4733
reportParseError(QLatin1String(XMLERR_EDECLORSDDECLEXPECTED));
+ − 4734
return false;
+ − 4735
}
+ − 4736
break;
+ − 4737
case SD:
+ − 4738
if (name() != QLatin1String("standalone")) {
+ − 4739
reportParseError(QLatin1String(XMLERR_SDDECLEXPECTED));
+ − 4740
return false;
+ − 4741
}
+ − 4742
if (string() == QLatin1String("yes")) {
+ − 4743
standalone = QXmlSimpleReaderPrivate::Yes;
+ − 4744
} else if (string() == QLatin1String("no")) {
+ − 4745
standalone = QXmlSimpleReaderPrivate::No;
+ − 4746
} else {
+ − 4747
reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
+ − 4748
return false;
+ − 4749
}
+ − 4750
break;
+ − 4751
case Qm:
+ − 4752
// test if the skipping was legal
+ − 4753
if (!atEnd() && c != QLatin1Char('>'))
+ − 4754
stringAddC(QLatin1Char('?'));
+ − 4755
break;
+ − 4756
case Done:
+ − 4757
return true;
+ − 4758
case -1:
+ − 4759
// Error
+ − 4760
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 4761
return false;
+ − 4762
}
+ − 4763
+ − 4764
if (atEnd()) {
+ − 4765
unexpectedEof(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4766
return false;
+ − 4767
}
+ − 4768
if (is_S(c)) {
+ − 4769
input = InpWs;
+ − 4770
} else if (determineNameChar(c) == NameBeginning) {
+ − 4771
input = InpNameBe;
+ − 4772
} else if (c == QLatin1Char('>')) {
+ − 4773
input = InpGt;
+ − 4774
} else if (c == QLatin1Char('?')) {
+ − 4775
input = InpQm;
+ − 4776
} else {
+ − 4777
input = InpUnknown;
+ − 4778
}
+ − 4779
state = table[state][input];
+ − 4780
+ − 4781
switch (state) {
+ − 4782
case QmI:
+ − 4783
next();
+ − 4784
break;
+ − 4785
case Name:
+ − 4786
parseName_useRef = false;
+ − 4787
if (!parseName()) {
+ − 4788
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4789
return false;
+ − 4790
}
+ − 4791
break;
+ − 4792
case Ws1:
+ − 4793
case Ws2:
+ − 4794
case Ws3:
+ − 4795
case Ws4:
+ − 4796
case Ws5:
+ − 4797
if (!eat_ws()) {
+ − 4798
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4799
return false;
+ − 4800
}
+ − 4801
break;
+ − 4802
case Version:
+ − 4803
if (!parseAttribute()) {
+ − 4804
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4805
return false;
+ − 4806
}
+ − 4807
break;
+ − 4808
case EorSD:
+ − 4809
if (!parseAttribute()) {
+ − 4810
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4811
return false;
+ − 4812
}
+ − 4813
break;
+ − 4814
case SD:
+ − 4815
// get the SDDecl (syntax like an attribute)
+ − 4816
if (standalone != QXmlSimpleReaderPrivate::Unknown) {
+ − 4817
// already parsed the standalone declaration
+ − 4818
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 4819
return false;
+ − 4820
}
+ − 4821
if (!parseAttribute()) {
+ − 4822
parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
+ − 4823
return false;
+ − 4824
}
+ − 4825
break;
+ − 4826
case ADone:
+ − 4827
next();
+ − 4828
break;
+ − 4829
case Char:
+ − 4830
stringAddC();
+ − 4831
next();
+ − 4832
break;
+ − 4833
case Qm:
+ − 4834
// skip the '?'
+ − 4835
next();
+ − 4836
break;
+ − 4837
case Done:
+ − 4838
next();
+ − 4839
break;
+ − 4840
}
+ − 4841
}
+ − 4842
return false;
+ − 4843
}
+ − 4844
+ − 4845
/*
+ − 4846
Parse a document type definition (doctypedecl [28]).
+ − 4847
+ − 4848
Precondition: the beginning '<!' of the doctype is already read the head
+ − 4849
stands on the 'D' of '<!DOCTYPE'.
+ − 4850
+ − 4851
If this function was successful, the head-position is on the first
+ − 4852
character after the document type definition.
+ − 4853
*/
+ − 4854
bool QXmlSimpleReaderPrivate::parseDoctype()
+ − 4855
{
+ − 4856
const signed char Init = 0;
+ − 4857
const signed char Doctype = 1; // read the doctype
+ − 4858
const signed char Ws1 = 2; // eat_ws
+ − 4859
const signed char Doctype2 = 3; // read the doctype, part 2
+ − 4860
const signed char Ws2 = 4; // eat_ws
+ − 4861
const signed char Sys = 5; // read SYSTEM or PUBLIC
+ − 4862
const signed char Ws3 = 6; // eat_ws
+ − 4863
const signed char MP = 7; // markupdecl or PEReference
+ − 4864
const signed char MPR = 8; // same as MP, but already reported
+ − 4865
const signed char PER = 9; // PERReference
+ − 4866
const signed char Mup = 10; // markupdecl
+ − 4867
const signed char Ws4 = 11; // eat_ws
+ − 4868
const signed char MPE = 12; // end of markupdecl or PEReference
+ − 4869
const signed char Done = 13;
+ − 4870
+ − 4871
const signed char InpWs = 0;
+ − 4872
const signed char InpD = 1; // 'D'
+ − 4873
const signed char InpS = 2; // 'S' or 'P'
+ − 4874
const signed char InpOB = 3; // [
+ − 4875
const signed char InpCB = 4; //]
+ − 4876
const signed char InpPer = 5; // %
+ − 4877
const signed char InpGt = 6; // >
+ − 4878
const signed char InpUnknown = 7;
+ − 4879
+ − 4880
static const signed char table[13][8] = {
+ − 4881
/* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
+ − 4882
{ -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
+ − 4883
{ Ws1, -1, -1, -1, -1, -1, -1, -1 }, // Doctype
+ − 4884
{ -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
+ − 4885
{ Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
+ − 4886
{ -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
+ − 4887
{ Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
+ − 4888
{ -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
+ − 4889
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
+ − 4890
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // MPR
+ − 4891
{ Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
+ − 4892
{ Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
+ − 4893
{ -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
+ − 4894
{ -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
+ − 4895
};
+ − 4896
signed char state;
+ − 4897
signed char input;
+ − 4898
+ − 4899
if (parseStack==0 || parseStack->isEmpty()) {
+ − 4900
startDTDwasReported = false;
+ − 4901
systemId.clear();
+ − 4902
publicId.clear();
+ − 4903
state = Init;
+ − 4904
} else {
+ − 4905
state = parseStack->pop().state;
+ − 4906
#if defined(QT_QXML_DEBUG)
+ − 4907
qDebug("QXmlSimpleReader: parseDoctype (cont) in state %d", state);
+ − 4908
#endif
+ − 4909
if (!parseStack->isEmpty()) {
+ − 4910
ParseFunction function = parseStack->top().function;
+ − 4911
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 4912
parseStack->pop();
+ − 4913
#if defined(QT_QXML_DEBUG)
+ − 4914
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 4915
#endif
+ − 4916
}
+ − 4917
if (!(this->*function)()) {
+ − 4918
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 4919
return false;
+ − 4920
}
+ − 4921
}
+ − 4922
}
+ − 4923
+ − 4924
for (;;) {
+ − 4925
switch (state) {
+ − 4926
case Doctype2:
+ − 4927
doctype = name();
+ − 4928
break;
+ − 4929
case MP:
+ − 4930
if (!startDTDwasReported && lexicalHnd ) {
+ − 4931
startDTDwasReported = true;
+ − 4932
if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
+ − 4933
reportParseError(lexicalHnd->errorString());
+ − 4934
return false;
+ − 4935
}
+ − 4936
}
+ − 4937
state = MPR;
+ − 4938
break;
+ − 4939
case Done:
+ − 4940
return true;
+ − 4941
case -1:
+ − 4942
// Error
+ − 4943
reportParseError(QLatin1String(XMLERR_ERRORPARSINGDOCTYPE));
+ − 4944
return false;
+ − 4945
}
+ − 4946
+ − 4947
if (atEnd()) {
+ − 4948
unexpectedEof(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 4949
return false;
+ − 4950
}
+ − 4951
if (is_S(c)) {
+ − 4952
input = InpWs;
+ − 4953
} else if (c == QLatin1Char('D')) {
+ − 4954
input = InpD;
+ − 4955
} else if (c == QLatin1Char('S')) {
+ − 4956
input = InpS;
+ − 4957
} else if (c == QLatin1Char('P')) {
+ − 4958
input = InpS;
+ − 4959
} else if (c == QLatin1Char('[')) {
+ − 4960
input = InpOB;
+ − 4961
} else if (c == QLatin1Char(']')) {
+ − 4962
input = InpCB;
+ − 4963
} else if (c == QLatin1Char('%')) {
+ − 4964
input = InpPer;
+ − 4965
} else if (c == QLatin1Char('>')) {
+ − 4966
input = InpGt;
+ − 4967
} else {
+ − 4968
input = InpUnknown;
+ − 4969
}
+ − 4970
state = table[state][input];
+ − 4971
+ − 4972
switch (state) {
+ − 4973
case Doctype:
+ − 4974
parseString_s = QLatin1String("DOCTYPE");
+ − 4975
if (!parseString()) {
+ − 4976
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 4977
return false;
+ − 4978
}
+ − 4979
break;
+ − 4980
case Ws1:
+ − 4981
case Ws2:
+ − 4982
case Ws3:
+ − 4983
case Ws4:
+ − 4984
if (!eat_ws()) {
+ − 4985
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 4986
return false;
+ − 4987
}
+ − 4988
break;
+ − 4989
case Doctype2:
+ − 4990
parseName_useRef = false;
+ − 4991
if (!parseName()) {
+ − 4992
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 4993
return false;
+ − 4994
}
+ − 4995
break;
+ − 4996
case Sys:
+ − 4997
parseExternalID_allowPublicID = false;
+ − 4998
if (!parseExternalID()) {
+ − 4999
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 5000
return false;
+ − 5001
}
+ − 5002
thisPublicId = publicId;
+ − 5003
thisSystemId = systemId;
+ − 5004
break;
+ − 5005
case MP:
+ − 5006
case MPR:
+ − 5007
if (!next_eat_ws()) {
+ − 5008
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 5009
return false;
+ − 5010
}
+ − 5011
break;
+ − 5012
case PER:
+ − 5013
parsePEReference_context = InDTD;
+ − 5014
if (!parsePEReference()) {
+ − 5015
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 5016
return false;
+ − 5017
}
+ − 5018
break;
+ − 5019
case Mup:
+ − 5020
if (!parseMarkupdecl()) {
+ − 5021
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 5022
return false;
+ − 5023
}
+ − 5024
break;
+ − 5025
case MPE:
+ − 5026
if (!next_eat_ws()) {
+ − 5027
parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ − 5028
return false;
+ − 5029
}
+ − 5030
break;
+ − 5031
case Done:
+ − 5032
if (lexicalHnd) {
+ − 5033
if (!startDTDwasReported) {
+ − 5034
startDTDwasReported = true;
+ − 5035
if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
+ − 5036
reportParseError(lexicalHnd->errorString());
+ − 5037
return false;
+ − 5038
}
+ − 5039
}
+ − 5040
if (!lexicalHnd->endDTD()) {
+ − 5041
reportParseError(lexicalHnd->errorString());
+ − 5042
return false;
+ − 5043
}
+ − 5044
}
+ − 5045
next();
+ − 5046
break;
+ − 5047
}
+ − 5048
}
+ − 5049
return false;
+ − 5050
}
+ − 5051
+ − 5052
/*
+ − 5053
Parse a ExternalID [75].
+ − 5054
+ − 5055
If allowPublicID is true parse ExternalID [75] or PublicID [83].
+ − 5056
*/
+ − 5057
bool QXmlSimpleReaderPrivate::parseExternalID()
+ − 5058
{
+ − 5059
const signed char Init = 0;
+ − 5060
const signed char Sys = 1; // parse 'SYSTEM'
+ − 5061
const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
+ − 5062
const signed char SysSQ = 3; // parse SystemLiteral with '
+ − 5063
const signed char SysSQ2 = 4; // parse SystemLiteral with '
+ − 5064
const signed char SysDQ = 5; // parse SystemLiteral with "
+ − 5065
const signed char SysDQ2 = 6; // parse SystemLiteral with "
+ − 5066
const signed char Pub = 7; // parse 'PUBLIC'
+ − 5067
const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
+ − 5068
const signed char PubSQ = 9; // parse PubidLiteral with '
+ − 5069
const signed char PubSQ2 = 10; // parse PubidLiteral with '
+ − 5070
const signed char PubDQ = 11; // parse PubidLiteral with "
+ − 5071
const signed char PubDQ2 = 12; // parse PubidLiteral with "
+ − 5072
const signed char PubE = 13; // finished parsing the PubidLiteral
+ − 5073
const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
+ − 5074
const signed char PDone = 15; // done if allowPublicID is true
+ − 5075
const signed char Done = 16;
+ − 5076
+ − 5077
const signed char InpSQ = 0; // '
+ − 5078
const signed char InpDQ = 1; // "
+ − 5079
const signed char InpS = 2; // S
+ − 5080
const signed char InpP = 3; // P
+ − 5081
const signed char InpWs = 4; // white space
+ − 5082
const signed char InpUnknown = 5;
+ − 5083
+ − 5084
static const signed char table[15][6] = {
+ − 5085
/* InpSQ InpDQ InpS InpP InpWs InpUnknown */
+ − 5086
{ -1, -1, Sys, Pub, -1, -1 }, // Init
+ − 5087
{ -1, -1, -1, -1, SysWS, -1 }, // Sys
+ − 5088
{ SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
+ − 5089
{ Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
+ − 5090
{ Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
+ − 5091
{ SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
+ − 5092
{ SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
+ − 5093
{ -1, -1, -1, -1, PubWS, -1 }, // Pub
+ − 5094
{ PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
+ − 5095
{ PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
+ − 5096
{ PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
+ − 5097
{ -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
+ − 5098
{ -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
+ − 5099
{ PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
+ − 5100
{ SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
+ − 5101
};
+ − 5102
signed char state;
+ − 5103
signed char input;
+ − 5104
+ − 5105
if (parseStack==0 || parseStack->isEmpty()) {
+ − 5106
systemId.clear();
+ − 5107
publicId.clear();
+ − 5108
state = Init;
+ − 5109
} else {
+ − 5110
state = parseStack->pop().state;
+ − 5111
#if defined(QT_QXML_DEBUG)
+ − 5112
qDebug("QXmlSimpleReader: parseExternalID (cont) in state %d", state);
+ − 5113
#endif
+ − 5114
if (!parseStack->isEmpty()) {
+ − 5115
ParseFunction function = parseStack->top().function;
+ − 5116
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 5117
parseStack->pop();
+ − 5118
#if defined(QT_QXML_DEBUG)
+ − 5119
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 5120
#endif
+ − 5121
}
+ − 5122
if (!(this->*function)()) {
+ − 5123
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5124
return false;
+ − 5125
}
+ − 5126
}
+ − 5127
}
+ − 5128
+ − 5129
for (;;) {
+ − 5130
switch (state) {
+ − 5131
case PDone:
+ − 5132
if (parseExternalID_allowPublicID) {
+ − 5133
publicId = string();
+ − 5134
return true;
+ − 5135
} else {
+ − 5136
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 5137
return false;
+ − 5138
}
+ − 5139
case Done:
+ − 5140
return true;
+ − 5141
case -1:
+ − 5142
// Error
+ − 5143
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 5144
return false;
+ − 5145
}
+ − 5146
+ − 5147
if (atEnd()) {
+ − 5148
unexpectedEof(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5149
return false;
+ − 5150
}
+ − 5151
if (is_S(c)) {
+ − 5152
input = InpWs;
+ − 5153
} else if (c == QLatin1Char('\'')) {
+ − 5154
input = InpSQ;
+ − 5155
} else if (c == QLatin1Char('"')) {
+ − 5156
input = InpDQ;
+ − 5157
} else if (c == QLatin1Char('S')) {
+ − 5158
input = InpS;
+ − 5159
} else if (c == QLatin1Char('P')) {
+ − 5160
input = InpP;
+ − 5161
} else {
+ − 5162
input = InpUnknown;
+ − 5163
}
+ − 5164
state = table[state][input];
+ − 5165
+ − 5166
switch (state) {
+ − 5167
case Sys:
+ − 5168
parseString_s = QLatin1String("SYSTEM");
+ − 5169
if (!parseString()) {
+ − 5170
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5171
return false;
+ − 5172
}
+ − 5173
break;
+ − 5174
case SysWS:
+ − 5175
if (!eat_ws()) {
+ − 5176
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5177
return false;
+ − 5178
}
+ − 5179
break;
+ − 5180
case SysSQ:
+ − 5181
case SysDQ:
+ − 5182
stringClear();
+ − 5183
next();
+ − 5184
break;
+ − 5185
case SysSQ2:
+ − 5186
case SysDQ2:
+ − 5187
stringAddC();
+ − 5188
next();
+ − 5189
break;
+ − 5190
case Pub:
+ − 5191
parseString_s = QLatin1String("PUBLIC");
+ − 5192
if (!parseString()) {
+ − 5193
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5194
return false;
+ − 5195
}
+ − 5196
break;
+ − 5197
case PubWS:
+ − 5198
if (!eat_ws()) {
+ − 5199
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5200
return false;
+ − 5201
}
+ − 5202
break;
+ − 5203
case PubSQ:
+ − 5204
case PubDQ:
+ − 5205
stringClear();
+ − 5206
next();
+ − 5207
break;
+ − 5208
case PubSQ2:
+ − 5209
case PubDQ2:
+ − 5210
stringAddC();
+ − 5211
next();
+ − 5212
break;
+ − 5213
case PubE:
+ − 5214
next();
+ − 5215
break;
+ − 5216
case PubWS2:
+ − 5217
publicId = string();
+ − 5218
if (!eat_ws()) {
+ − 5219
parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
+ − 5220
return false;
+ − 5221
}
+ − 5222
break;
+ − 5223
case Done:
+ − 5224
systemId = string();
+ − 5225
next();
+ − 5226
break;
+ − 5227
}
+ − 5228
}
+ − 5229
return false;
+ − 5230
}
+ − 5231
+ − 5232
/*
+ − 5233
Parse a markupdecl [29].
+ − 5234
*/
+ − 5235
bool QXmlSimpleReaderPrivate::parseMarkupdecl()
+ − 5236
{
+ − 5237
const signed char Init = 0;
+ − 5238
const signed char Lt = 1; // < was read
+ − 5239
const signed char Em = 2; // ! was read
+ − 5240
const signed char CE = 3; // E was read
+ − 5241
const signed char Qm = 4; // ? was read
+ − 5242
const signed char Dash = 5; // - was read
+ − 5243
const signed char CA = 6; // A was read
+ − 5244
const signed char CEL = 7; // EL was read
+ − 5245
const signed char CEN = 8; // EN was read
+ − 5246
const signed char CN = 9; // N was read
+ − 5247
const signed char Done = 10;
+ − 5248
+ − 5249
const signed char InpLt = 0; // <
+ − 5250
const signed char InpQm = 1; // ?
+ − 5251
const signed char InpEm = 2; // !
+ − 5252
const signed char InpDash = 3; // -
+ − 5253
const signed char InpA = 4; // A
+ − 5254
const signed char InpE = 5; // E
+ − 5255
const signed char InpL = 6; // L
+ − 5256
const signed char InpN = 7; // N
+ − 5257
const signed char InpUnknown = 8;
+ − 5258
+ − 5259
static const signed char table[4][9] = {
+ − 5260
/* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
+ − 5261
{ Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
+ − 5262
{ -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
+ − 5263
{ -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
+ − 5264
{ -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
+ − 5265
};
+ − 5266
signed char state;
+ − 5267
signed char input;
+ − 5268
+ − 5269
if (parseStack==0 || parseStack->isEmpty()) {
+ − 5270
state = Init;
+ − 5271
} else {
+ − 5272
state = parseStack->pop().state;
+ − 5273
#if defined(QT_QXML_DEBUG)
+ − 5274
qDebug("QXmlSimpleReader: parseMarkupdecl (cont) in state %d", state);
+ − 5275
#endif
+ − 5276
if (!parseStack->isEmpty()) {
+ − 5277
ParseFunction function = parseStack->top().function;
+ − 5278
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 5279
parseStack->pop();
+ − 5280
#if defined(QT_QXML_DEBUG)
+ − 5281
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 5282
#endif
+ − 5283
}
+ − 5284
if (!(this->*function)()) {
+ − 5285
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5286
return false;
+ − 5287
}
+ − 5288
}
+ − 5289
}
+ − 5290
+ − 5291
for (;;) {
+ − 5292
switch (state) {
+ − 5293
case Qm:
+ − 5294
if (contentHnd) {
+ − 5295
if (!contentHnd->processingInstruction(name(),string())) {
+ − 5296
reportParseError(contentHnd->errorString());
+ − 5297
return false;
+ − 5298
}
+ − 5299
}
+ − 5300
return true;
+ − 5301
case Dash:
+ − 5302
if (lexicalHnd) {
+ − 5303
if (!lexicalHnd->comment(string())) {
+ − 5304
reportParseError(lexicalHnd->errorString());
+ − 5305
return false;
+ − 5306
}
+ − 5307
}
+ − 5308
return true;
+ − 5309
case CA:
+ − 5310
return true;
+ − 5311
case CEL:
+ − 5312
return true;
+ − 5313
case CEN:
+ − 5314
return true;
+ − 5315
case CN:
+ − 5316
return true;
+ − 5317
case Done:
+ − 5318
return true;
+ − 5319
case -1:
+ − 5320
// Error
+ − 5321
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 5322
return false;
+ − 5323
}
+ − 5324
+ − 5325
if (atEnd()) {
+ − 5326
unexpectedEof(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5327
return false;
+ − 5328
}
+ − 5329
if (c == QLatin1Char('<')) {
+ − 5330
input = InpLt;
+ − 5331
} else if (c == QLatin1Char('?')) {
+ − 5332
input = InpQm;
+ − 5333
} else if (c == QLatin1Char('!')) {
+ − 5334
input = InpEm;
+ − 5335
} else if (c == QLatin1Char('-')) {
+ − 5336
input = InpDash;
+ − 5337
} else if (c == QLatin1Char('A')) {
+ − 5338
input = InpA;
+ − 5339
} else if (c == QLatin1Char('E')) {
+ − 5340
input = InpE;
+ − 5341
} else if (c == QLatin1Char('L')) {
+ − 5342
input = InpL;
+ − 5343
} else if (c == QLatin1Char('N')) {
+ − 5344
input = InpN;
+ − 5345
} else {
+ − 5346
input = InpUnknown;
+ − 5347
}
+ − 5348
state = table[state][input];
+ − 5349
+ − 5350
switch (state) {
+ − 5351
case Lt:
+ − 5352
next();
+ − 5353
break;
+ − 5354
case Em:
+ − 5355
next();
+ − 5356
break;
+ − 5357
case CE:
+ − 5358
next();
+ − 5359
break;
+ − 5360
case Qm:
+ − 5361
parsePI_xmldecl = false;
+ − 5362
if (!parsePI()) {
+ − 5363
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5364
return false;
+ − 5365
}
+ − 5366
break;
+ − 5367
case Dash:
+ − 5368
if (!parseComment()) {
+ − 5369
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5370
return false;
+ − 5371
}
+ − 5372
break;
+ − 5373
case CA:
+ − 5374
if (!parseAttlistDecl()) {
+ − 5375
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5376
return false;
+ − 5377
}
+ − 5378
break;
+ − 5379
case CEL:
+ − 5380
if (!parseElementDecl()) {
+ − 5381
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5382
return false;
+ − 5383
}
+ − 5384
break;
+ − 5385
case CEN:
+ − 5386
if (!parseEntityDecl()) {
+ − 5387
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5388
return false;
+ − 5389
}
+ − 5390
break;
+ − 5391
case CN:
+ − 5392
if (!parseNotationDecl()) {
+ − 5393
parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
+ − 5394
return false;
+ − 5395
}
+ − 5396
break;
+ − 5397
}
+ − 5398
}
+ − 5399
return false;
+ − 5400
}
+ − 5401
+ − 5402
/*
+ − 5403
Parse a PEReference [69]
+ − 5404
*/
+ − 5405
bool QXmlSimpleReaderPrivate::parsePEReference()
+ − 5406
{
+ − 5407
const signed char Init = 0;
+ − 5408
const signed char Next = 1;
+ − 5409
const signed char Name = 2;
+ − 5410
const signed char NameR = 3; // same as Name, but already reported
+ − 5411
const signed char Done = 4;
+ − 5412
+ − 5413
const signed char InpSemi = 0; // ;
+ − 5414
const signed char InpPer = 1; // %
+ − 5415
const signed char InpUnknown = 2;
+ − 5416
+ − 5417
static const signed char table[4][3] = {
+ − 5418
/* InpSemi InpPer InpUnknown */
+ − 5419
{ -1, Next, -1 }, // Init
+ − 5420
{ -1, -1, Name }, // Next
+ − 5421
{ Done, -1, -1 }, // Name
+ − 5422
{ Done, -1, -1 } // NameR
+ − 5423
};
+ − 5424
signed char state;
+ − 5425
signed char input;
+ − 5426
+ − 5427
if (parseStack==0 || parseStack->isEmpty()) {
+ − 5428
state = Init;
+ − 5429
} else {
+ − 5430
state = parseStack->pop().state;
+ − 5431
#if defined(QT_QXML_DEBUG)
+ − 5432
qDebug("QXmlSimpleReader: parsePEReference (cont) in state %d", state);
+ − 5433
#endif
+ − 5434
if (!parseStack->isEmpty()) {
+ − 5435
ParseFunction function = parseStack->top().function;
+ − 5436
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 5437
parseStack->pop();
+ − 5438
#if defined(QT_QXML_DEBUG)
+ − 5439
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 5440
#endif
+ − 5441
}
+ − 5442
if (!(this->*function)()) {
+ − 5443
parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
+ − 5444
return false;
+ − 5445
}
+ − 5446
}
+ − 5447
}
+ − 5448
+ − 5449
for (;;) {
+ − 5450
switch (state) {
+ − 5451
case Name:
+ − 5452
{
+ − 5453
bool skipIt = true;
+ − 5454
QString xmlRefString;
+ − 5455
+ − 5456
QMap<QString,QString>::Iterator it;
+ − 5457
it = parameterEntities.find(ref());
+ − 5458
if (it != parameterEntities.end()) {
+ − 5459
skipIt = false;
+ − 5460
xmlRefString = *it;
+ − 5461
} else if (entityRes) {
+ − 5462
QMap<QString,QXmlSimpleReaderPrivate::ExternParameterEntity>::Iterator it2;
+ − 5463
it2 = externParameterEntities.find(ref());
+ − 5464
QXmlInputSource *ret = 0;
+ − 5465
if (it2 != externParameterEntities.end()) {
+ − 5466
if (!entityRes->resolveEntity((*it2).publicId, (*it2).systemId, ret)) {
+ − 5467
delete ret;
+ − 5468
reportParseError(entityRes->errorString());
+ − 5469
return false;
+ − 5470
}
+ − 5471
if (ret) {
+ − 5472
xmlRefString = ret->data();
+ − 5473
delete ret;
+ − 5474
if (!stripTextDecl(xmlRefString)) {
+ − 5475
reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
+ − 5476
return false;
+ − 5477
}
+ − 5478
skipIt = false;
+ − 5479
}
+ − 5480
}
+ − 5481
}
+ − 5482
+ − 5483
if (skipIt) {
+ − 5484
if (contentHnd) {
+ − 5485
if (!contentHnd->skippedEntity(QLatin1Char('%') + ref())) {
+ − 5486
reportParseError(contentHnd->errorString());
+ − 5487
return false;
+ − 5488
}
+ − 5489
}
+ − 5490
} else {
+ − 5491
if (parsePEReference_context == InEntityValue) {
+ − 5492
// Included in literal
+ − 5493
if (!insertXmlRef(xmlRefString, ref(), true))
+ − 5494
return false;
+ − 5495
} else if (parsePEReference_context == InDTD) {
+ − 5496
// Included as PE
+ − 5497
if (!insertXmlRef(QLatin1Char(' ') + xmlRefString + QLatin1Char(' '), ref(), false))
+ − 5498
return false;
+ − 5499
}
+ − 5500
}
+ − 5501
}
+ − 5502
state = NameR;
+ − 5503
break;
+ − 5504
case Done:
+ − 5505
return true;
+ − 5506
case -1:
+ − 5507
// Error
+ − 5508
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 5509
return false;
+ − 5510
}
+ − 5511
+ − 5512
if (atEnd()) {
+ − 5513
unexpectedEof(&QXmlSimpleReaderPrivate::parsePEReference, state);
+ − 5514
return false;
+ − 5515
}
+ − 5516
if (c == QLatin1Char(';')) {
+ − 5517
input = InpSemi;
+ − 5518
} else if (c == QLatin1Char('%')) {
+ − 5519
input = InpPer;
+ − 5520
} else {
+ − 5521
input = InpUnknown;
+ − 5522
}
+ − 5523
state = table[state][input];
+ − 5524
+ − 5525
switch (state) {
+ − 5526
case Next:
+ − 5527
next();
+ − 5528
break;
+ − 5529
case Name:
+ − 5530
case NameR:
+ − 5531
parseName_useRef = true;
+ − 5532
if (!parseName()) {
+ − 5533
parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
+ − 5534
return false;
+ − 5535
}
+ − 5536
break;
+ − 5537
case Done:
+ − 5538
next();
+ − 5539
break;
+ − 5540
}
+ − 5541
}
+ − 5542
return false;
+ − 5543
}
+ − 5544
+ − 5545
/*
+ − 5546
Parse a AttlistDecl [52].
+ − 5547
+ − 5548
Precondition: the beginning '<!' is already read and the head
+ − 5549
stands on the 'A' of '<!ATTLIST'
+ − 5550
*/
+ − 5551
bool QXmlSimpleReaderPrivate::parseAttlistDecl()
+ − 5552
{
+ − 5553
const signed char Init = 0;
+ − 5554
const signed char Attlist = 1; // parse the string "ATTLIST"
+ − 5555
const signed char Ws = 2; // whitespace read
+ − 5556
const signed char Name = 3; // parse name
+ − 5557
const signed char Ws1 = 4; // whitespace read
+ − 5558
const signed char Attdef = 5; // parse the AttDef
+ − 5559
const signed char Ws2 = 6; // whitespace read
+ − 5560
const signed char Atttype = 7; // parse the AttType
+ − 5561
const signed char Ws3 = 8; // whitespace read
+ − 5562
const signed char DDecH = 9; // DefaultDecl with #
+ − 5563
const signed char DefReq = 10; // parse the string "REQUIRED"
+ − 5564
const signed char DefImp = 11; // parse the string "IMPLIED"
+ − 5565
const signed char DefFix = 12; // parse the string "FIXED"
+ − 5566
const signed char Attval = 13; // parse the AttValue
+ − 5567
const signed char Ws4 = 14; // whitespace read
+ − 5568
const signed char Done = 15;
+ − 5569
+ − 5570
const signed char InpWs = 0; // white space
+ − 5571
const signed char InpGt = 1; // >
+ − 5572
const signed char InpHash = 2; // #
+ − 5573
const signed char InpA = 3; // A
+ − 5574
const signed char InpI = 4; // I
+ − 5575
const signed char InpF = 5; // F
+ − 5576
const signed char InpR = 6; // R
+ − 5577
const signed char InpUnknown = 7;
+ − 5578
+ − 5579
static const signed char table[15][8] = {
+ − 5580
/* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
+ − 5581
{ -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
+ − 5582
{ Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
+ − 5583
{ -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
+ − 5584
{ Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
+ − 5585
{ -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
+ − 5586
{ Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
+ − 5587
{ -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
+ − 5588
{ Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
+ − 5589
{ -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
+ − 5590
{ -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
+ − 5591
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
+ − 5592
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
+ − 5593
{ Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
+ − 5594
{ Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
+ − 5595
{ -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
+ − 5596
};
+ − 5597
signed char state;
+ − 5598
signed char input;
+ − 5599
+ − 5600
if (parseStack==0 || parseStack->isEmpty()) {
+ − 5601
state = Init;
+ − 5602
} else {
+ − 5603
state = parseStack->pop().state;
+ − 5604
#if defined(QT_QXML_DEBUG)
+ − 5605
qDebug("QXmlSimpleReader: parseAttlistDecl (cont) in state %d", state);
+ − 5606
#endif
+ − 5607
if (!parseStack->isEmpty()) {
+ − 5608
ParseFunction function = parseStack->top().function;
+ − 5609
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 5610
parseStack->pop();
+ − 5611
#if defined(QT_QXML_DEBUG)
+ − 5612
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 5613
#endif
+ − 5614
}
+ − 5615
if (!(this->*function)()) {
+ − 5616
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5617
return false;
+ − 5618
}
+ − 5619
}
+ − 5620
}
+ − 5621
+ − 5622
for (;;) {
+ − 5623
switch (state) {
+ − 5624
case Name:
+ − 5625
attDeclEName = name();
+ − 5626
break;
+ − 5627
case Attdef:
+ − 5628
attDeclAName = name();
+ − 5629
break;
+ − 5630
case Done:
+ − 5631
return true;
+ − 5632
case -1:
+ − 5633
// Error
+ − 5634
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 5635
return false;
+ − 5636
}
+ − 5637
+ − 5638
if (atEnd()) {
+ − 5639
unexpectedEof(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5640
return false;
+ − 5641
}
+ − 5642
if (is_S(c)) {
+ − 5643
input = InpWs;
+ − 5644
} else if (c == QLatin1Char('>')) {
+ − 5645
input = InpGt;
+ − 5646
} else if (c == QLatin1Char('#')) {
+ − 5647
input = InpHash;
+ − 5648
} else if (c == QLatin1Char('A')) {
+ − 5649
input = InpA;
+ − 5650
} else if (c == QLatin1Char('I')) {
+ − 5651
input = InpI;
+ − 5652
} else if (c == QLatin1Char('F')) {
+ − 5653
input = InpF;
+ − 5654
} else if (c == QLatin1Char('R')) {
+ − 5655
input = InpR;
+ − 5656
} else {
+ − 5657
input = InpUnknown;
+ − 5658
}
+ − 5659
state = table[state][input];
+ − 5660
+ − 5661
switch (state) {
+ − 5662
case Attlist:
+ − 5663
parseString_s = QLatin1String("ATTLIST");
+ − 5664
if (!parseString()) {
+ − 5665
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5666
return false;
+ − 5667
}
+ − 5668
break;
+ − 5669
case Ws:
+ − 5670
case Ws1:
+ − 5671
case Ws2:
+ − 5672
case Ws3:
+ − 5673
if (!eat_ws()) {
+ − 5674
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5675
return false;
+ − 5676
}
+ − 5677
break;
+ − 5678
case Name:
+ − 5679
parseName_useRef = false;
+ − 5680
if (!parseName()) {
+ − 5681
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5682
return false;
+ − 5683
}
+ − 5684
break;
+ − 5685
case Attdef:
+ − 5686
parseName_useRef = false;
+ − 5687
if (!parseName()) {
+ − 5688
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5689
return false;
+ − 5690
}
+ − 5691
break;
+ − 5692
case Atttype:
+ − 5693
if (!parseAttType()) {
+ − 5694
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5695
return false;
+ − 5696
}
+ − 5697
break;
+ − 5698
case DDecH:
+ − 5699
next();
+ − 5700
break;
+ − 5701
case DefReq:
+ − 5702
parseString_s = QLatin1String("REQUIRED");
+ − 5703
if (!parseString()) {
+ − 5704
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5705
return false;
+ − 5706
}
+ − 5707
break;
+ − 5708
case DefImp:
+ − 5709
parseString_s = QLatin1String("IMPLIED");
+ − 5710
if (!parseString()) {
+ − 5711
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5712
return false;
+ − 5713
}
+ − 5714
break;
+ − 5715
case DefFix:
+ − 5716
parseString_s = QLatin1String("FIXED");
+ − 5717
if (!parseString()) {
+ − 5718
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5719
return false;
+ − 5720
}
+ − 5721
break;
+ − 5722
case Attval:
+ − 5723
if (!parseAttValue()) {
+ − 5724
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5725
return false;
+ − 5726
}
+ − 5727
break;
+ − 5728
case Ws4:
+ − 5729
if (declHnd) {
+ − 5730
// ### not all values are computed yet...
+ − 5731
if (!declHnd->attributeDecl(attDeclEName, attDeclAName, QLatin1String(""), QLatin1String(""), QLatin1String(""))) {
+ − 5732
reportParseError(declHnd->errorString());
+ − 5733
return false;
+ − 5734
}
+ − 5735
}
+ − 5736
if (!eat_ws()) {
+ − 5737
parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
+ − 5738
return false;
+ − 5739
}
+ − 5740
break;
+ − 5741
case Done:
+ − 5742
next();
+ − 5743
break;
+ − 5744
}
+ − 5745
}
+ − 5746
return false;
+ − 5747
}
+ − 5748
+ − 5749
/*
+ − 5750
Parse a AttType [54]
+ − 5751
*/
+ − 5752
bool QXmlSimpleReaderPrivate::parseAttType()
+ − 5753
{
+ − 5754
const signed char Init = 0;
+ − 5755
const signed char ST = 1; // StringType
+ − 5756
const signed char TTI = 2; // TokenizedType starting with 'I'
+ − 5757
const signed char TTI2 = 3; // TokenizedType helpstate
+ − 5758
const signed char TTI3 = 4; // TokenizedType helpstate
+ − 5759
const signed char TTE = 5; // TokenizedType starting with 'E'
+ − 5760
const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
+ − 5761
const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
+ − 5762
const signed char N = 8; // N read (TokenizedType or Notation)
+ − 5763
const signed char TTNM = 9; // TokenizedType starting with 'NM'
+ − 5764
const signed char TTNM2 = 10; // TokenizedType helpstate
+ − 5765
const signed char NO = 11; // Notation
+ − 5766
const signed char NO2 = 12; // Notation helpstate
+ − 5767
const signed char NO3 = 13; // Notation helpstate
+ − 5768
const signed char NOName = 14; // Notation, read name
+ − 5769
const signed char NO4 = 15; // Notation helpstate
+ − 5770
const signed char EN = 16; // Enumeration
+ − 5771
const signed char ENNmt = 17; // Enumeration, read Nmtoken
+ − 5772
const signed char EN2 = 18; // Enumeration helpstate
+ − 5773
const signed char ADone = 19; // almost done (make next and accept)
+ − 5774
const signed char Done = 20;
+ − 5775
+ − 5776
const signed char InpWs = 0; // whitespace
+ − 5777
const signed char InpOp = 1; // (
+ − 5778
const signed char InpCp = 2; //)
+ − 5779
const signed char InpPipe = 3; // |
+ − 5780
const signed char InpC = 4; // C
+ − 5781
const signed char InpE = 5; // E
+ − 5782
const signed char InpI = 6; // I
+ − 5783
const signed char InpM = 7; // M
+ − 5784
const signed char InpN = 8; // N
+ − 5785
const signed char InpO = 9; // O
+ − 5786
const signed char InpR = 10; // R
+ − 5787
const signed char InpS = 11; // S
+ − 5788
const signed char InpY = 12; // Y
+ − 5789
const signed char InpUnknown = 13;
+ − 5790
+ − 5791
static const signed char table[19][14] = {
+ − 5792
/* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
+ − 5793
{ -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
+ − 5794
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
+ − 5795
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
+ − 5796
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
+ − 5797
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
+ − 5798
{ -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
+ − 5799
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
+ − 5800
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
+ − 5801
{ -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
+ − 5802
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
+ − 5803
{ Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
+ − 5804
{ NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
+ − 5805
{ -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
+ − 5806
{ NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
+ − 5807
{ NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
+ − 5808
{ -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
+ − 5809
{ -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
+ − 5810
{ EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
+ − 5811
{ -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
+ − 5812
};
+ − 5813
signed char state;
+ − 5814
signed char input;
+ − 5815
+ − 5816
if (parseStack==0 || parseStack->isEmpty()) {
+ − 5817
state = Init;
+ − 5818
} else {
+ − 5819
state = parseStack->pop().state;
+ − 5820
#if defined(QT_QXML_DEBUG)
+ − 5821
qDebug("QXmlSimpleReader: parseAttType (cont) in state %d", state);
+ − 5822
#endif
+ − 5823
if (!parseStack->isEmpty()) {
+ − 5824
ParseFunction function = parseStack->top().function;
+ − 5825
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 5826
parseStack->pop();
+ − 5827
#if defined(QT_QXML_DEBUG)
+ − 5828
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 5829
#endif
+ − 5830
}
+ − 5831
if (!(this->*function)()) {
+ − 5832
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5833
return false;
+ − 5834
}
+ − 5835
}
+ − 5836
}
+ − 5837
+ − 5838
for (;;) {
+ − 5839
switch (state) {
+ − 5840
case ADone:
+ − 5841
return true;
+ − 5842
case Done:
+ − 5843
return true;
+ − 5844
case -1:
+ − 5845
// Error
+ − 5846
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 5847
return false;
+ − 5848
}
+ − 5849
+ − 5850
if (atEnd()) {
+ − 5851
unexpectedEof(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5852
return false;
+ − 5853
}
+ − 5854
if (is_S(c)) {
+ − 5855
input = InpWs;
+ − 5856
} else if (c == QLatin1Char('(')) {
+ − 5857
input = InpOp;
+ − 5858
} else if (c == QLatin1Char(')')) {
+ − 5859
input = InpCp;
+ − 5860
} else if (c == QLatin1Char('|')) {
+ − 5861
input = InpPipe;
+ − 5862
} else if (c == QLatin1Char('C')) {
+ − 5863
input = InpC;
+ − 5864
} else if (c == QLatin1Char('E')) {
+ − 5865
input = InpE;
+ − 5866
} else if (c == QLatin1Char('I')) {
+ − 5867
input = InpI;
+ − 5868
} else if (c == QLatin1Char('M')) {
+ − 5869
input = InpM;
+ − 5870
} else if (c == QLatin1Char('N')) {
+ − 5871
input = InpN;
+ − 5872
} else if (c == QLatin1Char('O')) {
+ − 5873
input = InpO;
+ − 5874
} else if (c == QLatin1Char('R')) {
+ − 5875
input = InpR;
+ − 5876
} else if (c == QLatin1Char('S')) {
+ − 5877
input = InpS;
+ − 5878
} else if (c == QLatin1Char('Y')) {
+ − 5879
input = InpY;
+ − 5880
} else {
+ − 5881
input = InpUnknown;
+ − 5882
}
+ − 5883
state = table[state][input];
+ − 5884
+ − 5885
switch (state) {
+ − 5886
case ST:
+ − 5887
parseString_s = QLatin1String("CDATA");
+ − 5888
if (!parseString()) {
+ − 5889
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5890
return false;
+ − 5891
}
+ − 5892
break;
+ − 5893
case TTI:
+ − 5894
parseString_s = QLatin1String("ID");
+ − 5895
if (!parseString()) {
+ − 5896
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5897
return false;
+ − 5898
}
+ − 5899
break;
+ − 5900
case TTI2:
+ − 5901
parseString_s = QLatin1String("REF");
+ − 5902
if (!parseString()) {
+ − 5903
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5904
return false;
+ − 5905
}
+ − 5906
break;
+ − 5907
case TTI3:
+ − 5908
next(); // S
+ − 5909
break;
+ − 5910
case TTE:
+ − 5911
parseString_s = QLatin1String("ENTIT");
+ − 5912
if (!parseString()) {
+ − 5913
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5914
return false;
+ − 5915
}
+ − 5916
break;
+ − 5917
case TTEY:
+ − 5918
next(); // Y
+ − 5919
break;
+ − 5920
case TTEI:
+ − 5921
parseString_s = QLatin1String("IES");
+ − 5922
if (!parseString()) {
+ − 5923
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5924
return false;
+ − 5925
}
+ − 5926
break;
+ − 5927
case N:
+ − 5928
next(); // N
+ − 5929
break;
+ − 5930
case TTNM:
+ − 5931
parseString_s = QLatin1String("MTOKEN");
+ − 5932
if (!parseString()) {
+ − 5933
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5934
return false;
+ − 5935
}
+ − 5936
break;
+ − 5937
case TTNM2:
+ − 5938
next(); // S
+ − 5939
break;
+ − 5940
case NO:
+ − 5941
parseString_s = QLatin1String("OTATION");
+ − 5942
if (!parseString()) {
+ − 5943
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5944
return false;
+ − 5945
}
+ − 5946
break;
+ − 5947
case NO2:
+ − 5948
if (!eat_ws()) {
+ − 5949
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5950
return false;
+ − 5951
}
+ − 5952
break;
+ − 5953
case NO3:
+ − 5954
if (!next_eat_ws()) {
+ − 5955
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5956
return false;
+ − 5957
}
+ − 5958
break;
+ − 5959
case NOName:
+ − 5960
parseName_useRef = false;
+ − 5961
if (!parseName()) {
+ − 5962
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5963
return false;
+ − 5964
}
+ − 5965
break;
+ − 5966
case NO4:
+ − 5967
if (!eat_ws()) {
+ − 5968
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5969
return false;
+ − 5970
}
+ − 5971
break;
+ − 5972
case EN:
+ − 5973
if (!next_eat_ws()) {
+ − 5974
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5975
return false;
+ − 5976
}
+ − 5977
break;
+ − 5978
case ENNmt:
+ − 5979
if (!parseNmtoken()) {
+ − 5980
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5981
return false;
+ − 5982
}
+ − 5983
break;
+ − 5984
case EN2:
+ − 5985
if (!eat_ws()) {
+ − 5986
parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
+ − 5987
return false;
+ − 5988
}
+ − 5989
break;
+ − 5990
case ADone:
+ − 5991
next();
+ − 5992
break;
+ − 5993
}
+ − 5994
}
+ − 5995
return false;
+ − 5996
}
+ − 5997
+ − 5998
/*
+ − 5999
Parse a AttValue [10]
+ − 6000
+ − 6001
Precondition: the head stands on the beginning " or '
+ − 6002
+ − 6003
If this function was successful, the head stands on the first
+ − 6004
character after the closing " or ' and the value of the attribute
+ − 6005
is in string().
+ − 6006
*/
+ − 6007
bool QXmlSimpleReaderPrivate::parseAttValue()
+ − 6008
{
+ − 6009
const signed char Init = 0;
+ − 6010
const signed char Dq = 1; // double quotes were read
+ − 6011
const signed char DqRef = 2; // read references in double quotes
+ − 6012
const signed char DqC = 3; // signed character read in double quotes
+ − 6013
const signed char Sq = 4; // single quotes were read
+ − 6014
const signed char SqRef = 5; // read references in single quotes
+ − 6015
const signed char SqC = 6; // signed character read in single quotes
+ − 6016
const signed char Done = 7;
+ − 6017
+ − 6018
const signed char InpDq = 0; // "
+ − 6019
const signed char InpSq = 1; // '
+ − 6020
const signed char InpAmp = 2; // &
+ − 6021
const signed char InpLt = 3; // <
+ − 6022
const signed char InpUnknown = 4;
+ − 6023
+ − 6024
static const signed char table[7][5] = {
+ − 6025
/* InpDq InpSq InpAmp InpLt InpUnknown */
+ − 6026
{ Dq, Sq, -1, -1, -1 }, // Init
+ − 6027
{ Done, DqC, DqRef, -1, DqC }, // Dq
+ − 6028
{ Done, DqC, DqRef, -1, DqC }, // DqRef
+ − 6029
{ Done, DqC, DqRef, -1, DqC }, // DqC
+ − 6030
{ SqC, Done, SqRef, -1, SqC }, // Sq
+ − 6031
{ SqC, Done, SqRef, -1, SqC }, // SqRef
+ − 6032
{ SqC, Done, SqRef, -1, SqC } // SqRef
+ − 6033
};
+ − 6034
signed char state;
+ − 6035
signed char input;
+ − 6036
+ − 6037
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6038
state = Init;
+ − 6039
} else {
+ − 6040
state = parseStack->pop().state;
+ − 6041
#if defined(QT_QXML_DEBUG)
+ − 6042
qDebug("QXmlSimpleReader: parseAttValue (cont) in state %d", state);
+ − 6043
#endif
+ − 6044
if (!parseStack->isEmpty()) {
+ − 6045
ParseFunction function = parseStack->top().function;
+ − 6046
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6047
parseStack->pop();
+ − 6048
#if defined(QT_QXML_DEBUG)
+ − 6049
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6050
#endif
+ − 6051
}
+ − 6052
if (!(this->*function)()) {
+ − 6053
parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
+ − 6054
return false;
+ − 6055
}
+ − 6056
}
+ − 6057
}
+ − 6058
+ − 6059
for (;;) {
+ − 6060
switch (state) {
+ − 6061
case Done:
+ − 6062
return true;
+ − 6063
case -1:
+ − 6064
// Error
+ − 6065
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 6066
return false;
+ − 6067
}
+ − 6068
+ − 6069
if (atEnd()) {
+ − 6070
unexpectedEof(&QXmlSimpleReaderPrivate::parseAttValue, state);
+ − 6071
return false;
+ − 6072
}
+ − 6073
if (c == QLatin1Char('"')) {
+ − 6074
input = InpDq;
+ − 6075
} else if (c == QLatin1Char('\'')) {
+ − 6076
input = InpSq;
+ − 6077
} else if (c == QLatin1Char('&')) {
+ − 6078
input = InpAmp;
+ − 6079
} else if (c == QLatin1Char('<')) {
+ − 6080
input = InpLt;
+ − 6081
} else {
+ − 6082
input = InpUnknown;
+ − 6083
}
+ − 6084
state = table[state][input];
+ − 6085
+ − 6086
switch (state) {
+ − 6087
case Dq:
+ − 6088
case Sq:
+ − 6089
stringClear();
+ − 6090
next();
+ − 6091
break;
+ − 6092
case DqRef:
+ − 6093
case SqRef:
+ − 6094
parseReference_context = InAttributeValue;
+ − 6095
if (!parseReference()) {
+ − 6096
parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
+ − 6097
return false;
+ − 6098
}
+ − 6099
break;
+ − 6100
case DqC:
+ − 6101
case SqC:
+ − 6102
stringAddC();
+ − 6103
next();
+ − 6104
break;
+ − 6105
case Done:
+ − 6106
next();
+ − 6107
break;
+ − 6108
}
+ − 6109
}
+ − 6110
return false;
+ − 6111
}
+ − 6112
+ − 6113
/*
+ − 6114
Parse a elementdecl [45].
+ − 6115
+ − 6116
Precondition: the beginning '<!E' is already read and the head
+ − 6117
stands on the 'L' of '<!ELEMENT'
+ − 6118
*/
+ − 6119
bool QXmlSimpleReaderPrivate::parseElementDecl()
+ − 6120
{
+ − 6121
const signed char Init = 0;
+ − 6122
const signed char Elem = 1; // parse the beginning string
+ − 6123
const signed char Ws1 = 2; // whitespace required
+ − 6124
const signed char Nam = 3; // parse Name
+ − 6125
const signed char Ws2 = 4; // whitespace required
+ − 6126
const signed char Empty = 5; // read EMPTY
+ − 6127
const signed char Any = 6; // read ANY
+ − 6128
const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
+ − 6129
const signed char Mix = 8; // read Mixed
+ − 6130
const signed char Mix2 = 9; //
+ − 6131
const signed char Mix3 = 10; //
+ − 6132
const signed char MixN1 = 11; //
+ − 6133
const signed char MixN2 = 12; //
+ − 6134
const signed char MixN3 = 13; //
+ − 6135
const signed char MixN4 = 14; //
+ − 6136
const signed char Cp = 15; // parse cp
+ − 6137
const signed char Cp2 = 16; //
+ − 6138
const signed char WsD = 17; // eat whitespace before Done
+ − 6139
const signed char Done = 18;
+ − 6140
+ − 6141
const signed char InpWs = 0;
+ − 6142
const signed char InpGt = 1; // >
+ − 6143
const signed char InpPipe = 2; // |
+ − 6144
const signed char InpOp = 3; // (
+ − 6145
const signed char InpCp = 4; //)
+ − 6146
const signed char InpHash = 5; // #
+ − 6147
const signed char InpQm = 6; // ?
+ − 6148
const signed char InpAst = 7; // *
+ − 6149
const signed char InpPlus = 8; // +
+ − 6150
const signed char InpA = 9; // A
+ − 6151
const signed char InpE = 10; // E
+ − 6152
const signed char InpL = 11; // L
+ − 6153
const signed char InpUnknown = 12;
+ − 6154
+ − 6155
static const signed char table[18][13] = {
+ − 6156
/* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
+ − 6157
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
+ − 6158
{ Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
+ − 6159
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
+ − 6160
{ Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
+ − 6161
{ -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
+ − 6162
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
+ − 6163
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
+ − 6164
{ -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
+ − 6165
{ Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
+ − 6166
{ -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
+ − 6167
{ WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
+ − 6168
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
+ − 6169
{ MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
+ − 6170
{ -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
+ − 6171
{ -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
+ − 6172
{ WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
+ − 6173
{ WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
+ − 6174
{ -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
+ − 6175
};
+ − 6176
signed char state;
+ − 6177
signed char input;
+ − 6178
+ − 6179
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6180
state = Init;
+ − 6181
} else {
+ − 6182
state = parseStack->pop().state;
+ − 6183
#if defined(QT_QXML_DEBUG)
+ − 6184
qDebug("QXmlSimpleReader: parseElementDecl (cont) in state %d", state);
+ − 6185
#endif
+ − 6186
if (!parseStack->isEmpty()) {
+ − 6187
ParseFunction function = parseStack->top().function;
+ − 6188
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6189
parseStack->pop();
+ − 6190
#if defined(QT_QXML_DEBUG)
+ − 6191
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6192
#endif
+ − 6193
}
+ − 6194
if (!(this->*function)()) {
+ − 6195
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6196
return false;
+ − 6197
}
+ − 6198
}
+ − 6199
}
+ − 6200
+ − 6201
for (;;) {
+ − 6202
switch (state) {
+ − 6203
case Done:
+ − 6204
return true;
+ − 6205
case -1:
+ − 6206
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 6207
return false;
+ − 6208
}
+ − 6209
+ − 6210
if (atEnd()) {
+ − 6211
unexpectedEof(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6212
return false;
+ − 6213
}
+ − 6214
if (is_S(c)) {
+ − 6215
input = InpWs;
+ − 6216
} else if (c == QLatin1Char('>')) {
+ − 6217
input = InpGt;
+ − 6218
} else if (c == QLatin1Char('|')) {
+ − 6219
input = InpPipe;
+ − 6220
} else if (c == QLatin1Char('(')) {
+ − 6221
input = InpOp;
+ − 6222
} else if (c == QLatin1Char(')')) {
+ − 6223
input = InpCp;
+ − 6224
} else if (c == QLatin1Char('#')) {
+ − 6225
input = InpHash;
+ − 6226
} else if (c == QLatin1Char('?')) {
+ − 6227
input = InpQm;
+ − 6228
} else if (c == QLatin1Char('*')) {
+ − 6229
input = InpAst;
+ − 6230
} else if (c == QLatin1Char('+')) {
+ − 6231
input = InpPlus;
+ − 6232
} else if (c == QLatin1Char('A')) {
+ − 6233
input = InpA;
+ − 6234
} else if (c == QLatin1Char('E')) {
+ − 6235
input = InpE;
+ − 6236
} else if (c == QLatin1Char('L')) {
+ − 6237
input = InpL;
+ − 6238
} else {
+ − 6239
input = InpUnknown;
+ − 6240
}
+ − 6241
state = table[state][input];
+ − 6242
+ − 6243
switch (state) {
+ − 6244
case Elem:
+ − 6245
parseString_s = QLatin1String("LEMENT");
+ − 6246
if (!parseString()) {
+ − 6247
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6248
return false;
+ − 6249
}
+ − 6250
break;
+ − 6251
case Ws1:
+ − 6252
if (!eat_ws()) {
+ − 6253
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6254
return false;
+ − 6255
}
+ − 6256
break;
+ − 6257
case Nam:
+ − 6258
parseName_useRef = false;
+ − 6259
if (!parseName()) {
+ − 6260
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6261
return false;
+ − 6262
}
+ − 6263
break;
+ − 6264
case Ws2:
+ − 6265
if (!eat_ws()) {
+ − 6266
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6267
return false;
+ − 6268
}
+ − 6269
break;
+ − 6270
case Empty:
+ − 6271
parseString_s = QLatin1String("EMPTY");
+ − 6272
if (!parseString()) {
+ − 6273
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6274
return false;
+ − 6275
}
+ − 6276
break;
+ − 6277
case Any:
+ − 6278
parseString_s = QLatin1String("ANY");
+ − 6279
if (!parseString()) {
+ − 6280
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6281
return false;
+ − 6282
}
+ − 6283
break;
+ − 6284
case Cont:
+ − 6285
if (!next_eat_ws()) {
+ − 6286
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6287
return false;
+ − 6288
}
+ − 6289
break;
+ − 6290
case Mix:
+ − 6291
parseString_s = QLatin1String("#PCDATA");
+ − 6292
if (!parseString()) {
+ − 6293
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6294
return false;
+ − 6295
}
+ − 6296
break;
+ − 6297
case Mix2:
+ − 6298
if (!eat_ws()) {
+ − 6299
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6300
return false;
+ − 6301
}
+ − 6302
break;
+ − 6303
case Mix3:
+ − 6304
next();
+ − 6305
break;
+ − 6306
case MixN1:
+ − 6307
if (!next_eat_ws()) {
+ − 6308
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6309
return false;
+ − 6310
}
+ − 6311
break;
+ − 6312
case MixN2:
+ − 6313
parseName_useRef = false;
+ − 6314
if (!parseName()) {
+ − 6315
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6316
return false;
+ − 6317
}
+ − 6318
break;
+ − 6319
case MixN3:
+ − 6320
if (!eat_ws()) {
+ − 6321
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6322
return false;
+ − 6323
}
+ − 6324
break;
+ − 6325
case MixN4:
+ − 6326
next();
+ − 6327
break;
+ − 6328
case Cp:
+ − 6329
if (!parseChoiceSeq()) {
+ − 6330
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6331
return false;
+ − 6332
}
+ − 6333
break;
+ − 6334
case Cp2:
+ − 6335
next();
+ − 6336
break;
+ − 6337
case WsD:
+ − 6338
if (!next_eat_ws()) {
+ − 6339
parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
+ − 6340
return false;
+ − 6341
}
+ − 6342
break;
+ − 6343
case Done:
+ − 6344
next();
+ − 6345
break;
+ − 6346
}
+ − 6347
}
+ − 6348
return false;
+ − 6349
}
+ − 6350
+ − 6351
/*
+ − 6352
Parse a NotationDecl [82].
+ − 6353
+ − 6354
Precondition: the beginning '<!' is already read and the head
+ − 6355
stands on the 'N' of '<!NOTATION'
+ − 6356
*/
+ − 6357
bool QXmlSimpleReaderPrivate::parseNotationDecl()
+ − 6358
{
+ − 6359
const signed char Init = 0;
+ − 6360
const signed char Not = 1; // read NOTATION
+ − 6361
const signed char Ws1 = 2; // eat whitespaces
+ − 6362
const signed char Nam = 3; // read Name
+ − 6363
const signed char Ws2 = 4; // eat whitespaces
+ − 6364
const signed char ExtID = 5; // parse ExternalID
+ − 6365
const signed char ExtIDR = 6; // same as ExtID, but already reported
+ − 6366
const signed char Ws3 = 7; // eat whitespaces
+ − 6367
const signed char Done = 8;
+ − 6368
+ − 6369
const signed char InpWs = 0;
+ − 6370
const signed char InpGt = 1; // >
+ − 6371
const signed char InpN = 2; // N
+ − 6372
const signed char InpUnknown = 3;
+ − 6373
+ − 6374
static const signed char table[8][4] = {
+ − 6375
/* InpWs InpGt InpN InpUnknown */
+ − 6376
{ -1, -1, Not, -1 }, // Init
+ − 6377
{ Ws1, -1, -1, -1 }, // Not
+ − 6378
{ -1, -1, Nam, Nam }, // Ws1
+ − 6379
{ Ws2, Done, -1, -1 }, // Nam
+ − 6380
{ -1, Done, ExtID, ExtID }, // Ws2
+ − 6381
{ Ws3, Done, -1, -1 }, // ExtID
+ − 6382
{ Ws3, Done, -1, -1 }, // ExtIDR
+ − 6383
{ -1, Done, -1, -1 } // Ws3
+ − 6384
};
+ − 6385
signed char state;
+ − 6386
signed char input;
+ − 6387
+ − 6388
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6389
state = Init;
+ − 6390
} else {
+ − 6391
state = parseStack->pop().state;
+ − 6392
#if defined(QT_QXML_DEBUG)
+ − 6393
qDebug("QXmlSimpleReader: parseNotationDecl (cont) in state %d", state);
+ − 6394
#endif
+ − 6395
if (!parseStack->isEmpty()) {
+ − 6396
ParseFunction function = parseStack->top().function;
+ − 6397
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6398
parseStack->pop();
+ − 6399
#if defined(QT_QXML_DEBUG)
+ − 6400
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6401
#endif
+ − 6402
}
+ − 6403
if (!(this->*function)()) {
+ − 6404
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6405
return false;
+ − 6406
}
+ − 6407
}
+ − 6408
}
+ − 6409
+ − 6410
for (;;) {
+ − 6411
switch (state) {
+ − 6412
case ExtID:
+ − 6413
// call the handler
+ − 6414
if (dtdHnd) {
+ − 6415
if (!dtdHnd->notationDecl(name(), publicId, systemId)) {
+ − 6416
reportParseError(dtdHnd->errorString());
+ − 6417
return false;
+ − 6418
}
+ − 6419
}
+ − 6420
state = ExtIDR;
+ − 6421
break;
+ − 6422
case Done:
+ − 6423
return true;
+ − 6424
case -1:
+ − 6425
// Error
+ − 6426
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 6427
return false;
+ − 6428
}
+ − 6429
+ − 6430
if (atEnd()) {
+ − 6431
unexpectedEof(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6432
return false;
+ − 6433
}
+ − 6434
if (is_S(c)) {
+ − 6435
input = InpWs;
+ − 6436
} else if (c == QLatin1Char('>')) {
+ − 6437
input = InpGt;
+ − 6438
} else if (c == QLatin1Char('N')) {
+ − 6439
input = InpN;
+ − 6440
} else {
+ − 6441
input = InpUnknown;
+ − 6442
}
+ − 6443
state = table[state][input];
+ − 6444
+ − 6445
switch (state) {
+ − 6446
case Not:
+ − 6447
parseString_s = QLatin1String("NOTATION");
+ − 6448
if (!parseString()) {
+ − 6449
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6450
return false;
+ − 6451
}
+ − 6452
break;
+ − 6453
case Ws1:
+ − 6454
if (!eat_ws()) {
+ − 6455
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6456
return false;
+ − 6457
}
+ − 6458
break;
+ − 6459
case Nam:
+ − 6460
parseName_useRef = false;
+ − 6461
if (!parseName()) {
+ − 6462
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6463
return false;
+ − 6464
}
+ − 6465
break;
+ − 6466
case Ws2:
+ − 6467
if (!eat_ws()) {
+ − 6468
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6469
return false;
+ − 6470
}
+ − 6471
break;
+ − 6472
case ExtID:
+ − 6473
case ExtIDR:
+ − 6474
parseExternalID_allowPublicID = true;
+ − 6475
if (!parseExternalID()) {
+ − 6476
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6477
return false;
+ − 6478
}
+ − 6479
break;
+ − 6480
case Ws3:
+ − 6481
if (!eat_ws()) {
+ − 6482
parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
+ − 6483
return false;
+ − 6484
}
+ − 6485
break;
+ − 6486
case Done:
+ − 6487
next();
+ − 6488
break;
+ − 6489
}
+ − 6490
}
+ − 6491
return false;
+ − 6492
}
+ − 6493
+ − 6494
/*
+ − 6495
Parse choice [49] or seq [50].
+ − 6496
+ − 6497
Precondition: the beginning '('S? is already read and the head
+ − 6498
stands on the first non-whitespace character after it.
+ − 6499
*/
+ − 6500
bool QXmlSimpleReaderPrivate::parseChoiceSeq()
+ − 6501
{
+ − 6502
const signed char Init = 0;
+ − 6503
const signed char Ws1 = 1; // eat whitespace
+ − 6504
const signed char CoS = 2; // choice or set
+ − 6505
const signed char Ws2 = 3; // eat whitespace
+ − 6506
const signed char More = 4; // more cp to read
+ − 6507
const signed char Name = 5; // read name
+ − 6508
const signed char Done = 6; //
+ − 6509
+ − 6510
const signed char InpWs = 0; // S
+ − 6511
const signed char InpOp = 1; // (
+ − 6512
const signed char InpCp = 2; //)
+ − 6513
const signed char InpQm = 3; // ?
+ − 6514
const signed char InpAst = 4; // *
+ − 6515
const signed char InpPlus = 5; // +
+ − 6516
const signed char InpPipe = 6; // |
+ − 6517
const signed char InpComm = 7; // ,
+ − 6518
const signed char InpUnknown = 8;
+ − 6519
+ − 6520
static const signed char table[6][9] = {
+ − 6521
/* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
+ − 6522
{ -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
+ − 6523
{ -1, CoS, -1, -1, -1, -1, -1, -1, CoS }, // Ws1
+ − 6524
{ Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS
+ − 6525
{ -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
+ − 6526
{ -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
+ − 6527
{ Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS)
+ − 6528
};
+ − 6529
signed char state;
+ − 6530
signed char input;
+ − 6531
+ − 6532
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6533
state = Init;
+ − 6534
} else {
+ − 6535
state = parseStack->pop().state;
+ − 6536
#if defined(QT_QXML_DEBUG)
+ − 6537
qDebug("QXmlSimpleReader: parseChoiceSeq (cont) in state %d", state);
+ − 6538
#endif
+ − 6539
if (!parseStack->isEmpty()) {
+ − 6540
ParseFunction function = parseStack->top().function;
+ − 6541
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6542
parseStack->pop();
+ − 6543
#if defined(QT_QXML_DEBUG)
+ − 6544
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6545
#endif
+ − 6546
}
+ − 6547
if (!(this->*function)()) {
+ − 6548
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6549
return false;
+ − 6550
}
+ − 6551
}
+ − 6552
}
+ − 6553
+ − 6554
for (;;) {
+ − 6555
switch (state) {
+ − 6556
case Done:
+ − 6557
return true;
+ − 6558
case -1:
+ − 6559
// Error
+ − 6560
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 6561
return false;
+ − 6562
}
+ − 6563
+ − 6564
if (atEnd()) {
+ − 6565
unexpectedEof(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6566
return false;
+ − 6567
}
+ − 6568
if (is_S(c)) {
+ − 6569
input = InpWs;
+ − 6570
} else if (c == QLatin1Char('(')) {
+ − 6571
input = InpOp;
+ − 6572
} else if (c == QLatin1Char(')')) {
+ − 6573
input = InpCp;
+ − 6574
} else if (c == QLatin1Char('?')) {
+ − 6575
input = InpQm;
+ − 6576
} else if (c == QLatin1Char('*')) {
+ − 6577
input = InpAst;
+ − 6578
} else if (c == QLatin1Char('+')) {
+ − 6579
input = InpPlus;
+ − 6580
} else if (c == QLatin1Char('|')) {
+ − 6581
input = InpPipe;
+ − 6582
} else if (c == QLatin1Char(',')) {
+ − 6583
input = InpComm;
+ − 6584
} else {
+ − 6585
input = InpUnknown;
+ − 6586
}
+ − 6587
state = table[state][input];
+ − 6588
+ − 6589
switch (state) {
+ − 6590
case Ws1:
+ − 6591
if (!next_eat_ws()) {
+ − 6592
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6593
return false;
+ − 6594
}
+ − 6595
break;
+ − 6596
case CoS:
+ − 6597
if (!parseChoiceSeq()) {
+ − 6598
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6599
return false;
+ − 6600
}
+ − 6601
break;
+ − 6602
case Ws2:
+ − 6603
if (!next_eat_ws()) {
+ − 6604
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6605
return false;
+ − 6606
}
+ − 6607
break;
+ − 6608
case More:
+ − 6609
if (!next_eat_ws()) {
+ − 6610
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6611
return false;
+ − 6612
}
+ − 6613
break;
+ − 6614
case Name:
+ − 6615
parseName_useRef = false;
+ − 6616
if (!parseName()) {
+ − 6617
parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
+ − 6618
return false;
+ − 6619
}
+ − 6620
break;
+ − 6621
case Done:
+ − 6622
next();
+ − 6623
break;
+ − 6624
}
+ − 6625
}
+ − 6626
return false;
+ − 6627
}
+ − 6628
+ − 6629
/*
+ − 6630
Parse a EntityDecl [70].
+ − 6631
+ − 6632
Precondition: the beginning '<!E' is already read and the head
+ − 6633
stand on the 'N' of '<!ENTITY'
+ − 6634
*/
+ − 6635
bool QXmlSimpleReaderPrivate::parseEntityDecl()
+ − 6636
{
+ − 6637
const signed char Init = 0;
+ − 6638
const signed char Ent = 1; // parse "ENTITY"
+ − 6639
const signed char Ws1 = 2; // white space read
+ − 6640
const signed char Name = 3; // parse name
+ − 6641
const signed char Ws2 = 4; // white space read
+ − 6642
const signed char EValue = 5; // parse entity value
+ − 6643
const signed char EValueR = 6; // same as EValue, but already reported
+ − 6644
const signed char ExtID = 7; // parse ExternalID
+ − 6645
const signed char Ws3 = 8; // white space read
+ − 6646
const signed char Ndata = 9; // parse "NDATA"
+ − 6647
const signed char Ws4 = 10; // white space read
+ − 6648
const signed char NNam = 11; // parse name
+ − 6649
const signed char NNamR = 12; // same as NNam, but already reported
+ − 6650
const signed char PEDec = 13; // parse PEDecl
+ − 6651
const signed char Ws6 = 14; // white space read
+ − 6652
const signed char PENam = 15; // parse name
+ − 6653
const signed char Ws7 = 16; // white space read
+ − 6654
const signed char PEVal = 17; // parse entity value
+ − 6655
const signed char PEValR = 18; // same as PEVal, but already reported
+ − 6656
const signed char PEEID = 19; // parse ExternalID
+ − 6657
const signed char PEEIDR = 20; // same as PEEID, but already reported
+ − 6658
const signed char WsE = 21; // white space read
+ − 6659
const signed char Done = 22;
+ − 6660
const signed char EDDone = 23; // done, but also report an external, unparsed entity decl
+ − 6661
+ − 6662
const signed char InpWs = 0; // white space
+ − 6663
const signed char InpPer = 1; // %
+ − 6664
const signed char InpQuot = 2; // " or '
+ − 6665
const signed char InpGt = 3; // >
+ − 6666
const signed char InpN = 4; // N
+ − 6667
const signed char InpUnknown = 5;
+ − 6668
+ − 6669
static const signed char table[22][6] = {
+ − 6670
/* InpWs InpPer InpQuot InpGt InpN InpUnknown */
+ − 6671
{ -1, -1, -1, -1, Ent, -1 }, // Init
+ − 6672
{ Ws1, -1, -1, -1, -1, -1 }, // Ent
+ − 6673
{ -1, PEDec, -1, -1, Name, Name }, // Ws1
+ − 6674
{ Ws2, -1, -1, -1, -1, -1 }, // Name
+ − 6675
{ -1, -1, EValue, -1, -1, ExtID }, // Ws2
+ − 6676
{ WsE, -1, -1, Done, -1, -1 }, // EValue
+ − 6677
{ WsE, -1, -1, Done, -1, -1 }, // EValueR
+ − 6678
{ Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
+ − 6679
{ -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
+ − 6680
{ Ws4, -1, -1, -1, -1, -1 }, // Ndata
+ − 6681
{ -1, -1, -1, -1, NNam, NNam }, // Ws4
+ − 6682
{ WsE, -1, -1, Done, -1, -1 }, // NNam
+ − 6683
{ WsE, -1, -1, Done, -1, -1 }, // NNamR
+ − 6684
{ Ws6, -1, -1, -1, -1, -1 }, // PEDec
+ − 6685
{ -1, -1, -1, -1, PENam, PENam }, // Ws6
+ − 6686
{ Ws7, -1, -1, -1, -1, -1 }, // PENam
+ − 6687
{ -1, -1, PEVal, -1, -1, PEEID }, // Ws7
+ − 6688
{ WsE, -1, -1, Done, -1, -1 }, // PEVal
+ − 6689
{ WsE, -1, -1, Done, -1, -1 }, // PEValR
+ − 6690
{ WsE, -1, -1, Done, -1, -1 }, // PEEID
+ − 6691
{ WsE, -1, -1, Done, -1, -1 }, // PEEIDR
+ − 6692
{ -1, -1, -1, Done, -1, -1 } // WsE
+ − 6693
};
+ − 6694
signed char state;
+ − 6695
signed char input;
+ − 6696
+ − 6697
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6698
state = Init;
+ − 6699
} else {
+ − 6700
state = parseStack->pop().state;
+ − 6701
#if defined(QT_QXML_DEBUG)
+ − 6702
qDebug("QXmlSimpleReader: parseEntityDecl (cont) in state %d", state);
+ − 6703
#endif
+ − 6704
if (!parseStack->isEmpty()) {
+ − 6705
ParseFunction function = parseStack->top().function;
+ − 6706
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6707
parseStack->pop();
+ − 6708
#if defined(QT_QXML_DEBUG)
+ − 6709
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6710
#endif
+ − 6711
}
+ − 6712
if (!(this->*function)()) {
+ − 6713
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6714
return false;
+ − 6715
}
+ − 6716
}
+ − 6717
}
+ − 6718
+ − 6719
for (;;) {
+ − 6720
switch (state) {
+ − 6721
case EValue:
+ − 6722
if ( !entityExist(name())) {
+ − 6723
entities.insert(name(), string());
+ − 6724
if (declHnd) {
+ − 6725
if (!declHnd->internalEntityDecl(name(), string())) {
+ − 6726
reportParseError(declHnd->errorString());
+ − 6727
return false;
+ − 6728
}
+ − 6729
}
+ − 6730
}
+ − 6731
state = EValueR;
+ − 6732
break;
+ − 6733
case NNam:
+ − 6734
if ( !entityExist(name())) {
+ − 6735
externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, ref()));
+ − 6736
if (dtdHnd) {
+ − 6737
if (!dtdHnd->unparsedEntityDecl(name(), publicId, systemId, ref())) {
+ − 6738
reportParseError(declHnd->errorString());
+ − 6739
return false;
+ − 6740
}
+ − 6741
}
+ − 6742
}
+ − 6743
state = NNamR;
+ − 6744
break;
+ − 6745
case PEVal:
+ − 6746
if ( !entityExist(name())) {
+ − 6747
parameterEntities.insert(name(), string());
+ − 6748
if (declHnd) {
+ − 6749
if (!declHnd->internalEntityDecl(QLatin1Char('%') + name(), string())) {
+ − 6750
reportParseError(declHnd->errorString());
+ − 6751
return false;
+ − 6752
}
+ − 6753
}
+ − 6754
}
+ − 6755
state = PEValR;
+ − 6756
break;
+ − 6757
case PEEID:
+ − 6758
if ( !entityExist(name())) {
+ − 6759
externParameterEntities.insert(name(), QXmlSimpleReaderPrivate::ExternParameterEntity(publicId, systemId));
+ − 6760
if (declHnd) {
+ − 6761
if (!declHnd->externalEntityDecl(QLatin1Char('%') + name(), publicId, systemId)) {
+ − 6762
reportParseError(declHnd->errorString());
+ − 6763
return false;
+ − 6764
}
+ − 6765
}
+ − 6766
}
+ − 6767
state = PEEIDR;
+ − 6768
break;
+ − 6769
case EDDone:
+ − 6770
if ( !entityExist(name())) {
+ − 6771
externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, QString()));
+ − 6772
if (declHnd) {
+ − 6773
if (!declHnd->externalEntityDecl(name(), publicId, systemId)) {
+ − 6774
reportParseError(declHnd->errorString());
+ − 6775
return false;
+ − 6776
}
+ − 6777
}
+ − 6778
}
+ − 6779
return true;
+ − 6780
case Done:
+ − 6781
return true;
+ − 6782
case -1:
+ − 6783
// Error
+ − 6784
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 6785
return false;
+ − 6786
}
+ − 6787
+ − 6788
if (atEnd()) {
+ − 6789
unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6790
return false;
+ − 6791
}
+ − 6792
if (is_S(c)) {
+ − 6793
input = InpWs;
+ − 6794
} else if (c == QLatin1Char('%')) {
+ − 6795
input = InpPer;
+ − 6796
} else if (c == QLatin1Char('"') || c == QLatin1Char('\'')) {
+ − 6797
input = InpQuot;
+ − 6798
} else if (c == QLatin1Char('>')) {
+ − 6799
input = InpGt;
+ − 6800
} else if (c == QLatin1Char('N')) {
+ − 6801
input = InpN;
+ − 6802
} else {
+ − 6803
input = InpUnknown;
+ − 6804
}
+ − 6805
state = table[state][input];
+ − 6806
+ − 6807
switch (state) {
+ − 6808
case Ent:
+ − 6809
parseString_s = QLatin1String("NTITY");
+ − 6810
if (!parseString()) {
+ − 6811
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6812
return false;
+ − 6813
}
+ − 6814
break;
+ − 6815
case Ws1:
+ − 6816
if (!eat_ws()) {
+ − 6817
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6818
return false;
+ − 6819
}
+ − 6820
break;
+ − 6821
case Name:
+ − 6822
parseName_useRef = false;
+ − 6823
if (!parseName()) {
+ − 6824
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6825
return false;
+ − 6826
}
+ − 6827
break;
+ − 6828
case Ws2:
+ − 6829
if (!eat_ws()) {
+ − 6830
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6831
return false;
+ − 6832
}
+ − 6833
break;
+ − 6834
case EValue:
+ − 6835
case EValueR:
+ − 6836
if (!parseEntityValue()) {
+ − 6837
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6838
return false;
+ − 6839
}
+ − 6840
break;
+ − 6841
case ExtID:
+ − 6842
parseExternalID_allowPublicID = false;
+ − 6843
if (!parseExternalID()) {
+ − 6844
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6845
return false;
+ − 6846
}
+ − 6847
break;
+ − 6848
case Ws3:
+ − 6849
if (!eat_ws()) {
+ − 6850
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6851
return false;
+ − 6852
}
+ − 6853
break;
+ − 6854
case Ndata:
+ − 6855
parseString_s = QLatin1String("NDATA");
+ − 6856
if (!parseString()) {
+ − 6857
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6858
return false;
+ − 6859
}
+ − 6860
break;
+ − 6861
case Ws4:
+ − 6862
if (!eat_ws()) {
+ − 6863
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6864
return false;
+ − 6865
}
+ − 6866
break;
+ − 6867
case NNam:
+ − 6868
case NNamR:
+ − 6869
parseName_useRef = true;
+ − 6870
if (!parseName()) {
+ − 6871
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6872
return false;
+ − 6873
}
+ − 6874
break;
+ − 6875
case PEDec:
+ − 6876
next();
+ − 6877
break;
+ − 6878
case Ws6:
+ − 6879
if (!eat_ws()) {
+ − 6880
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6881
return false;
+ − 6882
}
+ − 6883
break;
+ − 6884
case PENam:
+ − 6885
parseName_useRef = false;
+ − 6886
if (!parseName()) {
+ − 6887
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6888
return false;
+ − 6889
}
+ − 6890
break;
+ − 6891
case Ws7:
+ − 6892
if (!eat_ws()) {
+ − 6893
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6894
return false;
+ − 6895
}
+ − 6896
break;
+ − 6897
case PEVal:
+ − 6898
case PEValR:
+ − 6899
if (!parseEntityValue()) {
+ − 6900
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6901
return false;
+ − 6902
}
+ − 6903
break;
+ − 6904
case PEEID:
+ − 6905
case PEEIDR:
+ − 6906
parseExternalID_allowPublicID = false;
+ − 6907
if (!parseExternalID()) {
+ − 6908
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6909
return false;
+ − 6910
}
+ − 6911
break;
+ − 6912
case WsE:
+ − 6913
if (!eat_ws()) {
+ − 6914
parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
+ − 6915
return false;
+ − 6916
}
+ − 6917
break;
+ − 6918
case EDDone:
+ − 6919
next();
+ − 6920
break;
+ − 6921
case Done:
+ − 6922
next();
+ − 6923
break;
+ − 6924
}
+ − 6925
}
+ − 6926
return false;
+ − 6927
}
+ − 6928
+ − 6929
/*
+ − 6930
Parse a EntityValue [9]
+ − 6931
*/
+ − 6932
bool QXmlSimpleReaderPrivate::parseEntityValue()
+ − 6933
{
+ − 6934
const signed char Init = 0;
+ − 6935
const signed char Dq = 1; // EntityValue is double quoted
+ − 6936
const signed char DqC = 2; // signed character
+ − 6937
const signed char DqPER = 3; // PERefence
+ − 6938
const signed char DqRef = 4; // Reference
+ − 6939
const signed char Sq = 5; // EntityValue is double quoted
+ − 6940
const signed char SqC = 6; // signed character
+ − 6941
const signed char SqPER = 7; // PERefence
+ − 6942
const signed char SqRef = 8; // Reference
+ − 6943
const signed char Done = 9;
+ − 6944
+ − 6945
const signed char InpDq = 0; // "
+ − 6946
const signed char InpSq = 1; // '
+ − 6947
const signed char InpAmp = 2; // &
+ − 6948
const signed char InpPer = 3; // %
+ − 6949
const signed char InpUnknown = 4;
+ − 6950
+ − 6951
static const signed char table[9][5] = {
+ − 6952
/* InpDq InpSq InpAmp InpPer InpUnknown */
+ − 6953
{ Dq, Sq, -1, -1, -1 }, // Init
+ − 6954
{ Done, DqC, DqRef, DqPER, DqC }, // Dq
+ − 6955
{ Done, DqC, DqRef, DqPER, DqC }, // DqC
+ − 6956
{ Done, DqC, DqRef, DqPER, DqC }, // DqPER
+ − 6957
{ Done, DqC, DqRef, DqPER, DqC }, // DqRef
+ − 6958
{ SqC, Done, SqRef, SqPER, SqC }, // Sq
+ − 6959
{ SqC, Done, SqRef, SqPER, SqC }, // SqC
+ − 6960
{ SqC, Done, SqRef, SqPER, SqC }, // SqPER
+ − 6961
{ SqC, Done, SqRef, SqPER, SqC } // SqRef
+ − 6962
};
+ − 6963
signed char state;
+ − 6964
signed char input;
+ − 6965
+ − 6966
if (parseStack==0 || parseStack->isEmpty()) {
+ − 6967
state = Init;
+ − 6968
} else {
+ − 6969
state = parseStack->pop().state;
+ − 6970
#if defined(QT_QXML_DEBUG)
+ − 6971
qDebug("QXmlSimpleReader: parseEntityValue (cont) in state %d", state);
+ − 6972
#endif
+ − 6973
if (!parseStack->isEmpty()) {
+ − 6974
ParseFunction function = parseStack->top().function;
+ − 6975
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 6976
parseStack->pop();
+ − 6977
#if defined(QT_QXML_DEBUG)
+ − 6978
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 6979
#endif
+ − 6980
}
+ − 6981
if (!(this->*function)()) {
+ − 6982
parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
+ − 6983
return false;
+ − 6984
}
+ − 6985
}
+ − 6986
}
+ − 6987
+ − 6988
for (;;) {
+ − 6989
switch (state) {
+ − 6990
case Done:
+ − 6991
return true;
+ − 6992
case -1:
+ − 6993
// Error
+ − 6994
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 6995
return false;
+ − 6996
}
+ − 6997
+ − 6998
if (atEnd()) {
+ − 6999
unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityValue, state);
+ − 7000
return false;
+ − 7001
}
+ − 7002
if (c == QLatin1Char('"')) {
+ − 7003
input = InpDq;
+ − 7004
} else if (c == QLatin1Char('\'')) {
+ − 7005
input = InpSq;
+ − 7006
} else if (c == QLatin1Char('&')) {
+ − 7007
input = InpAmp;
+ − 7008
} else if (c == QLatin1Char('%')) {
+ − 7009
input = InpPer;
+ − 7010
} else {
+ − 7011
input = InpUnknown;
+ − 7012
}
+ − 7013
state = table[state][input];
+ − 7014
+ − 7015
switch (state) {
+ − 7016
case Dq:
+ − 7017
case Sq:
+ − 7018
stringClear();
+ − 7019
next();
+ − 7020
break;
+ − 7021
case DqC:
+ − 7022
case SqC:
+ − 7023
stringAddC();
+ − 7024
next();
+ − 7025
break;
+ − 7026
case DqPER:
+ − 7027
case SqPER:
+ − 7028
parsePEReference_context = InEntityValue;
+ − 7029
if (!parsePEReference()) {
+ − 7030
parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
+ − 7031
return false;
+ − 7032
}
+ − 7033
break;
+ − 7034
case DqRef:
+ − 7035
case SqRef:
+ − 7036
parseReference_context = InEntityValue;
+ − 7037
if (!parseReference()) {
+ − 7038
parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
+ − 7039
return false;
+ − 7040
}
+ − 7041
break;
+ − 7042
case Done:
+ − 7043
next();
+ − 7044
break;
+ − 7045
}
+ − 7046
}
+ − 7047
return false;
+ − 7048
}
+ − 7049
+ − 7050
/*
+ − 7051
Parse a comment [15].
+ − 7052
+ − 7053
Precondition: the beginning '<!' of the comment is already read and the head
+ − 7054
stands on the first '-' of '<!--'.
+ − 7055
+ − 7056
If this funktion was successful, the head-position is on the first
+ − 7057
character after the comment.
+ − 7058
*/
+ − 7059
bool QXmlSimpleReaderPrivate::parseComment()
+ − 7060
{
+ − 7061
const signed char Init = 0;
+ − 7062
const signed char Dash1 = 1; // the first dash was read
+ − 7063
const signed char Dash2 = 2; // the second dash was read
+ − 7064
const signed char Com = 3; // read comment
+ − 7065
const signed char Com2 = 4; // read comment (help state)
+ − 7066
const signed char ComE = 5; // finished reading comment
+ − 7067
const signed char Done = 6;
+ − 7068
+ − 7069
const signed char InpDash = 0; // -
+ − 7070
const signed char InpGt = 1; // >
+ − 7071
const signed char InpUnknown = 2;
+ − 7072
+ − 7073
static const signed char table[6][3] = {
+ − 7074
/* InpDash InpGt InpUnknown */
+ − 7075
{ Dash1, -1, -1 }, // Init
+ − 7076
{ Dash2, -1, -1 }, // Dash1
+ − 7077
{ Com2, Com, Com }, // Dash2
+ − 7078
{ Com2, Com, Com }, // Com
+ − 7079
{ ComE, Com, Com }, // Com2
+ − 7080
{ -1, Done, -1 } // ComE
+ − 7081
};
+ − 7082
signed char state;
+ − 7083
signed char input;
+ − 7084
+ − 7085
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7086
state = Init;
+ − 7087
} else {
+ − 7088
state = parseStack->pop().state;
+ − 7089
#if defined(QT_QXML_DEBUG)
+ − 7090
qDebug("QXmlSimpleReader: parseComment (cont) in state %d", state);
+ − 7091
#endif
+ − 7092
if (!parseStack->isEmpty()) {
+ − 7093
ParseFunction function = parseStack->top().function;
+ − 7094
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7095
parseStack->pop();
+ − 7096
#if defined(QT_QXML_DEBUG)
+ − 7097
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7098
#endif
+ − 7099
}
+ − 7100
if (!(this->*function)()) {
+ − 7101
parseFailed(&QXmlSimpleReaderPrivate::parseComment, state);
+ − 7102
return false;
+ − 7103
}
+ − 7104
}
+ − 7105
}
+ − 7106
+ − 7107
for (;;) {
+ − 7108
switch (state) {
+ − 7109
case Dash2:
+ − 7110
stringClear();
+ − 7111
break;
+ − 7112
case Com2:
+ − 7113
// if next character is not a dash than don't skip it
+ − 7114
if (!atEnd() && c != QLatin1Char('-'))
+ − 7115
stringAddC(QLatin1Char('-'));
+ − 7116
break;
+ − 7117
case Done:
+ − 7118
return true;
+ − 7119
case -1:
+ − 7120
// Error
+ − 7121
reportParseError(QLatin1String(XMLERR_ERRORPARSINGCOMMENT));
+ − 7122
return false;
+ − 7123
}
+ − 7124
+ − 7125
if (atEnd()) {
+ − 7126
unexpectedEof(&QXmlSimpleReaderPrivate::parseComment, state);
+ − 7127
return false;
+ − 7128
}
+ − 7129
if (c == QLatin1Char('-')) {
+ − 7130
input = InpDash;
+ − 7131
} else if (c == QLatin1Char('>')) {
+ − 7132
input = InpGt;
+ − 7133
} else {
+ − 7134
input = InpUnknown;
+ − 7135
}
+ − 7136
state = table[state][input];
+ − 7137
+ − 7138
switch (state) {
+ − 7139
case Dash1:
+ − 7140
next();
+ − 7141
break;
+ − 7142
case Dash2:
+ − 7143
next();
+ − 7144
break;
+ − 7145
case Com:
+ − 7146
stringAddC();
+ − 7147
next();
+ − 7148
break;
+ − 7149
case Com2:
+ − 7150
next();
+ − 7151
break;
+ − 7152
case ComE:
+ − 7153
next();
+ − 7154
break;
+ − 7155
case Done:
+ − 7156
next();
+ − 7157
break;
+ − 7158
}
+ − 7159
}
+ − 7160
return false;
+ − 7161
}
+ − 7162
+ − 7163
/*
+ − 7164
Parse an Attribute [41].
+ − 7165
+ − 7166
Precondition: the head stands on the first character of the name
+ − 7167
of the attribute (i.e. all whitespaces are already parsed).
+ − 7168
+ − 7169
The head stand on the next character after the end quotes. The
+ − 7170
variable name contains the name of the attribute and the variable
+ − 7171
string contains the value of the attribute.
+ − 7172
*/
+ − 7173
bool QXmlSimpleReaderPrivate::parseAttribute()
+ − 7174
{
+ − 7175
const int Init = 0;
+ − 7176
const int PName = 1; // parse name
+ − 7177
const int Ws = 2; // eat ws
+ − 7178
const int Eq = 3; // the '=' was read
+ − 7179
const int Quotes = 4; // " or ' were read
+ − 7180
+ − 7181
const int InpNameBe = 0;
+ − 7182
const int InpEq = 1; // =
+ − 7183
const int InpDq = 2; // "
+ − 7184
const int InpSq = 3; // '
+ − 7185
const int InpUnknown = 4;
+ − 7186
+ − 7187
static const int table[4][5] = {
+ − 7188
/* InpNameBe InpEq InpDq InpSq InpUnknown */
+ − 7189
{ PName, -1, -1, -1, -1 }, // Init
+ − 7190
{ -1, Eq, -1, -1, Ws }, // PName
+ − 7191
{ -1, Eq, -1, -1, -1 }, // Ws
+ − 7192
{ -1, -1, Quotes, Quotes, -1 } // Eq
+ − 7193
};
+ − 7194
int state;
+ − 7195
int input;
+ − 7196
+ − 7197
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7198
state = Init;
+ − 7199
} else {
+ − 7200
state = parseStack->pop().state;
+ − 7201
#if defined(QT_QXML_DEBUG)
+ − 7202
qDebug("QXmlSimpleReader: parseAttribute (cont) in state %d", state);
+ − 7203
#endif
+ − 7204
if (!parseStack->isEmpty()) {
+ − 7205
ParseFunction function = parseStack->top().function;
+ − 7206
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7207
parseStack->pop();
+ − 7208
#if defined(QT_QXML_DEBUG)
+ − 7209
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7210
#endif
+ − 7211
}
+ − 7212
if (!(this->*function)()) {
+ − 7213
parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7214
return false;
+ − 7215
}
+ − 7216
}
+ − 7217
}
+ − 7218
+ − 7219
for (;;) {
+ − 7220
switch (state) {
+ − 7221
case Quotes:
+ − 7222
// Done
+ − 7223
return true;
+ − 7224
case -1:
+ − 7225
// Error
+ − 7226
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 7227
return false;
+ − 7228
}
+ − 7229
+ − 7230
if (atEnd()) {
+ − 7231
unexpectedEof(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7232
return false;
+ − 7233
}
+ − 7234
if (determineNameChar(c) == NameBeginning) {
+ − 7235
input = InpNameBe;
+ − 7236
} else if (c == QLatin1Char('=')) {
+ − 7237
input = InpEq;
+ − 7238
} else if (c == QLatin1Char('"')) {
+ − 7239
input = InpDq;
+ − 7240
} else if (c == QLatin1Char('\'')) {
+ − 7241
input = InpSq;
+ − 7242
} else {
+ − 7243
input = InpUnknown;
+ − 7244
}
+ − 7245
state = table[state][input];
+ − 7246
+ − 7247
switch (state) {
+ − 7248
case PName:
+ − 7249
parseName_useRef = false;
+ − 7250
if (!parseName()) {
+ − 7251
parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7252
return false;
+ − 7253
}
+ − 7254
break;
+ − 7255
case Ws:
+ − 7256
if (!eat_ws()) {
+ − 7257
parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7258
return false;
+ − 7259
}
+ − 7260
break;
+ − 7261
case Eq:
+ − 7262
if (!next_eat_ws()) {
+ − 7263
parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7264
return false;
+ − 7265
}
+ − 7266
break;
+ − 7267
case Quotes:
+ − 7268
if (!parseAttValue()) {
+ − 7269
parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
+ − 7270
return false;
+ − 7271
}
+ − 7272
break;
+ − 7273
}
+ − 7274
}
+ − 7275
return false;
+ − 7276
}
+ − 7277
+ − 7278
/*
+ − 7279
Parse a Name [5] and store the name in name or ref (if useRef is true).
+ − 7280
*/
+ − 7281
bool QXmlSimpleReaderPrivate::parseName()
+ − 7282
{
+ − 7283
const int Init = 0;
+ − 7284
const int Name1 = 1; // parse first character of the name
+ − 7285
const int Name = 2; // parse name
+ − 7286
const int Done = 3;
+ − 7287
+ − 7288
static const int table[3][3] = {
+ − 7289
/* InpNameBe InpNameCh InpUnknown */
+ − 7290
{ Name1, -1, -1 }, // Init
+ − 7291
{ Name, Name, Done }, // Name1
+ − 7292
{ Name, Name, Done } // Name
+ − 7293
};
+ − 7294
int state;
+ − 7295
+ − 7296
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7297
state = Init;
+ − 7298
} else {
+ − 7299
state = parseStack->pop().state;
+ − 7300
#if defined(QT_QXML_DEBUG)
+ − 7301
qDebug("QXmlSimpleReader: parseName (cont) in state %d", state);
+ − 7302
#endif
+ − 7303
if (!parseStack->isEmpty()) {
+ − 7304
ParseFunction function = parseStack->top().function;
+ − 7305
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7306
parseStack->pop();
+ − 7307
#if defined(QT_QXML_DEBUG)
+ − 7308
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7309
#endif
+ − 7310
}
+ − 7311
if (!(this->*function)()) {
+ − 7312
parseFailed(&QXmlSimpleReaderPrivate::parseName, state);
+ − 7313
return false;
+ − 7314
}
+ − 7315
}
+ − 7316
}
+ − 7317
+ − 7318
for (;;) {
+ − 7319
switch (state) {
+ − 7320
case Done:
+ − 7321
return true;
+ − 7322
case -1:
+ − 7323
// Error
+ − 7324
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 7325
return false;
+ − 7326
}
+ − 7327
+ − 7328
if (atEnd()) {
+ − 7329
unexpectedEof(&QXmlSimpleReaderPrivate::parseName, state);
+ − 7330
return false;
+ − 7331
}
+ − 7332
+ − 7333
// we can safely do the (int) cast thanks to the Q_ASSERTs earlier in this function
+ − 7334
state = table[state][(int)fastDetermineNameChar(c)];
+ − 7335
+ − 7336
switch (state) {
+ − 7337
case Name1:
+ − 7338
if (parseName_useRef) {
+ − 7339
refClear();
+ − 7340
refAddC();
+ − 7341
} else {
+ − 7342
nameClear();
+ − 7343
nameAddC();
+ − 7344
}
+ − 7345
next();
+ − 7346
break;
+ − 7347
case Name:
+ − 7348
if (parseName_useRef) {
+ − 7349
refAddC();
+ − 7350
} else {
+ − 7351
nameAddC();
+ − 7352
}
+ − 7353
next();
+ − 7354
break;
+ − 7355
}
+ − 7356
}
+ − 7357
return false;
+ − 7358
}
+ − 7359
+ − 7360
/*
+ − 7361
Parse a Nmtoken [7] and store the name in name.
+ − 7362
*/
+ − 7363
bool QXmlSimpleReaderPrivate::parseNmtoken()
+ − 7364
{
+ − 7365
const signed char Init = 0;
+ − 7366
const signed char NameF = 1;
+ − 7367
const signed char Name = 2;
+ − 7368
const signed char Done = 3;
+ − 7369
+ − 7370
const signed char InpNameCh = 0; // NameChar without InpNameBe
+ − 7371
const signed char InpUnknown = 1;
+ − 7372
+ − 7373
static const signed char table[3][2] = {
+ − 7374
/* InpNameCh InpUnknown */
+ − 7375
{ NameF, -1 }, // Init
+ − 7376
{ Name, Done }, // NameF
+ − 7377
{ Name, Done } // Name
+ − 7378
};
+ − 7379
signed char state;
+ − 7380
signed char input;
+ − 7381
+ − 7382
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7383
state = Init;
+ − 7384
} else {
+ − 7385
state = parseStack->pop().state;
+ − 7386
#if defined(QT_QXML_DEBUG)
+ − 7387
qDebug("QXmlSimpleReader: parseNmtoken (cont) in state %d", state);
+ − 7388
#endif
+ − 7389
if (!parseStack->isEmpty()) {
+ − 7390
ParseFunction function = parseStack->top().function;
+ − 7391
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7392
parseStack->pop();
+ − 7393
#if defined(QT_QXML_DEBUG)
+ − 7394
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7395
#endif
+ − 7396
}
+ − 7397
if (!(this->*function)()) {
+ − 7398
parseFailed(&QXmlSimpleReaderPrivate::parseNmtoken, state);
+ − 7399
return false;
+ − 7400
}
+ − 7401
}
+ − 7402
}
+ − 7403
+ − 7404
for (;;) {
+ − 7405
switch (state) {
+ − 7406
case Done:
+ − 7407
return true;
+ − 7408
case -1:
+ − 7409
// Error
+ − 7410
reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
+ − 7411
return false;
+ − 7412
}
+ − 7413
+ − 7414
if (atEnd()) {
+ − 7415
unexpectedEof(&QXmlSimpleReaderPrivate::parseNmtoken, state);
+ − 7416
return false;
+ − 7417
}
+ − 7418
if (determineNameChar(c) == NotName) {
+ − 7419
input = InpUnknown;
+ − 7420
} else {
+ − 7421
input = InpNameCh;
+ − 7422
}
+ − 7423
state = table[state][input];
+ − 7424
+ − 7425
switch (state) {
+ − 7426
case NameF:
+ − 7427
nameClear();
+ − 7428
nameAddC();
+ − 7429
next();
+ − 7430
break;
+ − 7431
case Name:
+ − 7432
nameAddC();
+ − 7433
next();
+ − 7434
break;
+ − 7435
}
+ − 7436
}
+ − 7437
return false;
+ − 7438
}
+ − 7439
+ − 7440
/*
+ − 7441
Parse a Reference [67].
+ − 7442
+ − 7443
parseReference_charDataRead is set to true if the reference must not be
+ − 7444
parsed. The character(s) which the reference mapped to are appended to
+ − 7445
string. The head stands on the first character after the reference.
+ − 7446
+ − 7447
parseReference_charDataRead is set to false if the reference must be parsed.
+ − 7448
The charachter(s) which the reference mapped to are inserted at the reference
+ − 7449
position. The head stands on the first character of the replacement).
+ − 7450
*/
+ − 7451
bool QXmlSimpleReaderPrivate::parseReference()
+ − 7452
{
+ − 7453
// temporary variables (only used in very local context, so they don't
+ − 7454
// interfere with incremental parsing)
+ − 7455
uint tmp;
+ − 7456
bool ok;
+ − 7457
+ − 7458
const signed char Init = 0;
+ − 7459
const signed char SRef = 1; // start of a reference
+ − 7460
const signed char ChRef = 2; // parse CharRef
+ − 7461
const signed char ChDec = 3; // parse CharRef decimal
+ − 7462
const signed char ChHexS = 4; // start CharRef hexadecimal
+ − 7463
const signed char ChHex = 5; // parse CharRef hexadecimal
+ − 7464
const signed char Name = 6; // parse name
+ − 7465
const signed char DoneD = 7; // done CharRef decimal
+ − 7466
const signed char DoneH = 8; // done CharRef hexadecimal
+ − 7467
const signed char DoneN = 9; // done EntityRef
+ − 7468
+ − 7469
const signed char InpAmp = 0; // &
+ − 7470
const signed char InpSemi = 1; // ;
+ − 7471
const signed char InpHash = 2; // #
+ − 7472
const signed char InpX = 3; // x
+ − 7473
const signed char InpNum = 4; // 0-9
+ − 7474
const signed char InpHex = 5; // a-f A-F
+ − 7475
const signed char InpUnknown = 6;
+ − 7476
+ − 7477
static const signed char table[8][7] = {
+ − 7478
/* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
+ − 7479
{ SRef, -1, -1, -1, -1, -1, -1 }, // Init
+ − 7480
{ -1, -1, ChRef, Name, Name, Name, Name }, // SRef
+ − 7481
{ -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
+ − 7482
{ -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
+ − 7483
{ -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
+ − 7484
{ -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
+ − 7485
{ -1, DoneN, -1, -1, -1, -1, -1 } // Name
+ − 7486
};
+ − 7487
signed char state;
+ − 7488
signed char input;
+ − 7489
+ − 7490
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7491
parseReference_charDataRead = false;
+ − 7492
state = Init;
+ − 7493
} else {
+ − 7494
state = parseStack->pop().state;
+ − 7495
#if defined(QT_QXML_DEBUG)
+ − 7496
qDebug("QXmlSimpleReader: parseReference (cont) in state %d", state);
+ − 7497
#endif
+ − 7498
if (!parseStack->isEmpty()) {
+ − 7499
ParseFunction function = parseStack->top().function;
+ − 7500
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7501
parseStack->pop();
+ − 7502
#if defined(QT_QXML_DEBUG)
+ − 7503
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7504
#endif
+ − 7505
}
+ − 7506
if (!(this->*function)()) {
+ − 7507
parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
+ − 7508
return false;
+ − 7509
}
+ − 7510
}
+ − 7511
}
+ − 7512
+ − 7513
for (;;) {
+ − 7514
switch (state) {
+ − 7515
case DoneD:
+ − 7516
return true;
+ − 7517
case DoneH:
+ − 7518
return true;
+ − 7519
case DoneN:
+ − 7520
return true;
+ − 7521
case -1:
+ − 7522
// Error
+ − 7523
reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
+ − 7524
return false;
+ − 7525
}
+ − 7526
+ − 7527
if (atEnd()) {
+ − 7528
unexpectedEof(&QXmlSimpleReaderPrivate::parseReference, state);
+ − 7529
return false;
+ − 7530
}
+ − 7531
if (c.row()) {
+ − 7532
input = InpUnknown;
+ − 7533
} else if (c.cell() == '&') {
+ − 7534
input = InpAmp;
+ − 7535
} else if (c.cell() == ';') {
+ − 7536
input = InpSemi;
+ − 7537
} else if (c.cell() == '#') {
+ − 7538
input = InpHash;
+ − 7539
} else if (c.cell() == 'x') {
+ − 7540
input = InpX;
+ − 7541
} else if ('0' <= c.cell() && c.cell() <= '9') {
+ − 7542
input = InpNum;
+ − 7543
} else if ('a' <= c.cell() && c.cell() <= 'f') {
+ − 7544
input = InpHex;
+ − 7545
} else if ('A' <= c.cell() && c.cell() <= 'F') {
+ − 7546
input = InpHex;
+ − 7547
} else {
+ − 7548
input = InpUnknown;
+ − 7549
}
+ − 7550
state = table[state][input];
+ − 7551
+ − 7552
switch (state) {
+ − 7553
case SRef:
+ − 7554
refClear();
+ − 7555
next();
+ − 7556
break;
+ − 7557
case ChRef:
+ − 7558
next();
+ − 7559
break;
+ − 7560
case ChDec:
+ − 7561
refAddC();
+ − 7562
next();
+ − 7563
break;
+ − 7564
case ChHexS:
+ − 7565
next();
+ − 7566
break;
+ − 7567
case ChHex:
+ − 7568
refAddC();
+ − 7569
next();
+ − 7570
break;
+ − 7571
case Name:
+ − 7572
// read the name into the ref
+ − 7573
parseName_useRef = true;
+ − 7574
if (!parseName()) {
+ − 7575
parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
+ − 7576
return false;
+ − 7577
}
+ − 7578
break;
+ − 7579
case DoneD:
+ − 7580
tmp = ref().toUInt(&ok, 10);
+ − 7581
if (ok) {
+ − 7582
stringAddC(QChar(tmp));
+ − 7583
} else {
+ − 7584
reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
+ − 7585
return false;
+ − 7586
}
+ − 7587
parseReference_charDataRead = true;
+ − 7588
next();
+ − 7589
break;
+ − 7590
case DoneH:
+ − 7591
tmp = ref().toUInt(&ok, 16);
+ − 7592
if (ok) {
+ − 7593
stringAddC(QChar(tmp));
+ − 7594
} else {
+ − 7595
reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
+ − 7596
return false;
+ − 7597
}
+ − 7598
parseReference_charDataRead = true;
+ − 7599
next();
+ − 7600
break;
+ − 7601
case DoneN:
+ − 7602
if (!processReference())
+ − 7603
return false;
+ − 7604
next();
+ − 7605
break;
+ − 7606
}
+ − 7607
}
+ − 7608
return false;
+ − 7609
}
+ − 7610
+ − 7611
/*
+ − 7612
Helper function for parseReference()
+ − 7613
*/
+ − 7614
bool QXmlSimpleReaderPrivate::processReference()
+ − 7615
{
+ − 7616
QString reference = ref();
+ − 7617
if (reference == QLatin1String("amp")) {
+ − 7618
if (parseReference_context == InEntityValue) {
+ − 7619
// Bypassed
+ − 7620
stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('m')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char(';'));
+ − 7621
} else {
+ − 7622
// Included or Included in literal
+ − 7623
stringAddC(QLatin1Char('&'));
+ − 7624
}
+ − 7625
parseReference_charDataRead = true;
+ − 7626
} else if (reference == QLatin1String("lt")) {
+ − 7627
if (parseReference_context == InEntityValue) {
+ − 7628
// Bypassed
+ − 7629
stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('l')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
+ − 7630
} else {
+ − 7631
// Included or Included in literal
+ − 7632
stringAddC(QLatin1Char('<'));
+ − 7633
}
+ − 7634
parseReference_charDataRead = true;
+ − 7635
} else if (reference == QLatin1String("gt")) {
+ − 7636
if (parseReference_context == InEntityValue) {
+ − 7637
// Bypassed
+ − 7638
stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('g')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
+ − 7639
} else {
+ − 7640
// Included or Included in literal
+ − 7641
stringAddC(QLatin1Char('>'));
+ − 7642
}
+ − 7643
parseReference_charDataRead = true;
+ − 7644
} else if (reference == QLatin1String("apos")) {
+ − 7645
if (parseReference_context == InEntityValue) {
+ − 7646
// Bypassed
+ − 7647
stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('s')); stringAddC(QLatin1Char(';'));
+ − 7648
} else {
+ − 7649
// Included or Included in literal
+ − 7650
stringAddC(QLatin1Char('\''));
+ − 7651
}
+ − 7652
parseReference_charDataRead = true;
+ − 7653
} else if (reference == QLatin1String("quot")) {
+ − 7654
if (parseReference_context == InEntityValue) {
+ − 7655
// Bypassed
+ − 7656
stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('q')); stringAddC(QLatin1Char('u')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
+ − 7657
} else {
+ − 7658
// Included or Included in literal
+ − 7659
stringAddC(QLatin1Char('"'));
+ − 7660
}
+ − 7661
parseReference_charDataRead = true;
+ − 7662
} else {
+ − 7663
QMap<QString,QString>::Iterator it;
+ − 7664
it = entities.find(reference);
+ − 7665
if (it != entities.end()) {
+ − 7666
// "Internal General"
+ − 7667
switch (parseReference_context) {
+ − 7668
case InContent:
+ − 7669
// Included
+ − 7670
if (!insertXmlRef(*it, reference, false))
+ − 7671
return false;
+ − 7672
parseReference_charDataRead = false;
+ − 7673
break;
+ − 7674
case InAttributeValue:
+ − 7675
// Included in literal
+ − 7676
if (!insertXmlRef(*it, reference, true))
+ − 7677
return false;
+ − 7678
parseReference_charDataRead = false;
+ − 7679
break;
+ − 7680
case InEntityValue:
+ − 7681
{
+ − 7682
// Bypassed
+ − 7683
stringAddC(QLatin1Char('&'));
+ − 7684
for (int i=0; i<(int)reference.length(); i++) {
+ − 7685
stringAddC(reference[i]);
+ − 7686
}
+ − 7687
stringAddC(QLatin1Char(';'));
+ − 7688
parseReference_charDataRead = true;
+ − 7689
}
+ − 7690
break;
+ − 7691
case InDTD:
+ − 7692
// Forbidden
+ − 7693
parseReference_charDataRead = false;
+ − 7694
reportParseError(QLatin1String(XMLERR_INTERNALGENERALENTITYINDTD));
+ − 7695
return false;
+ − 7696
}
+ − 7697
} else {
+ − 7698
QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ − 7699
itExtern = externEntities.find(reference);
+ − 7700
if (itExtern == externEntities.end()) {
+ − 7701
// entity not declared
+ − 7702
// ### check this case for conformance
+ − 7703
if (parseReference_context == InEntityValue) {
+ − 7704
// Bypassed
+ − 7705
stringAddC(QLatin1Char('&'));
+ − 7706
for (int i=0; i<(int)reference.length(); i++) {
+ − 7707
stringAddC(reference[i]);
+ − 7708
}
+ − 7709
stringAddC(QLatin1Char(';'));
+ − 7710
parseReference_charDataRead = true;
+ − 7711
} else {
+ − 7712
// if we have some char data read, report it now
+ − 7713
if (parseReference_context == InContent) {
+ − 7714
if (contentCharDataRead) {
+ − 7715
if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
+ − 7716
if (contentHnd != 0 && !contentHnd->characters(string())) {
+ − 7717
reportParseError(contentHnd->errorString());
+ − 7718
return false;
+ − 7719
}
+ − 7720
}
+ − 7721
stringClear();
+ − 7722
contentCharDataRead = false;
+ − 7723
}
+ − 7724
}
+ − 7725
+ − 7726
if (contentHnd) {
+ − 7727
qt_xml_skipped_entity_in_content = parseReference_context == InContent;
+ − 7728
if (!contentHnd->skippedEntity(reference)) {
+ − 7729
qt_xml_skipped_entity_in_content = false;
+ − 7730
reportParseError(contentHnd->errorString());
+ − 7731
return false; // error
+ − 7732
}
+ − 7733
qt_xml_skipped_entity_in_content = false;
+ − 7734
}
+ − 7735
}
+ − 7736
} else if ((*itExtern).notation.isNull()) {
+ − 7737
// "External Parsed General"
+ − 7738
switch (parseReference_context) {
+ − 7739
case InContent:
+ − 7740
{
+ − 7741
// Included if validating
+ − 7742
bool skipIt = true;
+ − 7743
if (entityRes) {
+ − 7744
QXmlInputSource *ret = 0;
+ − 7745
if (!entityRes->resolveEntity((*itExtern).publicId, (*itExtern).systemId, ret)) {
+ − 7746
delete ret;
+ − 7747
reportParseError(entityRes->errorString());
+ − 7748
return false;
+ − 7749
}
+ − 7750
if (ret) {
+ − 7751
QString xmlRefString = ret->data();
+ − 7752
delete ret;
+ − 7753
if (!stripTextDecl(xmlRefString)) {
+ − 7754
reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
+ − 7755
return false;
+ − 7756
}
+ − 7757
if (!insertXmlRef(xmlRefString, reference, false))
+ − 7758
return false;
+ − 7759
skipIt = false;
+ − 7760
}
+ − 7761
}
+ − 7762
if (skipIt && contentHnd) {
+ − 7763
qt_xml_skipped_entity_in_content = true;
+ − 7764
if (!contentHnd->skippedEntity(reference)) {
+ − 7765
qt_xml_skipped_entity_in_content = false;
+ − 7766
reportParseError(contentHnd->errorString());
+ − 7767
return false; // error
+ − 7768
}
+ − 7769
qt_xml_skipped_entity_in_content = false;
+ − 7770
}
+ − 7771
parseReference_charDataRead = false;
+ − 7772
} break;
+ − 7773
case InAttributeValue:
+ − 7774
// Forbidden
+ − 7775
parseReference_charDataRead = false;
+ − 7776
reportParseError(QLatin1String(XMLERR_EXTERNALGENERALENTITYINAV));
+ − 7777
return false;
+ − 7778
case InEntityValue:
+ − 7779
{
+ − 7780
// Bypassed
+ − 7781
stringAddC(QLatin1Char('&'));
+ − 7782
for (int i=0; i<(int)reference.length(); i++) {
+ − 7783
stringAddC(reference[i]);
+ − 7784
}
+ − 7785
stringAddC(QLatin1Char(';'));
+ − 7786
parseReference_charDataRead = true;
+ − 7787
}
+ − 7788
break;
+ − 7789
case InDTD:
+ − 7790
// Forbidden
+ − 7791
parseReference_charDataRead = false;
+ − 7792
reportParseError(QLatin1String(XMLERR_EXTERNALGENERALENTITYINDTD));
+ − 7793
return false;
+ − 7794
}
+ − 7795
} else {
+ − 7796
// "Unparsed"
+ − 7797
// ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
+ − 7798
// Forbidden
+ − 7799
parseReference_charDataRead = false;
+ − 7800
reportParseError(QLatin1String(XMLERR_UNPARSEDENTITYREFERENCE));
+ − 7801
return false; // error
+ − 7802
}
+ − 7803
}
+ − 7804
}
+ − 7805
return true; // no error
+ − 7806
}
+ − 7807
+ − 7808
+ − 7809
/*
+ − 7810
Parses over a simple string.
+ − 7811
+ − 7812
After the string was successfully parsed, the head is on the first
+ − 7813
character after the string.
+ − 7814
*/
+ − 7815
bool QXmlSimpleReaderPrivate::parseString()
+ − 7816
{
+ − 7817
const signed char InpCharExpected = 0; // the character that was expected
+ − 7818
const signed char InpUnknown = 1;
+ − 7819
+ − 7820
signed char state; // state in this function is the position in the string s
+ − 7821
signed char input;
+ − 7822
+ − 7823
if (parseStack==0 || parseStack->isEmpty()) {
+ − 7824
Done = parseString_s.length();
+ − 7825
state = 0;
+ − 7826
} else {
+ − 7827
state = parseStack->pop().state;
+ − 7828
#if defined(QT_QXML_DEBUG)
+ − 7829
qDebug("QXmlSimpleReader: parseString (cont) in state %d", state);
+ − 7830
#endif
+ − 7831
if (!parseStack->isEmpty()) {
+ − 7832
ParseFunction function = parseStack->top().function;
+ − 7833
if (function == &QXmlSimpleReaderPrivate::eat_ws) {
+ − 7834
parseStack->pop();
+ − 7835
#if defined(QT_QXML_DEBUG)
+ − 7836
qDebug("QXmlSimpleReader: eat_ws (cont)");
+ − 7837
#endif
+ − 7838
}
+ − 7839
if (!(this->*function)()) {
+ − 7840
parseFailed(&QXmlSimpleReaderPrivate::parseString, state);
+ − 7841
return false;
+ − 7842
}
+ − 7843
}
+ − 7844
}
+ − 7845
+ − 7846
for (;;) {
+ − 7847
if (state == Done) {
+ − 7848
return true;
+ − 7849
}
+ − 7850
+ − 7851
if (atEnd()) {
+ − 7852
unexpectedEof(&QXmlSimpleReaderPrivate::parseString, state);
+ − 7853
return false;
+ − 7854
}
+ − 7855
if (c == parseString_s[(int)state]) {
+ − 7856
input = InpCharExpected;
+ − 7857
} else {
+ − 7858
input = InpUnknown;
+ − 7859
}
+ − 7860
if (input == InpCharExpected) {
+ − 7861
state++;
+ − 7862
} else {
+ − 7863
// Error
+ − 7864
reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
+ − 7865
return false;
+ − 7866
}
+ − 7867
+ − 7868
next();
+ − 7869
}
+ − 7870
return false;
+ − 7871
}
+ − 7872
+ − 7873
/*
+ − 7874
This private function inserts and reports an entity substitution. The
+ − 7875
substituted string is \a data and the name of the entity reference is \a
+ − 7876
name. If \a inLiteral is true, the entity is IncludedInLiteral (i.e., " and '
+ − 7877
must be quoted. Otherwise they are not quoted.
+ − 7878
+ − 7879
This function returns false on error.
+ − 7880
*/
+ − 7881
bool QXmlSimpleReaderPrivate::insertXmlRef(const QString &data, const QString &name, bool inLiteral)
+ − 7882
{
+ − 7883
if (inLiteral) {
+ − 7884
QString tmp = data;
+ − 7885
xmlRefStack.push(XmlRef(name, tmp.replace(QLatin1Char('\"'),
+ − 7886
QLatin1String(""")).replace(QLatin1Char('\''), QLatin1String("'"))));
+ − 7887
} else {
+ − 7888
xmlRefStack.push(XmlRef(name, data));
+ − 7889
}
+ − 7890
int n = qMax(parameterEntities.count(), entities.count());
+ − 7891
if (xmlRefStack.count() > n+1) {
+ − 7892
// recursive entities
+ − 7893
reportParseError(QLatin1String(XMLERR_RECURSIVEENTITIES));
+ − 7894
return false;
+ − 7895
}
+ − 7896
if (reportEntities && lexicalHnd) {
+ − 7897
if (!lexicalHnd->startEntity(name)) {
+ − 7898
reportParseError(lexicalHnd->errorString());
+ − 7899
return false;
+ − 7900
}
+ − 7901
}
+ − 7902
return true;
+ − 7903
}
+ − 7904
+ − 7905
/*
+ − 7906
This private function moves the cursor to the next character.
+ − 7907
*/
+ − 7908
void QXmlSimpleReaderPrivate::next()
+ − 7909
{
+ − 7910
int count = xmlRefStack.size();
+ − 7911
while (count != 0) {
+ − 7912
if (xmlRefStack.top().isEmpty()) {
+ − 7913
xmlRefStack.pop_back();
+ − 7914
count--;
+ − 7915
} else {
+ − 7916
c = xmlRefStack.top().next();
+ − 7917
return;
+ − 7918
}
+ − 7919
}
+ − 7920
+ − 7921
// the following could be written nicer, but since it is a time-critical
+ − 7922
// function, rather optimize for speed
+ − 7923
ushort uc = c.unicode();
+ − 7924
c = inputSource->next();
+ − 7925
// If we are not incremental parsing, we just skip over EndOfData chars to give the
+ − 7926
// parser an uninterrupted stream of document chars.
+ − 7927
if (c == QXmlInputSource::EndOfData && parseStack == 0)
+ − 7928
c = inputSource->next();
+ − 7929
if (uc == '\n') {
+ − 7930
lineNr++;
+ − 7931
columnNr = -1;
+ − 7932
} else if (uc == '\r') {
+ − 7933
if (c != QLatin1Char('\n')) {
+ − 7934
lineNr++;
+ − 7935
columnNr = -1;
+ − 7936
}
+ − 7937
}
+ − 7938
++columnNr;
+ − 7939
}
+ − 7940
+ − 7941
/*
+ − 7942
This private function moves the cursor to the next non-whitespace character.
+ − 7943
This function does not move the cursor if the actual cursor position is a
+ − 7944
non-whitespace charcter.
+ − 7945
+ − 7946
Returns false when you use incremental parsing and this function reaches EOF
+ − 7947
with reading only whitespace characters. In this case it also poplulates the
+ − 7948
parseStack with useful information. In all other cases, this function returns
+ − 7949
true.
+ − 7950
*/
+ − 7951
bool QXmlSimpleReaderPrivate::eat_ws()
+ − 7952
{
+ − 7953
while (!atEnd()) {
+ − 7954
if (!is_S(c)) {
+ − 7955
return true;
+ − 7956
}
+ − 7957
next();
+ − 7958
}
+ − 7959
if (parseStack != 0) {
+ − 7960
unexpectedEof(&QXmlSimpleReaderPrivate::eat_ws, 0);
+ − 7961
return false;
+ − 7962
}
+ − 7963
return true;
+ − 7964
}
+ − 7965
+ − 7966
bool QXmlSimpleReaderPrivate::next_eat_ws()
+ − 7967
{
+ − 7968
next();
+ − 7969
return eat_ws();
+ − 7970
}
+ − 7971
+ − 7972
+ − 7973
/*
+ − 7974
This private function initializes the reader. \a i is the input source to
+ − 7975
read the data from.
+ − 7976
*/
+ − 7977
void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i)
+ − 7978
{
+ − 7979
lineNr = 0;
+ − 7980
columnNr = -1;
+ − 7981
inputSource = const_cast<QXmlInputSource *>(i);
+ − 7982
initData();
+ − 7983
+ − 7984
externParameterEntities.clear();
+ − 7985
parameterEntities.clear();
+ − 7986
externEntities.clear();
+ − 7987
entities.clear();
+ − 7988
+ − 7989
tags.clear();
+ − 7990
+ − 7991
doctype.clear();
+ − 7992
xmlVersion.clear();
+ − 7993
encoding.clear();
+ − 7994
standalone = QXmlSimpleReaderPrivate::Unknown;
+ − 7995
error.clear();
+ − 7996
}
+ − 7997
+ − 7998
/*
+ − 7999
This private function initializes the XML data related variables. Especially,
+ − 8000
it reads the data from the input source.
+ − 8001
*/
+ − 8002
void QXmlSimpleReaderPrivate::initData()
+ − 8003
{
+ − 8004
c = QXmlInputSource::EndOfData;
+ − 8005
xmlRefStack.clear();
+ − 8006
next();
+ − 8007
}
+ − 8008
+ − 8009
/*
+ − 8010
Returns true if a entity with the name \a e exists,
+ − 8011
otherwise returns false.
+ − 8012
*/
+ − 8013
bool QXmlSimpleReaderPrivate::entityExist(const QString& e) const
+ − 8014
{
+ − 8015
if ( parameterEntities.find(e) == parameterEntities.end() &&
+ − 8016
externParameterEntities.find(e) == externParameterEntities.end() &&
+ − 8017
externEntities.find(e) == externEntities.end() &&
+ − 8018
entities.find(e) == entities.end()) {
+ − 8019
return false;
+ − 8020
} else {
+ − 8021
return true;
+ − 8022
}
+ − 8023
}
+ − 8024
+ − 8025
void QXmlSimpleReaderPrivate::reportParseError(const QString& error)
+ − 8026
{
+ − 8027
this->error = error;
+ − 8028
if (errorHnd) {
+ − 8029
if (this->error.isNull()) {
+ − 8030
const QXmlParseException ex(QLatin1String(XMLERR_OK), columnNr+1, lineNr+1,
+ − 8031
thisPublicId, thisSystemId);
+ − 8032
errorHnd->fatalError(ex);
+ − 8033
} else {
+ − 8034
const QXmlParseException ex(this->error, columnNr+1, lineNr+1,
+ − 8035
thisPublicId, thisSystemId);
+ − 8036
errorHnd->fatalError(ex);
+ − 8037
}
+ − 8038
}
+ − 8039
}
+ − 8040
+ − 8041
/*
+ − 8042
This private function is called when a parsing function encounters an
+ − 8043
unexpected EOF. It decides what to do (depending on incremental parsing or
+ − 8044
not). \a where is a pointer to the function where the error occurred and \a
+ − 8045
state is the parsing state in this function.
+ − 8046
*/
+ − 8047
void QXmlSimpleReaderPrivate::unexpectedEof(ParseFunction where, int state)
+ − 8048
{
+ − 8049
if (parseStack == 0) {
+ − 8050
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
+ − 8051
} else {
+ − 8052
if (c == QXmlInputSource::EndOfDocument) {
+ − 8053
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
+ − 8054
} else {
+ − 8055
pushParseState(where, state);
+ − 8056
}
+ − 8057
}
+ − 8058
}
+ − 8059
+ − 8060
/*
+ − 8061
This private function is called when a parse...() function returned false. It
+ − 8062
determines if there was an error or if incremental parsing simply went out of
+ − 8063
data and does the right thing for the case. \a where is a pointer to the
+ − 8064
function where the error occurred and \a state is the parsing state in this
+ − 8065
function.
+ − 8066
*/
+ − 8067
void QXmlSimpleReaderPrivate::parseFailed(ParseFunction where, int state)
+ − 8068
{
+ − 8069
if (parseStack!=0 && error.isNull()) {
+ − 8070
pushParseState(where, state);
+ − 8071
}
+ − 8072
}
+ − 8073
+ − 8074
/*
+ − 8075
This private function pushes the function pointer \a function and state \a
+ − 8076
state to the parse stack. This is used when you are doing an incremental
+ − 8077
parsing and reach the end of file too early.
+ − 8078
+ − 8079
Only call this function when d->parseStack!=0.
+ − 8080
*/
+ − 8081
void QXmlSimpleReaderPrivate::pushParseState(ParseFunction function, int state)
+ − 8082
{
+ − 8083
QXmlSimpleReaderPrivate::ParseState ps;
+ − 8084
ps.function = function;
+ − 8085
ps.state = state;
+ − 8086
parseStack->push(ps);
+ − 8087
}
+ − 8088
+ − 8089
inline static void updateValue(QString &value, const QChar *array, int &arrayPos, int &valueLen)
+ − 8090
{
+ − 8091
value.resize(valueLen + arrayPos);
+ − 8092
memcpy(value.data() + valueLen, array, arrayPos * sizeof(QChar));
+ − 8093
valueLen += arrayPos;
+ − 8094
arrayPos = 0;
+ − 8095
}
+ − 8096
+ − 8097
// use buffers instead of QString::operator+= when single characters are read
+ − 8098
const QString& QXmlSimpleReaderPrivate::string()
+ − 8099
{
+ − 8100
updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
+ − 8101
return stringValue;
+ − 8102
}
+ − 8103
const QString& QXmlSimpleReaderPrivate::name()
+ − 8104
{
+ − 8105
updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
+ − 8106
return nameValue;
+ − 8107
}
+ − 8108
const QString& QXmlSimpleReaderPrivate::ref()
+ − 8109
{
+ − 8110
updateValue(refValue, refArray, refArrayPos, refValueLen);
+ − 8111
return refValue;
+ − 8112
}
+ − 8113
+ − 8114
void QXmlSimpleReaderPrivate::stringAddC(QChar ch)
+ − 8115
{
+ − 8116
if (stringArrayPos == 256)
+ − 8117
updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
+ − 8118
stringArray[stringArrayPos++] = ch;
+ − 8119
}
+ − 8120
void QXmlSimpleReaderPrivate::nameAddC(QChar ch)
+ − 8121
{
+ − 8122
if (nameArrayPos == 256)
+ − 8123
updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
+ − 8124
nameArray[nameArrayPos++] = ch;
+ − 8125
}
+ − 8126
void QXmlSimpleReaderPrivate::refAddC(QChar ch)
+ − 8127
{
+ − 8128
if (refArrayPos == 256)
+ − 8129
updateValue(refValue, refArray, refArrayPos, refValueLen);
+ − 8130
refArray[refArrayPos++] = ch;
+ − 8131
}
+ − 8132
QT_END_NAMESPACE