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