Qt 4.8
qxml.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qxml.h"
43 #include "qtextcodec.h"
44 #include "qbuffer.h"
45 #include "qregexp.h"
46 #include "qmap.h"
47 #include "qhash.h"
48 #include "qstack.h"
49 #include <qdebug.h>
50 
51 
52 #ifdef Q_CC_BOR // borland 6 finds bogus warnings when building this file in uic3
53 # pragma warn -8080
54 #endif
55 
56 //#define QT_QXML_DEBUG
57 
58 // Error strings for the XML reader
59 #define XMLERR_OK QT_TRANSLATE_NOOP("QXml", "no error occurred")
60 #define XMLERR_ERRORBYCONSUMER QT_TRANSLATE_NOOP("QXml", "error triggered by consumer")
61 #define XMLERR_UNEXPECTEDEOF QT_TRANSLATE_NOOP("QXml", "unexpected end of file")
62 #define XMLERR_MORETHANONEDOCTYPE QT_TRANSLATE_NOOP("QXml", "more than one document type definition")
63 #define XMLERR_ERRORPARSINGELEMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing element")
64 #define XMLERR_TAGMISMATCH QT_TRANSLATE_NOOP("QXml", "tag mismatch")
65 #define XMLERR_ERRORPARSINGCONTENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing content")
66 #define XMLERR_UNEXPECTEDCHARACTER QT_TRANSLATE_NOOP("QXml", "unexpected character")
67 #define XMLERR_INVALIDNAMEFORPI QT_TRANSLATE_NOOP("QXml", "invalid name for processing instruction")
68 #define XMLERR_VERSIONEXPECTED QT_TRANSLATE_NOOP("QXml", "version expected while reading the XML declaration")
69 #define XMLERR_WRONGVALUEFORSDECL QT_TRANSLATE_NOOP("QXml", "wrong value for standalone declaration")
70 #define XMLERR_EDECLORSDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "encoding declaration or standalone declaration expected while reading the XML declaration")
71 #define XMLERR_SDDECLEXPECTED QT_TRANSLATE_NOOP("QXml", "standalone declaration expected while reading the XML declaration")
72 #define XMLERR_ERRORPARSINGDOCTYPE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing document type definition")
73 #define XMLERR_LETTEREXPECTED QT_TRANSLATE_NOOP("QXml", "letter is expected")
74 #define XMLERR_ERRORPARSINGCOMMENT QT_TRANSLATE_NOOP("QXml", "error occurred while parsing comment")
75 #define XMLERR_ERRORPARSINGREFERENCE QT_TRANSLATE_NOOP("QXml", "error occurred while parsing reference")
76 #define XMLERR_INTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "internal general entity reference not allowed in DTD")
77 #define XMLERR_EXTERNALGENERALENTITYINAV QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in attribute value")
78 #define XMLERR_EXTERNALGENERALENTITYINDTD QT_TRANSLATE_NOOP("QXml", "external parsed general entity reference not allowed in DTD")
79 #define XMLERR_UNPARSEDENTITYREFERENCE QT_TRANSLATE_NOOP("QXml", "unparsed entity reference in wrong context")
80 #define XMLERR_RECURSIVEENTITIES QT_TRANSLATE_NOOP("QXml", "recursive entities")
81 #define XMLERR_ERRORINTEXTDECL QT_TRANSLATE_NOOP("QXml", "error in the text declaration of an external entity")
82 
84 
85 // the constants for the lookup table
86 static const signed char cltWS = 0; // white space
87 static const signed char cltPer = 1; // %
88 static const signed char cltAmp = 2; // &
89 static const signed char cltGt = 3; // >
90 static const signed char cltLt = 4; // <
91 static const signed char cltSlash = 5; // /
92 static const signed char cltQm = 6; // ?
93 static const signed char cltEm = 7; // !
94 static const signed char cltDash = 8; // -
95 static const signed char cltCB = 9; // ]
96 static const signed char cltOB = 10; // [
97 static const signed char cltEq = 11; // =
98 static const signed char cltDq = 12; // "
99 static const signed char cltSq = 13; // '
100 static const signed char cltUnknown = 14;
101 
102 // Hack for letting QDom know where the skipped entity occurred
103 // ### Qt5: the use of this variable means the code isn't reentrant.
105 
106 // character lookup table
107 static const signed char charLookupTable[256]={
109  cltUnknown, // 0x08
110  cltWS, // 0x09 \t
111  cltWS, // 0x0A \n
112  cltUnknown, // 0x0B
113  cltUnknown, // 0x0C
114  cltWS, // 0x0D \r
115  cltUnknown, // 0x0E
116  cltUnknown, // 0x0F
119  cltWS, // 0x20 Space
120  cltEm, // 0x21 !
121  cltDq, // 0x22 "
122  cltUnknown, // 0x23
123  cltUnknown, // 0x24
124  cltPer, // 0x25 %
125  cltAmp, // 0x26 &
126  cltSq, // 0x27 '
127  cltUnknown, // 0x28
128  cltUnknown, // 0x29
129  cltUnknown, // 0x2A
130  cltUnknown, // 0x2B
131  cltUnknown, // 0x2C
132  cltDash, // 0x2D -
133  cltUnknown, // 0x2E
134  cltSlash, // 0x2F /
136  cltUnknown, // 0x38
137  cltUnknown, // 0x39
138  cltUnknown, // 0x3A
139  cltUnknown, // 0x3B
140  cltLt, // 0x3C <
141  cltEq, // 0x3D =
142  cltGt, // 0x3E >
143  cltQm, // 0x3F ?
147  cltUnknown, // 0x58
148  cltUnknown, // 0x59
149  cltUnknown, // 0x5A
150  cltOB, // 0x5B [
151  cltUnknown, // 0x5C
152  cltCB, // 0x5D]
153  cltUnknown, // 0x5E
154  cltUnknown, // 0x5F
175 };
176 
177 //
178 // local helper functions
179 //
180 
181 /*
182  This function strips the TextDecl [77] ("<?xml ...?>") from the string \a
183  str. The stripped version is stored in \a str. If this function finds an
184  invalid TextDecl, it returns false, otherwise true.
185 
186  This function is used for external entities since those can include an
187  TextDecl that must be stripped before inserting the entity.
188 */
189 static bool stripTextDecl(QString& str)
190 {
191  QString textDeclStart(QLatin1String("<?xml"));
192  if (str.startsWith(textDeclStart)) {
193  QRegExp textDecl(QString::fromLatin1(
194  "^<\\?xml\\s+"
195  "(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
196  "\\s*"
197  "(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
198  "\\s*\\?>"
199  ));
200  QString strTmp = str.replace(textDecl, QLatin1String(""));
201  if (strTmp.length() != str.length())
202  return false; // external entity has wrong TextDecl
203  str = strTmp;
204  }
205  return true;
206 }
207 
208 
210 {
211 };
212 
213 /* \class QXmlInputSourcePrivate
214  \internal
215 
216  There's a slight misdesign in this class that can
217  be worth to keep in mind: the `str' member is
218  a buffer which QXmlInputSource::next() returns from,
219  and which is populated from the input device or input
220  stream. However, when the input is a QString(the user called
221  QXmlInputSource::setData()), `str' has two roles: it's the
222  buffer, but also the source. This /seems/ to be no problem
223  because in the case of having no device or stream, the QString
224  is read in one go.
225  */
227 {
228 public:
231 
233  const QChar *unicode;
234  int pos;
235  int length;
237 #ifndef QT_NO_TEXTCODEC
239 #endif
240 
244 };
246 {
247 public:
249  : column(-1), line(-1)
250  {
251  }
253  : msg(other.msg), column(other.column), line(other.line),
254  pub(other.pub), sys(other.sys)
255  {
256  }
257 
259  int column;
260  int line;
263 
264 };
265 
267 {
268 };
269 
271 {
272 };
273 
275 {
276 public:
278 private:
279  // functions
281  void initIncrementalParsing();
282 
283  // used to determine if elements are correctly nested
285 
286  // used by parseReference() and parsePEReference()
287  enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
288 
289  // used for entity declarations
291  {
294  : publicId(p), systemId(s) {}
297 
299  };
301  {
303  ExternEntity(const QString &p, const QString &s, const QString &n)
304  : publicId(p), systemId(s), notation(n) {}
309  };
314 
315  // used for parsing of entity references
316  struct XmlRef {
318  : index(0) {}
319  XmlRef(const QString &_name, const QString &_value)
320  : name(_name), value(_value), index(0) {}
321  bool isEmpty() const { return index == value.length(); }
322  QChar next() { return value.at(index++); }
325  int index;
326  };
328 
329  // used for standalone declaration
330  enum Standalone { Yes, No, Unknown };
331 
332  QString doctype; // only used for the doctype
333  QString xmlVersion; // only used to store the version information
334  QString encoding; // only used to store the encoding
335  Standalone standalone; // used to store the value of the standalone declaration
336 
337  QString publicId; // used by parseExternalID() to store the public ID
338  QString systemId; // used by parseExternalID() to store the system ID
339 
340  // Since publicId/systemId is used as temporary variables by parseExternalID(), it
341  // might overwrite the PUBLIC/SYSTEM for the document we're parsing. In effect, we would
342  // possibly send off an QXmlParseException that has the PUBLIC/SYSTEM of a entity declaration
343  // instead of those of the current document.
344  // Hence we have these two variables for storing the document's data.
347 
348  QString attDeclEName; // use by parseAttlistDecl()
349  QString attDeclAName; // use by parseAttlistDecl()
350 
351  // flags for some features support
356 
357  // used to build the attribute list
359 
360  // used in QXmlSimpleReader::parseContent() to decide whether character
361  // data was read
363 
364  // helper classes
367 
368  // error string
370 
371  // arguments for parse functions (this is needed to allow incremental
372  // parsing)
380 
381  // for incremental parsing
382  struct ParseState {
383  typedef bool (QXmlSimpleReaderPrivate::*ParseFunction)();
384  ParseFunction function;
385  int state;
386  };
388 
389  // used in parseProlog()
392 
393  // used in parseDoctype()
395 
396  // used in parseString()
397  signed char Done;
398 
399 
400  // variables
407 
409 
410  QChar c; // the character at reading position
411  int lineNr; // number of line
412  int columnNr; // position in line
413 
414  QChar nameArray[256]; // only used for names
415  QString nameValue; // only used for names
418  QChar refArray[256]; // only used for references
419  QString refValue; // only used for references
422  QChar stringArray[256]; // used for any other strings that are parsed
423  QString stringValue; // used for any other strings that are parsed
427 
429  // The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (int>) times.
432  // The limit to the amount of times the DTD parsing functions can be called
433  // for the DTD currently being parsed.
434  static const int dtdRecursionLimit = 2;
435  // The maximum amount of characters an entity value may contain, after expansion.
436  static const int entityCharacterLimit = 1024;
437 
438  const QString &string();
439  void stringClear();
440  void stringAddC(QChar);
441  inline void stringAddC() { stringAddC(c); }
442  const QString &name();
443  void nameClear();
444  void nameAddC(QChar);
445  inline void nameAddC() { nameAddC(c); }
446  const QString &ref();
447  void refClear();
448  void refAddC(QChar);
449  inline void refAddC() { refAddC(c); }
450 
451  // private functions
452  bool eat_ws();
453  bool next_eat_ws();
454 
455  void QT_FASTCALL next();
456  bool atEnd();
457 
458  void init(const QXmlInputSource* i);
459  void initData();
460 
461  bool entityExist(const QString&) const;
462 
463  bool parseBeginOrContinue(int state, bool incremental);
464 
465  bool parseProlog();
466  bool parseElement();
467  bool processElementEmptyTag();
468  bool processElementETagBegin2();
469  bool processElementAttribute();
470  bool parseMisc();
471  bool parseContent();
472 
473  bool parsePI();
474  bool parseDoctype();
475  bool parseComment();
476 
477  bool parseName();
478  bool parseNmtoken();
479  bool parseAttribute();
480  bool parseReference();
481  bool processReference();
482 
483  bool parseExternalID();
484  bool parsePEReference();
485  bool parseMarkupdecl();
486  bool parseAttlistDecl();
487  bool parseAttType();
488  bool parseAttValue();
489  bool parseElementDecl();
490  bool parseNotationDecl();
491  bool parseChoiceSeq();
492  bool parseEntityDecl();
493  bool parseEntityValue();
494 
495  bool parseString();
496 
497  bool insertXmlRef(const QString&, const QString&, bool);
498 
499  bool reportEndEntities();
500  void reportParseError(const QString& error);
501 
502  typedef bool (QXmlSimpleReaderPrivate::*ParseFunction) ();
503  void unexpectedEof(ParseFunction where, int state);
504  void parseFailed(ParseFunction where, int state);
505  void pushParseState(ParseFunction function, int state);
506  bool isExpandedEntityValueTooLarge(QString *errorMessage);
507 
510 
512 };
513 
573  const QString& p, const QString& s)
575 {
576  d->msg = name;
577  d->column = c;
578  d->line = l;
579  d->pub = p;
580  d->sys = s;
581 }
582 
587  d(new QXmlParseExceptionPrivate(*other.d))
588 {
589 
590 }
591 
596 {
597 }
598 
603 {
604  return d->msg;
605 }
610 {
611  return d->column;
612 }
617 {
618  return d->line;
619 }
624 {
625  return d->pub;
626 }
631 {
632  return d->sys;
633 }
634 
635 
659 {
660 }
661 
666 {
667 }
668 
690 {
691 public:
693  {
694  reader = parent;
695  }
697  {
698  }
699 
700  int columnNumber() const
701  {
702  return (reader->d_ptr->columnNr == -1 ? -1 : reader->d_ptr->columnNr + 1);
703  }
704  int lineNumber() const
705  {
706  return (reader->d_ptr->lineNr == -1 ? -1 : reader->d_ptr->lineNr + 1);
707  }
708 // QString getPublicId()
709 // QString getSystemId()
710 
711 private:
713 };
714 
715 /*********************************************
716  *
717  * QXmlNamespaceSupport
718  *
719  *********************************************/
720 
722 
724 {
725 public:
727  {
728  ns.insert(QLatin1String("xml"), QLatin1String("http://www.w3.org/XML/1998/namespace")); // the XML namespace
729  }
730 
732  {
733  }
734 
736  NamespaceMap ns;
737 };
738 
766 {
768 }
769 
774 {
775  delete d;
776 }
777 
790 void QXmlNamespaceSupport::setPrefix(const QString& pre, const QString& uri)
791 {
792  if(pre.isNull()) {
793  d->ns.insert(QLatin1String(""), uri);
794  } else {
795  d->ns.insert(pre, uri);
796  }
797 }
798 
810 {
811  NamespaceMap::const_iterator itc, it = d->ns.constBegin();
812  while ((itc=it) != d->ns.constEnd()) {
813  ++it;
814  if (*itc == uri && !itc.key().isEmpty())
815  return itc.key();
816  }
817  return QLatin1String("");
818 }
819 
826 {
827  return d->ns[prefix];
828 }
829 
837  QString& localname) const
838 {
839  int pos = qname.indexOf(QLatin1Char(':'));
840  if (pos == -1)
841  pos = qname.size();
842 
843  prefix = qname.left(pos);
844  localname = qname.mid(pos+1);
845 }
846 
865  bool isAttribute,
866  QString& nsuri, QString& localname) const
867 {
868  int len = qname.size();
869  const QChar *data = qname.constData();
870  for (int pos = 0; pos < len; ++pos) {
871  if (data[pos] == QLatin1Char(':')) {
872  nsuri = uri(qname.left(pos));
873  localname = qname.mid(pos + 1);
874  return;
875  }
876  }
877 
878  // there was no ':'
879  nsuri.clear();
880  // attributes don't take default namespace
881  if (!isAttribute && !d->ns.isEmpty()) {
882  /*
883  We want to access d->ns.value(""), but as an optimization
884  we use the fact that "" compares less than any other
885  string, so it's either first in the map or not there.
886  */
887  NamespaceMap::const_iterator first = d->ns.constBegin();
888  if (first.key().isEmpty())
889  nsuri = first.value(); // get default namespace
890  }
891  localname = qname;
892 }
893 
902 {
903  QStringList list;
904 
905  NamespaceMap::const_iterator itc, it = d->ns.constBegin();
906  while ((itc=it) != d->ns.constEnd()) {
907  ++it;
908  if (!itc.key().isEmpty())
909  list.append(itc.key());
910  }
911  return list;
912 }
913 
932 {
933  QStringList list;
934 
935  NamespaceMap::const_iterator itc, it = d->ns.constBegin();
936  while ((itc=it) != d->ns.constEnd()) {
937  ++it;
938  if (*itc == uri && !itc.key().isEmpty())
939  list.append(itc.key());
940  }
941  return list;
942 }
943 
955 {
956  d->nsStack.push(d->ns);
957 }
958 
969 {
970  d->ns.clear();
971  if(!d->nsStack.isEmpty())
972  d->ns = d->nsStack.pop();
973 }
974 
979 {
981  delete d;
982  d = newD;
983 }
984 
985 
986 
987 /*********************************************
988  *
989  * QXmlAttributes
990  *
991  *********************************************/
992 
1041 int QXmlAttributes::index(const QString& qName) const
1042 {
1043  for (int i = 0; i < attList.size(); ++i) {
1044  if (attList.at(i).qname == qName)
1045  return i;
1046  }
1047  return -1;
1048 }
1049 
1052 int QXmlAttributes::index(const QLatin1String& qName) const
1053 {
1054  for (int i = 0; i < attList.size(); ++i) {
1055  if (attList.at(i).qname == qName)
1056  return i;
1057  }
1058  return -1;
1059 }
1060 
1077 int QXmlAttributes::index(const QString& uri, const QString& localPart) const
1078 {
1079  for (int i = 0; i < attList.size(); ++i) {
1080  const Attribute &att = attList.at(i);
1081  if (att.uri == uri && att.localname == localPart)
1082  return i;
1083  }
1084  return -1;
1085 }
1086 
1093 {
1094  return attList.count();
1095 }
1096 
1115 {
1116  return attList.at(index).localname;
1117 }
1118 
1126 {
1127  return attList.at(index).qname;
1128 }
1129 
1138 {
1139  return attList.at(index).uri;
1140 }
1141 
1149 {
1150  return QLatin1String("CDATA");
1151 }
1152 
1164 {
1165  return QLatin1String("CDATA");
1166 }
1167 
1183 {
1184  return QLatin1String("CDATA");
1185 }
1186 
1193 {
1194  return attList.at(index).value;
1195 }
1196 
1209 {
1210  int i = index(qName);
1211  if (i == -1)
1212  return QString();
1213  return attList.at(i).value;
1214 }
1215 
1228 {
1229  int i = index(qName);
1230  if (i == -1)
1231  return QString();
1232  return attList.at(i).value;
1233 }
1234 
1247 QString QXmlAttributes::value(const QString& uri, const QString& localName) const
1248 {
1249  int i = index(uri, localName);
1250  if (i == -1)
1251  return QString();
1252  return attList.at(i).value;
1253 }
1254 
1261 {
1262  attList.clear();
1263 }
1264 
1273 void QXmlAttributes::append(const QString &qName, const QString &uri, const QString &localPart, const QString &value)
1274 {
1275  Attribute att;
1276  att.qname = qName;
1277  att.uri = uri;
1278  att.localname = localPart;
1279  att.value = value;
1280 
1281  attList.append(att);
1282 }
1283 
1284 
1285 /*********************************************
1286  *
1287  * QXmlInputSource
1288  *
1289  *********************************************/
1290 
1335 // the following two are guaranteed not to be a character
1336 const ushort QXmlInputSource::EndOfData = 0xfffe;
1337 const ushort QXmlInputSource::EndOfDocument = 0xffff;
1338 
1339 /*
1340  Common part of the constructors.
1341 */
1343 {
1344  d = new QXmlInputSourcePrivate;
1345 
1346  QT_TRY {
1347  d->inputDevice = 0;
1348  d->inputStream = 0;
1349 
1350  setData(QString());
1351 #ifndef QT_NO_TEXTCODEC
1352  d->encMapper = 0;
1353 #endif
1354  d->nextReturnedEndOfData = true; // first call to next() will call fetchData()
1355 
1356  d->encodingDeclBytes.clear();
1357  d->encodingDeclChars.clear();
1358  d->lookingForEncodingDecl = true;
1359  } QT_CATCH(...) {
1360  delete(d);
1361  QT_RETHROW;
1362  }
1363 }
1364 
1371 {
1372  init();
1373 }
1374 
1384 {
1385  init();
1386  d->inputDevice = dev;
1387  if (dev->isOpen())
1388  d->inputDevice->setTextModeEnabled(false);
1389 }
1390 
1391 #ifdef QT3_SUPPORT
1392 
1399 {
1400  init();
1401  d->inputStream = &stream;
1402 }
1403 
1408 {
1409  init();
1410  d->inputDevice = &file;
1411 }
1412 #endif
1413 
1418 {
1419  // ### Qt 5: close the input device. See task 153111
1420 #ifndef QT_NO_TEXTCODEC
1421  delete d->encMapper;
1422 #endif
1423  delete d;
1424 }
1425 
1445 {
1446  if (d->pos >= d->length) {
1447  if (d->nextReturnedEndOfData) {
1448  d->nextReturnedEndOfData = false;
1449  fetchData();
1450  if (d->pos >= d->length) {
1451  return EndOfDocument;
1452  }
1453  return next();
1454  }
1455  d->nextReturnedEndOfData = true;
1456  return EndOfData;
1457  }
1458 
1459  // QXmlInputSource has no way to signal encoding errors. The best we can do
1460  // is return EndOfDocument. We do *not* return EndOfData, because the reader
1461  // will then just call this function again to get the next char.
1462  QChar c = d->unicode[d->pos++];
1463  if (c.unicode() == EndOfData)
1464  c = EndOfDocument;
1465  return c;
1466 }
1467 
1480 {
1481  d->nextReturnedEndOfData = false;
1482  d->pos = 0;
1483 }
1484 
1492 {
1493  if (d->nextReturnedEndOfData) {
1494  QXmlInputSource *that = const_cast<QXmlInputSource*>(this);
1495  that->d->nextReturnedEndOfData = false;
1496  that->fetchData();
1497  }
1498  return d->str;
1499 }
1500 
1510 {
1511  d->str = dat;
1512  d->unicode = dat.unicode();
1513  d->pos = 0;
1514  d->length = d->str.length();
1515  d->nextReturnedEndOfData = false;
1516 }
1517 
1528 {
1529  setData(fromRawData(dat));
1530 }
1531 
1552 {
1553  enum
1554  {
1555  BufferSize = 1024
1556  };
1557 
1558  QByteArray rawData;
1559 
1560  if (d->inputDevice || d->inputStream) {
1561  QIODevice *device = d->inputDevice ? d->inputDevice : d->inputStream->device();
1562 
1563  if (!device) {
1564  if (d->inputStream && d->inputStream->string()) {
1565  QString *s = d->inputStream->string();
1566  rawData = QByteArray((const char *) s->constData(), s->size() * sizeof(QChar));
1567  }
1568  } else if (device->isOpen() || device->open(QIODevice::ReadOnly)) {
1569  rawData.resize(BufferSize);
1570  qint64 size = device->read(rawData.data(), BufferSize);
1571 
1572  if (size != -1) {
1573  // We don't want to give fromRawData() less than four bytes if we can avoid it.
1574  while (size < 4) {
1575  if (!device->waitForReadyRead(-1))
1576  break;
1577  int ret = device->read(rawData.data() + size, BufferSize - size);
1578  if (ret <= 0)
1579  break;
1580  size += ret;
1581  }
1582  }
1583 
1584  rawData.resize(qMax(qint64(0), size));
1585  }
1586 
1587  /* We do this inside the "if (d->inputDevice ..." scope
1588  * because if we're not using a stream or device, that is,
1589  * the user set a QString manually, we don't want to set
1590  * d->str. */
1591  setData(fromRawData(rawData));
1592  }
1593 }
1594 
1595 #ifndef QT_NO_TEXTCODEC
1596 static QString extractEncodingDecl(const QString &text, bool *needMoreText)
1597 {
1598  *needMoreText = false;
1599 
1600  int l = text.length();
1601  QString snip = QString::fromLatin1("<?xml").left(l);
1602  if (l > 0 && !text.startsWith(snip))
1603  return QString();
1604 
1605  int endPos = text.indexOf(QLatin1Char('>'));
1606  if (endPos == -1) {
1607  *needMoreText = l < 255; // we won't look forever
1608  return QString();
1609  }
1610 
1611  int pos = text.indexOf(QLatin1String("encoding"));
1612  if (pos == -1 || pos >= endPos)
1613  return QString();
1614 
1615  while (pos < endPos) {
1616  ushort uc = text.at(pos).unicode();
1617  if (uc == '\'' || uc == '"')
1618  break;
1619  ++pos;
1620  }
1621 
1622  if (pos == endPos)
1623  return QString();
1624 
1625  QString encoding;
1626  ++pos;
1627  while (pos < endPos) {
1628  ushort uc = text.at(pos).unicode();
1629  if (uc == '\'' || uc == '"')
1630  break;
1631  encoding.append(uc);
1632  ++pos;
1633  }
1634 
1635  return encoding;
1636 }
1637 #endif // QT_NO_TEXTCODEC
1638 
1651 {
1652 #ifdef QT_NO_TEXTCODEC
1653  Q_UNUSED(beginning);
1654  return QString::fromAscii(data.constData(), data.size());
1655 #else
1656  if (data.size() == 0)
1657  return QString();
1658  if (beginning) {
1659  delete d->encMapper;
1660  d->encMapper = 0;
1661  }
1662 
1663  int mib = 106; // UTF-8
1664 
1665  // This is the initial UTF codec we will read the encoding declaration with
1666  if (d->encMapper == 0) {
1667  d->encodingDeclBytes.clear();
1668  d->encodingDeclChars.clear();
1669  d->lookingForEncodingDecl = true;
1670 
1671  // look for byte order mark and read the first 5 characters
1672  if (data.size() >= 4) {
1673  uchar ch1 = data.at(0);
1674  uchar ch2 = data.at(1);
1675  uchar ch3 = data.at(2);
1676  uchar ch4 = data.at(3);
1677 
1678  if ((ch1 == 0 && ch2 == 0 && ch3 == 0xfe && ch4 == 0xff) ||
1679  (ch1 == 0xff && ch2 == 0xfe && ch3 == 0 && ch4 == 0))
1680  mib = 1017; // UTF-32 with byte order mark
1681  else if (ch1 == 0x3c && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x00)
1682  mib = 1019; // UTF-32LE
1683  else if (ch1 == 0x00 && ch2 == 0x00 && ch3 == 0x00 && ch4 == 0x3c)
1684  mib = 1018; // UTF-32BE
1685  }
1686  if (mib == 106 && data.size() >= 2) {
1687  uchar ch1 = data.at(0);
1688  uchar ch2 = data.at(1);
1689 
1690  if ((ch1 == 0xfe && ch2 == 0xff) || (ch1 == 0xff && ch2 == 0xfe))
1691  mib = 1015; // UTF-16 with byte order mark
1692  else if (ch1 == 0x3c && ch2 == 0x00)
1693  mib = 1014; // UTF-16LE
1694  else if (ch1 == 0x00 && ch2 == 0x3c)
1695  mib = 1013; // UTF-16BE
1696  }
1697 
1699  Q_ASSERT(codec);
1700 
1701  d->encMapper = codec->makeDecoder();
1702  }
1703 
1704  QString input = d->encMapper->toUnicode(data, data.size());
1705 
1706  if (d->lookingForEncodingDecl) {
1707  d->encodingDeclChars += input;
1708 
1709  bool needMoreText;
1710  QString encoding = extractEncodingDecl(d->encodingDeclChars, &needMoreText);
1711 
1712  if (!encoding.isEmpty()) {
1713  if (QTextCodec *codec = QTextCodec::codecForName(encoding.toLatin1())) {
1714  /* If the encoding is the same, we don't have to do toUnicode() all over again. */
1715  if(codec->mibEnum() != mib) {
1716  delete d->encMapper;
1717  d->encMapper = codec->makeDecoder();
1718 
1719  /* The variable input can potentially be large, so we deallocate
1720  * it before calling toUnicode() in order to avoid having two
1721  * large QStrings in memory simultaneously. */
1722  input.clear();
1723 
1724  // prime the decoder with the data so far
1725  d->encMapper->toUnicode(d->encodingDeclBytes, d->encodingDeclBytes.size());
1726  // now feed it the new data
1727  input = d->encMapper->toUnicode(data, data.size());
1728  }
1729  }
1730  }
1731 
1732  d->encodingDeclBytes += data;
1733  d->lookingForEncodingDecl = needMoreText;
1734  }
1735 
1736  return input;
1737 #endif
1738 }
1739 
1740 
1741 /*********************************************
1742  *
1743  * QXmlDefaultHandler
1744  *
1745  *********************************************/
1746 
2641 {
2642 }
2643 
2653 {
2654  return true;
2655 }
2656 
2666 {
2667  return true;
2668 }
2669 
2679 {
2680  return true;
2681 }
2682 
2692 {
2693  return true;
2694 }
2695 
2705  const QString&, const QXmlAttributes&)
2706 {
2707  return true;
2708 }
2709 
2719  const QString&)
2720 {
2721  return true;
2722 }
2723 
2733 {
2734  return true;
2735 }
2736 
2746 {
2747  return true;
2748 }
2749 
2759  const QString&)
2760 {
2761  return true;
2762 }
2763 
2773 {
2774  return true;
2775 }
2776 
2786 {
2787  return true;
2788 }
2789 
2799 {
2800  return true;
2801 }
2802 
2812 {
2813  return true;
2814 }
2815 
2825  const QString&)
2826 {
2827  return true;
2828 }
2829 
2839  const QString&, const QString&)
2840 {
2841  return true;
2842 }
2843 
2854  QXmlInputSource*& ret)
2855 {
2856  ret = 0;
2857  return true;
2858 }
2859 
2869 {
2871 }
2872 
2882 {
2883  return true;
2884 }
2885 
2895 {
2896  return true;
2897 }
2898 
2908 {
2909  return true;
2910 }
2911 
2921 {
2922  return true;
2923 }
2924 
2934 {
2935  return true;
2936 }
2937 
2947 {
2948  return true;
2949 }
2950 
2960 {
2961  return true;
2962 }
2963 
2972 bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QString&, const QString&, const QString&)
2973 {
2974  return true;
2975 }
2976 
2986 {
2987  return true;
2988 }
2989 
2999 {
3000  return true;
3001 }
3002 
3003 
3004 /*********************************************
3005  *
3006  * QXmlSimpleReaderPrivate
3007  *
3008  *********************************************/
3009 
3011 {
3012  return (c.unicode()|0x0001) == 0xffff;
3013 }
3014 
3016 {
3017  stringValueLen = 0; stringArrayPos = 0;
3018 }
3020 {
3021  nameValueLen = 0; nameArrayPos = 0;
3022 }
3023 
3025 {
3026  refValueLen = 0; refArrayPos = 0;
3027 }
3028 
3030 {
3031  q_ptr = reader;
3032  parseStack = 0;
3033 
3034  locator.reset(new QXmlSimpleReaderLocator(reader));
3035  entityRes = 0;
3036  dtdHnd = 0;
3037  contentHnd = 0;
3038  errorHnd = 0;
3039  lexicalHnd = 0;
3040  declHnd = 0;
3041 
3042  // default feature settings
3043  useNamespaces = true;
3044  useNamespacePrefixes = false;
3045  reportWhitespaceCharData = true;
3046  reportEntities = false;
3047 }
3048 
3050 {
3051  delete parseStack;
3052 }
3053 
3055 {
3056  if(parseStack)
3057  parseStack->clear();
3058  else
3059  parseStack = new QStack<ParseState>;
3060 }
3061 
3062 /*********************************************
3063  *
3064  * QXmlSimpleReader
3065  *
3066  *********************************************/
3067 
3380 static inline bool is_S(QChar ch)
3381 {
3382  ushort uc = ch.unicode();
3383  return (uc == ' ' || uc == '\t' || uc == '\n' || uc == '\r');
3384 }
3385 
3387 
3388 static const char Begi = (char)NameBeginning;
3389 static const char NtBg = (char)NameNotBeginning;
3390 static const char NotN = (char)NotName;
3391 
3392 static const char nameCharTable[128] =
3393 {
3394 // 0x00
3395  NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
3396  NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
3397 // 0x10
3398  NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
3399  NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
3400 // 0x20 (0x2D is '-', 0x2E is '.')
3401  NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
3402  NotN, NotN, NotN, NotN, NotN, NtBg, NtBg, NotN,
3403 // 0x30 (0x30..0x39 are '0'..'9', 0x3A is ':')
3404  NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg,
3405  NtBg, NtBg, Begi, NotN, NotN, NotN, NotN, NotN,
3406 // 0x40 (0x41..0x5A are 'A'..'Z')
3407  NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3408  Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3409 // 0x50 (0x5F is '_')
3410  Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3411  Begi, Begi, Begi, NotN, NotN, NotN, NotN, Begi,
3412 // 0x60 (0x61..0x7A are 'a'..'z')
3413  NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3414  Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3415 // 0x70
3416  Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
3417  Begi, Begi, Begi, NotN, NotN, NotN, NotN, NotN
3418 };
3419 
3421 {
3422  ushort uc = ch.unicode();
3423  if (!(uc & ~0x7f)) // uc < 128
3424  return (NameChar)nameCharTable[uc];
3425 
3426  QChar::Category cat = ch.category();
3427  // ### some these categories might be slightly wrong
3428  if ((cat >= QChar::Letter_Uppercase && cat <= QChar::Letter_Other)
3429  || cat == QChar::Number_Letter)
3430  return NameBeginning;
3431  if ((cat >= QChar::Number_DecimalDigit && cat <= QChar::Number_Other)
3432  || (cat >= QChar::Mark_NonSpacing && cat <= QChar::Mark_Enclosing))
3433  return NameNotBeginning;
3434  return NotName;
3435 }
3436 
3438 {
3439  return fastDetermineNameChar(ch);
3440 }
3441 
3447  : d_ptr(new QXmlSimpleReaderPrivate(this))
3448 {
3449 }
3450 
3455 {
3456 }
3457 
3461 bool QXmlSimpleReader::feature(const QString& name, bool *ok) const
3462 {
3463  const QXmlSimpleReaderPrivate *d = d_func();
3464 
3465  // Qt5 ###: Change these strings to qt.nokia.com
3466  if (ok != 0)
3467  *ok = true;
3468  if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
3469  return d->useNamespaces;
3470  } else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
3471  return d->useNamespacePrefixes;
3472  } else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData")) { // Shouldn't change in Qt 4
3473  return d->reportWhitespaceCharData;
3474  } else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
3475  return d->reportEntities;
3476  } else {
3477  qWarning("Unknown feature %s", name.toLatin1().data());
3478  if (ok != 0)
3479  *ok = false;
3480  }
3481  return false;
3482 }
3483 
3517 void QXmlSimpleReader::setFeature(const QString& name, bool enable)
3518 {
3520  // Qt5 ###: Change these strings to qt.nokia.com
3521  if (name == QLatin1String("http://xml.org/sax/features/namespaces")) {
3522  d->useNamespaces = enable;
3523  } else if (name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")) {
3524  d->useNamespacePrefixes = enable;
3525  } else if (name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData")) { // Shouldn't change in Qt 4
3526  d->reportWhitespaceCharData = enable;
3527  } else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
3528  d->reportEntities = enable;
3529  } else {
3530  qWarning("Unknown feature %s", name.toLatin1().data());
3531  }
3532 }
3533 
3536 bool QXmlSimpleReader::hasFeature(const QString& name) const
3537 {
3538  // Qt5 ###: Change these strings to qt.nokia.com
3539  if (name == QLatin1String("http://xml.org/sax/features/namespaces")
3540  || name == QLatin1String("http://xml.org/sax/features/namespace-prefixes")
3541  || name == QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData") // Shouldn't change in Qt 4
3542  || name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { // Shouldn't change in Qt 4
3543  return true;
3544  } else {
3545  return false;
3546  }
3547 }
3548 
3551 void* QXmlSimpleReader::property(const QString&, bool *ok) const
3552 {
3553  if (ok != 0)
3554  *ok = false;
3555  return 0;
3556 }
3557 
3561 {
3562 }
3563 
3568 {
3569  return false;
3570 }
3571 
3576 {
3578  d->entityRes = handler;
3579 }
3580 
3585 {
3586  const QXmlSimpleReaderPrivate *d = d_func();
3587  return d->entityRes;
3588 }
3589 
3594 {
3596  d->dtdHnd = handler;
3597 }
3598 
3603 {
3604  const QXmlSimpleReaderPrivate *d = d_func();
3605  return d->dtdHnd;
3606 }
3607 
3612 {
3614  d->contentHnd = handler;
3615 }
3616 
3621 {
3622  const QXmlSimpleReaderPrivate *d = d_func();
3623  return d->contentHnd;
3624 }
3625 
3630 {
3632  d->errorHnd = handler;
3633 }
3634 
3639 {
3640  const QXmlSimpleReaderPrivate *d = d_func();
3641  return d->errorHnd;
3642 }
3643 
3648 {
3650  d->lexicalHnd = handler;
3651 }
3652 
3657 {
3658  const QXmlSimpleReaderPrivate *d = d_func();
3659  return d->lexicalHnd;
3660 }
3661 
3666 {
3668  d->declHnd = handler;
3669 }
3670 
3675 {
3676  const QXmlSimpleReaderPrivate *d = d_func();
3677  return d->declHnd;
3678 }
3679 
3680 
3681 
3686 {
3687  return parse(&input, false);
3688 }
3689 
3695 {
3696  return parse(input, false);
3697 }
3698 
3724 bool QXmlSimpleReader::parse(const QXmlInputSource *input, bool incremental)
3725 {
3727 
3728  d->literalEntitySizes.clear();
3729  d->referencesToOtherEntities.clear();
3730  d->expandedSizes.clear();
3731 
3732  if (incremental) {
3733  d->initIncrementalParsing();
3734  } else {
3735  delete d->parseStack;
3736  d->parseStack = 0;
3737  }
3738  d->init(input);
3739 
3740  // call the handler
3741  if (d->contentHnd) {
3742  d->contentHnd->setDocumentLocator(d->locator.data());
3743  if (!d->contentHnd->startDocument()) {
3744  d->reportParseError(d->contentHnd->errorString());
3745  d->tags.clear();
3746  return false;
3747  }
3748  }
3750  return d->parseBeginOrContinue(0, incremental);
3751 }
3752 
3779 {
3781  if (d->parseStack == 0 || d->parseStack->isEmpty())
3782  return false;
3783  d->initData();
3784  int state = d->parseStack->pop().state;
3785  return d->parseBeginOrContinue(state, true);
3786 }
3787 
3788 /*
3789  Common part of parse() and parseContinue()
3790 */
3791 bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
3792 {
3793  bool atEndOrig = atEnd();
3794 
3795  if (state==0) {
3796  if (!parseProlog()) {
3797  if (incremental && error.isNull()) {
3798  pushParseState(0, 0);
3799  return true;
3800  } else {
3801  tags.clear();
3802  return false;
3803  }
3804  }
3805  state = 1;
3806  }
3807  if (state==1) {
3808  if (!parseElement()) {
3809  if (incremental && error.isNull()) {
3810  pushParseState(0, 1);
3811  return true;
3812  } else {
3813  tags.clear();
3814  return false;
3815  }
3816  }
3817  state = 2;
3818  }
3819  // parse Misc*
3820  while (!atEnd()) {
3821  if (!parseMisc()) {
3822  if (incremental && error.isNull()) {
3823  pushParseState(0, 2);
3824  return true;
3825  } else {
3826  tags.clear();
3827  return false;
3828  }
3829  }
3830  }
3831  if (!atEndOrig && incremental) {
3832  // we parsed something at all, so be prepared to come back later
3833  pushParseState(0, 2);
3834  return true;
3835  }
3836  // is stack empty?
3837  if (!tags.isEmpty() && !error.isNull()) {
3838  reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
3839  tags.clear();
3840  return false;
3841  }
3842  // call the handler
3843  if (contentHnd) {
3844  delete parseStack;
3845  parseStack = 0;
3846  if (!contentHnd->endDocument()) {
3847  reportParseError(contentHnd->errorString());
3848  return false;
3849  }
3850  }
3851  return true;
3852 }
3853 
3854 //
3855 // The following private parse functions have another semantics for the return
3856 // value: They return true iff parsing has finished successfully (i.e. the end
3857 // of the XML file must be reached!). If one of these functions return false,
3858 // there is only an error when d->error.isNULL() is also false.
3859 //
3860 
3861 /*
3862  For the incremental parsing, it is very important that the parse...()
3863  functions have a certain structure. Since it might be hard to understand how
3864  they work, here is a description of the layout of these functions:
3865 
3866  bool QXmlSimpleReader::parse...()
3867  {
3868 (1) const signed char Init = 0;
3869  ...
3870 
3871 (2) const signed char Inp... = 0;
3872  ...
3873 
3874 (3) static const signed char table[3][2] = {
3875  ...
3876  };
3877  signed char state;
3878  signed char input;
3879 
3880 (4) if (d->parseStack == 0 || d->parseStack->isEmpty()) {
3881 (4a) ...
3882  } else {
3883 (4b) ...
3884  }
3885 
3886  for (; ;) {
3887 (5) switch (state) {
3888  ...
3889  }
3890 
3891 (6)
3892 (6a) if (atEnd()) {
3893  unexpectedEof(&QXmlSimpleReader::parseNmtoken, state);
3894  return false;
3895  }
3896 (6b) if (determineNameChar(c) != NotName) {
3897  ...
3898  }
3899 (7) state = table[state][input];
3900 
3901 (8) switch (state) {
3902  ...
3903  }
3904  }
3905  }
3906 
3907  Explanation:
3908  ad 1: constants for the states (used in the transition table)
3909  ad 2: constants for the input (used in the transition table)
3910  ad 3: the transition table for the state machine
3911  ad 4: test if we are in a parseContinue() step
3912  a) if no, do inititalizations
3913  b) if yes, restore the state and call parse functions recursively
3914  ad 5: Do some actions according to the state; from the logical execution
3915  order, this code belongs after 8 (see there for an explanation)
3916  ad 6: Check the character that is at the actual "cursor" position:
3917  a) If we reached the EOF, report either error or push the state (in the
3918  case of incremental parsing).
3919  b) Otherwise, set the input character constant for the transition
3920  table.
3921  ad 7: Get the new state according to the input that was read.
3922  ad 8: Do some actions according to the state. The last line in every case
3923  statement reads new data (i.e. it move the cursor). This can also be
3924  done by calling another parse...() function. If you need processing for
3925  this state after that, you have to put it into the switch statement 5.
3926  This ensures that you have a well defined re-entry point, when you ran
3927  out of data.
3928 */
3929 
3930 /*
3931  Parses the prolog [22].
3932 */
3933 
3935 {
3936  const signed char Init = 0;
3937  const signed char EatWS = 1; // eat white spaces
3938  const signed char Lt = 2; // '<' read
3939  const signed char Em = 3; // '!' read
3940  const signed char DocType = 4; // read doctype
3941  const signed char Comment = 5; // read comment
3942  const signed char CommentR = 6; // same as Comment, but already reported
3943  const signed char PInstr = 7; // read PI
3944  const signed char PInstrR = 8; // same as PInstr, but already reported
3945  const signed char Done = 9;
3946 
3947  const signed char InpWs = 0;
3948  const signed char InpLt = 1; // <
3949  const signed char InpQm = 2; // ?
3950  const signed char InpEm = 3; // !
3951  const signed char InpD = 4; // D
3952  const signed char InpDash = 5; // -
3953  const signed char InpUnknown = 6;
3954 
3955  static const signed char table[9][7] = {
3956  /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
3957  { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
3958  { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
3959  { -1, -1, PInstr,Em, Done, -1, Done }, // Lt
3960  { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
3961  { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
3962  { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
3963  { EatWS, Lt, -1, -1, -1, -1, -1 }, // CommentR
3964  { EatWS, Lt, -1, -1, -1, -1, -1 }, // PInstr
3965  { EatWS, Lt, -1, -1, -1, -1, -1 } // PInstrR
3966  };
3967  signed char state;
3968  signed char input;
3969 
3970  if (parseStack == 0 || parseStack->isEmpty()) {
3971  xmldecl_possible = true;
3972  doctype_read = false;
3973  state = Init;
3974  } else {
3975  state = parseStack->pop().state;
3976 #if defined(QT_QXML_DEBUG)
3977  qDebug("QXmlSimpleReader: parseProlog (cont) in state %d", state);
3978 #endif
3979  if (!parseStack->isEmpty()) {
3980  ParseFunction function = parseStack->top().function;
3981  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
3982  parseStack->pop();
3983 #if defined(QT_QXML_DEBUG)
3984  qDebug("QXmlSimpleReader: eat_ws (cont)");
3985 #endif
3986  }
3987  if (!(this->*function)()) {
3988  parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
3989  return false;
3990  }
3991  }
3992  }
3993 
3994  for (;;) {
3995  switch (state) {
3996  case DocType:
3997  if (doctype_read) {
3998  reportParseError(QLatin1String(XMLERR_MORETHANONEDOCTYPE));
3999  return false;
4000  } else {
4001  doctype_read = false;
4002  }
4003  break;
4004  case Comment:
4005  if (lexicalHnd) {
4006  if (!lexicalHnd->comment(string())) {
4007  reportParseError(lexicalHnd->errorString());
4008  return false;
4009  }
4010  }
4011  state = CommentR;
4012  break;
4013  case PInstr:
4014  // call the handler
4015  if (contentHnd) {
4016  if (xmldecl_possible && !xmlVersion.isEmpty()) {
4017  QString value(QLatin1String("version='"));
4018  value += xmlVersion;
4019  value += QLatin1Char('\'');
4020  if (!encoding.isEmpty()) {
4021  value += QLatin1String(" encoding='");
4022  value += encoding;
4023  value += QLatin1Char('\'');
4024  }
4025  if (standalone == QXmlSimpleReaderPrivate::Yes) {
4026  value += QLatin1String(" standalone='yes'");
4027  } else if (standalone == QXmlSimpleReaderPrivate::No) {
4028  value += QLatin1String(" standalone='no'");
4029  }
4030  if (!contentHnd->processingInstruction(QLatin1String("xml"), value)) {
4031  reportParseError(contentHnd->errorString());
4032  return false;
4033  }
4034  } else {
4035  if (!contentHnd->processingInstruction(name(), string())) {
4036  reportParseError(contentHnd->errorString());
4037  return false;
4038  }
4039  }
4040  }
4041  // XML declaration only on first position possible
4042  xmldecl_possible = false;
4043  state = PInstrR;
4044  break;
4045  case Done:
4046  return true;
4047  case -1:
4048  reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
4049  return false;
4050  }
4051 
4052  if (atEnd()) {
4053  unexpectedEof(&QXmlSimpleReaderPrivate::parseProlog, state);
4054  return false;
4055  }
4056  if (is_S(c)) {
4057  input = InpWs;
4058  } else if (c == QLatin1Char('<')) {
4059  input = InpLt;
4060  } else if (c == QLatin1Char('?')) {
4061  input = InpQm;
4062  } else if (c == QLatin1Char('!')) {
4063  input = InpEm;
4064  } else if (c == QLatin1Char('D')) {
4065  input = InpD;
4066  } else if (c == QLatin1Char('-')) {
4067  input = InpDash;
4068  } else {
4069  input = InpUnknown;
4070  }
4071  state = table[state][input];
4072 
4073  switch (state) {
4074  case EatWS:
4075  // XML declaration only on first position possible
4076  xmldecl_possible = false;
4077  if (!eat_ws()) {
4078  parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
4079  return false;
4080  }
4081  break;
4082  case Lt:
4083  next();
4084  break;
4085  case Em:
4086  // XML declaration only on first position possible
4087  xmldecl_possible = false;
4088  next();
4089  break;
4090  case DocType:
4091  if (!parseDoctype()) {
4092  parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
4093  return false;
4094  }
4095  break;
4096  case Comment:
4097  case CommentR:
4098  if (!parseComment()) {
4099  parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
4100  return false;
4101  }
4102  break;
4103  case PInstr:
4104  case PInstrR:
4105  parsePI_xmldecl = xmldecl_possible;
4106  if (!parsePI()) {
4107  parseFailed(&QXmlSimpleReaderPrivate::parseProlog, state);
4108  return false;
4109  }
4110  break;
4111  }
4112  }
4113  return false;
4114 }
4115 
4116 /*
4117  Parse an element [39].
4118 
4119  Precondition: the opening '<' is already read.
4120 */
4122 {
4123  const int Init = 0;
4124  const int ReadName = 1;
4125  const int Ws1 = 2;
4126  const int STagEnd = 3;
4127  const int STagEnd2 = 4;
4128  const int ETagBegin = 5;
4129  const int ETagBegin2 = 6;
4130  const int Ws2 = 7;
4131  const int EmptyTag = 8;
4132  const int Attrib = 9;
4133  const int AttribPro = 10; // like Attrib, but processAttribute was already called
4134  const int Ws3 = 11;
4135  const int Done = 12;
4136 
4137  const int InpWs = 0; // whitespace
4138  const int InpNameBe = 1; // NameBeginning
4139  const int InpGt = 2; // >
4140  const int InpSlash = 3; // /
4141  const int InpUnknown = 4;
4142 
4143  static const int table[12][5] = {
4144  /* InpWs InpNameBe InpGt InpSlash InpUnknown */
4145  { -1, ReadName, -1, -1, -1 }, // Init
4146  { Ws1, Attrib, STagEnd, EmptyTag, -1 }, // ReadName
4147  { -1, Attrib, STagEnd, EmptyTag, -1 }, // Ws1
4148  { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
4149  { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
4150  { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
4151  { Ws2, -1, Done, -1, -1 }, // ETagBegin2
4152  { -1, -1, Done, -1, -1 }, // Ws2
4153  { -1, -1, Done, -1, -1 }, // EmptyTag
4154  { Ws3, Attrib, STagEnd, EmptyTag, -1 }, // Attrib
4155  { Ws3, Attrib, STagEnd, EmptyTag, -1 }, // AttribPro
4156  { -1, Attrib, STagEnd, EmptyTag, -1 } // Ws3
4157  };
4158  int state;
4159  int input;
4160 
4161  if (parseStack == 0 || parseStack->isEmpty()) {
4162  state = Init;
4163  } else {
4164  state = parseStack->pop().state;
4165 #if defined(QT_QXML_DEBUG)
4166  qDebug("QXmlSimpleReader: parseElement (cont) in state %d", state);
4167 #endif
4168  if (!parseStack->isEmpty()) {
4169  ParseFunction function = parseStack->top().function;
4170  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
4171  parseStack->pop();
4172 #if defined(QT_QXML_DEBUG)
4173  qDebug("QXmlSimpleReader: eat_ws (cont)");
4174 #endif
4175  }
4176  if (!(this->*function)()) {
4177  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4178  return false;
4179  }
4180  }
4181  }
4182 
4183  for (;;) {
4184  switch (state) {
4185  case ReadName:
4186  // store it on the stack
4187  tags.push(name());
4188  // empty the attributes
4189  attList.clear();
4190  if (useNamespaces)
4191  namespaceSupport.pushContext();
4192  break;
4193  case ETagBegin2:
4194  if (!processElementETagBegin2())
4195  return false;
4196  break;
4197  case Attrib:
4198  if (!processElementAttribute())
4199  return false;
4200  state = AttribPro;
4201  break;
4202  case Done:
4203  return true;
4204  case -1:
4205  reportParseError(QLatin1String(XMLERR_ERRORPARSINGELEMENT));
4206  return false;
4207  }
4208 
4209  if (atEnd()) {
4210  unexpectedEof(&QXmlSimpleReaderPrivate::parseElement, state);
4211  return false;
4212  }
4214  input = InpNameBe;
4215  } else if (c == QLatin1Char('>')) {
4216  input = InpGt;
4217  } else if (is_S(c)) {
4218  input = InpWs;
4219  } else if (c == QLatin1Char('/')) {
4220  input = InpSlash;
4221  } else {
4222  input = InpUnknown;
4223  }
4224  state = table[state][input];
4225 
4226  switch (state) {
4227  case ReadName:
4228  parseName_useRef = false;
4229  if (!parseName()) {
4230  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4231  return false;
4232  }
4233  break;
4234  case Ws1:
4235  case Ws2:
4236  case Ws3:
4237  if (!eat_ws()) {
4238  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4239  return false;
4240  }
4241  break;
4242  case STagEnd:
4243  // call the handler
4244  if (contentHnd) {
4245  const QString &tagsTop = tags.top();
4246  if (useNamespaces) {
4247  QString uri, lname;
4248  namespaceSupport.processName(tagsTop, false, uri, lname);
4249  if (!contentHnd->startElement(uri, lname, tagsTop, attList)) {
4250  reportParseError(contentHnd->errorString());
4251  return false;
4252  }
4253  } else {
4254  if (!contentHnd->startElement(QString(), QString(), tagsTop, attList)) {
4255  reportParseError(contentHnd->errorString());
4256  return false;
4257  }
4258  }
4259  }
4260  next();
4261  break;
4262  case STagEnd2:
4263  if (!parseContent()) {
4264  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4265  return false;
4266  }
4267  break;
4268  case ETagBegin:
4269  next();
4270  break;
4271  case ETagBegin2:
4272  // get the name of the tag
4273  parseName_useRef = false;
4274  if (!parseName()) {
4275  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4276  return false;
4277  }
4278  break;
4279  case EmptyTag:
4280  if (tags.isEmpty()) {
4281  reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
4282  return false;
4283  }
4284  if (!processElementEmptyTag())
4285  return false;
4286  next();
4287  break;
4288  case Attrib:
4289  case AttribPro:
4290  // get name and value of attribute
4291  if (!parseAttribute()) {
4292  parseFailed(&QXmlSimpleReaderPrivate::parseElement, state);
4293  return false;
4294  }
4295  break;
4296  case Done:
4297  next();
4298  break;
4299  }
4300  }
4301  return false;
4302 }
4303 
4304 /*
4305  Helper to break down the size of the code in the case statement.
4306  Return false on error, otherwise true.
4307 */
4309 {
4310  QString uri, lname;
4311  // pop the stack and call the handler
4312  if (contentHnd) {
4313  if (useNamespaces) {
4314  // report startElement first...
4315  namespaceSupport.processName(tags.top(), false, uri, lname);
4316  if (!contentHnd->startElement(uri, lname, tags.top(), attList)) {
4317  reportParseError(contentHnd->errorString());
4318  return false;
4319  }
4320  // ... followed by endElement...
4321  if (!contentHnd->endElement(uri, lname, tags.pop())) {
4322  reportParseError(contentHnd->errorString());
4323  return false;
4324  }
4325  // ... followed by endPrefixMapping
4326  QStringList prefixesBefore, prefixesAfter;
4327  if (contentHnd) {
4328  prefixesBefore = namespaceSupport.prefixes();
4329  }
4330  namespaceSupport.popContext();
4331  // call the handler for prefix mapping
4332  prefixesAfter = namespaceSupport.prefixes();
4333  for (QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it) {
4334  if (!prefixesAfter.contains(*it)) {
4335  if (!contentHnd->endPrefixMapping(*it)) {
4336  reportParseError(contentHnd->errorString());
4337  return false;
4338  }
4339  }
4340  }
4341  } else {
4342  // report startElement first...
4343  if (!contentHnd->startElement(QString(), QString(), tags.top(), attList)) {
4344  reportParseError(contentHnd->errorString());
4345  return false;
4346  }
4347  // ... followed by endElement
4348  if (!contentHnd->endElement(QString(), QString(), tags.pop())) {
4349  reportParseError(contentHnd->errorString());
4350  return false;
4351  }
4352  }
4353  } else {
4354  tags.pop_back();
4355  namespaceSupport.popContext();
4356  }
4357  return true;
4358 }
4359 /*
4360  Helper to break down the size of the code in the case statement.
4361  Return false on error, otherwise true.
4362 */
4364 {
4365  const QString &name = QXmlSimpleReaderPrivate::name();
4366 
4367  // pop the stack and compare it with the name
4368  if (tags.pop() != name) {
4369  reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
4370  return false;
4371  }
4372  // call the handler
4373  if (contentHnd) {
4374  QString uri, lname;
4375 
4376  if (useNamespaces)
4377  namespaceSupport.processName(name, false, uri, lname);
4378  if (!contentHnd->endElement(uri, lname, name)) {
4379  reportParseError(contentHnd->errorString());
4380  return false;
4381  }
4382  }
4383  if (useNamespaces) {
4384  NamespaceMap prefixesBefore, prefixesAfter;
4385  if (contentHnd)
4386  prefixesBefore = namespaceSupport.d->ns;
4387 
4388  namespaceSupport.popContext();
4389  // call the handler for prefix mapping
4390  if (contentHnd) {
4391  prefixesAfter = namespaceSupport.d->ns;
4392  if (prefixesBefore.size() != prefixesAfter.size()) {
4393  for (NamespaceMap::const_iterator it = prefixesBefore.constBegin(); it != prefixesBefore.constEnd(); ++it) {
4394  if (!it.key().isEmpty() && !prefixesAfter.contains(it.key())) {
4395  if (!contentHnd->endPrefixMapping(it.key())) {
4396  reportParseError(contentHnd->errorString());
4397  return false;
4398  }
4399  }
4400  }
4401  }
4402  }
4403  }
4404  return true;
4405 }
4406 /*
4407  Helper to break down the size of the code in the case statement.
4408  Return false on error, otherwise true.
4409 */
4411 {
4412  QString uri, lname, prefix;
4413  const QString &name = QXmlSimpleReaderPrivate::name();
4414  const QString &string = QXmlSimpleReaderPrivate::string();
4415 
4416  // add the attribute to the list
4417  if (useNamespaces) {
4418  // is it a namespace declaration?
4419  namespaceSupport.splitName(name, prefix, lname);
4420  if (prefix == QLatin1String("xmlns")) {
4421  // namespace declaration
4422  namespaceSupport.setPrefix(lname, string);
4423  if (useNamespacePrefixes) {
4424  // according to http://www.w3.org/2000/xmlns/, the "prefix"
4425  // xmlns maps to the namespace name
4426  // http://www.w3.org/2000/xmlns/
4427  attList.append(name, QLatin1String("http://www.w3.org/2000/xmlns/"), lname, string);
4428  }
4429  // call the handler for prefix mapping
4430  if (contentHnd) {
4431  if (!contentHnd->startPrefixMapping(lname, string)) {
4432  reportParseError(contentHnd->errorString());
4433  return false;
4434  }
4435  }
4436  } else {
4437  // no namespace delcaration
4438  namespaceSupport.processName(name, true, uri, lname);
4439  attList.append(name, uri, lname, string);
4440  }
4441  } else {
4442  // no namespace support
4443  attList.append(name, uri, lname, string);
4444  }
4445  return true;
4446 }
4447 
4448 /*
4449  Parse a content [43].
4450 
4451  A content is only used between tags. If a end tag is found the < is already
4452  read and the head stand on the '/' of the end tag '</name>'.
4453 */
4455 {
4456  const signed char Init = 0;
4457  const signed char ChD = 1; // CharData
4458  const signed char ChD1 = 2; // CharData help state
4459  const signed char ChD2 = 3; // CharData help state
4460  const signed char Ref = 4; // Reference
4461  const signed char Lt = 5; // '<' read
4462  const signed char PInstr = 6; // PI
4463  const signed char PInstrR = 7; // same as PInstr, but already reported
4464  const signed char Elem = 8; // Element
4465  const signed char Em = 9; // '!' read
4466  const signed char Com = 10; // Comment
4467  const signed char ComR = 11; // same as Com, but already reported
4468  const signed char CDS = 12; // CDSect
4469  const signed char CDS1 = 13; // read a CDSect
4470  const signed char CDS2 = 14; // read a CDSect (help state)
4471  const signed char CDS3 = 15; // read a CDSect (help state)
4472  const signed char Done = 16; // finished reading content
4473 
4474  const signed char InpLt = 0; // <
4475  const signed char InpGt = 1; // >
4476  const signed char InpSlash = 2; // /
4477  const signed char InpQMark = 3; // ?
4478  const signed char InpEMark = 4; // !
4479  const signed char InpAmp = 5; // &
4480  const signed char InpDash = 6; // -
4481  const signed char InpOpenB = 7; // [
4482  const signed char InpCloseB = 8; //]
4483  const signed char InpUnknown = 9;
4484 
4485  static const signed char mapCLT2FSMChar[] = {
4486  InpUnknown, // white space
4487  InpUnknown, // %
4488  InpAmp, // &
4489  InpGt, // >
4490  InpLt, // <
4491  InpSlash, // /
4492  InpQMark, // ?
4493  InpEMark, // !
4494  InpDash, // -
4495  InpCloseB, //]
4496  InpOpenB, // [
4497  InpUnknown, // =
4498  InpUnknown, // "
4499  InpUnknown, // '
4500  InpUnknown // unknown
4501  };
4502 
4503  static const signed char table[16][10] = {
4504  /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
4505  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
4506  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
4507  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
4508  { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
4509  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
4510  { -1, -1, Done, PInstr, Em, -1, -1, -1, -1, Elem }, // Lt
4511  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstr (same as Init)
4512  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstrR
4513  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
4514  { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
4515  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
4516  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // ComR
4517  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
4518  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
4519  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
4520  { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
4521  };
4522  signed char state;
4523  signed char input;
4524 
4525  if (parseStack == 0 || parseStack->isEmpty()) {
4526  contentCharDataRead = false;
4527  state = Init;
4528  } else {
4529  state = parseStack->pop().state;
4530 #if defined(QT_QXML_DEBUG)
4531  qDebug("QXmlSimpleReader: parseContent (cont) in state %d", state);
4532 #endif
4533  if (!parseStack->isEmpty()) {
4534  ParseFunction function = parseStack->top().function;
4535  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
4536  parseStack->pop();
4537 #if defined(QT_QXML_DEBUG)
4538  qDebug("QXmlSimpleReader: eat_ws (cont)");
4539 #endif
4540  }
4541  if (!(this->*function)()) {
4542  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4543  return false;
4544  }
4545  }
4546  }
4547 
4548  for (;;) {
4549  switch (state) {
4550  case Ref:
4551  if (!contentCharDataRead)
4552  contentCharDataRead = parseReference_charDataRead;
4553  break;
4554  case PInstr:
4555  if (contentHnd) {
4556  if (!contentHnd->processingInstruction(name(),string())) {
4557  reportParseError(contentHnd->errorString());
4558  return false;
4559  }
4560  }
4561  state = PInstrR;
4562  break;
4563  case Com:
4564  if (lexicalHnd) {
4565  if (!lexicalHnd->comment(string())) {
4566  reportParseError(lexicalHnd->errorString());
4567  return false;
4568  }
4569  }
4570  state = ComR;
4571  break;
4572  case CDS:
4573  stringClear();
4574  break;
4575  case CDS2:
4576  if (!atEnd() && c != QLatin1Char(']'))
4577  stringAddC(QLatin1Char(']'));
4578  break;
4579  case CDS3:
4580  // test if this skipping was legal
4581  if (!atEnd()) {
4582  if (c == QLatin1Char('>')) {
4583  // the end of the CDSect
4584  if (lexicalHnd) {
4585  if (!lexicalHnd->startCDATA()) {
4586  reportParseError(lexicalHnd->errorString());
4587  return false;
4588  }
4589  }
4590  if (contentHnd) {
4591  if (!contentHnd->characters(string())) {
4592  reportParseError(contentHnd->errorString());
4593  return false;
4594  }
4595  }
4596  if (lexicalHnd) {
4597  if (!lexicalHnd->endCDATA()) {
4598  reportParseError(lexicalHnd->errorString());
4599  return false;
4600  }
4601  }
4602  } else if (c == QLatin1Char(']')) {
4603  // three or more ']'
4604  stringAddC(QLatin1Char(']'));
4605  } else {
4606  // after ']]' comes another character
4607  stringAddC(QLatin1Char(']'));
4608  stringAddC(QLatin1Char(']'));
4609  }
4610  }
4611  break;
4612  case Done:
4613  // call the handler for CharData
4614  if (contentHnd) {
4615  if (contentCharDataRead) {
4616  if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
4617  if (!contentHnd->characters(string())) {
4618  reportParseError(contentHnd->errorString());
4619  return false;
4620  }
4621  }
4622  }
4623  }
4624  // Done
4625  return true;
4626  case -1:
4627  // Error
4628  reportParseError(QLatin1String(XMLERR_ERRORPARSINGCONTENT));
4629  return false;
4630  }
4631 
4632  // get input (use lookup-table instead of nested ifs for performance
4633  // reasons)
4634  if (atEnd()) {
4635  unexpectedEof(&QXmlSimpleReaderPrivate::parseContent, state);
4636  return false;
4637  }
4638  if (c.row()) {
4639  input = InpUnknown;
4640  } else {
4641  input = mapCLT2FSMChar[charLookupTable[c.cell()]];
4642  }
4643  state = table[state][input];
4644 
4645  switch (state) {
4646  case Init:
4647  // skip the ending '>' of a CDATASection
4648  next();
4649  break;
4650  case ChD:
4651  // on first call: clear string
4652  if (!contentCharDataRead) {
4653  contentCharDataRead = true;
4654  stringClear();
4655  }
4656  stringAddC();
4657  if (reportEntities) {
4658  if (!reportEndEntities())
4659  return false;
4660  }
4661  next();
4662  break;
4663  case ChD1:
4664  // on first call: clear string
4665  if (!contentCharDataRead) {
4666  contentCharDataRead = true;
4667  stringClear();
4668  }
4669  stringAddC();
4670  if (reportEntities) {
4671  if (!reportEndEntities())
4672  return false;
4673  }
4674  next();
4675  break;
4676  case ChD2:
4677  stringAddC();
4678  if (reportEntities) {
4679  if (!reportEndEntities())
4680  return false;
4681  }
4682  next();
4683  break;
4684  case Ref:
4685  if (!contentCharDataRead) {
4686  // reference may be CharData; so clear string to be safe
4687  stringClear();
4688  parseReference_context = InContent;
4689  if (!parseReference()) {
4690  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4691  return false;
4692  }
4693  } else {
4694  if (reportEntities) {
4695  // report character data in chunks
4696  if (contentHnd) {
4697  if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
4698  if (!contentHnd->characters(string())) {
4699  reportParseError(contentHnd->errorString());
4700  return false;
4701  }
4702  }
4703  }
4704  stringClear();
4705  }
4706  parseReference_context = InContent;
4707  if (!parseReference()) {
4708  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4709  return false;
4710  }
4711  }
4712  break;
4713  case Lt:
4714  // call the handler for CharData
4715  if (contentHnd) {
4716  if (contentCharDataRead) {
4717  if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
4718  if (!contentHnd->characters(string())) {
4719  reportParseError(contentHnd->errorString());
4720  return false;
4721  }
4722  }
4723  }
4724  }
4725  contentCharDataRead = false;
4726  next();
4727  break;
4728  case PInstr:
4729  case PInstrR:
4730  parsePI_xmldecl = false;
4731  if (!parsePI()) {
4732  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4733  return false;
4734  }
4735  break;
4736  case Elem:
4737  if (!parseElement()) {
4738  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4739  return false;
4740  }
4741  break;
4742  case Em:
4743  next();
4744  break;
4745  case Com:
4746  case ComR:
4747  if (!parseComment()) {
4748  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4749  return false;
4750  }
4751  break;
4752  case CDS:
4753  parseString_s = QLatin1String("[CDATA[");
4754  if (!parseString()) {
4755  parseFailed(&QXmlSimpleReaderPrivate::parseContent, state);
4756  return false;
4757  }
4758  break;
4759  case CDS1:
4760  stringAddC();
4761  next();
4762  break;
4763  case CDS2:
4764  // skip ']'
4765  next();
4766  break;
4767  case CDS3:
4768  // skip ']'...
4769  next();
4770  break;
4771  }
4772  }
4773  return false;
4774 }
4775 
4777 {
4778  int count = (int)xmlRefStack.count();
4779  while (count != 0 && xmlRefStack.top().isEmpty()) {
4780  if (contentHnd) {
4781  if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
4782  if (!contentHnd->characters(string())) {
4783  reportParseError(contentHnd->errorString());
4784  return false;
4785  }
4786  }
4787  }
4788  stringClear();
4789  if (lexicalHnd) {
4790  if (!lexicalHnd->endEntity(xmlRefStack.top().name)) {
4791  reportParseError(lexicalHnd->errorString());
4792  return false;
4793  }
4794  }
4795  xmlRefStack.pop_back();
4796  count--;
4797  }
4798  return true;
4799 }
4800 
4801 /*
4802  Parse Misc [27].
4803 */
4805 {
4806  const signed char Init = 0;
4807  const signed char Lt = 1; // '<' was read
4808  const signed char Comment = 2; // read comment
4809  const signed char eatWS = 3; // eat whitespaces
4810  const signed char PInstr = 4; // read PI
4811  const signed char Comment2 = 5; // read comment
4812 
4813  const signed char InpWs = 0; // S
4814  const signed char InpLt = 1; // <
4815  const signed char InpQm = 2; // ?
4816  const signed char InpEm = 3; // !
4817  const signed char InpUnknown = 4;
4818 
4819  static const signed char table[3][5] = {
4820  /* InpWs InpLt InpQm InpEm InpUnknown */
4821  { eatWS, Lt, -1, -1, -1 }, // Init
4822  { -1, -1, PInstr,Comment, -1 }, // Lt
4823  { -1, -1, -1, -1, Comment2 } // Comment
4824  };
4825  signed char state;
4826  signed char input;
4827 
4828  if (parseStack==0 || parseStack->isEmpty()) {
4829  state = Init;
4830  } else {
4831  state = parseStack->pop().state;
4832 #if defined(QT_QXML_DEBUG)
4833  qDebug("QXmlSimpleReader: parseMisc (cont) in state %d", state);
4834 #endif
4835  if (!parseStack->isEmpty()) {
4836  ParseFunction function = parseStack->top().function;
4837  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
4838  parseStack->pop();
4839 #if defined(QT_QXML_DEBUG)
4840  qDebug("QXmlSimpleReader: eat_ws (cont)");
4841 #endif
4842  }
4843  if (!(this->*function)()) {
4844  parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
4845  return false;
4846  }
4847  }
4848  }
4849 
4850  for (;;) {
4851  switch (state) {
4852  case eatWS:
4853  return true;
4854  case PInstr:
4855  if (contentHnd) {
4856  if (!contentHnd->processingInstruction(name(),string())) {
4857  reportParseError(contentHnd->errorString());
4858  return false;
4859  }
4860  }
4861  return true;
4862  case Comment2:
4863  if (lexicalHnd) {
4864  if (!lexicalHnd->comment(string())) {
4865  reportParseError(lexicalHnd->errorString());
4866  return false;
4867  }
4868  }
4869  return true;
4870  case -1:
4871  // Error
4872  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
4873  return false;
4874  }
4875 
4876  if (atEnd()) {
4877  unexpectedEof(&QXmlSimpleReaderPrivate::parseMisc, state);
4878  return false;
4879  }
4880  if (is_S(c)) {
4881  input = InpWs;
4882  } else if (c == QLatin1Char('<')) {
4883  input = InpLt;
4884  } else if (c == QLatin1Char('?')) {
4885  input = InpQm;
4886  } else if (c == QLatin1Char('!')) {
4887  input = InpEm;
4888  } else {
4889  input = InpUnknown;
4890  }
4891  state = table[state][input];
4892 
4893  switch (state) {
4894  case eatWS:
4895  if (!eat_ws()) {
4896  parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
4897  return false;
4898  }
4899  break;
4900  case Lt:
4901  next();
4902  break;
4903  case PInstr:
4904  parsePI_xmldecl = false;
4905  if (!parsePI()) {
4906  parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
4907  return false;
4908  }
4909  break;
4910  case Comment:
4911  next();
4912  break;
4913  case Comment2:
4914  if (!parseComment()) {
4915  parseFailed(&QXmlSimpleReaderPrivate::parseMisc, state);
4916  return false;
4917  }
4918  break;
4919  }
4920  }
4921  return false;
4922 }
4923 
4924 /*
4925  Parse a processing instruction [16].
4926 
4927  If xmldec is true, it tries to parse a PI or a XML declaration [23].
4928 
4929  Precondition: the beginning '<' of the PI is already read and the head stand
4930  on the '?' of '<?'.
4931 
4932  If this funktion was successful, the head-position is on the first
4933  character after the PI.
4934 */
4936 {
4937  const signed char Init = 0;
4938  const signed char QmI = 1; // ? was read
4939  const signed char Name = 2; // read Name
4940  const signed char XMLDecl = 3; // read XMLDecl
4941  const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
4942  const signed char PInstr = 5; // read PI
4943  const signed char Ws2 = 6; // eat ws after Name of PI
4944  const signed char Version = 7; // read versionInfo
4945  const signed char Ws3 = 8; // eat ws after versionInfo
4946  const signed char EorSD = 9; // read EDecl or SDDecl
4947  const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
4948  const signed char SD = 11; // read SDDecl
4949  const signed char Ws5 = 12; // eat ws after SDDecl
4950  const signed char ADone = 13; // almost done
4951  const signed char Char = 14; // Char was read
4952  const signed char Qm = 15; // Qm was read
4953  const signed char Done = 16; // finished reading content
4954 
4955  const signed char InpWs = 0; // whitespace
4956  const signed char InpNameBe = 1; // NameBeginning
4957  const signed char InpGt = 2; // >
4958  const signed char InpQm = 3; // ?
4959  const signed char InpUnknown = 4;
4960 
4961  static const signed char table[16][5] = {
4962  /* InpWs, InpNameBe InpGt InpQm InpUnknown */
4963  { -1, -1, -1, QmI, -1 }, // Init
4964  { -1, Name, -1, -1, -1 }, // QmI
4965  { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
4966  { Ws1, -1, -1, -1, -1 }, // XMLDecl
4967  { -1, Version, -1, -1, -1 }, // Ws1
4968  { Ws2, -1, -1, Qm, -1 }, // PInstr
4969  { Char, Char, Char, Qm, Char }, // Ws2
4970  { Ws3, -1, -1, ADone, -1 }, // Version
4971  { -1, EorSD, -1, ADone, -1 }, // Ws3
4972  { Ws4, -1, -1, ADone, -1 }, // EorSD
4973  { -1, SD, -1, ADone, -1 }, // Ws4
4974  { Ws5, -1, -1, ADone, -1 }, // SD
4975  { -1, -1, -1, ADone, -1 }, // Ws5
4976  { -1, -1, Done, -1, -1 }, // ADone
4977  { Char, Char, Char, Qm, Char }, // Char
4978  { Char, Char, Done, Qm, Char }, // Qm
4979  };
4980  signed char state;
4981  signed char input;
4982 
4983  if (parseStack==0 || parseStack->isEmpty()) {
4984  state = Init;
4985  } else {
4986  state = parseStack->pop().state;
4987 #if defined(QT_QXML_DEBUG)
4988  qDebug("QXmlSimpleReader: parsePI (cont) in state %d", state);
4989 #endif
4990  if (!parseStack->isEmpty()) {
4991  ParseFunction function = parseStack->top().function;
4992  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
4993  parseStack->pop();
4994 #if defined(QT_QXML_DEBUG)
4995  qDebug("QXmlSimpleReader: eat_ws (cont)");
4996 #endif
4997  }
4998  if (!(this->*function)()) {
4999  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5000  return false;
5001  }
5002  }
5003  }
5004 
5005  for (;;) {
5006  switch (state) {
5007  case Name:
5008  // test what name was read and determine the next state
5009  // (not very beautiful, I admit)
5010  if (name().toLower() == QLatin1String("xml")) {
5011  if (parsePI_xmldecl && name() == QLatin1String("xml")) {
5012  state = XMLDecl;
5013  } else {
5014  reportParseError(QLatin1String(XMLERR_INVALIDNAMEFORPI));
5015  return false;
5016  }
5017  } else {
5018  state = PInstr;
5019  stringClear();
5020  }
5021  break;
5022  case Version:
5023  // get version (syntax like an attribute)
5024  if (name() != QLatin1String("version")) {
5025  reportParseError(QLatin1String(XMLERR_VERSIONEXPECTED));
5026  return false;
5027  }
5028  xmlVersion = string();
5029  break;
5030  case EorSD:
5031  // get the EDecl or SDDecl (syntax like an attribute)
5032  if (name() == QLatin1String("standalone")) {
5033  if (string()== QLatin1String("yes")) {
5034  standalone = QXmlSimpleReaderPrivate::Yes;
5035  } else if (string() == QLatin1String("no")) {
5036  standalone = QXmlSimpleReaderPrivate::No;
5037  } else {
5038  reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
5039  return false;
5040  }
5041  } else if (name() == QLatin1String("encoding")) {
5042  encoding = string();
5043  } else {
5044  reportParseError(QLatin1String(XMLERR_EDECLORSDDECLEXPECTED));
5045  return false;
5046  }
5047  break;
5048  case SD:
5049  if (name() != QLatin1String("standalone")) {
5050  reportParseError(QLatin1String(XMLERR_SDDECLEXPECTED));
5051  return false;
5052  }
5053  if (string() == QLatin1String("yes")) {
5054  standalone = QXmlSimpleReaderPrivate::Yes;
5055  } else if (string() == QLatin1String("no")) {
5056  standalone = QXmlSimpleReaderPrivate::No;
5057  } else {
5058  reportParseError(QLatin1String(XMLERR_WRONGVALUEFORSDECL));
5059  return false;
5060  }
5061  break;
5062  case Qm:
5063  // test if the skipping was legal
5064  if (!atEnd() && c != QLatin1Char('>'))
5065  stringAddC(QLatin1Char('?'));
5066  break;
5067  case Done:
5068  return true;
5069  case -1:
5070  // Error
5071  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
5072  return false;
5073  }
5074 
5075  if (atEnd()) {
5076  unexpectedEof(&QXmlSimpleReaderPrivate::parsePI, state);
5077  return false;
5078  }
5079  if (is_S(c)) {
5080  input = InpWs;
5081  } else if (determineNameChar(c) == NameBeginning) {
5082  input = InpNameBe;
5083  } else if (c == QLatin1Char('>')) {
5084  input = InpGt;
5085  } else if (c == QLatin1Char('?')) {
5086  input = InpQm;
5087  } else {
5088  input = InpUnknown;
5089  }
5090  state = table[state][input];
5091 
5092  switch (state) {
5093  case QmI:
5094  next();
5095  break;
5096  case Name:
5097  parseName_useRef = false;
5098  if (!parseName()) {
5099  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5100  return false;
5101  }
5102  break;
5103  case Ws1:
5104  case Ws2:
5105  case Ws3:
5106  case Ws4:
5107  case Ws5:
5108  if (!eat_ws()) {
5109  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5110  return false;
5111  }
5112  break;
5113  case Version:
5114  if (!parseAttribute()) {
5115  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5116  return false;
5117  }
5118  break;
5119  case EorSD:
5120  if (!parseAttribute()) {
5121  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5122  return false;
5123  }
5124  break;
5125  case SD:
5126  // get the SDDecl (syntax like an attribute)
5127  if (standalone != QXmlSimpleReaderPrivate::Unknown) {
5128  // already parsed the standalone declaration
5129  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
5130  return false;
5131  }
5132  if (!parseAttribute()) {
5133  parseFailed(&QXmlSimpleReaderPrivate::parsePI, state);
5134  return false;
5135  }
5136  break;
5137  case ADone:
5138  next();
5139  break;
5140  case Char:
5141  stringAddC();
5142  next();
5143  break;
5144  case Qm:
5145  // skip the '?'
5146  next();
5147  break;
5148  case Done:
5149  next();
5150  break;
5151  }
5152  }
5153  return false;
5154 }
5155 
5156 /*
5157  Parse a document type definition (doctypedecl [28]).
5158 
5159  Precondition: the beginning '<!' of the doctype is already read the head
5160  stands on the 'D' of '<!DOCTYPE'.
5161 
5162  If this function was successful, the head-position is on the first
5163  character after the document type definition.
5164 */
5166 {
5167  const signed char Init = 0;
5168  const signed char Doctype = 1; // read the doctype
5169  const signed char Ws1 = 2; // eat_ws
5170  const signed char Doctype2 = 3; // read the doctype, part 2
5171  const signed char Ws2 = 4; // eat_ws
5172  const signed char Sys = 5; // read SYSTEM or PUBLIC
5173  const signed char Ws3 = 6; // eat_ws
5174  const signed char MP = 7; // markupdecl or PEReference
5175  const signed char MPR = 8; // same as MP, but already reported
5176  const signed char PER = 9; // PERReference
5177  const signed char Mup = 10; // markupdecl
5178  const signed char Ws4 = 11; // eat_ws
5179  const signed char MPE = 12; // end of markupdecl or PEReference
5180  const signed char Done = 13;
5181 
5182  const signed char InpWs = 0;
5183  const signed char InpD = 1; // 'D'
5184  const signed char InpS = 2; // 'S' or 'P'
5185  const signed char InpOB = 3; // [
5186  const signed char InpCB = 4; //]
5187  const signed char InpPer = 5; // %
5188  const signed char InpGt = 6; // >
5189  const signed char InpUnknown = 7;
5190 
5191  static const signed char table[13][8] = {
5192  /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
5193  { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
5194  { Ws1, -1, -1, -1, -1, -1, -1, -1 }, // Doctype
5195  { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
5196  { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
5197  { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
5198  { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
5199  { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
5200  { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
5201  { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MPR
5202  { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
5203  { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
5204  { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
5205  { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
5206  };
5207  signed char state;
5208  signed char input;
5209 
5210  if (parseStack==0 || parseStack->isEmpty()) {
5211  startDTDwasReported = false;
5212  systemId.clear();
5213  publicId.clear();
5214  state = Init;
5215  } else {
5216  state = parseStack->pop().state;
5217 #if defined(QT_QXML_DEBUG)
5218  qDebug("QXmlSimpleReader: parseDoctype (cont) in state %d", state);
5219 #endif
5220  if (!parseStack->isEmpty()) {
5221  ParseFunction function = parseStack->top().function;
5222  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
5223  parseStack->pop();
5224 #if defined(QT_QXML_DEBUG)
5225  qDebug("QXmlSimpleReader: eat_ws (cont)");
5226 #endif
5227  }
5228  if (!(this->*function)()) {
5229  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5230  return false;
5231  }
5232  }
5233  }
5234 
5235  for (;;) {
5236  switch (state) {
5237  case Doctype2:
5238  doctype = name();
5239  break;
5240  case MP:
5241  if (!startDTDwasReported && lexicalHnd ) {
5242  startDTDwasReported = true;
5243  if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
5244  reportParseError(lexicalHnd->errorString());
5245  return false;
5246  }
5247  }
5248  state = MPR;
5249  break;
5250  case Done:
5251  return true;
5252  case -1:
5253  // Error
5254  reportParseError(QLatin1String(XMLERR_ERRORPARSINGDOCTYPE));
5255  return false;
5256  }
5257 
5258  if (atEnd()) {
5259  unexpectedEof(&QXmlSimpleReaderPrivate::parseDoctype, state);
5260  return false;
5261  }
5262  if (is_S(c)) {
5263  input = InpWs;
5264  } else if (c == QLatin1Char('D')) {
5265  input = InpD;
5266  } else if (c == QLatin1Char('S')) {
5267  input = InpS;
5268  } else if (c == QLatin1Char('P')) {
5269  input = InpS;
5270  } else if (c == QLatin1Char('[')) {
5271  input = InpOB;
5272  } else if (c == QLatin1Char(']')) {
5273  input = InpCB;
5274  } else if (c == QLatin1Char('%')) {
5275  input = InpPer;
5276  } else if (c == QLatin1Char('>')) {
5277  input = InpGt;
5278  } else {
5279  input = InpUnknown;
5280  }
5281  state = table[state][input];
5282 
5283  switch (state) {
5284  case Doctype:
5285  parseString_s = QLatin1String("DOCTYPE");
5286  if (!parseString()) {
5287  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5288  return false;
5289  }
5290  break;
5291  case Ws1:
5292  case Ws2:
5293  case Ws3:
5294  case Ws4:
5295  if (!eat_ws()) {
5296  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5297  return false;
5298  }
5299  break;
5300  case Doctype2:
5301  parseName_useRef = false;
5302  if (!parseName()) {
5303  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5304  return false;
5305  }
5306  break;
5307  case Sys:
5308  parseExternalID_allowPublicID = false;
5309  if (!parseExternalID()) {
5310  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5311  return false;
5312  }
5313  thisPublicId = publicId;
5314  thisSystemId = systemId;
5315  break;
5316  case MP:
5317  case MPR:
5318  if (!next_eat_ws()) {
5319  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5320  return false;
5321  }
5322  break;
5323  case PER:
5324  parsePEReference_context = InDTD;
5325  if (!parsePEReference()) {
5326  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5327  return false;
5328  }
5329  break;
5330  case Mup:
5331  if (dtdRecursionLimit > 0 && parameterEntities.size() > dtdRecursionLimit) {
5332  reportParseError(QString::fromLatin1(
5333  "DTD parsing exceeded recursion limit of %1.").arg(dtdRecursionLimit));
5334  return false;
5335  }
5336  if (!parseMarkupdecl()) {
5337  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5338  return false;
5339  }
5340  break;
5341  case MPE:
5342  if (!next_eat_ws()) {
5343  parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
5344  return false;
5345  }
5346  break;
5347  case Done:
5348  if (lexicalHnd) {
5349  if (!startDTDwasReported) {
5350  startDTDwasReported = true;
5351  if (!lexicalHnd->startDTD(doctype, publicId, systemId)) {
5352  reportParseError(lexicalHnd->errorString());
5353  return false;
5354  }
5355  }
5356  if (!lexicalHnd->endDTD()) {
5357  reportParseError(lexicalHnd->errorString());
5358  return false;
5359  }
5360  }
5361  next();
5362  break;
5363  }
5364  }
5365  return false;
5366 }
5367 
5368 /*
5369  Parse a ExternalID [75].
5370 
5371  If allowPublicID is true parse ExternalID [75] or PublicID [83].
5372 */
5374 {
5375  const signed char Init = 0;
5376  const signed char Sys = 1; // parse 'SYSTEM'
5377  const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
5378  const signed char SysSQ = 3; // parse SystemLiteral with '
5379  const signed char SysSQ2 = 4; // parse SystemLiteral with '
5380  const signed char SysDQ = 5; // parse SystemLiteral with "
5381  const signed char SysDQ2 = 6; // parse SystemLiteral with "
5382  const signed char Pub = 7; // parse 'PUBLIC'
5383  const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
5384  const signed char PubSQ = 9; // parse PubidLiteral with '
5385  const signed char PubSQ2 = 10; // parse PubidLiteral with '
5386  const signed char PubDQ = 11; // parse PubidLiteral with "
5387  const signed char PubDQ2 = 12; // parse PubidLiteral with "
5388  const signed char PubE = 13; // finished parsing the PubidLiteral
5389  const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
5390  const signed char PDone = 15; // done if allowPublicID is true
5391  const signed char Done = 16;
5392 
5393  const signed char InpSQ = 0; // '
5394  const signed char InpDQ = 1; // "
5395  const signed char InpS = 2; // S
5396  const signed char InpP = 3; // P
5397  const signed char InpWs = 4; // white space
5398  const signed char InpUnknown = 5;
5399 
5400  static const signed char table[15][6] = {
5401  /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
5402  { -1, -1, Sys, Pub, -1, -1 }, // Init
5403  { -1, -1, -1, -1, SysWS, -1 }, // Sys
5404  { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
5405  { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
5406  { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
5407  { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
5408  { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
5409  { -1, -1, -1, -1, PubWS, -1 }, // Pub
5410  { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
5411  { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
5412  { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
5413  { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
5414  { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
5415  { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
5416  { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
5417  };
5418  signed char state;
5419  signed char input;
5420 
5421  if (parseStack==0 || parseStack->isEmpty()) {
5422  systemId.clear();
5423  publicId.clear();
5424  state = Init;
5425  } else {
5426  state = parseStack->pop().state;
5427 #if defined(QT_QXML_DEBUG)
5428  qDebug("QXmlSimpleReader: parseExternalID (cont) in state %d", state);
5429 #endif
5430  if (!parseStack->isEmpty()) {
5431  ParseFunction function = parseStack->top().function;
5432  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
5433  parseStack->pop();
5434 #if defined(QT_QXML_DEBUG)
5435  qDebug("QXmlSimpleReader: eat_ws (cont)");
5436 #endif
5437  }
5438  if (!(this->*function)()) {
5439  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5440  return false;
5441  }
5442  }
5443  }
5444 
5445  for (;;) {
5446  switch (state) {
5447  case PDone:
5448  if (parseExternalID_allowPublicID) {
5449  publicId = string();
5450  return true;
5451  } else {
5452  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
5453  return false;
5454  }
5455  case Done:
5456  return true;
5457  case -1:
5458  // Error
5459  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
5460  return false;
5461  }
5462 
5463  if (atEnd()) {
5464  unexpectedEof(&QXmlSimpleReaderPrivate::parseExternalID, state);
5465  return false;
5466  }
5467  if (is_S(c)) {
5468  input = InpWs;
5469  } else if (c == QLatin1Char('\'')) {
5470  input = InpSQ;
5471  } else if (c == QLatin1Char('"')) {
5472  input = InpDQ;
5473  } else if (c == QLatin1Char('S')) {
5474  input = InpS;
5475  } else if (c == QLatin1Char('P')) {
5476  input = InpP;
5477  } else {
5478  input = InpUnknown;
5479  }
5480  state = table[state][input];
5481 
5482  switch (state) {
5483  case Sys:
5484  parseString_s = QLatin1String("SYSTEM");
5485  if (!parseString()) {
5486  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5487  return false;
5488  }
5489  break;
5490  case SysWS:
5491  if (!eat_ws()) {
5492  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5493  return false;
5494  }
5495  break;
5496  case SysSQ:
5497  case SysDQ:
5498  stringClear();
5499  next();
5500  break;
5501  case SysSQ2:
5502  case SysDQ2:
5503  stringAddC();
5504  next();
5505  break;
5506  case Pub:
5507  parseString_s = QLatin1String("PUBLIC");
5508  if (!parseString()) {
5509  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5510  return false;
5511  }
5512  break;
5513  case PubWS:
5514  if (!eat_ws()) {
5515  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5516  return false;
5517  }
5518  break;
5519  case PubSQ:
5520  case PubDQ:
5521  stringClear();
5522  next();
5523  break;
5524  case PubSQ2:
5525  case PubDQ2:
5526  stringAddC();
5527  next();
5528  break;
5529  case PubE:
5530  next();
5531  break;
5532  case PubWS2:
5533  publicId = string();
5534  if (!eat_ws()) {
5535  parseFailed(&QXmlSimpleReaderPrivate::parseExternalID, state);
5536  return false;
5537  }
5538  break;
5539  case Done:
5540  systemId = string();
5541  next();
5542  break;
5543  }
5544  }
5545  return false;
5546 }
5547 
5548 /*
5549  Parse a markupdecl [29].
5550 */
5552 {
5553  const signed char Init = 0;
5554  const signed char Lt = 1; // < was read
5555  const signed char Em = 2; // ! was read
5556  const signed char CE = 3; // E was read
5557  const signed char Qm = 4; // ? was read
5558  const signed char Dash = 5; // - was read
5559  const signed char CA = 6; // A was read
5560  const signed char CEL = 7; // EL was read
5561  const signed char CEN = 8; // EN was read
5562  const signed char CN = 9; // N was read
5563  const signed char Done = 10;
5564 
5565  const signed char InpLt = 0; // <
5566  const signed char InpQm = 1; // ?
5567  const signed char InpEm = 2; // !
5568  const signed char InpDash = 3; // -
5569  const signed char InpA = 4; // A
5570  const signed char InpE = 5; // E
5571  const signed char InpL = 6; // L
5572  const signed char InpN = 7; // N
5573  const signed char InpUnknown = 8;
5574 
5575  static const signed char table[4][9] = {
5576  /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
5577  { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
5578  { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
5579  { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
5580  { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
5581  };
5582  signed char state;
5583  signed char input;
5584 
5585  if (parseStack==0 || parseStack->isEmpty()) {
5586  state = Init;
5587  } else {
5588  state = parseStack->pop().state;
5589 #if defined(QT_QXML_DEBUG)
5590  qDebug("QXmlSimpleReader: parseMarkupdecl (cont) in state %d", state);
5591 #endif
5592  if (!parseStack->isEmpty()) {
5593  ParseFunction function = parseStack->top().function;
5594  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
5595  parseStack->pop();
5596 #if defined(QT_QXML_DEBUG)
5597  qDebug("QXmlSimpleReader: eat_ws (cont)");
5598 #endif
5599  }
5600  if (!(this->*function)()) {
5601  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5602  return false;
5603  }
5604  }
5605  }
5606 
5607  for (;;) {
5608  switch (state) {
5609  case Qm:
5610  if (contentHnd) {
5611  if (!contentHnd->processingInstruction(name(),string())) {
5612  reportParseError(contentHnd->errorString());
5613  return false;
5614  }
5615  }
5616  return true;
5617  case Dash:
5618  if (lexicalHnd) {
5619  if (!lexicalHnd->comment(string())) {
5620  reportParseError(lexicalHnd->errorString());
5621  return false;
5622  }
5623  }
5624  return true;
5625  case CA:
5626  return true;
5627  case CEL:
5628  return true;
5629  case CEN:
5630  return true;
5631  case CN:
5632  return true;
5633  case Done:
5634  return true;
5635  case -1:
5636  // Error
5637  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
5638  return false;
5639  }
5640 
5641  if (atEnd()) {
5642  unexpectedEof(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5643  return false;
5644  }
5645  if (c == QLatin1Char('<')) {
5646  input = InpLt;
5647  } else if (c == QLatin1Char('?')) {
5648  input = InpQm;
5649  } else if (c == QLatin1Char('!')) {
5650  input = InpEm;
5651  } else if (c == QLatin1Char('-')) {
5652  input = InpDash;
5653  } else if (c == QLatin1Char('A')) {
5654  input = InpA;
5655  } else if (c == QLatin1Char('E')) {
5656  input = InpE;
5657  } else if (c == QLatin1Char('L')) {
5658  input = InpL;
5659  } else if (c == QLatin1Char('N')) {
5660  input = InpN;
5661  } else {
5662  input = InpUnknown;
5663  }
5664  state = table[state][input];
5665 
5666  switch (state) {
5667  case Lt:
5668  next();
5669  break;
5670  case Em:
5671  next();
5672  break;
5673  case CE:
5674  next();
5675  break;
5676  case Qm:
5677  parsePI_xmldecl = false;
5678  if (!parsePI()) {
5679  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5680  return false;
5681  }
5682  break;
5683  case Dash:
5684  if (!parseComment()) {
5685  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5686  return false;
5687  }
5688  break;
5689  case CA:
5690  if (!parseAttlistDecl()) {
5691  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5692  return false;
5693  }
5694  break;
5695  case CEL:
5696  if (!parseElementDecl()) {
5697  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5698  return false;
5699  }
5700  break;
5701  case CEN:
5702  if (!parseEntityDecl()) {
5703  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5704  return false;
5705  }
5706  break;
5707  case CN:
5708  if (!parseNotationDecl()) {
5709  parseFailed(&QXmlSimpleReaderPrivate::parseMarkupdecl, state);
5710  return false;
5711  }
5712  break;
5713  }
5714  }
5715  return false;
5716 }
5717 
5718 /*
5719  Parse a PEReference [69]
5720 */
5722 {
5723  const signed char Init = 0;
5724  const signed char Next = 1;
5725  const signed char Name = 2;
5726  const signed char NameR = 3; // same as Name, but already reported
5727  const signed char Done = 4;
5728 
5729  const signed char InpSemi = 0; // ;
5730  const signed char InpPer = 1; // %
5731  const signed char InpUnknown = 2;
5732 
5733  static const signed char table[4][3] = {
5734  /* InpSemi InpPer InpUnknown */
5735  { -1, Next, -1 }, // Init
5736  { -1, -1, Name }, // Next
5737  { Done, -1, -1 }, // Name
5738  { Done, -1, -1 } // NameR
5739  };
5740  signed char state;
5741  signed char input;
5742 
5743  if (parseStack==0 || parseStack->isEmpty()) {
5744  state = Init;
5745  } else {
5746  state = parseStack->pop().state;
5747 #if defined(QT_QXML_DEBUG)
5748  qDebug("QXmlSimpleReader: parsePEReference (cont) in state %d", state);
5749 #endif
5750  if (!parseStack->isEmpty()) {
5751  ParseFunction function = parseStack->top().function;
5752  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
5753  parseStack->pop();
5754 #if defined(QT_QXML_DEBUG)
5755  qDebug("QXmlSimpleReader: eat_ws (cont)");
5756 #endif
5757  }
5758  if (!(this->*function)()) {
5759  parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
5760  return false;
5761  }
5762  }
5763  }
5764 
5765  for (;;) {
5766  switch (state) {
5767  case Name:
5768  {
5769  bool skipIt = true;
5770  QString xmlRefString;
5771 
5773  it = parameterEntities.find(ref());
5774  if (it != parameterEntities.end()) {
5775  skipIt = false;
5776  xmlRefString = *it;
5777  } else if (entityRes) {
5779  it2 = externParameterEntities.find(ref());
5780  QXmlInputSource *ret = 0;
5781  if (it2 != externParameterEntities.end()) {
5782  if (!entityRes->resolveEntity((*it2).publicId, (*it2).systemId, ret)) {
5783  delete ret;
5784  reportParseError(entityRes->errorString());
5785  return false;
5786  }
5787  if (ret) {
5788  xmlRefString = ret->data();
5789  delete ret;
5790  if (!stripTextDecl(xmlRefString)) {
5791  reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
5792  return false;
5793  }
5794  skipIt = false;
5795  }
5796  }
5797  }
5798 
5799  if (skipIt) {
5800  if (contentHnd) {
5801  if (!contentHnd->skippedEntity(QLatin1Char('%') + ref())) {
5802  reportParseError(contentHnd->errorString());
5803  return false;
5804  }
5805  }
5806  } else {
5807  if (parsePEReference_context == InEntityValue) {
5808  // Included in literal
5809  if (!insertXmlRef(xmlRefString, ref(), true))
5810  return false;
5811  } else if (parsePEReference_context == InDTD) {
5812  // Included as PE
5813  if (!insertXmlRef(QLatin1Char(' ') + xmlRefString + QLatin1Char(' '), ref(), false))
5814  return false;
5815  }
5816  }
5817  }
5818  state = NameR;
5819  break;
5820  case Done:
5821  return true;
5822  case -1:
5823  // Error
5824  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
5825  return false;
5826  }
5827 
5828  if (atEnd()) {
5829  unexpectedEof(&QXmlSimpleReaderPrivate::parsePEReference, state);
5830  return false;
5831  }
5832  if (c == QLatin1Char(';')) {
5833  input = InpSemi;
5834  } else if (c == QLatin1Char('%')) {
5835  input = InpPer;
5836  } else {
5837  input = InpUnknown;
5838  }
5839  state = table[state][input];
5840 
5841  switch (state) {
5842  case Next:
5843  next();
5844  break;
5845  case Name:
5846  case NameR:
5847  parseName_useRef = true;
5848  if (!parseName()) {
5849  parseFailed(&QXmlSimpleReaderPrivate::parsePEReference, state);
5850  return false;
5851  }
5852  break;
5853  case Done:
5854  next();
5855  break;
5856  }
5857  }
5858  return false;
5859 }
5860 
5861 /*
5862  Parse a AttlistDecl [52].
5863 
5864  Precondition: the beginning '<!' is already read and the head
5865  stands on the 'A' of '<!ATTLIST'
5866 */
5868 {
5869  const signed char Init = 0;
5870  const signed char Attlist = 1; // parse the string "ATTLIST"
5871  const signed char Ws = 2; // whitespace read
5872  const signed char Name = 3; // parse name
5873  const signed char Ws1 = 4; // whitespace read
5874  const signed char Attdef = 5; // parse the AttDef
5875  const signed char Ws2 = 6; // whitespace read
5876  const signed char Atttype = 7; // parse the AttType
5877  const signed char Ws3 = 8; // whitespace read
5878  const signed char DDecH = 9; // DefaultDecl with #
5879  const signed char DefReq = 10; // parse the string "REQUIRED"
5880  const signed char DefImp = 11; // parse the string "IMPLIED"
5881  const signed char DefFix = 12; // parse the string "FIXED"
5882  const signed char Attval = 13; // parse the AttValue
5883  const signed char Ws4 = 14; // whitespace read
5884  const signed char Done = 15;
5885 
5886  const signed char InpWs = 0; // white space
5887  const signed char InpGt = 1; // >
5888  const signed char InpHash = 2; // #
5889  const signed char InpA = 3; // A
5890  const signed char InpI = 4; // I
5891  const signed char InpF = 5; // F
5892  const signed char InpR = 6; // R
5893  const signed char InpUnknown = 7;
5894 
5895  static const signed char table[15][8] = {
5896  /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
5897  { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
5898  { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
5899  { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
5900  { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
5901  { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
5902  { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
5903  { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
5904  { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
5905  { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
5906  { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
5907  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
5908  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
5909  { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
5910  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
5911  { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
5912  };
5913  signed char state;
5914  signed char input;
5915 
5916  if (parseStack==0 || parseStack->isEmpty()) {
5917  state = Init;
5918  } else {
5919  state = parseStack->pop().state;
5920 #if defined(QT_QXML_DEBUG)
5921  qDebug("QXmlSimpleReader: parseAttlistDecl (cont) in state %d", state);
5922 #endif
5923  if (!parseStack->isEmpty()) {
5924  ParseFunction function = parseStack->top().function;
5925  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
5926  parseStack->pop();
5927 #if defined(QT_QXML_DEBUG)
5928  qDebug("QXmlSimpleReader: eat_ws (cont)");
5929 #endif
5930  }
5931  if (!(this->*function)()) {
5932  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
5933  return false;
5934  }
5935  }
5936  }
5937 
5938  for (;;) {
5939  switch (state) {
5940  case Name:
5941  attDeclEName = name();
5942  break;
5943  case Attdef:
5944  attDeclAName = name();
5945  break;
5946  case Done:
5947  return true;
5948  case -1:
5949  // Error
5950  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
5951  return false;
5952  }
5953 
5954  if (atEnd()) {
5955  unexpectedEof(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
5956  return false;
5957  }
5958  if (is_S(c)) {
5959  input = InpWs;
5960  } else if (c == QLatin1Char('>')) {
5961  input = InpGt;
5962  } else if (c == QLatin1Char('#')) {
5963  input = InpHash;
5964  } else if (c == QLatin1Char('A')) {
5965  input = InpA;
5966  } else if (c == QLatin1Char('I')) {
5967  input = InpI;
5968  } else if (c == QLatin1Char('F')) {
5969  input = InpF;
5970  } else if (c == QLatin1Char('R')) {
5971  input = InpR;
5972  } else {
5973  input = InpUnknown;
5974  }
5975  state = table[state][input];
5976 
5977  switch (state) {
5978  case Attlist:
5979  parseString_s = QLatin1String("ATTLIST");
5980  if (!parseString()) {
5981  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
5982  return false;
5983  }
5984  break;
5985  case Ws:
5986  case Ws1:
5987  case Ws2:
5988  case Ws3:
5989  if (!eat_ws()) {
5990  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
5991  return false;
5992  }
5993  break;
5994  case Name:
5995  parseName_useRef = false;
5996  if (!parseName()) {
5997  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
5998  return false;
5999  }
6000  break;
6001  case Attdef:
6002  parseName_useRef = false;
6003  if (!parseName()) {
6004  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6005  return false;
6006  }
6007  break;
6008  case Atttype:
6009  if (!parseAttType()) {
6010  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6011  return false;
6012  }
6013  break;
6014  case DDecH:
6015  next();
6016  break;
6017  case DefReq:
6018  parseString_s = QLatin1String("REQUIRED");
6019  if (!parseString()) {
6020  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6021  return false;
6022  }
6023  break;
6024  case DefImp:
6025  parseString_s = QLatin1String("IMPLIED");
6026  if (!parseString()) {
6027  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6028  return false;
6029  }
6030  break;
6031  case DefFix:
6032  parseString_s = QLatin1String("FIXED");
6033  if (!parseString()) {
6034  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6035  return false;
6036  }
6037  break;
6038  case Attval:
6039  if (!parseAttValue()) {
6040  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6041  return false;
6042  }
6043  break;
6044  case Ws4:
6045  if (declHnd) {
6046  // ### not all values are computed yet...
6047  if (!declHnd->attributeDecl(attDeclEName, attDeclAName, QLatin1String(""), QLatin1String(""), QLatin1String(""))) {
6048  reportParseError(declHnd->errorString());
6049  return false;
6050  }
6051  }
6052  if (!eat_ws()) {
6053  parseFailed(&QXmlSimpleReaderPrivate::parseAttlistDecl, state);
6054  return false;
6055  }
6056  break;
6057  case Done:
6058  next();
6059  break;
6060  }
6061  }
6062  return false;
6063 }
6064 
6065 /*
6066  Parse a AttType [54]
6067 */
6069 {
6070  const signed char Init = 0;
6071  const signed char ST = 1; // StringType
6072  const signed char TTI = 2; // TokenizedType starting with 'I'
6073  const signed char TTI2 = 3; // TokenizedType helpstate
6074  const signed char TTI3 = 4; // TokenizedType helpstate
6075  const signed char TTE = 5; // TokenizedType starting with 'E'
6076  const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
6077  const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
6078  const signed char N = 8; // N read (TokenizedType or Notation)
6079  const signed char TTNM = 9; // TokenizedType starting with 'NM'
6080  const signed char TTNM2 = 10; // TokenizedType helpstate
6081  const signed char NO = 11; // Notation
6082  const signed char NO2 = 12; // Notation helpstate
6083  const signed char NO3 = 13; // Notation helpstate
6084  const signed char NOName = 14; // Notation, read name
6085  const signed char NO4 = 15; // Notation helpstate
6086  const signed char EN = 16; // Enumeration
6087  const signed char ENNmt = 17; // Enumeration, read Nmtoken
6088  const signed char EN2 = 18; // Enumeration helpstate
6089  const signed char ADone = 19; // almost done (make next and accept)
6090  const signed char Done = 20;
6091 
6092  const signed char InpWs = 0; // whitespace
6093  const signed char InpOp = 1; // (
6094  const signed char InpCp = 2; //)
6095  const signed char InpPipe = 3; // |
6096  const signed char InpC = 4; // C
6097  const signed char InpE = 5; // E
6098  const signed char InpI = 6; // I
6099  const signed char InpM = 7; // M
6100  const signed char InpN = 8; // N
6101  const signed char InpO = 9; // O
6102  const signed char InpR = 10; // R
6103  const signed char InpS = 11; // S
6104  const signed char InpY = 12; // Y
6105  const signed char InpUnknown = 13;
6106 
6107  static const signed char table[19][14] = {
6108  /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
6109  { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
6110  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
6111  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
6112  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
6113  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
6114  { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
6115  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
6116  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
6117  { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
6118  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
6119  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
6120  { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
6121  { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
6122  { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
6123  { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
6124  { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
6125  { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
6126  { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
6127  { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
6128  };
6129  signed char state;
6130  signed char input;
6131 
6132  if (parseStack==0 || parseStack->isEmpty()) {
6133  state = Init;
6134  } else {
6135  state = parseStack->pop().state;
6136 #if defined(QT_QXML_DEBUG)
6137  qDebug("QXmlSimpleReader: parseAttType (cont) in state %d", state);
6138 #endif
6139  if (!parseStack->isEmpty()) {
6140  ParseFunction function = parseStack->top().function;
6141  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
6142  parseStack->pop();
6143 #if defined(QT_QXML_DEBUG)
6144  qDebug("QXmlSimpleReader: eat_ws (cont)");
6145 #endif
6146  }
6147  if (!(this->*function)()) {
6148  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6149  return false;
6150  }
6151  }
6152  }
6153 
6154  for (;;) {
6155  switch (state) {
6156  case ADone:
6157  return true;
6158  case Done:
6159  return true;
6160  case -1:
6161  // Error
6162  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
6163  return false;
6164  }
6165 
6166  if (atEnd()) {
6167  unexpectedEof(&QXmlSimpleReaderPrivate::parseAttType, state);
6168  return false;
6169  }
6170  if (is_S(c)) {
6171  input = InpWs;
6172  } else if (c == QLatin1Char('(')) {
6173  input = InpOp;
6174  } else if (c == QLatin1Char(')')) {
6175  input = InpCp;
6176  } else if (c == QLatin1Char('|')) {
6177  input = InpPipe;
6178  } else if (c == QLatin1Char('C')) {
6179  input = InpC;
6180  } else if (c == QLatin1Char('E')) {
6181  input = InpE;
6182  } else if (c == QLatin1Char('I')) {
6183  input = InpI;
6184  } else if (c == QLatin1Char('M')) {
6185  input = InpM;
6186  } else if (c == QLatin1Char('N')) {
6187  input = InpN;
6188  } else if (c == QLatin1Char('O')) {
6189  input = InpO;
6190  } else if (c == QLatin1Char('R')) {
6191  input = InpR;
6192  } else if (c == QLatin1Char('S')) {
6193  input = InpS;
6194  } else if (c == QLatin1Char('Y')) {
6195  input = InpY;
6196  } else {
6197  input = InpUnknown;
6198  }
6199  state = table[state][input];
6200 
6201  switch (state) {
6202  case ST:
6203  parseString_s = QLatin1String("CDATA");
6204  if (!parseString()) {
6205  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6206  return false;
6207  }
6208  break;
6209  case TTI:
6210  parseString_s = QLatin1String("ID");
6211  if (!parseString()) {
6212  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6213  return false;
6214  }
6215  break;
6216  case TTI2:
6217  parseString_s = QLatin1String("REF");
6218  if (!parseString()) {
6219  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6220  return false;
6221  }
6222  break;
6223  case TTI3:
6224  next(); // S
6225  break;
6226  case TTE:
6227  parseString_s = QLatin1String("ENTIT");
6228  if (!parseString()) {
6229  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6230  return false;
6231  }
6232  break;
6233  case TTEY:
6234  next(); // Y
6235  break;
6236  case TTEI:
6237  parseString_s = QLatin1String("IES");
6238  if (!parseString()) {
6239  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6240  return false;
6241  }
6242  break;
6243  case N:
6244  next(); // N
6245  break;
6246  case TTNM:
6247  parseString_s = QLatin1String("MTOKEN");
6248  if (!parseString()) {
6249  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6250  return false;
6251  }
6252  break;
6253  case TTNM2:
6254  next(); // S
6255  break;
6256  case NO:
6257  parseString_s = QLatin1String("OTATION");
6258  if (!parseString()) {
6259  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6260  return false;
6261  }
6262  break;
6263  case NO2:
6264  if (!eat_ws()) {
6265  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6266  return false;
6267  }
6268  break;
6269  case NO3:
6270  if (!next_eat_ws()) {
6271  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6272  return false;
6273  }
6274  break;
6275  case NOName:
6276  parseName_useRef = false;
6277  if (!parseName()) {
6278  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6279  return false;
6280  }
6281  break;
6282  case NO4:
6283  if (!eat_ws()) {
6284  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6285  return false;
6286  }
6287  break;
6288  case EN:
6289  if (!next_eat_ws()) {
6290  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6291  return false;
6292  }
6293  break;
6294  case ENNmt:
6295  if (!parseNmtoken()) {
6296  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6297  return false;
6298  }
6299  break;
6300  case EN2:
6301  if (!eat_ws()) {
6302  parseFailed(&QXmlSimpleReaderPrivate::parseAttType, state);
6303  return false;
6304  }
6305  break;
6306  case ADone:
6307  next();
6308  break;
6309  }
6310  }
6311  return false;
6312 }
6313 
6314 /*
6315  Parse a AttValue [10]
6316 
6317  Precondition: the head stands on the beginning " or '
6318 
6319  If this function was successful, the head stands on the first
6320  character after the closing " or ' and the value of the attribute
6321  is in string().
6322 */
6324 {
6325  const signed char Init = 0;
6326  const signed char Dq = 1; // double quotes were read
6327  const signed char DqRef = 2; // read references in double quotes
6328  const signed char DqC = 3; // signed character read in double quotes
6329  const signed char Sq = 4; // single quotes were read
6330  const signed char SqRef = 5; // read references in single quotes
6331  const signed char SqC = 6; // signed character read in single quotes
6332  const signed char Done = 7;
6333 
6334  const signed char InpDq = 0; // "
6335  const signed char InpSq = 1; // '
6336  const signed char InpAmp = 2; // &
6337  const signed char InpLt = 3; // <
6338  const signed char InpUnknown = 4;
6339 
6340  static const signed char table[7][5] = {
6341  /* InpDq InpSq InpAmp InpLt InpUnknown */
6342  { Dq, Sq, -1, -1, -1 }, // Init
6343  { Done, DqC, DqRef, -1, DqC }, // Dq
6344  { Done, DqC, DqRef, -1, DqC }, // DqRef
6345  { Done, DqC, DqRef, -1, DqC }, // DqC
6346  { SqC, Done, SqRef, -1, SqC }, // Sq
6347  { SqC, Done, SqRef, -1, SqC }, // SqRef
6348  { SqC, Done, SqRef, -1, SqC } // SqRef
6349  };
6350  signed char state;
6351  signed char input;
6352 
6353  if (parseStack==0 || parseStack->isEmpty()) {
6354  state = Init;
6355  } else {
6356  state = parseStack->pop().state;
6357 #if defined(QT_QXML_DEBUG)
6358  qDebug("QXmlSimpleReader: parseAttValue (cont) in state %d", state);
6359 #endif
6360  if (!parseStack->isEmpty()) {
6361  ParseFunction function = parseStack->top().function;
6362  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
6363  parseStack->pop();
6364 #if defined(QT_QXML_DEBUG)
6365  qDebug("QXmlSimpleReader: eat_ws (cont)");
6366 #endif
6367  }
6368  if (!(this->*function)()) {
6369  parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
6370  return false;
6371  }
6372  }
6373  }
6374 
6375  for (;;) {
6376  switch (state) {
6377  case Done:
6378  return true;
6379  case -1:
6380  // Error
6381  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
6382  return false;
6383  }
6384 
6385  if (atEnd()) {
6386  unexpectedEof(&QXmlSimpleReaderPrivate::parseAttValue, state);
6387  return false;
6388  }
6389  if (c == QLatin1Char('"')) {
6390  input = InpDq;
6391  } else if (c == QLatin1Char('\'')) {
6392  input = InpSq;
6393  } else if (c == QLatin1Char('&')) {
6394  input = InpAmp;
6395  } else if (c == QLatin1Char('<')) {
6396  input = InpLt;
6397  } else {
6398  input = InpUnknown;
6399  }
6400  state = table[state][input];
6401 
6402  switch (state) {
6403  case Dq:
6404  case Sq:
6405  stringClear();
6406  next();
6407  break;
6408  case DqRef:
6409  case SqRef:
6410  parseReference_context = InAttributeValue;
6411  if (!parseReference()) {
6412  parseFailed(&QXmlSimpleReaderPrivate::parseAttValue, state);
6413  return false;
6414  }
6415  break;
6416  case DqC:
6417  case SqC:
6418  stringAddC();
6419  next();
6420  break;
6421  case Done:
6422  next();
6423  break;
6424  }
6425  }
6426  return false;
6427 }
6428 
6429 /*
6430  Parse a elementdecl [45].
6431 
6432  Precondition: the beginning '<!E' is already read and the head
6433  stands on the 'L' of '<!ELEMENT'
6434 */
6436 {
6437  const signed char Init = 0;
6438  const signed char Elem = 1; // parse the beginning string
6439  const signed char Ws1 = 2; // whitespace required
6440  const signed char Nam = 3; // parse Name
6441  const signed char Ws2 = 4; // whitespace required
6442  const signed char Empty = 5; // read EMPTY
6443  const signed char Any = 6; // read ANY
6444  const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
6445  const signed char Mix = 8; // read Mixed
6446  const signed char Mix2 = 9; //
6447  const signed char Mix3 = 10; //
6448  const signed char MixN1 = 11; //
6449  const signed char MixN2 = 12; //
6450  const signed char MixN3 = 13; //
6451  const signed char MixN4 = 14; //
6452  const signed char Cp = 15; // parse cp
6453  const signed char Cp2 = 16; //
6454  const signed char WsD = 17; // eat whitespace before Done
6455  const signed char Done = 18;
6456 
6457  const signed char InpWs = 0;
6458  const signed char InpGt = 1; // >
6459  const signed char InpPipe = 2; // |
6460  const signed char InpOp = 3; // (
6461  const signed char InpCp = 4; //)
6462  const signed char InpHash = 5; // #
6463  const signed char InpQm = 6; // ?
6464  const signed char InpAst = 7; // *
6465  const signed char InpPlus = 8; // +
6466  const signed char InpA = 9; // A
6467  const signed char InpE = 10; // E
6468  const signed char InpL = 11; // L
6469  const signed char InpUnknown = 12;
6470 
6471  static const signed char table[18][13] = {
6472  /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
6473  { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
6474  { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
6475  { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
6476  { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
6477  { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
6478  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
6479  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
6480  { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
6481  { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
6482  { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
6483  { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
6484  { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
6485  { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
6486  { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
6487  { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
6488  { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
6489  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
6490  { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
6491  };
6492  signed char state;
6493  signed char input;
6494 
6495  if (parseStack==0 || parseStack->isEmpty()) {
6496  state = Init;
6497  } else {
6498  state = parseStack->pop().state;
6499 #if defined(QT_QXML_DEBUG)
6500  qDebug("QXmlSimpleReader: parseElementDecl (cont) in state %d", state);
6501 #endif
6502  if (!parseStack->isEmpty()) {
6503  ParseFunction function = parseStack->top().function;
6504  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
6505  parseStack->pop();
6506 #if defined(QT_QXML_DEBUG)
6507  qDebug("QXmlSimpleReader: eat_ws (cont)");
6508 #endif
6509  }
6510  if (!(this->*function)()) {
6511  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6512  return false;
6513  }
6514  }
6515  }
6516 
6517  for (;;) {
6518  switch (state) {
6519  case Done:
6520  return true;
6521  case -1:
6522  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
6523  return false;
6524  }
6525 
6526  if (atEnd()) {
6527  unexpectedEof(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6528  return false;
6529  }
6530  if (is_S(c)) {
6531  input = InpWs;
6532  } else if (c == QLatin1Char('>')) {
6533  input = InpGt;
6534  } else if (c == QLatin1Char('|')) {
6535  input = InpPipe;
6536  } else if (c == QLatin1Char('(')) {
6537  input = InpOp;
6538  } else if (c == QLatin1Char(')')) {
6539  input = InpCp;
6540  } else if (c == QLatin1Char('#')) {
6541  input = InpHash;
6542  } else if (c == QLatin1Char('?')) {
6543  input = InpQm;
6544  } else if (c == QLatin1Char('*')) {
6545  input = InpAst;
6546  } else if (c == QLatin1Char('+')) {
6547  input = InpPlus;
6548  } else if (c == QLatin1Char('A')) {
6549  input = InpA;
6550  } else if (c == QLatin1Char('E')) {
6551  input = InpE;
6552  } else if (c == QLatin1Char('L')) {
6553  input = InpL;
6554  } else {
6555  input = InpUnknown;
6556  }
6557  state = table[state][input];
6558 
6559  switch (state) {
6560  case Elem:
6561  parseString_s = QLatin1String("LEMENT");
6562  if (!parseString()) {
6563  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6564  return false;
6565  }
6566  break;
6567  case Ws1:
6568  if (!eat_ws()) {
6569  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6570  return false;
6571  }
6572  break;
6573  case Nam:
6574  parseName_useRef = false;
6575  if (!parseName()) {
6576  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6577  return false;
6578  }
6579  break;
6580  case Ws2:
6581  if (!eat_ws()) {
6582  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6583  return false;
6584  }
6585  break;
6586  case Empty:
6587  parseString_s = QLatin1String("EMPTY");
6588  if (!parseString()) {
6589  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6590  return false;
6591  }
6592  break;
6593  case Any:
6594  parseString_s = QLatin1String("ANY");
6595  if (!parseString()) {
6596  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6597  return false;
6598  }
6599  break;
6600  case Cont:
6601  if (!next_eat_ws()) {
6602  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6603  return false;
6604  }
6605  break;
6606  case Mix:
6607  parseString_s = QLatin1String("#PCDATA");
6608  if (!parseString()) {
6609  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6610  return false;
6611  }
6612  break;
6613  case Mix2:
6614  if (!eat_ws()) {
6615  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6616  return false;
6617  }
6618  break;
6619  case Mix3:
6620  next();
6621  break;
6622  case MixN1:
6623  if (!next_eat_ws()) {
6624  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6625  return false;
6626  }
6627  break;
6628  case MixN2:
6629  parseName_useRef = false;
6630  if (!parseName()) {
6631  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6632  return false;
6633  }
6634  break;
6635  case MixN3:
6636  if (!eat_ws()) {
6637  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6638  return false;
6639  }
6640  break;
6641  case MixN4:
6642  next();
6643  break;
6644  case Cp:
6645  if (!parseChoiceSeq()) {
6646  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6647  return false;
6648  }
6649  break;
6650  case Cp2:
6651  next();
6652  break;
6653  case WsD:
6654  if (!next_eat_ws()) {
6655  parseFailed(&QXmlSimpleReaderPrivate::parseElementDecl, state);
6656  return false;
6657  }
6658  break;
6659  case Done:
6660  next();
6661  break;
6662  }
6663  }
6664  return false;
6665 }
6666 
6667 /*
6668  Parse a NotationDecl [82].
6669 
6670  Precondition: the beginning '<!' is already read and the head
6671  stands on the 'N' of '<!NOTATION'
6672 */
6674 {
6675  const signed char Init = 0;
6676  const signed char Not = 1; // read NOTATION
6677  const signed char Ws1 = 2; // eat whitespaces
6678  const signed char Nam = 3; // read Name
6679  const signed char Ws2 = 4; // eat whitespaces
6680  const signed char ExtID = 5; // parse ExternalID
6681  const signed char ExtIDR = 6; // same as ExtID, but already reported
6682  const signed char Ws3 = 7; // eat whitespaces
6683  const signed char Done = 8;
6684 
6685  const signed char InpWs = 0;
6686  const signed char InpGt = 1; // >
6687  const signed char InpN = 2; // N
6688  const signed char InpUnknown = 3;
6689 
6690  static const signed char table[8][4] = {
6691  /* InpWs InpGt InpN InpUnknown */
6692  { -1, -1, Not, -1 }, // Init
6693  { Ws1, -1, -1, -1 }, // Not
6694  { -1, -1, Nam, Nam }, // Ws1
6695  { Ws2, Done, -1, -1 }, // Nam
6696  { -1, Done, ExtID, ExtID }, // Ws2
6697  { Ws3, Done, -1, -1 }, // ExtID
6698  { Ws3, Done, -1, -1 }, // ExtIDR
6699  { -1, Done, -1, -1 } // Ws3
6700  };
6701  signed char state;
6702  signed char input;
6703 
6704  if (parseStack==0 || parseStack->isEmpty()) {
6705  state = Init;
6706  } else {
6707  state = parseStack->pop().state;
6708 #if defined(QT_QXML_DEBUG)
6709  qDebug("QXmlSimpleReader: parseNotationDecl (cont) in state %d", state);
6710 #endif
6711  if (!parseStack->isEmpty()) {
6712  ParseFunction function = parseStack->top().function;
6713  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
6714  parseStack->pop();
6715 #if defined(QT_QXML_DEBUG)
6716  qDebug("QXmlSimpleReader: eat_ws (cont)");
6717 #endif
6718  }
6719  if (!(this->*function)()) {
6720  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6721  return false;
6722  }
6723  }
6724  }
6725 
6726  for (;;) {
6727  switch (state) {
6728  case ExtID:
6729  // call the handler
6730  if (dtdHnd) {
6731  if (!dtdHnd->notationDecl(name(), publicId, systemId)) {
6732  reportParseError(dtdHnd->errorString());
6733  return false;
6734  }
6735  }
6736  state = ExtIDR;
6737  break;
6738  case Done:
6739  return true;
6740  case -1:
6741  // Error
6742  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
6743  return false;
6744  }
6745 
6746  if (atEnd()) {
6747  unexpectedEof(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6748  return false;
6749  }
6750  if (is_S(c)) {
6751  input = InpWs;
6752  } else if (c == QLatin1Char('>')) {
6753  input = InpGt;
6754  } else if (c == QLatin1Char('N')) {
6755  input = InpN;
6756  } else {
6757  input = InpUnknown;
6758  }
6759  state = table[state][input];
6760 
6761  switch (state) {
6762  case Not:
6763  parseString_s = QLatin1String("NOTATION");
6764  if (!parseString()) {
6765  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6766  return false;
6767  }
6768  break;
6769  case Ws1:
6770  if (!eat_ws()) {
6771  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6772  return false;
6773  }
6774  break;
6775  case Nam:
6776  parseName_useRef = false;
6777  if (!parseName()) {
6778  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6779  return false;
6780  }
6781  break;
6782  case Ws2:
6783  if (!eat_ws()) {
6784  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6785  return false;
6786  }
6787  break;
6788  case ExtID:
6789  case ExtIDR:
6790  parseExternalID_allowPublicID = true;
6791  if (!parseExternalID()) {
6792  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6793  return false;
6794  }
6795  break;
6796  case Ws3:
6797  if (!eat_ws()) {
6798  parseFailed(&QXmlSimpleReaderPrivate::parseNotationDecl, state);
6799  return false;
6800  }
6801  break;
6802  case Done:
6803  next();
6804  break;
6805  }
6806  }
6807  return false;
6808 }
6809 
6810 /*
6811  Parse choice [49] or seq [50].
6812 
6813  Precondition: the beginning '('S? is already read and the head
6814  stands on the first non-whitespace character after it.
6815 */
6817 {
6818  const signed char Init = 0;
6819  const signed char Ws1 = 1; // eat whitespace
6820  const signed char CoS = 2; // choice or set
6821  const signed char Ws2 = 3; // eat whitespace
6822  const signed char More = 4; // more cp to read
6823  const signed char Name = 5; // read name
6824  const signed char Done = 6; //
6825 
6826  const signed char InpWs = 0; // S
6827  const signed char InpOp = 1; // (
6828  const signed char InpCp = 2; //)
6829  const signed char InpQm = 3; // ?
6830  const signed char InpAst = 4; // *
6831  const signed char InpPlus = 5; // +
6832  const signed char InpPipe = 6; // |
6833  const signed char InpComm = 7; // ,
6834  const signed char InpUnknown = 8;
6835 
6836  static const signed char table[6][9] = {
6837  /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
6838  { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
6839  { -1, CoS, -1, -1, -1, -1, -1, -1, CoS }, // Ws1
6840  { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS
6841  { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
6842  { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
6843  { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS)
6844  };
6845  signed char state;
6846  signed char input;
6847 
6848  if (parseStack==0 || parseStack->isEmpty()) {
6849  state = Init;
6850  } else {
6851  state = parseStack->pop().state;
6852 #if defined(QT_QXML_DEBUG)
6853  qDebug("QXmlSimpleReader: parseChoiceSeq (cont) in state %d", state);
6854 #endif
6855  if (!parseStack->isEmpty()) {
6856  ParseFunction function = parseStack->top().function;
6857  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
6858  parseStack->pop();
6859 #if defined(QT_QXML_DEBUG)
6860  qDebug("QXmlSimpleReader: eat_ws (cont)");
6861 #endif
6862  }
6863  if (!(this->*function)()) {
6864  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6865  return false;
6866  }
6867  }
6868  }
6869 
6870  for (;;) {
6871  switch (state) {
6872  case Done:
6873  return true;
6874  case -1:
6875  // Error
6876  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
6877  return false;
6878  }
6879 
6880  if (atEnd()) {
6881  unexpectedEof(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6882  return false;
6883  }
6884  if (is_S(c)) {
6885  input = InpWs;
6886  } else if (c == QLatin1Char('(')) {
6887  input = InpOp;
6888  } else if (c == QLatin1Char(')')) {
6889  input = InpCp;
6890  } else if (c == QLatin1Char('?')) {
6891  input = InpQm;
6892  } else if (c == QLatin1Char('*')) {
6893  input = InpAst;
6894  } else if (c == QLatin1Char('+')) {
6895  input = InpPlus;
6896  } else if (c == QLatin1Char('|')) {
6897  input = InpPipe;
6898  } else if (c == QLatin1Char(',')) {
6899  input = InpComm;
6900  } else {
6901  input = InpUnknown;
6902  }
6903  state = table[state][input];
6904 
6905  switch (state) {
6906  case Ws1:
6907  if (!next_eat_ws()) {
6908  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6909  return false;
6910  }
6911  break;
6912  case CoS:
6913  if (!parseChoiceSeq()) {
6914  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6915  return false;
6916  }
6917  break;
6918  case Ws2:
6919  if (!next_eat_ws()) {
6920  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6921  return false;
6922  }
6923  break;
6924  case More:
6925  if (!next_eat_ws()) {
6926  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6927  return false;
6928  }
6929  break;
6930  case Name:
6931  parseName_useRef = false;
6932  if (!parseName()) {
6933  parseFailed(&QXmlSimpleReaderPrivate::parseChoiceSeq, state);
6934  return false;
6935  }
6936  break;
6937  case Done:
6938  next();
6939  break;
6940  }
6941  }
6942  return false;
6943 }
6944 
6946 {
6947  QString entityNameBuffer;
6948 
6949  // For every entity, check how many times all entity names were referenced in its value.
6950  for (QMap<QString,QString>::const_iterator toSearchIt = entities.constBegin();
6951  toSearchIt != entities.constEnd();
6952  ++toSearchIt) {
6953  const QString &toSearch = toSearchIt.key();
6954 
6955  // Don't check the same entities twice.
6956  if (!literalEntitySizes.contains(toSearch)) {
6957  // The amount of characters that weren't entity names, but literals, like 'X'.
6958  QString leftOvers = entities.value(toSearch);
6959  // How many times was entityName referenced by toSearch?
6960  for (QMap<QString,QString>::const_iterator referencedIt = entities.constBegin();
6961  referencedIt != entities.constEnd();
6962  ++referencedIt) {
6963  const QString &entityName = referencedIt.key();
6964 
6965  for (int i = 0; i < leftOvers.size() && i != -1; ) {
6966  entityNameBuffer = QLatin1Char('&') + entityName + QLatin1Char(';');
6967 
6968  i = leftOvers.indexOf(entityNameBuffer, i);
6969  if (i != -1) {
6970  leftOvers.remove(i, entityName.size() + 2);
6971  // The entityName we're currently trying to find was matched in this string; increase our count.
6972  ++referencesToOtherEntities[toSearch][entityName];
6973  }
6974  }
6975  }
6976  literalEntitySizes[toSearch] = leftOvers.size();
6977  }
6978  }
6979 
6980  for (QHash<QString, QHash<QString, int> >::const_iterator entityIt = referencesToOtherEntities.constBegin();
6981  entityIt != referencesToOtherEntities.constEnd();
6982  ++entityIt) {
6983  const QString &entity = entityIt.key();
6984 
6985  QHash<QString, int>::iterator expandedIt = expandedSizes.find(entity);
6986  if (expandedIt == expandedSizes.end()) {
6987  expandedIt = expandedSizes.insert(entity, literalEntitySizes.value(entity));
6988  for (QHash<QString, int>::const_iterator referenceIt = entityIt->constBegin();
6989  referenceIt != entityIt->constEnd();
6990  ++referenceIt) {
6991  const QString &referenceTo = referenceIt.key();
6992  const int references = referencesToOtherEntities.value(entity).value(referenceTo);
6993  // The total size of an entity's value is the expanded size of all of its referenced entities, plus its literal size.
6994  *expandedIt += expandedSizes.value(referenceTo) * references + literalEntitySizes.value(referenceTo) * references;
6995  }
6996 
6997  if (*expandedIt > entityCharacterLimit) {
6998  if (errorMessage) {
6999  *errorMessage = QString::fromLatin1("The XML entity \"%1\" expands to a string that is too large to process (%2 characters > %3).")
7000  .arg(entity, *expandedIt, entityCharacterLimit);
7001  }
7002  return true;
7003  }
7004  }
7005  }
7006  return false;
7007 }
7008 
7009 /*
7010  Parse a EntityDecl [70].
7011 
7012  Precondition: the beginning '<!E' is already read and the head
7013  stand on the 'N' of '<!ENTITY'
7014 */
7016 {
7017  const signed char Init = 0;
7018  const signed char Ent = 1; // parse "ENTITY"
7019  const signed char Ws1 = 2; // white space read
7020  const signed char Name = 3; // parse name
7021  const signed char Ws2 = 4; // white space read
7022  const signed char EValue = 5; // parse entity value
7023  const signed char EValueR = 6; // same as EValue, but already reported
7024  const signed char ExtID = 7; // parse ExternalID
7025  const signed char Ws3 = 8; // white space read
7026  const signed char Ndata = 9; // parse "NDATA"
7027  const signed char Ws4 = 10; // white space read
7028  const signed char NNam = 11; // parse name
7029  const signed char NNamR = 12; // same as NNam, but already reported
7030  const signed char PEDec = 13; // parse PEDecl
7031  const signed char Ws6 = 14; // white space read
7032  const signed char PENam = 15; // parse name
7033  const signed char Ws7 = 16; // white space read
7034  const signed char PEVal = 17; // parse entity value
7035  const signed char PEValR = 18; // same as PEVal, but already reported
7036  const signed char PEEID = 19; // parse ExternalID
7037  const signed char PEEIDR = 20; // same as PEEID, but already reported
7038  const signed char WsE = 21; // white space read
7039  const signed char Done = 22;
7040  const signed char EDDone = 23; // done, but also report an external, unparsed entity decl
7041 
7042  const signed char InpWs = 0; // white space
7043  const signed char InpPer = 1; // %
7044  const signed char InpQuot = 2; // " or '
7045  const signed char InpGt = 3; // >
7046  const signed char InpN = 4; // N
7047  const signed char InpUnknown = 5;
7048 
7049  static const signed char table[22][6] = {
7050  /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
7051  { -1, -1, -1, -1, Ent, -1 }, // Init
7052  { Ws1, -1, -1, -1, -1, -1 }, // Ent
7053  { -1, PEDec, -1, -1, Name, Name }, // Ws1
7054  { Ws2, -1, -1, -1, -1, -1 }, // Name
7055  { -1, -1, EValue, -1, -1, ExtID }, // Ws2
7056  { WsE, -1, -1, Done, -1, -1 }, // EValue
7057  { WsE, -1, -1, Done, -1, -1 }, // EValueR
7058  { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
7059  { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
7060  { Ws4, -1, -1, -1, -1, -1 }, // Ndata
7061  { -1, -1, -1, -1, NNam, NNam }, // Ws4
7062  { WsE, -1, -1, Done, -1, -1 }, // NNam
7063  { WsE, -1, -1, Done, -1, -1 }, // NNamR
7064  { Ws6, -1, -1, -1, -1, -1 }, // PEDec
7065  { -1, -1, -1, -1, PENam, PENam }, // Ws6
7066  { Ws7, -1, -1, -1, -1, -1 }, // PENam
7067  { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
7068  { WsE, -1, -1, Done, -1, -1 }, // PEVal
7069  { WsE, -1, -1, Done, -1, -1 }, // PEValR
7070  { WsE, -1, -1, Done, -1, -1 }, // PEEID
7071  { WsE, -1, -1, Done, -1, -1 }, // PEEIDR
7072  { -1, -1, -1, Done, -1, -1 } // WsE
7073  };
7074  signed char state;
7075  signed char input;
7076 
7077  if (parseStack==0 || parseStack->isEmpty()) {
7078  state = Init;
7079  } else {
7080  state = parseStack->pop().state;
7081 #if defined(QT_QXML_DEBUG)
7082  qDebug("QXmlSimpleReader: parseEntityDecl (cont) in state %d", state);
7083 #endif
7084  if (!parseStack->isEmpty()) {
7085  ParseFunction function = parseStack->top().function;
7086  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7087  parseStack->pop();
7088 #if defined(QT_QXML_DEBUG)
7089  qDebug("QXmlSimpleReader: eat_ws (cont)");
7090 #endif
7091  }
7092  if (!(this->*function)()) {
7093  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7094  return false;
7095  }
7096  }
7097  }
7098 
7099  for (;;) {
7100  switch (state) {
7101  case EValue:
7102  if ( !entityExist(name())) {
7103  QString errorMessage;
7104  if (isExpandedEntityValueTooLarge(&errorMessage)) {
7105  reportParseError(errorMessage);
7106  return false;
7107  }
7108 
7109  entities.insert(name(), string());
7110  if (declHnd) {
7111  if (!declHnd->internalEntityDecl(name(), string())) {
7112  reportParseError(declHnd->errorString());
7113  return false;
7114  }
7115  }
7116  }
7117  state = EValueR;
7118  break;
7119  case NNam:
7120  if ( !entityExist(name())) {
7121  externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, ref()));
7122  if (dtdHnd) {
7123  if (!dtdHnd->unparsedEntityDecl(name(), publicId, systemId, ref())) {
7124  reportParseError(declHnd->errorString());
7125  return false;
7126  }
7127  }
7128  }
7129  state = NNamR;
7130  break;
7131  case PEVal:
7132  if ( !entityExist(name())) {
7133  parameterEntities.insert(name(), string());
7134  if (declHnd) {
7135  if (!declHnd->internalEntityDecl(QLatin1Char('%') + name(), string())) {
7136  reportParseError(declHnd->errorString());
7137  return false;
7138  }
7139  }
7140  }
7141  state = PEValR;
7142  break;
7143  case PEEID:
7144  if ( !entityExist(name())) {
7145  externParameterEntities.insert(name(), QXmlSimpleReaderPrivate::ExternParameterEntity(publicId, systemId));
7146  if (declHnd) {
7147  if (!declHnd->externalEntityDecl(QLatin1Char('%') + name(), publicId, systemId)) {
7148  reportParseError(declHnd->errorString());
7149  return false;
7150  }
7151  }
7152  }
7153  state = PEEIDR;
7154  break;
7155  case EDDone:
7156  if ( !entityExist(name())) {
7157  externEntities.insert(name(), QXmlSimpleReaderPrivate::ExternEntity(publicId, systemId, QString()));
7158  if (declHnd) {
7159  if (!declHnd->externalEntityDecl(name(), publicId, systemId)) {
7160  reportParseError(declHnd->errorString());
7161  return false;
7162  }
7163  }
7164  }
7165  return true;
7166  case Done:
7167  return true;
7168  case -1:
7169  // Error
7170  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
7171  return false;
7172  }
7173 
7174  if (atEnd()) {
7175  unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7176  return false;
7177  }
7178  if (is_S(c)) {
7179  input = InpWs;
7180  } else if (c == QLatin1Char('%')) {
7181  input = InpPer;
7182  } else if (c == QLatin1Char('"') || c == QLatin1Char('\'')) {
7183  input = InpQuot;
7184  } else if (c == QLatin1Char('>')) {
7185  input = InpGt;
7186  } else if (c == QLatin1Char('N')) {
7187  input = InpN;
7188  } else {
7189  input = InpUnknown;
7190  }
7191  state = table[state][input];
7192 
7193  switch (state) {
7194  case Ent:
7195  parseString_s = QLatin1String("NTITY");
7196  if (!parseString()) {
7197  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7198  return false;
7199  }
7200  break;
7201  case Ws1:
7202  if (!eat_ws()) {
7203  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7204  return false;
7205  }
7206  break;
7207  case Name:
7208  parseName_useRef = false;
7209  if (!parseName()) {
7210  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7211  return false;
7212  }
7213  break;
7214  case Ws2:
7215  if (!eat_ws()) {
7216  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7217  return false;
7218  }
7219  break;
7220  case EValue:
7221  case EValueR:
7222  if (!parseEntityValue()) {
7223  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7224  return false;
7225  }
7226  break;
7227  case ExtID:
7228  parseExternalID_allowPublicID = false;
7229  if (!parseExternalID()) {
7230  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7231  return false;
7232  }
7233  break;
7234  case Ws3:
7235  if (!eat_ws()) {
7236  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7237  return false;
7238  }
7239  break;
7240  case Ndata:
7241  parseString_s = QLatin1String("NDATA");
7242  if (!parseString()) {
7243  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7244  return false;
7245  }
7246  break;
7247  case Ws4:
7248  if (!eat_ws()) {
7249  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7250  return false;
7251  }
7252  break;
7253  case NNam:
7254  case NNamR:
7255  parseName_useRef = true;
7256  if (!parseName()) {
7257  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7258  return false;
7259  }
7260  break;
7261  case PEDec:
7262  next();
7263  break;
7264  case Ws6:
7265  if (!eat_ws()) {
7266  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7267  return false;
7268  }
7269  break;
7270  case PENam:
7271  parseName_useRef = false;
7272  if (!parseName()) {
7273  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7274  return false;
7275  }
7276  break;
7277  case Ws7:
7278  if (!eat_ws()) {
7279  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7280  return false;
7281  }
7282  break;
7283  case PEVal:
7284  case PEValR:
7285  if (!parseEntityValue()) {
7286  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7287  return false;
7288  }
7289  break;
7290  case PEEID:
7291  case PEEIDR:
7292  parseExternalID_allowPublicID = false;
7293  if (!parseExternalID()) {
7294  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7295  return false;
7296  }
7297  break;
7298  case WsE:
7299  if (!eat_ws()) {
7300  parseFailed(&QXmlSimpleReaderPrivate::parseEntityDecl, state);
7301  return false;
7302  }
7303  break;
7304  case EDDone:
7305  next();
7306  break;
7307  case Done:
7308  next();
7309  break;
7310  }
7311  }
7312  return false;
7313 }
7314 
7315 /*
7316  Parse a EntityValue [9]
7317 */
7319 {
7320  const signed char Init = 0;
7321  const signed char Dq = 1; // EntityValue is double quoted
7322  const signed char DqC = 2; // signed character
7323  const signed char DqPER = 3; // PERefence
7324  const signed char DqRef = 4; // Reference
7325  const signed char Sq = 5; // EntityValue is double quoted
7326  const signed char SqC = 6; // signed character
7327  const signed char SqPER = 7; // PERefence
7328  const signed char SqRef = 8; // Reference
7329  const signed char Done = 9;
7330 
7331  const signed char InpDq = 0; // "
7332  const signed char InpSq = 1; // '
7333  const signed char InpAmp = 2; // &
7334  const signed char InpPer = 3; // %
7335  const signed char InpUnknown = 4;
7336 
7337  static const signed char table[9][5] = {
7338  /* InpDq InpSq InpAmp InpPer InpUnknown */
7339  { Dq, Sq, -1, -1, -1 }, // Init
7340  { Done, DqC, DqRef, DqPER, DqC }, // Dq
7341  { Done, DqC, DqRef, DqPER, DqC }, // DqC
7342  { Done, DqC, DqRef, DqPER, DqC }, // DqPER
7343  { Done, DqC, DqRef, DqPER, DqC }, // DqRef
7344  { SqC, Done, SqRef, SqPER, SqC }, // Sq
7345  { SqC, Done, SqRef, SqPER, SqC }, // SqC
7346  { SqC, Done, SqRef, SqPER, SqC }, // SqPER
7347  { SqC, Done, SqRef, SqPER, SqC } // SqRef
7348  };
7349  signed char state;
7350  signed char input;
7351 
7352  if (parseStack==0 || parseStack->isEmpty()) {
7353  state = Init;
7354  } else {
7355  state = parseStack->pop().state;
7356 #if defined(QT_QXML_DEBUG)
7357  qDebug("QXmlSimpleReader: parseEntityValue (cont) in state %d", state);
7358 #endif
7359  if (!parseStack->isEmpty()) {
7360  ParseFunction function = parseStack->top().function;
7361  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7362  parseStack->pop();
7363 #if defined(QT_QXML_DEBUG)
7364  qDebug("QXmlSimpleReader: eat_ws (cont)");
7365 #endif
7366  }
7367  if (!(this->*function)()) {
7368  parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
7369  return false;
7370  }
7371  }
7372  }
7373 
7374  for (;;) {
7375  switch (state) {
7376  case Done:
7377  return true;
7378  case -1:
7379  // Error
7380  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
7381  return false;
7382  }
7383 
7384  if (atEnd()) {
7385  unexpectedEof(&QXmlSimpleReaderPrivate::parseEntityValue, state);
7386  return false;
7387  }
7388  if (c == QLatin1Char('"')) {
7389  input = InpDq;
7390  } else if (c == QLatin1Char('\'')) {
7391  input = InpSq;
7392  } else if (c == QLatin1Char('&')) {
7393  input = InpAmp;
7394  } else if (c == QLatin1Char('%')) {
7395  input = InpPer;
7396  } else {
7397  input = InpUnknown;
7398  }
7399  state = table[state][input];
7400 
7401  switch (state) {
7402  case Dq:
7403  case Sq:
7404  stringClear();
7405  next();
7406  break;
7407  case DqC:
7408  case SqC:
7409  stringAddC();
7410  next();
7411  break;
7412  case DqPER:
7413  case SqPER:
7414  parsePEReference_context = InEntityValue;
7415  if (!parsePEReference()) {
7416  parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
7417  return false;
7418  }
7419  break;
7420  case DqRef:
7421  case SqRef:
7422  parseReference_context = InEntityValue;
7423  if (!parseReference()) {
7424  parseFailed(&QXmlSimpleReaderPrivate::parseEntityValue, state);
7425  return false;
7426  }
7427  break;
7428  case Done:
7429  next();
7430  break;
7431  }
7432  }
7433  return false;
7434 }
7435 
7436 /*
7437  Parse a comment [15].
7438 
7439  Precondition: the beginning '<!' of the comment is already read and the head
7440  stands on the first '-' of '<!--'.
7441 
7442  If this funktion was successful, the head-position is on the first
7443  character after the comment.
7444 */
7446 {
7447  const signed char Init = 0;
7448  const signed char Dash1 = 1; // the first dash was read
7449  const signed char Dash2 = 2; // the second dash was read
7450  const signed char Com = 3; // read comment
7451  const signed char Com2 = 4; // read comment (help state)
7452  const signed char ComE = 5; // finished reading comment
7453  const signed char Done = 6;
7454 
7455  const signed char InpDash = 0; // -
7456  const signed char InpGt = 1; // >
7457  const signed char InpUnknown = 2;
7458 
7459  static const signed char table[6][3] = {
7460  /* InpDash InpGt InpUnknown */
7461  { Dash1, -1, -1 }, // Init
7462  { Dash2, -1, -1 }, // Dash1
7463  { Com2, Com, Com }, // Dash2
7464  { Com2, Com, Com }, // Com
7465  { ComE, Com, Com }, // Com2
7466  { -1, Done, -1 } // ComE
7467  };
7468  signed char state;
7469  signed char input;
7470 
7471  if (parseStack==0 || parseStack->isEmpty()) {
7472  state = Init;
7473  } else {
7474  state = parseStack->pop().state;
7475 #if defined(QT_QXML_DEBUG)
7476  qDebug("QXmlSimpleReader: parseComment (cont) in state %d", state);
7477 #endif
7478  if (!parseStack->isEmpty()) {
7479  ParseFunction function = parseStack->top().function;
7480  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7481  parseStack->pop();
7482 #if defined(QT_QXML_DEBUG)
7483  qDebug("QXmlSimpleReader: eat_ws (cont)");
7484 #endif
7485  }
7486  if (!(this->*function)()) {
7487  parseFailed(&QXmlSimpleReaderPrivate::parseComment, state);
7488  return false;
7489  }
7490  }
7491  }
7492 
7493  for (;;) {
7494  switch (state) {
7495  case Dash2:
7496  stringClear();
7497  break;
7498  case Com2:
7499  // if next character is not a dash than don't skip it
7500  if (!atEnd() && c != QLatin1Char('-'))
7501  stringAddC(QLatin1Char('-'));
7502  break;
7503  case Done:
7504  return true;
7505  case -1:
7506  // Error
7507  reportParseError(QLatin1String(XMLERR_ERRORPARSINGCOMMENT));
7508  return false;
7509  }
7510 
7511  if (atEnd()) {
7512  unexpectedEof(&QXmlSimpleReaderPrivate::parseComment, state);
7513  return false;
7514  }
7515  if (c == QLatin1Char('-')) {
7516  input = InpDash;
7517  } else if (c == QLatin1Char('>')) {
7518  input = InpGt;
7519  } else {
7520  input = InpUnknown;
7521  }
7522  state = table[state][input];
7523 
7524  switch (state) {
7525  case Dash1:
7526  next();
7527  break;
7528  case Dash2:
7529  next();
7530  break;
7531  case Com:
7532  stringAddC();
7533  next();
7534  break;
7535  case Com2:
7536  next();
7537  break;
7538  case ComE:
7539  next();
7540  break;
7541  case Done:
7542  next();
7543  break;
7544  }
7545  }
7546  return false;
7547 }
7548 
7549 /*
7550  Parse an Attribute [41].
7551 
7552  Precondition: the head stands on the first character of the name
7553  of the attribute (i.e. all whitespaces are already parsed).
7554 
7555  The head stand on the next character after the end quotes. The
7556  variable name contains the name of the attribute and the variable
7557  string contains the value of the attribute.
7558 */
7560 {
7561  const int Init = 0;
7562  const int PName = 1; // parse name
7563  const int Ws = 2; // eat ws
7564  const int Eq = 3; // the '=' was read
7565  const int Quotes = 4; // " or ' were read
7566 
7567  const int InpNameBe = 0;
7568  const int InpEq = 1; // =
7569  const int InpDq = 2; // "
7570  const int InpSq = 3; // '
7571  const int InpUnknown = 4;
7572 
7573  static const int table[4][5] = {
7574  /* InpNameBe InpEq InpDq InpSq InpUnknown */
7575  { PName, -1, -1, -1, -1 }, // Init
7576  { -1, Eq, -1, -1, Ws }, // PName
7577  { -1, Eq, -1, -1, -1 }, // Ws
7578  { -1, -1, Quotes, Quotes, -1 } // Eq
7579  };
7580  int state;
7581  int input;
7582 
7583  if (parseStack==0 || parseStack->isEmpty()) {
7584  state = Init;
7585  } else {
7586  state = parseStack->pop().state;
7587 #if defined(QT_QXML_DEBUG)
7588  qDebug("QXmlSimpleReader: parseAttribute (cont) in state %d", state);
7589 #endif
7590  if (!parseStack->isEmpty()) {
7591  ParseFunction function = parseStack->top().function;
7592  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7593  parseStack->pop();
7594 #if defined(QT_QXML_DEBUG)
7595  qDebug("QXmlSimpleReader: eat_ws (cont)");
7596 #endif
7597  }
7598  if (!(this->*function)()) {
7599  parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
7600  return false;
7601  }
7602  }
7603  }
7604 
7605  for (;;) {
7606  switch (state) {
7607  case Quotes:
7608  // Done
7609  return true;
7610  case -1:
7611  // Error
7612  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
7613  return false;
7614  }
7615 
7616  if (atEnd()) {
7617  unexpectedEof(&QXmlSimpleReaderPrivate::parseAttribute, state);
7618  return false;
7619  }
7620  if (determineNameChar(c) == NameBeginning) {
7621  input = InpNameBe;
7622  } else if (c == QLatin1Char('=')) {
7623  input = InpEq;
7624  } else if (c == QLatin1Char('"')) {
7625  input = InpDq;
7626  } else if (c == QLatin1Char('\'')) {
7627  input = InpSq;
7628  } else {
7629  input = InpUnknown;
7630  }
7631  state = table[state][input];
7632 
7633  switch (state) {
7634  case PName:
7635  parseName_useRef = false;
7636  if (!parseName()) {
7637  parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
7638  return false;
7639  }
7640  break;
7641  case Ws:
7642  if (!eat_ws()) {
7643  parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
7644  return false;
7645  }
7646  break;
7647  case Eq:
7648  if (!next_eat_ws()) {
7649  parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
7650  return false;
7651  }
7652  break;
7653  case Quotes:
7654  if (!parseAttValue()) {
7655  parseFailed(&QXmlSimpleReaderPrivate::parseAttribute, state);
7656  return false;
7657  }
7658  break;
7659  }
7660  }
7661  return false;
7662 }
7663 
7664 /*
7665  Parse a Name [5] and store the name in name or ref (if useRef is true).
7666 */
7668 {
7669  const int Init = 0;
7670  const int Name1 = 1; // parse first character of the name
7671  const int Name = 2; // parse name
7672  const int Done = 3;
7673 
7674  static const int table[3][3] = {
7675  /* InpNameBe InpNameCh InpUnknown */
7676  { Name1, -1, -1 }, // Init
7677  { Name, Name, Done }, // Name1
7678  { Name, Name, Done } // Name
7679  };
7680  int state;
7681 
7682  if (parseStack==0 || parseStack->isEmpty()) {
7683  state = Init;
7684  } else {
7685  state = parseStack->pop().state;
7686 #if defined(QT_QXML_DEBUG)
7687  qDebug("QXmlSimpleReader: parseName (cont) in state %d", state);
7688 #endif
7689  if (!parseStack->isEmpty()) {
7690  ParseFunction function = parseStack->top().function;
7691  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7692  parseStack->pop();
7693 #if defined(QT_QXML_DEBUG)
7694  qDebug("QXmlSimpleReader: eat_ws (cont)");
7695 #endif
7696  }
7697  if (!(this->*function)()) {
7698  parseFailed(&QXmlSimpleReaderPrivate::parseName, state);
7699  return false;
7700  }
7701  }
7702  }
7703 
7704  for (;;) {
7705  switch (state) {
7706  case Done:
7707  return true;
7708  case -1:
7709  // Error
7710  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
7711  return false;
7712  }
7713 
7714  if (atEnd()) {
7715  unexpectedEof(&QXmlSimpleReaderPrivate::parseName, state);
7716  return false;
7717  }
7718 
7719  // we can safely do the (int) cast thanks to the Q_ASSERTs earlier in this function
7720  state = table[state][(int)fastDetermineNameChar(c)];
7721 
7722  switch (state) {
7723  case Name1:
7724  if (parseName_useRef) {
7725  refClear();
7726  refAddC();
7727  } else {
7728  nameClear();
7729  nameAddC();
7730  }
7731  next();
7732  break;
7733  case Name:
7734  if (parseName_useRef) {
7735  refAddC();
7736  } else {
7737  nameAddC();
7738  }
7739  next();
7740  break;
7741  }
7742  }
7743  return false;
7744 }
7745 
7746 /*
7747  Parse a Nmtoken [7] and store the name in name.
7748 */
7750 {
7751  const signed char Init = 0;
7752  const signed char NameF = 1;
7753  const signed char Name = 2;
7754  const signed char Done = 3;
7755 
7756  const signed char InpNameCh = 0; // NameChar without InpNameBe
7757  const signed char InpUnknown = 1;
7758 
7759  static const signed char table[3][2] = {
7760  /* InpNameCh InpUnknown */
7761  { NameF, -1 }, // Init
7762  { Name, Done }, // NameF
7763  { Name, Done } // Name
7764  };
7765  signed char state;
7766  signed char input;
7767 
7768  if (parseStack==0 || parseStack->isEmpty()) {
7769  state = Init;
7770  } else {
7771  state = parseStack->pop().state;
7772 #if defined(QT_QXML_DEBUG)
7773  qDebug("QXmlSimpleReader: parseNmtoken (cont) in state %d", state);
7774 #endif
7775  if (!parseStack->isEmpty()) {
7776  ParseFunction function = parseStack->top().function;
7777  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7778  parseStack->pop();
7779 #if defined(QT_QXML_DEBUG)
7780  qDebug("QXmlSimpleReader: eat_ws (cont)");
7781 #endif
7782  }
7783  if (!(this->*function)()) {
7784  parseFailed(&QXmlSimpleReaderPrivate::parseNmtoken, state);
7785  return false;
7786  }
7787  }
7788  }
7789 
7790  for (;;) {
7791  switch (state) {
7792  case Done:
7793  return true;
7794  case -1:
7795  // Error
7796  reportParseError(QLatin1String(XMLERR_LETTEREXPECTED));
7797  return false;
7798  }
7799 
7800  if (atEnd()) {
7801  unexpectedEof(&QXmlSimpleReaderPrivate::parseNmtoken, state);
7802  return false;
7803  }
7804  if (determineNameChar(c) == NotName) {
7805  input = InpUnknown;
7806  } else {
7807  input = InpNameCh;
7808  }
7809  state = table[state][input];
7810 
7811  switch (state) {
7812  case NameF:
7813  nameClear();
7814  nameAddC();
7815  next();
7816  break;
7817  case Name:
7818  nameAddC();
7819  next();
7820  break;
7821  }
7822  }
7823  return false;
7824 }
7825 
7826 /*
7827  Parse a Reference [67].
7828 
7829  parseReference_charDataRead is set to true if the reference must not be
7830  parsed. The character(s) which the reference mapped to are appended to
7831  string. The head stands on the first character after the reference.
7832 
7833  parseReference_charDataRead is set to false if the reference must be parsed.
7834  The charachter(s) which the reference mapped to are inserted at the reference
7835  position. The head stands on the first character of the replacement).
7836 */
7838 {
7839  // temporary variables (only used in very local context, so they don't
7840  // interfere with incremental parsing)
7841  uint tmp;
7842  bool ok;
7843 
7844  const signed char Init = 0;
7845  const signed char SRef = 1; // start of a reference
7846  const signed char ChRef = 2; // parse CharRef
7847  const signed char ChDec = 3; // parse CharRef decimal
7848  const signed char ChHexS = 4; // start CharRef hexadecimal
7849  const signed char ChHex = 5; // parse CharRef hexadecimal
7850  const signed char Name = 6; // parse name
7851  const signed char DoneD = 7; // done CharRef decimal
7852  const signed char DoneH = 8; // done CharRef hexadecimal
7853  const signed char DoneN = 9; // done EntityRef
7854 
7855  const signed char InpAmp = 0; // &
7856  const signed char InpSemi = 1; // ;
7857  const signed char InpHash = 2; // #
7858  const signed char InpX = 3; // x
7859  const signed char InpNum = 4; // 0-9
7860  const signed char InpHex = 5; // a-f A-F
7861  const signed char InpUnknown = 6;
7862 
7863  static const signed char table[8][7] = {
7864  /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
7865  { SRef, -1, -1, -1, -1, -1, -1 }, // Init
7866  { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
7867  { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
7868  { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
7869  { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
7870  { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
7871  { -1, DoneN, -1, -1, -1, -1, -1 } // Name
7872  };
7873  signed char state;
7874  signed char input;
7875 
7876  if (parseStack==0 || parseStack->isEmpty()) {
7877  parseReference_charDataRead = false;
7878  state = Init;
7879  } else {
7880  state = parseStack->pop().state;
7881 #if defined(QT_QXML_DEBUG)
7882  qDebug("QXmlSimpleReader: parseReference (cont) in state %d", state);
7883 #endif
7884  if (!parseStack->isEmpty()) {
7885  ParseFunction function = parseStack->top().function;
7886  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
7887  parseStack->pop();
7888 #if defined(QT_QXML_DEBUG)
7889  qDebug("QXmlSimpleReader: eat_ws (cont)");
7890 #endif
7891  }
7892  if (!(this->*function)()) {
7893  parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
7894  return false;
7895  }
7896  }
7897  }
7898 
7899  for (;;) {
7900  switch (state) {
7901  case DoneD:
7902  return true;
7903  case DoneH:
7904  return true;
7905  case DoneN:
7906  return true;
7907  case -1:
7908  // Error
7909  reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
7910  return false;
7911  }
7912 
7913  if (atEnd()) {
7914  unexpectedEof(&QXmlSimpleReaderPrivate::parseReference, state);
7915  return false;
7916  }
7917  if (c.row()) {
7918  input = InpUnknown;
7919  } else if (c.cell() == '&') {
7920  input = InpAmp;
7921  } else if (c.cell() == ';') {
7922  input = InpSemi;
7923  } else if (c.cell() == '#') {
7924  input = InpHash;
7925  } else if (c.cell() == 'x') {
7926  input = InpX;
7927  } else if ('0' <= c.cell() && c.cell() <= '9') {
7928  input = InpNum;
7929  } else if ('a' <= c.cell() && c.cell() <= 'f') {
7930  input = InpHex;
7931  } else if ('A' <= c.cell() && c.cell() <= 'F') {
7932  input = InpHex;
7933  } else {
7934  input = InpUnknown;
7935  }
7936  state = table[state][input];
7937 
7938  switch (state) {
7939  case SRef:
7940  refClear();
7941  next();
7942  break;
7943  case ChRef:
7944  next();
7945  break;
7946  case ChDec:
7947  refAddC();
7948  next();
7949  break;
7950  case ChHexS:
7951  next();
7952  break;
7953  case ChHex:
7954  refAddC();
7955  next();
7956  break;
7957  case Name:
7958  // read the name into the ref
7959  parseName_useRef = true;
7960  if (!parseName()) {
7961  parseFailed(&QXmlSimpleReaderPrivate::parseReference, state);
7962  return false;
7963  }
7964  break;
7965  case DoneD:
7966  tmp = ref().toUInt(&ok, 10);
7967  if (ok) {
7968  stringAddC(QChar(tmp));
7969  } else {
7970  reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
7971  return false;
7972  }
7973  parseReference_charDataRead = true;
7974  next();
7975  break;
7976  case DoneH:
7977  tmp = ref().toUInt(&ok, 16);
7978  if (ok) {
7979  stringAddC(QChar(tmp));
7980  } else {
7981  reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
7982  return false;
7983  }
7984  parseReference_charDataRead = true;
7985  next();
7986  break;
7987  case DoneN:
7988  if (!processReference())
7989  return false;
7990  next();
7991  break;
7992  }
7993  }
7994  return false;
7995 }
7996 
7997 /*
7998  Helper function for parseReference()
7999 */
8001 {
8002  QString reference = ref();
8003  if (reference == QLatin1String("amp")) {
8004  if (parseReference_context == InEntityValue) {
8005  // Bypassed
8006  stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('m')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char(';'));
8007  } else {
8008  // Included or Included in literal
8009  stringAddC(QLatin1Char('&'));
8010  }
8011  parseReference_charDataRead = true;
8012  } else if (reference == QLatin1String("lt")) {
8013  if (parseReference_context == InEntityValue) {
8014  // Bypassed
8015  stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('l')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
8016  } else {
8017  // Included or Included in literal
8018  stringAddC(QLatin1Char('<'));
8019  }
8020  parseReference_charDataRead = true;
8021  } else if (reference == QLatin1String("gt")) {
8022  if (parseReference_context == InEntityValue) {
8023  // Bypassed
8024  stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('g')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
8025  } else {
8026  // Included or Included in literal
8027  stringAddC(QLatin1Char('>'));
8028  }
8029  parseReference_charDataRead = true;
8030  } else if (reference == QLatin1String("apos")) {
8031  if (parseReference_context == InEntityValue) {
8032  // Bypassed
8033  stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('a')); stringAddC(QLatin1Char('p')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('s')); stringAddC(QLatin1Char(';'));
8034  } else {
8035  // Included or Included in literal
8036  stringAddC(QLatin1Char('\''));
8037  }
8038  parseReference_charDataRead = true;
8039  } else if (reference == QLatin1String("quot")) {
8040  if (parseReference_context == InEntityValue) {
8041  // Bypassed
8042  stringAddC(QLatin1Char('&')); stringAddC(QLatin1Char('q')); stringAddC(QLatin1Char('u')); stringAddC(QLatin1Char('o')); stringAddC(QLatin1Char('t')); stringAddC(QLatin1Char(';'));
8043  } else {
8044  // Included or Included in literal
8045  stringAddC(QLatin1Char('"'));
8046  }
8047  parseReference_charDataRead = true;
8048  } else {
8050  it = entities.find(reference);
8051  if (it != entities.end()) {
8052  // "Internal General"
8053  switch (parseReference_context) {
8054  case InContent:
8055  // Included
8056  if (!insertXmlRef(*it, reference, false))
8057  return false;
8058  parseReference_charDataRead = false;
8059  break;
8060  case InAttributeValue:
8061  // Included in literal
8062  if (!insertXmlRef(*it, reference, true))
8063  return false;
8064  parseReference_charDataRead = false;
8065  break;
8066  case InEntityValue:
8067  {
8068  // Bypassed
8069  stringAddC(QLatin1Char('&'));
8070  for (int i=0; i<(int)reference.length(); i++) {
8071  stringAddC(reference[i]);
8072  }
8073  stringAddC(QLatin1Char(';'));
8074  parseReference_charDataRead = true;
8075  }
8076  break;
8077  case InDTD:
8078  // Forbidden
8079  parseReference_charDataRead = false;
8081  return false;
8082  }
8083  } else {
8085  itExtern = externEntities.find(reference);
8086  if (itExtern == externEntities.end()) {
8087  // entity not declared
8088  // ### check this case for conformance
8089  if (parseReference_context == InEntityValue) {
8090  // Bypassed
8091  stringAddC(QLatin1Char('&'));
8092  for (int i=0; i<(int)reference.length(); i++) {
8093  stringAddC(reference[i]);
8094  }
8095  stringAddC(QLatin1Char(';'));
8096  parseReference_charDataRead = true;
8097  } else {
8098  // if we have some char data read, report it now
8099  if (parseReference_context == InContent) {
8100  if (contentCharDataRead) {
8101  if (reportWhitespaceCharData || !string().simplified().isEmpty()) {
8102  if (contentHnd != 0 && !contentHnd->characters(string())) {
8103  reportParseError(contentHnd->errorString());
8104  return false;
8105  }
8106  }
8107  stringClear();
8108  contentCharDataRead = false;
8109  }
8110  }
8111 
8112  if (contentHnd) {
8113  qt_xml_skipped_entity_in_content = parseReference_context == InContent;
8114  if (!contentHnd->skippedEntity(reference)) {
8116  reportParseError(contentHnd->errorString());
8117  return false; // error
8118  }
8120  }
8121  }
8122  } else if ((*itExtern).notation.isNull()) {
8123  // "External Parsed General"
8124  switch (parseReference_context) {
8125  case InContent:
8126  {
8127  // Included if validating
8128  bool skipIt = true;
8129  if (entityRes) {
8130  QXmlInputSource *ret = 0;
8131  if (!entityRes->resolveEntity((*itExtern).publicId, (*itExtern).systemId, ret)) {
8132  delete ret;
8133  reportParseError(entityRes->errorString());
8134  return false;
8135  }
8136  if (ret) {
8137  QString xmlRefString;
8138  QString buffer = ret->data();
8139  while (buffer.length()>0){
8140  xmlRefString += buffer;
8141  ret->fetchData();
8142  buffer = ret->data();
8143  }
8144  delete ret;
8145  if (!stripTextDecl(xmlRefString)) {
8146  reportParseError(QLatin1String(XMLERR_ERRORINTEXTDECL));
8147  return false;
8148  }
8149  if (!insertXmlRef(xmlRefString, reference, false))
8150  return false;
8151  skipIt = false;
8152  }
8153  }
8154  if (skipIt && contentHnd) {
8156  if (!contentHnd->skippedEntity(reference)) {
8158  reportParseError(contentHnd->errorString());
8159  return false; // error
8160  }
8162  }
8163  parseReference_charDataRead = false;
8164  } break;
8165  case InAttributeValue:
8166  // Forbidden
8167  parseReference_charDataRead = false;
8169  return false;
8170  case InEntityValue:
8171  {
8172  // Bypassed
8173  stringAddC(QLatin1Char('&'));
8174  for (int i=0; i<(int)reference.length(); i++) {
8175  stringAddC(reference[i]);
8176  }
8177  stringAddC(QLatin1Char(';'));
8178  parseReference_charDataRead = true;
8179  }
8180  break;
8181  case InDTD:
8182  // Forbidden
8183  parseReference_charDataRead = false;
8185  return false;
8186  }
8187  } else {
8188  // "Unparsed"
8189  // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
8190  // Forbidden
8191  parseReference_charDataRead = false;
8192  reportParseError(QLatin1String(XMLERR_UNPARSEDENTITYREFERENCE));
8193  return false; // error
8194  }
8195  }
8196  }
8197  return true; // no error
8198 }
8199 
8200 
8201 /*
8202  Parses over a simple string.
8203 
8204  After the string was successfully parsed, the head is on the first
8205  character after the string.
8206 */
8208 {
8209  const signed char InpCharExpected = 0; // the character that was expected
8210  const signed char InpUnknown = 1;
8211 
8212  signed char state; // state in this function is the position in the string s
8213  signed char input;
8214 
8215  if (parseStack==0 || parseStack->isEmpty()) {
8216  Done = parseString_s.length();
8217  state = 0;
8218  } else {
8219  state = parseStack->pop().state;
8220 #if defined(QT_QXML_DEBUG)
8221  qDebug("QXmlSimpleReader: parseString (cont) in state %d", state);
8222 #endif
8223  if (!parseStack->isEmpty()) {
8224  ParseFunction function = parseStack->top().function;
8225  if (function == &QXmlSimpleReaderPrivate::eat_ws) {
8226  parseStack->pop();
8227 #if defined(QT_QXML_DEBUG)
8228  qDebug("QXmlSimpleReader: eat_ws (cont)");
8229 #endif
8230  }
8231  if (!(this->*function)()) {
8232  parseFailed(&QXmlSimpleReaderPrivate::parseString, state);
8233  return false;
8234  }
8235  }
8236  }
8237 
8238  for (;;) {
8239  if (state == Done) {
8240  return true;
8241  }
8242 
8243  if (atEnd()) {
8244  unexpectedEof(&QXmlSimpleReaderPrivate::parseString, state);
8245  return false;
8246  }
8247  if (c == parseString_s[(int)state]) {
8248  input = InpCharExpected;
8249  } else {
8250  input = InpUnknown;
8251  }
8252  if (input == InpCharExpected) {
8253  state++;
8254  } else {
8255  // Error
8256  reportParseError(QLatin1String(XMLERR_UNEXPECTEDCHARACTER));
8257  return false;
8258  }
8259 
8260  next();
8261  }
8262  return false;
8263 }
8264 
8265 /*
8266  This private function inserts and reports an entity substitution. The
8267  substituted string is \a data and the name of the entity reference is \a
8268  name. If \a inLiteral is true, the entity is IncludedInLiteral (i.e., " and '
8269  must be quoted. Otherwise they are not quoted.
8270 
8271  This function returns false on error.
8272 */
8273 bool QXmlSimpleReaderPrivate::insertXmlRef(const QString &data, const QString &name, bool inLiteral)
8274 {
8275  if (inLiteral) {
8276  QString tmp = data;
8277  xmlRefStack.push(XmlRef(name, tmp.replace(QLatin1Char('\"'),
8278  QLatin1String("&quot;")).replace(QLatin1Char('\''), QLatin1String("&apos;"))));
8279  } else {
8280  xmlRefStack.push(XmlRef(name, data));
8281  }
8282  int n = qMax(parameterEntities.count(), entities.count());
8283  if (xmlRefStack.count() > n+1) {
8284  // recursive entities
8285  reportParseError(QLatin1String(XMLERR_RECURSIVEENTITIES));
8286  return false;
8287  }
8288  if (reportEntities && lexicalHnd) {
8289  if (!lexicalHnd->startEntity(name)) {
8290  reportParseError(lexicalHnd->errorString());
8291  return false;
8292  }
8293  }
8294  return true;
8295 }
8296 
8297 /*
8298  This private function moves the cursor to the next character.
8299 */
8301 {
8302  int count = xmlRefStack.size();
8303  while (count != 0) {
8304  if (xmlRefStack.top().isEmpty()) {
8305  xmlRefStack.pop_back();
8306  count--;
8307  } else {
8308  c = xmlRefStack.top().next();
8309  return;
8310  }
8311  }
8312 
8313  // the following could be written nicer, but since it is a time-critical
8314  // function, rather optimize for speed
8315  ushort uc = c.unicode();
8316  c = inputSource->next();
8317  // If we are not incremental parsing, we just skip over EndOfData chars to give the
8318  // parser an uninterrupted stream of document chars.
8319  if (c == QXmlInputSource::EndOfData && parseStack == 0)
8320  c = inputSource->next();
8321  if (uc == '\n') {
8322  lineNr++;
8323  columnNr = -1;
8324  } else if (uc == '\r') {
8325  if (c != QLatin1Char('\n')) {
8326  lineNr++;
8327  columnNr = -1;
8328  }
8329  }
8330  ++columnNr;
8331 }
8332 
8333 /*
8334  This private function moves the cursor to the next non-whitespace character.
8335  This function does not move the cursor if the actual cursor position is a
8336  non-whitespace charcter.
8337 
8338  Returns false when you use incremental parsing and this function reaches EOF
8339  with reading only whitespace characters. In this case it also poplulates the
8340  parseStack with useful information. In all other cases, this function returns
8341  true.
8342 */
8344 {
8345  while (!atEnd()) {
8346  if (!is_S(c)) {
8347  return true;
8348  }
8349  next();
8350  }
8351  if (parseStack != 0) {
8352  unexpectedEof(&QXmlSimpleReaderPrivate::eat_ws, 0);
8353  return false;
8354  }
8355  return true;
8356 }
8357 
8359 {
8360  next();
8361  return eat_ws();
8362 }
8363 
8364 
8365 /*
8366  This private function initializes the reader. \a i is the input source to
8367  read the data from.
8368 */
8370 {
8371  lineNr = 0;
8372  columnNr = -1;
8373  inputSource = const_cast<QXmlInputSource *>(i);
8374  initData();
8375 
8376  externParameterEntities.clear();
8377  parameterEntities.clear();
8378  externEntities.clear();
8379  entities.clear();
8380 
8381  tags.clear();
8382 
8383  doctype.clear();
8384  xmlVersion.clear();
8385  encoding.clear();
8386  standalone = QXmlSimpleReaderPrivate::Unknown;
8387  error.clear();
8388 }
8389 
8390 /*
8391  This private function initializes the XML data related variables. Especially,
8392  it reads the data from the input source.
8393 */
8395 {
8397  xmlRefStack.clear();
8398  next();
8399 }
8400 
8401 /*
8402  Returns true if a entity with the name \a e exists,
8403  otherwise returns false.
8404 */
8406 {
8407  if ( parameterEntities.find(e) == parameterEntities.end() &&
8408  externParameterEntities.find(e) == externParameterEntities.end() &&
8409  externEntities.find(e) == externEntities.end() &&
8410  entities.find(e) == entities.end()) {
8411  return false;
8412  } else {
8413  return true;
8414  }
8415 }
8416 
8418 {
8419  this->error = error;
8420  if (errorHnd) {
8421  if (this->error.isNull()) {
8422  const QXmlParseException ex(QLatin1String(XMLERR_OK), columnNr+1, lineNr+1,
8423  thisPublicId, thisSystemId);
8424  errorHnd->fatalError(ex);
8425  } else {
8426  const QXmlParseException ex(this->error, columnNr+1, lineNr+1,
8427  thisPublicId, thisSystemId);
8428  errorHnd->fatalError(ex);
8429  }
8430  }
8431 }
8432 
8433 /*
8434  This private function is called when a parsing function encounters an
8435  unexpected EOF. It decides what to do (depending on incremental parsing or
8436  not). \a where is a pointer to the function where the error occurred and \a
8437  state is the parsing state in this function.
8438 */
8439 void QXmlSimpleReaderPrivate::unexpectedEof(ParseFunction where, int state)
8440 {
8441  if (parseStack == 0) {
8442  reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
8443  } else {
8444  if (c == QXmlInputSource::EndOfDocument) {
8445  reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
8446  } else {
8447  pushParseState(where, state);
8448  }
8449  }
8450 }
8451 
8452 /*
8453  This private function is called when a parse...() function returned false. It
8454  determines if there was an error or if incremental parsing simply went out of
8455  data and does the right thing for the case. \a where is a pointer to the
8456  function where the error occurred and \a state is the parsing state in this
8457  function.
8458 */
8459 void QXmlSimpleReaderPrivate::parseFailed(ParseFunction where, int state)
8460 {
8461  if (parseStack!=0 && error.isNull()) {
8462  pushParseState(where, state);
8463  }
8464 }
8465 
8466 /*
8467  This private function pushes the function pointer \a function and state \a
8468  state to the parse stack. This is used when you are doing an incremental
8469  parsing and reach the end of file too early.
8470 
8471  Only call this function when d->parseStack!=0.
8472 */
8473 void QXmlSimpleReaderPrivate::pushParseState(ParseFunction function, int state)
8474 {
8476  ps.function = function;
8477  ps.state = state;
8478  parseStack->push(ps);
8479 }
8480 
8481 inline static void updateValue(QString &value, const QChar *array, int &arrayPos, int &valueLen)
8482 {
8483  value.resize(valueLen + arrayPos);
8484  memcpy(value.data() + valueLen, array, arrayPos * sizeof(QChar));
8485  valueLen += arrayPos;
8486  arrayPos = 0;
8487 }
8488 
8489 // use buffers instead of QString::operator+= when single characters are read
8491 {
8492  updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
8493  return stringValue;
8494 }
8496 {
8497  updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
8498  return nameValue;
8499 }
8501 {
8502  updateValue(refValue, refArray, refArrayPos, refValueLen);
8503  return refValue;
8504 }
8505 
8507 {
8508  if (stringArrayPos == 256)
8509  updateValue(stringValue, stringArray, stringArrayPos, stringValueLen);
8510  stringArray[stringArrayPos++] = ch;
8511 }
8513 {
8514  if (nameArrayPos == 256)
8515  updateValue(nameValue, nameArray, nameArrayPos, nameValueLen);
8516  nameArray[nameArrayPos++] = ch;
8517 }
8519 {
8520  if (refArrayPos == 256)
8521  updateValue(refValue, refArray, refArrayPos, refValueLen);
8522  refArray[refArrayPos++] = ch;
8523 }
void * property(const QString &name, bool *ok=0) const
Reimplemented Function
Definition: qxml.cpp:3551
static const signed char cltLt
Definition: qxml.cpp:90
static const ushort EndOfData
Definition: qxml.h:172
double d
Definition: qnumeric_p.h:62
void reset()
Resets this namespace support object ready for reuse.
Definition: qxml.cpp:978
virtual void fetchData()
This function reads more data from the device that was set during construction.
Definition: qxml.cpp:1551
void processName(const QString &, bool, QString &, QString &) const
Processes a raw XML 1.0 name in the current context by removing the prefix and looking it up among th...
Definition: qxml.cpp:864
void setDeclHandler(QXmlDeclHandler *handler)
Reimplemented Function
Definition: qxml.cpp:3665
QByteArray encodingDeclBytes
Definition: qxml.cpp:241
void popContext()
Reverts to the previous namespace context.
Definition: qxml.cpp:968
QStack< ParseState > * parseStack
Definition: qxml.cpp:387
static NameChar determineNameChar(QChar ch)
Definition: qxml.cpp:3437
The QXmlLocator class provides the XML handler classes with information about the parsing position wi...
Definition: qxml.h:285
#define Q_DUMMY_COMPARISON_OPERATOR(C)
Definition: qglobal.h:2104
QMap< QString, QString > entities
Definition: qxml.cpp:313
bool parseBeginOrContinue(int state, bool incremental)
Definition: qxml.cpp:3791
Category
This enum maps the Unicode character categories.
Definition: qchar.h:106
static bool stripTextDecl(QString &str)
Definition: qxml.cpp:189
unsigned char c[8]
Definition: qnumeric_p.h:62
The QXmlLexicalHandler class provides an interface to report the lexical content of XML data...
Definition: qxml.h:346
virtual bool skippedEntity(const QString &name)=0
Some readers may skip entities if they have not seen the declarations (e.
bool endPrefixMapping(const QString &prefix)
This reimplementation does nothing.
Definition: qxml.cpp:2691
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
virtual QString errorString() const =0
The reader calls this function to get an error string if any of the handler functions returns false...
QString value(int index) const
Returns an attribute&#39;s value for the attribute at position index.
Definition: qxml.cpp:1192
QString localName(int index) const
Looks up an attribute&#39;s local name for the attribute at position index.
Definition: qxml.cpp:1114
bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)
This reimplementation does nothing.
Definition: qxml.cpp:2838
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
#define XMLERR_UNEXPECTEDCHARACTER
Definition: qxml.cpp:66
bool processElementAttribute()
Definition: qxml.cpp:4410
virtual bool waitForReadyRead(int msecs)
Blocks until new data is available for reading and the readyRead() signal has been emitted...
Definition: qiodevice.cpp:1616
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
#define XMLERR_OK
Definition: qxml.cpp:59
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
virtual ~QXmlSimpleReader()
Destroys the simple XML reader.
Definition: qxml.cpp:3454
virtual QString errorString() const =0
The reader calls this function to get an error string if any of the handler functions returns false...
virtual bool parseContinue()
Continues incremental parsing, taking input from the QXmlInputSource that was specified with the most...
Definition: qxml.cpp:3778
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
QXmlNamespaceSupport()
Constructs a QXmlNamespaceSupport.
Definition: qxml.cpp:765
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
QXmlSimpleReader()
Constructs a simple XML reader.
Definition: qxml.cpp:3446
bool processElementEmptyTag()
Definition: qxml.cpp:4308
#define it(className, varName)
QString type(int index) const
Looks up an attribute&#39;s type for the attribute at position index.
Definition: qxml.cpp:1148
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
bool hasFeature(const QString &name) const
Reimplemented Function
Definition: qxml.cpp:3536
void QT_FASTCALL next()
Definition: qxml.cpp:8300
QIODevice * inputDevice
Definition: qxml.cpp:229
static const signed char cltEm
Definition: qxml.cpp:93
#define XMLERR_ERRORPARSINGDOCTYPE
Definition: qxml.cpp:72
int index(const QString &qName) const
Looks up the index of an attribute by the qualified name qName.
Definition: qxml.cpp:1041
QXmlParseExceptionPrivate(const QXmlParseExceptionPrivate &other)
Definition: qxml.cpp:252
ExternEntity(const QString &p, const QString &s, const QString &n)
Definition: qxml.cpp:303
#define error(msg)
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
bool notationDecl(const QString &name, const QString &publicId, const QString &systemId)
This reimplementation does nothing.
Definition: qxml.cpp:2824
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QXmlAttributes attList
Definition: qxml.cpp:358
The QTextDecoder class provides a state-based decoder.
Definition: qtextcodec.h:177
bool parse(const QXmlInputSource &input)
Reimplemented Function
Definition: qxml.cpp:3685
QTextDecoder * encMapper
Definition: qxml.cpp:238
static const signed char cltSlash
Definition: qxml.cpp:91
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
static const signed char cltOB
Definition: qxml.cpp:96
int count(const Key &key) const
Returns the number of items associated with key key.
Definition: qmap.h:539
int size() const
Returns the number of (key, value) pairs in the map.
Definition: qmap.h:201
static const signed char cltWS
Definition: qxml.cpp:86
virtual void reset()
This function sets the position used by next() to the beginning of the data returned by data()...
Definition: qxml.cpp:1479
static const char nameCharTable[128]
Definition: qxml.cpp:3392
The QXmlNamespaceSupport class is a helper class for XML readers which want to include namespace supp...
Definition: qxml.h:88
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QXmlSimpleReaderPrivate(QXmlSimpleReader *reader)
Definition: qxml.cpp:3029
#define XMLERR_TAGMISMATCH
Definition: qxml.cpp:64
QTextDecoder * makeDecoder() const
Creates a QTextDecoder which stores enough state to decode chunks of char * data to create chunks of ...
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define XMLERR_VERSIONEXPECTED
Definition: qxml.cpp:68
#define XMLERR_ERRORPARSINGELEMENT
Definition: qxml.cpp:63
QXmlLexicalHandler * lexicalHnd
Definition: qxml.cpp:405
iterator find(const Key &key)
Returns an iterator pointing to the item with key key in the map.
Definition: qmap.h:618
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)=0
The reader calls this function when it has parsed a start element tag.
#define XMLERR_INTERNALGENERALENTITYINDTD
Definition: qxml.cpp:76
bool hasProperty(const QString &name) const
Reimplemented Function
Definition: qxml.cpp:3567
QXmlParseException(const QString &name=QString(), int c=-1, int l=-1, const QString &p=QString(), const QString &s=QString())
Constructs a parse exception with the error string name for column c and line l for the public identi...
Definition: qxml.cpp:572
static const char NotN
Definition: qxml.cpp:3390
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setProperty(const QString &name, void *value)
Reimplemented Function
Definition: qxml.cpp:3560
bool skippedEntity(const QString &name)
This reimplementation does nothing.
Definition: qxml.cpp:2772
QXmlLexicalHandler * lexicalHandler() const
Reimplemented Function
Definition: qxml.cpp:3656
int count() const
Returns the number of attributes in the list.
Definition: qxml.h:420
void setErrorHandler(QXmlErrorHandler *handler)
Reimplemented Function
Definition: qxml.cpp:3629
virtual bool startDTD(const QString &name, const QString &publicId, const QString &systemId)=0
The reader calls this function to report the start of a DTD declaration, if any.
QStringList prefixes() const
Returns a list of all the prefixes currently declared.
Definition: qxml.cpp:901
bool endCDATA()
This reimplementation does nothing.
Definition: qxml.cpp:2946
The QXmlErrorHandler class provides an interface to report errors in XML data.
Definition: qxml.h:319
static QString extractEncodingDecl(const QString &text, bool *needMoreText)
Definition: qxml.cpp:1596
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool reportWhitespaceCharData
Definition: qxml.cpp:354
#define XMLERR_MORETHANONEDOCTYPE
Definition: qxml.cpp:62
The QXmlDTDHandler class provides an interface to report DTD content of XML data. ...
Definition: qxml.h:329
QScopedPointer< QXmlSimpleReaderPrivate > d_ptr
Definition: qxml.h:276
#define Q_D(Class)
Definition: qglobal.h:2482
QTextStream * inputStream
Definition: qxml.cpp:230
virtual QString fromRawData(const QByteArray &data, bool beginning=false)
This function reads the XML file from data and tries to recognize the encoding.
Definition: qxml.cpp:1650
static const signed char cltQm
Definition: qxml.cpp:92
#define XMLERR_UNPARSEDENTITYREFERENCE
Definition: qxml.cpp:79
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
#define QT_FASTCALL
Definition: qglobal.h:1161
#define XMLERR_SDDECLEXPECTED
Definition: qxml.cpp:71
QXmlSimpleReader * reader
Definition: qxml.cpp:712
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
int columnNumber() const
Returns the column number (starting at 1) or -1 if there is no column number available.
Definition: qxml.cpp:700
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
bool insertXmlRef(const QString &, const QString &, bool)
Definition: qxml.cpp:8273
bool parseExternalID_allowPublicID
Definition: qxml.cpp:377
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
Category category() const
Returns the character&#39;s category.
Definition: qchar.cpp:853
iterator Iterator
Qt-style synonym for QList::iterator.
Definition: qlist.h:278
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void setLexicalHandler(QXmlLexicalHandler *handler)
Reimplemented Function
Definition: qxml.cpp:3647
bool qt_xml_skipped_entity_in_content
Definition: qxml.cpp:104
static const signed char cltAmp
Definition: qxml.cpp:88
void unexpectedEof(ParseFunction where, int state)
Definition: qxml.cpp:8439
static const signed char cltSq
Definition: qxml.cpp:99
void parseFailed(ParseFunction where, int state)
Definition: qxml.cpp:8459
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
T pop()
Removes the top item from the stack and returns it.
Definition: qstack.h:67
void pop_back()
This function is provided for STL compatibility.
Definition: qvector.h:283
Q_CORE_EXPORT void qDebug(const char *,...)
bool characters(const QString &ch)
This reimplementation does nothing.
Definition: qxml.cpp:2732
The QXmlSimpleReader class provides an implementation of a simple XML parser.
Definition: qxml.h:241
bool nextReturnedEndOfData
Definition: qxml.cpp:236
#define QT_RETHROW
Definition: qglobal.h:1539
unsigned char uchar
Definition: qglobal.h:994
bool startEntity(const QString &name)
This reimplementation does nothing.
Definition: qxml.cpp:2907
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void pushParseState(ParseFunction function, int state)
Definition: qxml.cpp:8473
virtual ~QXmlInputSource()
Destructor.
Definition: qxml.cpp:1417
static const signed char cltUnknown
Definition: qxml.cpp:100
#define XMLERR_LETTEREXPECTED
Definition: qxml.cpp:73
QStack< XmlRef > xmlRefStack
Definition: qxml.cpp:327
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual bool attributeDecl(const QString &eName, const QString &aName, const QString &type, const QString &valueDefault, const QString &value)=0
The reader calls this function to report an attribute type declaration.
virtual QString errorString() const =0
The reader calls this function to get an error string if any of the handler functions returns false...
bool isOpen() const
Returns true if the device is open; otherwise returns false.
Definition: qiodevice.cpp:530
QXmlLocator()
Constructor.
Definition: qxml.cpp:658
static FILE * stream
static bool isEmpty(const char *str)
bool endDTD()
This reimplementation does nothing.
Definition: qxml.cpp:2894
bool startCDATA()
This reimplementation does nothing.
Definition: qxml.cpp:2933
#define XMLERR_ERRORPARSINGREFERENCE
Definition: qxml.cpp:75
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
void setContentHandler(QXmlContentHandler *handler)
Reimplemented Function
Definition: qxml.cpp:3611
virtual bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)=0
The reader calls this function when it finds an unparsed entity declaration.
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
bool entityExist(const QString &) const
Definition: qxml.cpp:8405
static bool is_S(QChar ch)
Definition: qxml.cpp:3380
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define XMLERR_ERRORPARSINGCOMMENT
Definition: qxml.cpp:74
static bool init
Standalone standalone
Definition: qxml.cpp:335
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
Definition: qmime_win.cpp:141
const char * name
#define XMLERR_ERRORPARSINGCONTENT
Definition: qxml.cpp:65
void reportParseError(const QString &error)
Definition: qxml.cpp:8417
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
int lineNumber() const
Returns the line number (starting at 1) or -1 if there is no line number available.
Definition: qxml.cpp:704
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
virtual void setData(const QString &dat)
Sets the data of the input source to dat.
Definition: qxml.cpp:1509
bool lookingForEncodingDecl
Definition: qxml.cpp:243
XmlRef(const QString &_name, const QString &_value)
Definition: qxml.cpp:319
QXmlSimpleReaderLocator(QXmlSimpleReader *parent)
Definition: qxml.cpp:692
#define XMLERR_INVALIDNAMEFORPI
Definition: qxml.cpp:67
Q_CORE_EXPORT void qWarning(const char *,...)
#define XMLERR_ERRORINTEXTDECL
Definition: qxml.cpp:81
virtual int mibEnum() const =0
Subclasses of QTextCodec must reimplement this function.
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QMap< QString, ExternParameterEntity > externParameterEntities
Definition: qxml.cpp:310
static QTextCodec * codec(MYSQL *mysql)
Definition: qsql_mysql.cpp:220
virtual bool comment(const QString &ch)=0
The reader calls this function to report an XML comment anywhere in the document. ...
QXmlContentHandler * contentHandler() const
Reimplemented Function
Definition: qxml.cpp:3620
int mib
int columnNumber() const
Returns the column number where the error occurred.
Definition: qxml.cpp:609
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
static QTextCodec * codecForMib(int mib)
Returns the QTextCodec which matches the MIBenum mib.
bool parseReference_charDataRead
Definition: qxml.cpp:375
The QXmlContentHandler class provides an interface to report the logical content of XML data...
Definition: qxml.h:301
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
#define XMLERR_RECURSIVEENTITIES
Definition: qxml.cpp:80
ushort Char
__int64 qint64
Definition: qglobal.h:942
QXmlDeclHandler * declHnd
Definition: qxml.cpp:406
bool internalEntityDecl(const QString &name, const QString &value)
This reimplementation does nothing.
Definition: qxml.cpp:2985
bool startPrefixMapping(const QString &prefix, const QString &uri)
This reimplementation does nothing.
Definition: qxml.cpp:2678
void setEntityResolver(QXmlEntityResolver *handler)
Reimplemented Function
Definition: qxml.cpp:3575
virtual QString data() const
Returns the data the input source contains or an empty string if the input source does not contain an...
Definition: qxml.cpp:1491
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the map.
Definition: qmap.h:374
virtual bool startEntity(const QString &name)=0
The reader calls this function to report the start of an entity called name.
bool processingInstruction(const QString &target, const QString &data)
This reimplementation does nothing.
Definition: qxml.cpp:2758
~QXmlNamespaceSupport()
Destroys a QXmlNamespaceSupport.
Definition: qxml.cpp:773
#define QT_CATCH(A)
Definition: qglobal.h:1537
void push(const T &t)
Adds element t to the top of the stack.
Definition: qstack.h:60
#define XMLERR_EXTERNALGENERALENTITYINDTD
Definition: qxml.cpp:78
static const signed char cltPer
Definition: qxml.cpp:87
virtual bool notationDecl(const QString &name, const QString &publicId, const QString &systemId)=0
The reader calls this function when it has parsed a notation declaration.
virtual bool processingInstruction(const QString &target, const QString &data)=0
The reader calls this function when it has parsed a processing instruction.
void reset(T *other=0)
Deletes the existing object it is pointing to if any, and sets its pointer to other.
static void updateValue(QString &value, const QChar *array, int &arrayPos, int &valueLen)
Definition: qxml.cpp:8481
bool startDTD(const QString &name, const QString &publicId, const QString &systemId)
This reimplementation does nothing.
Definition: qxml.cpp:2881
QXmlEntityResolver * entityRes
Definition: qxml.cpp:404
bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)
This reimplementation does nothing.
Definition: qxml.cpp:2998
QHash< QString, int > expandedSizes
Definition: qxml.cpp:431
void setDTDHandler(QXmlDTDHandler *handler)
Reimplemented Function
Definition: qxml.cpp:3593
virtual bool endDocument()=0
The reader calls this function after it has finished parsing.
bool comment(const QString &ch)
This reimplementation does nothing.
Definition: qxml.cpp:2959
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
virtual bool startCDATA()=0
The reader calls this function to report the start of a CDATA section.
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QXmlNamespaceSupport namespaceSupport
Definition: qxml.cpp:366
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
QHash< QString, int > literalEntitySizes
Definition: qxml.cpp:428
QString message() const
Returns the error message.
Definition: qxml.cpp:602
static const signed char cltDash
Definition: qxml.cpp:94
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:380
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
virtual bool endEntity(const QString &name)=0
The reader calls this function to report the end of an entity called name.
virtual bool endPrefixMapping(const QString &prefix)=0
The reader calls this function to signal the end of a prefix mapping for the prefix prefix...
ExternParameterEntity(const QString &p, const QString &s)
Definition: qxml.cpp:293
bool isExpandedEntityValueTooLarge(QString *errorMessage)
Definition: qxml.cpp:6945
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
QXmlErrorHandler * errorHnd
Definition: qxml.cpp:402
~QXmlParseException()
Destroys the QXmlParseException.
Definition: qxml.cpp:595
QString & append(QChar c)
Definition: qstring.cpp:1777
QMap< QString, QString > parameterEntities
Definition: qxml.cpp:311
void initIncrementalParsing()
Definition: qxml.cpp:3054
bool endEntity(const QString &name)
This reimplementation does nothing.
Definition: qxml.cpp:2920
void * fetchData(QTestData *data, const char *tagName, int typeId)
Definition: qtestcase.cpp:1635
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
static const signed char cltGt
Definition: qxml.cpp:89
int length() const
Returns the number of attributes in the list.
Definition: qxml.cpp:1092
#define XMLERR_EXTERNALGENERALENTITYINAV
Definition: qxml.cpp:77
NameChar
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
QString uri(int index) const
Looks up an attribute&#39;s namespace URI for the attribute at position index.
Definition: qxml.cpp:1137
static const char Begi
Definition: qxml.cpp:3388
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:73
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
unsigned short ushort
Definition: qglobal.h:995
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
static const signed char cltDq
Definition: qxml.cpp:98
QString systemId() const
Returns the system identifier where the error occurred.
Definition: qxml.cpp:630
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
virtual QString errorString() const =0
The reader calls this function to get an error string, e.
QMap< QString, QString > NamespaceMap
Definition: qxml.cpp:721
EntityRecognitionContext parseReference_context
Definition: qxml.cpp:376
void resize(int size)
Sets the size of the byte array to size bytes.
QXmlEntityResolver * entityResolver() const
Reimplemented Function
Definition: qxml.cpp:3584
QString errorString() const
Returns the default error string.
Definition: qxml.cpp:2868
bool warning(const QXmlParseException &exception)
This reimplementation does nothing.
Definition: qxml.cpp:2785
const QString & name()
Definition: qxml.cpp:8495
QStack< NamespaceMap > nsStack
Definition: qxml.cpp:735
virtual bool characters(const QString &ch)=0
The reader calls this function when it has parsed a chunk of character data (either normal character ...
virtual bool endCDATA()=0
The reader calls this function to report the end of a CDATA section.
virtual ~QXmlLocator()
Destructor.
Definition: qxml.cpp:665
uint toUInt(bool *ok=0, int base=10) const
Returns the string converted to an unsigned int using base base, which is 10 by default and must be b...
Definition: qstring.cpp:6120
uchar cell() const
Returns the cell (least significant byte) of the Unicode character.
Definition: qchar.h:283
EntityRecognitionContext parsePEReference_context
Definition: qxml.cpp:378
signed char Done
Definition: qxml.cpp:397
QString qName(int index) const
Looks up an attribute&#39;s XML 1.0 qualified name for the attribute at position index.
Definition: qxml.cpp:1125
QFactoryLoader * l
void splitName(const QString &, QString &, QString &) const
Splits the name qname at the &#39;:&#39; and returns the prefix in prefix and the local name in localname...
Definition: qxml.cpp:836
void init()
Definition: qxml.cpp:1342
QXmlDTDHandler * dtdHnd
Definition: qxml.cpp:403
static QTextCodec * codecForName(const QByteArray &name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is c...
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
bool fatalError(const QXmlParseException &exception)
This reimplementation does nothing.
Definition: qxml.cpp:2811
bool resolveEntity(const QString &publicId, const QString &systemId, QXmlInputSource *&ret)
Sets ret to 0, so that the reader uses the system identifier provided in the XML document.
Definition: qxml.cpp:2853
static const signed char cltEq
Definition: qxml.cpp:97
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
QXmlInputSourcePrivate * d
Definition: qxml.h:185
virtual bool open(OpenMode mode)
Opens the device and sets its OpenMode to mode.
Definition: qiodevice.cpp:570
quint16 index
virtual bool endDTD()=0
The reader calls this function to report the end of a DTD declaration, if any.
void init(const QXmlInputSource *i)
Definition: qxml.cpp:8369
const QString & ref()
Definition: qxml.cpp:8500
bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
This reimplementation does nothing.
Definition: qxml.cpp:2704
QString prefix(const QString &) const
Returns one of the prefixes mapped to the namespace URI uri.
Definition: qxml.cpp:809
The QXmlAttributes class provides XML attributes.
Definition: qxml.h:119
QString publicId() const
Returns the public identifier where the error occurred.
Definition: qxml.cpp:623
bool error(const QXmlParseException &exception)
This reimplementation does nothing.
Definition: qxml.cpp:2798
QScopedPointer< QXmlLocator > locator
Definition: qxml.cpp:365
QXmlDTDHandler * DTDHandler() const
Reimplemented Function
Definition: qxml.cpp:3602
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
The QXmlEntityResolver class provides an interface to resolve external entities contained in XML data...
Definition: qxml.h:338
static const char NtBg
Definition: qxml.cpp:3389
QHash< QString, QHash< QString, int > > referencesToOtherEntities
Definition: qxml.cpp:430
bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
This reimplementation does nothing.
Definition: qxml.cpp:2718
The QXmlDeclHandler class provides an interface to report declaration content of XML data...
Definition: qxml.h:360
QString encodingDeclChars
Definition: qxml.cpp:242
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
virtual bool resolveEntity(const QString &publicId, const QString &systemId, QXmlInputSource *&ret)=0
The reader calls this function before it opens any external entity, except the top-level document ent...
static const signed char charLookupTable[256]
Definition: qxml.cpp:107
void setPrefix(const QString &, const QString &)
This function declares a prefix pre in the current namespace context to be the namespace URI uri...
Definition: qxml.cpp:790
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
static const signed char cltCB
Definition: qxml.cpp:95
void append(const QString &qName, const QString &uri, const QString &localPart, const QString &value)
Appends a new attribute entry to the list of attributes.
Definition: qxml.cpp:1273
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
The QXmlInputSource class provides the input data for the QXmlReader subclasses.
Definition: qxml.h:158
#define XMLERR_UNEXPECTEDEOF
Definition: qxml.cpp:61
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
QImageIOHandler * handler
QXmlInputSource * inputSource
Definition: qxml.cpp:408
#define class
virtual QString errorString() const =0
The reader calls this function to get an error string if any of the handler functions returns false...
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
#define XMLERR_WRONGVALUEFORSDECL
Definition: qxml.cpp:69
const QString & string()
Definition: qxml.cpp:8490
void setFeature(const QString &name, bool value)
Turns on the feature name if enable is true; otherwise turns it off.
Definition: qxml.cpp:3517
bool startDocument()
This reimplementation does nothing.
Definition: qxml.cpp:2652
bool endDocument()
This reimplementation does nothing.
Definition: qxml.cpp:2665
QXmlInputSource()
Constructs an input source which contains no data.
Definition: qxml.cpp:1370
bool feature(const QString &name, bool *ok=0) const
Reimplemented Function
Definition: qxml.cpp:3461
const QChar * unicode
Definition: qxml.cpp:233
QXmlDeclHandler * declHandler() const
Reimplemented Function
Definition: qxml.cpp:3674
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
uchar row() const
Returns the row (most significant byte) of the Unicode character.
Definition: qchar.h:284
static NameChar fastDetermineNameChar(QChar ch)
Definition: qxml.cpp:3420
QString uri(const QString &) const
Looks up the prefix prefix in the current context and returns the currently-mapped namespace URI...
Definition: qxml.cpp:825
static const ushort EndOfDocument
Definition: qxml.h:173
#define QT_TRY
Definition: qglobal.h:1536
bool ignorableWhitespace(const QString &ch)
This reimplementation does nothing.
Definition: qxml.cpp:2745
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
virtual bool internalEntityDecl(const QString &name, const QString &value)=0
The reader calls this function to report an internal entity declaration.
virtual bool startPrefixMapping(const QString &prefix, const QString &uri)=0
The reader calls this function to signal the begin of a prefix-URI namespace mapping scope...
QMap< QString, ExternEntity > externEntities
Definition: qxml.cpp:312
QStack< QString > tags
Definition: qxml.cpp:284
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QScopedPointer< QXmlParseExceptionPrivate > d
Definition: qxml.h:207
QXmlContentHandler * contentHnd
Definition: qxml.cpp:401
virtual QChar next()
Returns the next character of the input source.
Definition: qxml.cpp:1444
void clear()
Removes all items from the map.
Definition: qmap.h:444
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
void setDocumentLocator(QXmlLocator *locator)
This reimplementation does nothing.
Definition: qxml.cpp:2640
#define text
Definition: qobjectdefs.h:80
The QXmlParseException class is used to report errors with the QXmlErrorHandler interface.
Definition: qxml.h:192
virtual bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)=0
The reader calls this function to report a parsed external entity declaration.
T & top()
Returns a reference to the stack&#39;s top item.
Definition: qstack.h:72
#define XMLERR_EDECLORSDDECLEXPECTED
Definition: qxml.cpp:70
int lineNumber() const
Returns the line number where the error occurred.
Definition: qxml.cpp:616
QXmlNamespaceSupportPrivate * d
Definition: qxml.h:108
void clear()
Clears the list of attributes.
Definition: qxml.cpp:1260
bool processElementETagBegin2()
Definition: qxml.cpp:4363
bool attributeDecl(const QString &eName, const QString &aName, const QString &type, const QString &valueDefault, const QString &value)
This reimplementation does nothing.
Definition: qxml.cpp:2972
friend class const_iterator
Definition: qmap.h:369
QXmlErrorHandler * errorHandler() const
Reimplemented Function
Definition: qxml.cpp:3638
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)=0
The reader calls this function when it has parsed an end element tag with the qualified name qName...
void pushContext()
Starts a new namespace context.
Definition: qxml.cpp:954
virtual bool fatalError(const QXmlParseException &exception)=0
A reader must use this function to report a non-recoverable error.
#define XMLERR_ERRORBYCONSUMER
Definition: qxml.cpp:60