qxml.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 **
4 ** Implementation of QXmlSimpleReader and related classes.
5 **
6 ** Created : 000518
7 **
8 ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9 **
10 ** This file is part of the XML module of the Qt GUI Toolkit.
11 **
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech AS of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
15 **
16 ** This file may be distributed and/or modified under the terms of the
17 ** GNU General Public License version 2 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
20 **
21 ** Licensees holding valid Qt Enterprise Edition licenses may use this
22 ** file in accordance with the Qt Commercial License Agreement provided
23 ** with the Software.
24 **
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 **
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 ** information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
32 **
33 ** Contact info@trolltech.com if any conditions of this licensing are
34 ** not clear to you.
35 **
36 **********************************************************************/
37 
38 #define QT_XML_CPP
39 #include "qxml.h"
40 #include "qtextcodec.h"
41 #include "qbuffer.h"
42 
43 #ifndef QT_NO_XML
44 // NOT REVISED
45 
46 // Error strings for the XML reader
47 #define XMLERR_OK "no error occured"
48 #define XMLERR_TAGMISMATCH "tag mismatch"
49 #define XMLERR_UNEXPECTEDEOF "unexpected end of file"
50 #define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached"
51 #define XMLERR_LETTEREXPECTED "letter is expected"
52 #define XMLERR_ERRORPARSINGELEMENT "error while parsing element"
53 #define XMLERR_ERRORPARSINGPROLOG "error while parsing prolog"
54 #define XMLERR_ERRORPARSINGMAINELEMENT "error while parsing main element"
55 #define XMLERR_ERRORPARSINGCONTENT "error while parsing content"
56 #define XMLERR_ERRORPARSINGNAME "error while parsing name"
57 #define XMLERR_ERRORPARSINGNMTOKEN "error while parsing Nmtoken"
58 #define XMLERR_ERRORPARSINGATTRIBUTE "error while parsing attribute"
59 #define XMLERR_ERRORPARSINGMISC "error while parsing misc"
60 #define XMLERR_ERRORPARSINGCHOICE "error while parsing choice or seq"
61 #define XMLERR_ERRORBYCONSUMER "error triggered by consumer"
62 #define XMLERR_UNEXPECTEDCHARACTER "unexpected character"
63 #define XMLERR_EQUALSIGNEXPECTED "expected '=' but not found"
64 #define XMLERR_QUOTATIONEXPECTED "expected \" or ' but not found"
65 #define XMLERR_ERRORPARSINGREFERENCE "error while parsing reference"
66 #define XMLERR_ERRORPARSINGPI "error while parsing processing instruction"
67 #define XMLERR_ERRORPARSINGATTLISTDECL "error while parsing attribute list declaration"
68 #define XMLERR_ERRORPARSINGATTTYPE "error while parsing attribute type declaration"
69 #define XMLERR_ERRORPARSINGATTVALUE "error while parsing attribute value declaration"
70 #define XMLERR_ERRORPARSINGELEMENTDECL "error while parsing element declaration"
71 #define XMLERR_ERRORPARSINGENTITYDECL "error while parsing entity declaration"
72 #define XMLERR_ERRORPARSINGNOTATIONDECL "error while parsing notation declaration"
73 #define XMLERR_ERRORPARSINGEXTERNALID "error while parsing external id"
74 #define XMLERR_ERRORPARSINGCOMMENT "error while parsing comment"
75 #define XMLERR_ERRORPARSINGENTITYVALUE "error while parsing entity value declaration"
76 #define XMLERR_CDSECTHEADEREXPECTED "expected the header for a cdata section"
77 #define XMLERR_MORETHANONEDOCTYPE "more than one document type definition"
78 #define XMLERR_ERRORPARSINGDOCTYPE "error while parsing document type definition"
79 #define XMLERR_INVALIDNAMEFORPI "invalid name for processing instruction"
80 #define XMLERR_VERSIONEXPECTED "version expected while reading the XML declaration"
81 #define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration"
82 #define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration"
83 #define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration"
84 #define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference in wrong context"
85 #define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
86 #define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
87 #define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value"
88 
89 
90 // the constants for the lookup table
91 static const signed char cltWS = 0; // white space
92 static const signed char cltPer = 1; // %
93 static const signed char cltAmp = 2; // &
94 static const signed char cltGt = 3; // >
95 static const signed char cltLt = 4; // <
96 static const signed char cltSlash = 5; // /
97 static const signed char cltQm = 6; // ?
98 static const signed char cltEm = 7; // !
99 static const signed char cltDash = 8; // -
100 static const signed char cltCB = 9; // ]
101 static const signed char cltOB = 10; // [
102 static const signed char cltEq = 11; // =
103 static const signed char cltDq = 12; // "
104 static const signed char cltSq = 13; // '
105 static const signed char cltUnknown = 14;
106 
107 // character lookup table
108 static const signed char charLookupTable[256]={
110  cltUnknown, // 0x08
111  cltWS, // 0x09 \t
112  cltWS, // 0x0A \n
113  cltUnknown, // 0x0B
114  cltUnknown, // 0x0C
115  cltWS, // 0x0D \r
116  cltUnknown, // 0x0E
117  cltUnknown, // 0x0F
120  cltWS, // 0x20 Space
121  cltEm, // 0x21 !
122  cltDq, // 0x22 "
123  cltUnknown, // 0x23
124  cltUnknown, // 0x24
125  cltPer, // 0x25 %
126  cltAmp, // 0x26 &
127  cltSq, // 0x27 '
128  cltUnknown, // 0x28
129  cltUnknown, // 0x29
130  cltUnknown, // 0x2A
131  cltUnknown, // 0x2B
132  cltUnknown, // 0x2C
133  cltDash, // 0x2D -
134  cltUnknown, // 0x2E
135  cltSlash, // 0x2F /
137  cltUnknown, // 0x38
138  cltUnknown, // 0x39
139  cltUnknown, // 0x3A
140  cltUnknown, // 0x3B
141  cltLt, // 0x3C <
142  cltEq, // 0x3D =
143  cltGt, // 0x3E >
144  cltQm, // 0x3F ?
148  cltUnknown, // 0x58
149  cltUnknown, // 0x59
150  cltUnknown, // 0x5A
151  cltOB, // 0x5B [
152  cltUnknown, // 0x5C
153  cltCB, // 0x5D ]
154  cltUnknown, // 0x5E
155  cltUnknown, // 0x5F
176 };
177 
178 
180 {
181 };
183 {
184 };
186 {
187 };
189 {
190 };
192 {
193 };
195 {
196 };
197 
198 #if defined(Q_FULL_TEMPLATE_INSTANTIATION)
200 {
201  return FALSE;
202 }
203 #endif
204 
205 /*!
206  \class QXmlParseException qxml.h
207  \brief The QXmlParseException class is used to report errors with the
208  QXmlErrorHandler interface.
209 
210  \module XML
211 
212  \sa QXmlErrorHandler
213 */
214 /*!
215  \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
216 
217  Constructs a parse exception with the error string \a name in the column
218  \a c and line \a l for the public identifier \a p and the system identifier
219  \a s.
220 */
221 /*!
222  Returns the error message.
223 */
225 {
226  return msg;
227 }
228 /*!
229  Returns the column number the error occured.
230 */
232 {
233  return column;
234 }
235 /*!
236  Returns the line number the error occured.
237 */
239 {
240  return line;
241 }
242 /*!
243  Returns the public identifier the error occured.
244 */
246 {
247  return pub;
248 }
249 /*!
250  Returns the system identifier the error occured.
251 */
253 {
254  return sys;
255 }
256 
257 
258 /*!
259  \class QXmlLocator qxml.h
260  \brief The QXmlLocator class provides the XML handler classes with
261  information about the actual parsing position.
262 
263  \module XML
264 
265  The reader reports a QXmlLocator to the content handler before he starts to
266  parse the document. This is done with the
267  QXmlContentHandler::setDocumentLocator() function. The handler classes can
268  now use this locator to get the actual position the reader is at.
269 */
270 /*!
271  \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent )
272 
273  Constructor.
274 */
275 /*!
276  \fn QXmlLocator::~QXmlLocator()
277 
278  Destructor.
279 */
280 /*!
281  Gets the column number (starting with 1) or -1 if there is no column number
282  available.
283 */
285 {
286  return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
287 }
288 /*!
289  Gets the line number (starting with 1) or -1 if there is no line number
290  available.
291 */
293 {
294  return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
295 }
296 
297 
298 /*********************************************
299  *
300  * QXmlNamespaceSupport
301  *
302  *********************************************/
303 
304 /*!
305  \class QXmlNamespaceSupport qxml.h
306  \brief The QXmlNamespaceSupport class is a helper class for XML readers which
307  want to include namespace support.
308 
309  \module XML
310 
311  It provides some functions that makes it easy to handle namespaces. Its main
312  use is for subclasses of QXmlReader which want to provide namespace
313  support.
314 
315  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
316 */
317 
318 /*!
319  Constructs a QXmlNamespaceSupport.
320 */
322 {
323  reset();
324 }
325 
326 /*!
327  Destructs a QXmlNamespaceSupport.
328 */
330 {
331 }
332 
333 /*!
334  This function declares a prefix in the current namespace context; the prefix
335  will remain in force until this context is popped, unless it is shadowed in a
336  descendant context.
337 
338  Note that there is an asymmetry in this library: while prefix() will not
339  return the default "" prefix, even if you have declared one; to check for a
340  default prefix, you have to look it up explicitly using uri(). This
341  asymmetry exists to make it easier to look up prefixes for attribute names,
342  where the default prefix is not allowed.
343 */
344 void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
345 {
346  if( pre.isNull() ) {
347  ns.insert( "", uri );
348  } else {
349  ns.insert( pre, uri );
350  }
351 }
352 
353 /*!
354  Returns one of the prefixes mapped to a namespace URI.
355 
356  If more than one prefix is currently mapped to the same URI, this function
357  will make an arbitrary selection; if you want all of the prefixes, use the
358  prefixes() function instead.
359 
360  Note: this will never return the empty (default) prefix; to check for a
361  default prefix, use the uri() function with an argument of "".
362 */
364 {
365  QMap<QString, QString>::ConstIterator itc, it = ns.begin();
366  while ( (itc=it) != ns.end() ) {
367  ++it;
368  if ( itc.data() == uri && !itc.key().isEmpty() )
369  return itc.key();
370  }
371  return "";
372 }
373 
374 /*!
375  Looks up a prefix in the current context and returns the currently-mapped
376  namespace URI. Use the empty string ("") for the default namespace.
377 */
379 {
380  const QString& returi = ns[ prefix ];
381  return returi;
382 }
383 
384 /*!
385  Splits the name at the ':' and returns the prefix and the local name.
386 */
388  QString& prefix, QString& localname ) const
389 {
390  uint pos;
391  // search the ':'
392  for( pos=0; pos<qname.length(); pos++ ) {
393  if ( qname.at(pos) == ':' )
394  break;
395  }
396  // and split
397  prefix = qname.left( pos );
398  localname = qname.mid( pos+1 );
399 }
400 
401 /*!
402  Processes a raw XML 1.0 name in the current context by removing the prefix
403  and looking it up among the prefixes currently declared.
404 
405  First parameter is the raw XML 1.0 name to be processed. The second parameter
406  is a flag wheter the name is the name of an attribute (TRUE) or not (FALSE).
407 
408  The return values will be stored in the last two parameters as follows:
409  <ul>
410  <li> The namespace URI, or an empty string if none is in use.
411  <li> The local name (without prefix).
412  </ul>
413 
414  If the raw name has a prefix that has not been declared, then the return
415  value will be empty.
416 
417  Note that attribute names are processed differently than element names: an
418  unprefixed element name will received the default namespace (if any), while
419  an unprefixed element name will not
420 */
422  bool isAttribute,
423  QString& nsuri, QString& localname ) const
424 {
425  uint pos;
426  // search the ':'
427  for( pos=0; pos<qname.length(); pos++ ) {
428  if ( qname.at(pos) == ':' )
429  break;
430  }
431  if ( pos < qname.length() ) {
432  // there was a ':'
433  nsuri = uri( qname.left( pos ) );
434  localname = qname.mid( pos+1 );
435  } else {
436  // there was no ':'
437  if ( isAttribute ) {
438  nsuri = ""; // attributes don't take default namespace
439  } else {
440  nsuri = uri( "" ); // get default namespace
441  }
442  localname = qname;
443  }
444 }
445 
446 /*!
447  Returns an enumeration of all prefixes currently declared.
448 
449  Note: if there is a default prefix, it will not be returned in this
450  enumeration; check for the default prefix using uri() with an argument
451  of "".
452 */
454 {
455  QStringList list;
456 
457  QMap<QString, QString>::ConstIterator itc, it = ns.begin();
458  while ( (itc=it) != ns.end() ) {
459  ++it;
460  if ( !itc.key().isEmpty() )
461  list.append( itc.key() );
462  }
463  return list;
464 }
465 
466 /*!
467  Returns a list of all prefixes currently declared for a URI.
468 
469  The xml: prefix will be included. If you want only one prefix that's
470  mapped to the namespace URI, and you don't care which one you get, use the
471  prefix() function instead.
472 
473  Note: the empty (default) prefix is never included in this enumeration; to
474  check for the presence of a default namespace, use uri() with an
475  argument of "".
476 */
478 {
479  QStringList list;
480 
481  QMap<QString, QString>::ConstIterator itc, it = ns.begin();
482  while ( (itc=it) != ns.end() ) {
483  ++it;
484  if ( itc.data() == uri && !itc.key().isEmpty() )
485  list.append( itc.key() );
486  }
487  return list;
488 }
489 
490 /*!
491  Starts a new namespace context.
492 
493  Normally, you should push a new context at the beginning of each XML element:
494  the new context will automatically inherit the declarations of its parent
495  context, but it will also keep track of which declarations were made within
496  this context.
497 */
499 {
500  nsStack.push( ns );
501 }
502 
503 /*!
504  Reverts to the previous namespace context.
505 
506  Normally, you should pop the context at the end of each XML element. After
507  popping the context, all namespace prefix mappings that were previously in
508  force are restored.
509 */
511 {
512  if( !nsStack.isEmpty() )
513  ns = nsStack.pop();
514 }
515 
516 /*!
517  Resets this namespace support object for reuse.
518 */
520 {
521  nsStack.clear();
522  ns.clear();
523  ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
524 }
525 
526 
527 
528 /*********************************************
529  *
530  * QXmlAttributes
531  *
532  *********************************************/
533 
534 /*!
535  \class QXmlAttributes qxml.h
536  \brief The QXmlAttributes class provides XML attributes.
537 
538  \module XML
539 
540  If attributes are reported by QXmlContentHandler::startElement() this
541  class is used to pass the attribute values. It provides you with different
542  functions to access the attribute names and values.
543 */
544 /*!
545  \fn QXmlAttributes::QXmlAttributes()
546 
547  Constructs an empty attribute list.
548 */
549 /*!
550  \fn QXmlAttributes::~QXmlAttributes()
551 
552  Destructs attributes.
553 */
554 
555 /*!
556  Look up the index of an attribute by an XML 1.0 qualified name.
557 
558  Returns the index of the attribute (starting with 0) or -1 if it wasn't
559  found.
560 
561  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
562 */
563 int QXmlAttributes::index( const QString& qName ) const
564 {
565  return qnameList.findIndex( qName );
566 }
567 
568 /*!
569  Looks up the index of an attribute by a namespace name.
570 
571  \a uri specifies the namespace URI, or the empty string if the name has no
572  namespace URI. \a localPart specifies the attribute's local name.
573 
574  Returns the index of the attribute (starting with 0) or -1 if it wasn't
575  found.
576 
577  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
578 */
579 int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
580 {
581  uint count = uriList.count();
582  for ( uint i=0; i<count; i++ ) {
583  if ( uriList[i] == uri && localnameList[i] == localPart )
584  return i;
585  }
586  return -1;
587 }
588 
589 /*!
590  Returns the number of attributes in the list.
591 */
593 {
594  return valueList.count();
595 }
596 
597 /*!
598  Looks up an attribute's local name by index (starting with 0).
599 
600  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
601 */
603 {
604  return localnameList[index];
605 }
606 
607 /*!
608  Looks up an attribute's XML 1.0 qualified name by index (starting with 0).
609 
610  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
611 */
613 {
614  return qnameList[index];
615 }
616 
617 /*!
618  Looks up an attribute's namespace URI by index (starting with 0).
619 
620  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
621 */
623 {
624  return uriList[index];
625 }
626 
627 /*!
628  Looks up an attribute's type by index (starting with 0).
629 
630  At the moment only 'CDATA' is returned.
631 */
633 {
634  return "CDATA";
635 }
636 
637 /*!
638  Looks up an attribute's type by XML 1.0 qualified name.
639 
640  At the moment only 'CDATA' is returned.
641 */
643 {
644  return "CDATA";
645 }
646 
647 /*!
648  Looks up an attribute's type by namespace name.
649 
650  The first parameter specifies the namespace URI, or the empty string if
651  the name has no namespace URI. The second parameter specifies the
652  attribute's local name.
653 
654  At the moment only 'CDATA' is returned.
655 */
657 {
658  return "CDATA";
659 }
660 
661 /*!
662  Looks up an attribute's value by index (starting with 0).
663 */
665 {
666  return valueList[index];
667 }
668 
669 /*!
670  Looks up an attribute's value by XML 1.0 qualified name.
671 
672  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
673 */
674 QString QXmlAttributes::value( const QString& qName ) const
675 {
676  int i = index( qName );
677  if ( i == -1 )
678  return QString::null;
679  return valueList[ i ];
680 }
681 
682 /*!
683  Looks up an attribute's value by namespace name.
684 
685  \a uri specifies the namespace URI, or the empty string if the name has no
686  namespace URI. \a localName specifies the attribute's local name.
687 
688  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
689 */
690 QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
691 {
692  int i = index( uri, localName );
693  if ( i == -1 )
694  return QString::null;
695  return valueList[ i ];
696 }
697 
698 
699 /*********************************************
700  *
701  * QXmlInputSource
702  *
703  *********************************************/
704 
705 /*!
706  \class QXmlInputSource qxml.h
707  \brief The QXmlInputSource class is the source where XML data is read from.
708 
709  \module XML
710 
711  All subclasses of QXmlReader read the input from this class.
712 */
713 
714 /*!
715  Returns all the data this input source contains.
716 */
718 {
719  return input;
720 }
721 
722 /*!
723  Constructs a input source which contains no data.
724 */
726 {
727  input = "";
728 }
729 
730 /*!
731  Constructs a input source and get the data from the text stream.
732 */
734 {
735  QByteArray rawData;
736  if ( stream.device()->isDirectAccess() ) {
737  rawData = stream.device()->readAll();
738  } else {
739  int nread = 0;
740  const int bufsize = 512;
741  while ( !stream.device()->atEnd() ) {
742  rawData.resize( nread + bufsize );
743  nread += stream.device()->readBlock( rawData.data()+nread, bufsize );
744  }
745  rawData.resize( nread );
746  }
747  readInput( rawData );
748 }
749 
750 /*!
751  Constructs a input source and get the data from a file. If the file cannot be
752  read the input source is empty.
753 */
755 {
756  if ( !file.open(IO_ReadOnly) ) {
757  input = "";
758  return;
759  }
760  QByteArray rawData = file.readAll();
761  readInput( rawData );
762  file.close();
763 }
764 
765 /*!
766  Destructor.
767 */
769 {
770 }
771 
772 /*!
773  Sets the data of the input source to \a dat.
774 */
776 {
777  input = dat;
778 }
779 
780 /*!
781  Read the XML file from the byte array; try to recoginize the encoding.
782 */
783 // ### The input source should not do the encoding detection!
785 {
786  QBuffer buf( rawData );
787  buf.open( IO_ReadOnly );
788  QTextStream *stream = new QTextStream( &buf );
789  QChar tmp;
790  // assume UTF8 or UTF16 at first
792  input = "";
793  // read the first 5 characters
794  for ( int i=0; i<5; i++ ) {
795  *stream >> tmp;
796  input += tmp;
797  }
798  // starts the document with an XML declaration?
799  if ( input == "<?xml" ) {
800  // read the whole XML declaration
801  do {
802  *stream >> tmp;
803  input += tmp;
804  } while( tmp != '>' );
805  // and try to find out if there is an encoding
806  int pos = input.find( "encoding" );
807  if ( pos != -1 ) {
809  do {
810  pos++;
811  if ( pos > (int)input.length() )
812  goto finished;
813  } while( input[pos] != '"' && input[pos] != '\'' );
814  pos++;
815  while( input[pos] != '"' && input[pos] != '\'' ) {
816  encoding += input[pos];
817  pos++;
818  if ( pos > (int)input.length() )
819  goto finished;
820  }
821  delete stream;
822  stream = new QTextStream( &buf );
823  stream->setCodec( QTextCodec::codecForName( encoding.utf8() ) );
824  buf.reset();
825  input = "";
826  }
827  }
828 finished:
829  input += stream->read();
830  delete stream;
831  buf.close();
832 }
833 
834 
835 /*********************************************
836  *
837  * QXmlDefaultHandler
838  *
839  *********************************************/
840 
841 /*!
842  \class QXmlContentHandler qxml.h
843  \brief The QXmlContentHandler class provides an interface to report logical
844  content of XML data.
845 
846  \module XML
847 
848  If the application needs to be informed of basic parsing events, it
849  implements this interface and sets it with QXmlReader::setContentHandler().
850  The reader reports basic document-related events like the start and end of
851  elements and character data through this interface.
852 
853  The order of events in this interface is very important, and mirrors the
854  order of information in the document itself. For example, all of an element's
855  content (character data, processing instructions, and/or subelements) will
856  appear, in order, between the startElement() event and the corresponding
857  endElement() event.
858 
859  The class QXmlDefaultHandler gives a default implementation for this
860  interface; subclassing from this class is very convenient if you want only be
861  informed of some parsing events.
862 
863  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
864 
865  \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
866  QXmlLexicalHandler
867 */
868 /*!
869  \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
870 
871  The reader calls this function before he starts parsing the document. The
872  argument \a locator is a pointer to a QXmlLocator which allows the
873  application to get the actual position of the parsing in the document.
874 
875  Do not destroy the \a locator; it is destroyed when the reader is destroyed
876  (do not use the \a locator after the reader got destroyed).
877 */
878 /*!
879  \fn bool QXmlContentHandler::startDocument()
880 
881  The reader calls this function when he starts parsing the document.
882  The reader will call this function only once before any other functions in
883  this class or in the QXmlDTDHandler class are called (except
884  QXmlContentHandler::setDocumentLocator()).
885 
886  If this function returns FALSE the reader will stop parsing and will report
887  an error. The reader will use the function errorString() to get the error
888  message that will be used for reporting the error.
889 
890  \sa endDocument()
891 */
892 /*!
893  \fn bool QXmlContentHandler::endDocument()
894 
895  The reader calls this function after he has finished the parsing. It
896  is only called once. It is the last function of all handler functions that is
897  called. It is called after the reader has read all input or has abandoned
898  parsing because of a fatal error.
899 
900  If this function returns FALSE the reader will stop parsing and will report
901  an error. The reader will use the function errorString() to get the error
902  message that will be used for reporting the error.
903 
904  \sa startDocument()
905 */
906 /*!
907  \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
908 
909  The reader calls this function to signal the begin of a prefix-URI
910  namespace mapping scope. This information is not necessary for normal
911  namespace processing since the reader automatically replaces prefixes for
912  element and attribute names.
913 
914  Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to
915  be properly nested relative to each-other: all startPrefixMapping events will
916  occur before the corresponding startElement event, and all endPrefixMapping
917  events will occur after the corresponding endElement event, but their order
918  is not otherwise guaranteed.
919 
920  The argument \a prefix is the namespace prefix being declared and the
921  argument \a uri is the namespace URI the prefix is mapped to.
922 
923  If this function returns FALSE the reader will stop parsing and will report
924  an error. The reader will use the function errorString() to get the error
925  message that will be used for reporting the error.
926 
927  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
928 
929  \sa endPrefixMapping()
930 */
931 /*!
932  \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
933 
934  The reader calls this function to signal the end of a prefix mapping.
935 
936  If this function returns FALSE the reader will stop parsing and will report
937  an error. The reader will use the function errorString() to get the error
938  message that will be used for reporting the error.
939 
940  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
941 
942  \sa startPrefixMapping()
943 */
944 /*!
945  \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
946 
947  The reader calls this function when he has parsed a start element tag.
948 
949  There will be a corresponding endElement() call when the corresponding end
950  element tag was read. The startElement() and endElement() calls are always
951  nested correctly. Empty element tags (e.g. &lt;a/&gt;) are reported by
952  startElement() directly followed by a call to endElement().
953 
954  The attribute list provided will contain only attributes with explicit
955  values. The attribute list will contain attributes used for namespace
956  declaration (i.e. attributes starting with xmlns) only if the
957  namespace-prefix property of the reader is TRUE.
958 
959  The argument \a uri is the namespace URI, or the empty string if the element
960  has no namespace URI or if namespace processing is not being performed, \a
961  localName is the local name (without prefix), or the empty string if
962  namespace processing is not being performed, \a qName is the qualified name
963  (with prefix), or the empty string if qualified names are not available and
964  \a atts are the attributes attached to the element. If there are no
965  attributes, \a atts is an empty attributes object
966 
967  If this function returns FALSE the reader will stop parsing and will report
968  an error. The reader will use the function errorString() to get the error
969  message that will be used for reporting the error.
970 
971  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
972 
973  \sa endElement()
974 */
975 /*!
976  \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
977 
978  The reader calls this function when he has parsed an end element tag.
979 
980  If this function returns FALSE the reader will stop parsing and will report
981  an error. The reader will use the function errorString() to get the error
982  message that will be used for reporting the error.
983 
984  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
985 
986  \sa startElement()
987 */
988 /*!
989  \fn bool QXmlContentHandler::characters( const QString& ch )
990 
991  The reader calls this function when he has parsed a chunk of character
992  data (either normal character data or character data inside a CDATA section;
993  if you have to distinguish between those two types you have to use
994  QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in
995  addition).
996 
997  Some readers will report whitespace in element content using the
998  ignorableWhitespace() function rather than this one (QXmlSimpleReader will
999  do it not though).
1000 
1001  A reader is allowed to report the character data of an element in more than
1002  one chunk; e.g. a reader might want to report "a &amp;lt; b" in three
1003  characters() events ("a ", "<" and " b").
1004 
1005  If this function returns FALSE the reader will stop parsing and will report
1006  an error. The reader will use the function errorString() to get the error
1007  message that will be used for reporting the error.
1008 */
1009 /*!
1010  \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
1011 
1012  Some readers may use this function to report each chunk of whitespace in
1013  element content (QXmlSimpleReader does not though).
1014 
1015  If this function returns FALSE the reader will stop parsing and will report
1016  an error. The reader will use the function errorString() to get the error
1017  message that will be used for reporting the error.
1018 */
1019 /*!
1020  \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
1021 
1022  The reader calls this function when he has parsed a processing
1023  instruction.
1024 
1025  \a target is the target name of the processing instruction and \a data is the
1026  data of the processing instruction.
1027 
1028  If this function returns FALSE the reader will stop parsing and will report
1029  an error. The reader will use the function errorString() to get the error
1030  message that will be used for reporting the error.
1031 */
1032 /*!
1033  \fn bool QXmlContentHandler::skippedEntity( const QString& name )
1034 
1035  Some readers may skip entities if they have not seen the declarations (e.g.
1036  because they are in an external DTD). If they do so they will report it by
1037  calling this function.
1038 
1039  If this function returns FALSE the reader will stop parsing and will report
1040  an error. The reader will use the function errorString() to get the error
1041  message that will be used for reporting the error.
1042 */
1043 /*!
1044  \fn QString QXmlContentHandler::errorString()
1045 
1046  The reader calls this function to get an error string if any of the handler
1047  functions returns FALSE to him.
1048 */
1049 
1050 
1051 /*!
1052  \class QXmlErrorHandler qxml.h
1053  \brief The QXmlErrorHandler class provides an interface to report errors in
1054  XML data.
1055 
1056  \module XML
1057 
1058  If the application is interested in reporting errors to the user or any other
1059  customized error handling, you should subclass this class.
1060 
1061  You can set the error handler with QXmlReader::setErrorHandler().
1062 
1063  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1064 
1065  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1066  QXmlLexicalHandler
1067 */
1068 /*!
1069  \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
1070 
1071  A reader might use this function to report a warning. Warnings are conditions
1072  that are not errors or fatal errors as defined by the XML 1.0 specification.
1073 
1074  If this function returns FALSE the reader will stop parsing and will report
1075  an error. The reader will use the function errorString() to get the error
1076  message that will be used for reporting the error.
1077 */
1078 /*!
1079  \fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
1080 
1081  A reader might use this function to report a recoverable error. A recoverable
1082  error corresponds to the definiton of "error" in section 1.2 of the XML 1.0
1083  specification.
1084 
1085  The reader must continue to provide normal parsing events after invoking this
1086  function.
1087 
1088  If this function returns FALSE the reader will stop parsing and will report
1089  an error. The reader will use the function errorString() to get the error
1090  message that will be used for reporting the error.
1091 */
1092 /*!
1093  \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
1094 
1095  A reader must use this function to report a non-recoverable error.
1096 
1097  If this function returns TRUE the reader might try to go on parsing and
1098  reporting further errors; but no regular parsing events are reported.
1099 */
1100 /*!
1101  \fn QString QXmlErrorHandler::errorString()
1102 
1103  The reader calls this function to get an error string if any of the handler
1104  functions returns FALSE to him.
1105 */
1106 
1107 
1108 /*!
1109  \class QXmlDTDHandler qxml.h
1110  \brief The QXmlDTDHandler class provides an interface to report DTD content
1111  of XML data.
1112 
1113  \module XML
1114 
1115  If an application needs information about notations and unparsed entities,
1116  then the application implements this interface and registers an instance with
1117  QXmlReader::setDTDHandler().
1118 
1119  Note that this interface includes only those DTD events that the XML
1120  recommendation requires processors to report: notation and unparsed entity
1121  declarations.
1122 
1123  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1124 
1125  \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
1126  QXmlLexicalHandler
1127 */
1128 /*!
1129  \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
1130 
1131  The reader calls this function when he has parsed a notation
1132  declaration.
1133 
1134  The argument \a name is the notation name, \a publicId is the notations's
1135  public identifier and \a systemId is the notations's system identifier.
1136 
1137  If this function returns FALSE the reader will stop parsing and will report
1138  an error. The reader will use the function errorString() to get the error
1139  message that will be used for reporting the error.
1140 */
1141 /*!
1142  \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
1143 
1144  The reader calls this function when he finds an unparsed entity declaration.
1145 
1146  The argument \a name is the unparsed entity's name, \a publicId is the
1147  entity's public identifier, \a systemId is the entity's system identifier and
1148  \a notation is the name of the associated notation.
1149 
1150  If this function returns FALSE the reader will stop parsing and will report
1151  an error. The reader will use the function errorString() to get the error
1152  message that will be used for reporting the error.
1153 */
1154 /*!
1155  \fn QString QXmlDTDHandler::errorString()
1156 
1157  The reader calls this function to get an error string if any of the handler
1158  functions returns FALSE to him.
1159 */
1160 
1161 
1162 /*!
1163  \class QXmlEntityResolver qxml.h
1164  \brief The QXmlEntityResolver class provides an interface to resolve extern
1165  entities contained in XML data.
1166 
1167  \module XML
1168 
1169  If an application needs to implement customized handling for external
1170  entities, it must implement this interface and register it with
1171  QXmlReader::setEntityResolver().
1172 
1173  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1174 
1175  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
1176  QXmlLexicalHandler
1177 */
1178 /*!
1179  \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret )
1180 
1181  The reader will call this function before he opens any external entity,
1182  except the top-level document entity. The application may request the reader
1183  to resolve the entity itself (\a ret is 0) or to use an entirely different
1184  input source (\a ret points to the input source).
1185 
1186  The reader will delete the input source \a ret when he no longer needs it. So
1187  you should allocate it on the heap with \c new.
1188 
1189  The argument \a publicId is the public identifier of the external entity, \a
1190  systemId is the system identifier of the external entity and \a ret is the
1191  return value of this function: if it is 0 the reader should resolve the
1192  entity itself, if it is non-zero it must point to an input source which the
1193  reader will use instead.
1194 
1195  If this function returns FALSE the reader will stop parsing and will report
1196  an error. The reader will use the function errorString() to get the error
1197  message that will be used for reporting the error.
1198 */
1199 /*!
1200  \fn QString QXmlEntityResolver::errorString()
1201 
1202  The reader calls this function to get an error string if any of the handler
1203  functions returns FALSE to him.
1204 */
1205 
1206 
1207 /*!
1208  \class QXmlLexicalHandler qxml.h
1209  \brief The QXmlLexicalHandler class provides an interface to report lexical
1210  content of XML data.
1211 
1212  \module XML
1213 
1214  The events in the lexical handler apply to the entire document, not just to
1215  the document element, and all lexical handler events appear between the
1216  content handler's startDocument and endDocument events.
1217 
1218  You can set the lexical handler with QXmlReader::setLexicalHandler().
1219 
1220  This interface is designed after the SAX2 extension LexicalHandler. The
1221  functions startEntity() and endEntity() are not included though.
1222 
1223  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1224 
1225  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1226  QXmlErrorHandler
1227 */
1228 /*!
1229  \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
1230 
1231  The reader calls this function to report the start of a DTD declaration, if
1232  any.
1233 
1234  All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear
1235  between the startDTD() and endDTD() calls.
1236 
1237  If this function returns FALSE the reader will stop parsing and will report
1238  an error. The reader will use the function errorString() to get the error
1239  message that will be used for reporting the error.
1240 
1241  \sa endDTD()
1242 */
1243 /*!
1244  \fn bool QXmlLexicalHandler::endDTD()
1245 
1246  The reader calls this function to report the end of a DTD declaration, if
1247  any.
1248 
1249  If this function returns FALSE the reader will stop parsing and will report
1250  an error. The reader will use the function errorString() to get the error
1251  message that will be used for reporting the error.
1252 
1253  \sa startDTD()
1254 */
1255 /*!
1256  \fn bool QXmlLexicalHandler::startCDATA()
1257 
1258  The reader calls this function to report the start of a CDATA section. The
1259  content of the CDATA section will be reported through the regular
1260  QXmlContentHandler::characters(). This function is intended only to report
1261  the boundary.
1262 
1263  If this function returns FALSE the reader will stop parsing and will report
1264  an error. The reader will use the function errorString() to get the error
1265  message that will be used for reporting the error.
1266 
1267  \sa endCDATA()
1268 */
1269 /*!
1270  \fn bool QXmlLexicalHandler::endCDATA()
1271 
1272  The reader calls this function to report the end of a CDATA section.
1273 
1274  If this function returns FALSE the reader will stop parsing and will report
1275  an error. The reader will use the function errorString() to get the error
1276  message that will be used for reporting the error.
1277 
1278  \sa startCDATA()
1279 */
1280 /*!
1281  \fn bool QXmlLexicalHandler::comment( const QString& ch )
1282 
1283  The reader calls this function to report an XML comment anywhere in the
1284  document.
1285 
1286  If this function returns FALSE the reader will stop parsing and will report
1287  an error. The reader will use the function errorString() to get the error
1288  message that will be used for reporting the error.
1289 */
1290 /*!
1291  \fn QString QXmlLexicalHandler::errorString()
1292 
1293  The reader calls this function to get an error string if any of the handler
1294  functions returns FALSE to him.
1295 */
1296 
1297 
1298 /*!
1299  \class QXmlDeclHandler qxml.h
1300  \brief The QXmlDeclHandler class provides an interface to report declaration
1301  content of XML data.
1302 
1303  \module XML
1304 
1305  You can set the declaration handler with QXmlReader::setDeclHandler().
1306 
1307  This interface is designed after the SAX2 extension DeclHandler.
1308 
1309  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1310 
1311  \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
1312  QXmlLexicalHandler
1313 */
1314 /*!
1315  \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
1316 
1317  The reader calls this function to report an attribute type declaration. Only
1318  the effective (first) declaration for an attribute will be reported.
1319 
1320  If this function returns FALSE the reader will stop parsing and will report
1321  an error. The reader will use the function errorString() to get the error
1322  message that will be used for reporting the error.
1323 */
1324 /*!
1325  \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
1326 
1327  The reader calls this function to report an internal entity declaration. Only
1328  the effective (first) declaration will be reported.
1329 
1330  If this function returns FALSE the reader will stop parsing and will report
1331  an error. The reader will use the function errorString() to get the error
1332  message that will be used for reporting the error.
1333 */
1334 /*!
1335  \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
1336 
1337  The reader calls this function to report a parsed external entity
1338  declaration. Only the effective (first) declaration for each entity will be
1339  reported.
1340 
1341  If this function returns FALSE the reader will stop parsing and will report
1342  an error. The reader will use the function errorString() to get the error
1343  message that will be used for reporting the error.
1344 */
1345 /*!
1346  \fn QString QXmlDeclHandler::errorString()
1347 
1348  The reader calls this function to get an error string if any of the handler
1349  functions returns FALSE to him.
1350 */
1351 
1352 
1353 /*!
1354  \class QXmlDefaultHandler qxml.h
1355  \brief The QXmlDefaultHandler class provides a default implementation of all
1356  XML handler classes.
1357 
1358  \module XML
1359 
1360  Very often you are only interested in parts of the things that that the
1361  reader reports to you. This class simply implements a default behaviour of
1362  the handler classes (most of the time: do nothing). Normally this is the
1363  class you subclass for implementing your customized handler.
1364 
1365  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
1366 
1367  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
1368  QXmlErrorHandler QXmlLexicalHandler
1369 */
1370 /*!
1371  \fn QXmlDefaultHandler::QXmlDefaultHandler()
1372 
1373  Constructor.
1374 */
1375 /*!
1376  \fn QXmlDefaultHandler::~QXmlDefaultHandler()
1377 
1378  Destructor.
1379 */
1380 
1381 /*!
1382  Does nothing.
1383 */
1385 {
1386 }
1387 
1388 /*!
1389  Does nothing.
1390 */
1392 {
1393  return TRUE;
1394 }
1395 
1396 /*!
1397  Does nothing.
1398 */
1400 {
1401  return TRUE;
1402 }
1403 
1404 /*!
1405  Does nothing.
1406 */
1408 {
1409  return TRUE;
1410 }
1411 
1412 /*!
1413  Does nothing.
1414 */
1416 {
1417  return TRUE;
1418 }
1419 
1420 /*!
1421  Does nothing.
1422 */
1424  const QString&, const QXmlAttributes& )
1425 {
1426  return TRUE;
1427 }
1428 
1429 /*!
1430  Does nothing.
1431 */
1433  const QString& )
1434 {
1435  return TRUE;
1436 }
1437 
1438 /*!
1439  Does nothing.
1440 */
1442 {
1443  return TRUE;
1444 }
1445 
1446 /*!
1447  Does nothing.
1448 */
1450 {
1451  return TRUE;
1452 }
1453 
1454 /*!
1455  Does nothing.
1456 */
1458  const QString& )
1459 {
1460  return TRUE;
1461 }
1462 
1463 /*!
1464  Does nothing.
1465 */
1467 {
1468  return TRUE;
1469 }
1470 
1471 /*!
1472  Does nothing.
1473 */
1475 {
1476  return TRUE;
1477 }
1478 
1479 /*!
1480  Does nothing.
1481 */
1483 {
1484  return TRUE;
1485 }
1486 
1487 /*!
1488  Does nothing.
1489 */
1491 {
1492  return TRUE;
1493 }
1494 
1495 /*!
1496  Does nothing.
1497 */
1499  const QString& )
1500 {
1501  return TRUE;
1502 }
1503 
1504 /*!
1505  Does nothing.
1506 */
1508  const QString&, const QString& )
1509 {
1510  return TRUE;
1511 }
1512 
1513 /*!
1514  Always sets \a ret to 0, so that the reader will use the system identifier
1515  provided in the XML document.
1516 */
1518  QXmlInputSource* &ret )
1519 {
1520  ret = 0;
1521  return TRUE;
1522 }
1523 
1524 /*!
1525  Returns the default error string.
1526 */
1528 {
1529  return QString( XMLERR_ERRORBYCONSUMER );
1530 }
1531 
1532 /*!
1533  Does nothing.
1534 */
1535 bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
1536 {
1537  return TRUE;
1538 }
1539 
1540 /*!
1541  Does nothing.
1542 */
1544 {
1545  return TRUE;
1546 }
1547 
1548 #if 0
1549 /*!
1550  Does nothing.
1551 */
1552 bool QXmlDefaultHandler::startEntity( const QString& )
1553 {
1554  return TRUE;
1555 }
1556 
1557 /*!
1558  Does nothing.
1559 */
1560 bool QXmlDefaultHandler::endEntity( const QString& )
1561 {
1562  return TRUE;
1563 }
1564 #endif
1565 
1566 /*!
1567  Does nothing.
1568 */
1570 {
1571  return TRUE;
1572 }
1573 
1574 /*!
1575  Does nothing.
1576 */
1578 {
1579  return TRUE;
1580 }
1581 
1582 /*!
1583  Does nothing.
1584 */
1586 {
1587  return TRUE;
1588 }
1589 
1590 /*!
1591  Does nothing.
1592 */
1593 bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
1594 {
1595  return TRUE;
1596 }
1597 
1598 /*!
1599  Does nothing.
1600 */
1602 {
1603  return TRUE;
1604 }
1605 
1606 /*!
1607  Does nothing.
1608 */
1610 {
1611  return TRUE;
1612 }
1613 
1614 
1615 /*********************************************
1616  *
1617  * QXmlSimpleReaderPrivate
1618  *
1619  *********************************************/
1620 
1622 {
1623 private:
1624  // constructor
1626  { }
1627 
1628 
1629  // used for entity declarations
1631  {
1634  : publicId(p), systemId(s) {}
1637  };
1639  {
1641  ExternEntity( const QString &p, const QString &s, const QString &n )
1642  : publicId(p), systemId(s), notation(n) {}
1646  };
1651 
1652  // used for standalone declaration
1653  enum Standalone { Yes, No, Unknown };
1654 
1655  QString doctype; // only used for the doctype
1656  QString xmlVersion; // only used to store the version information
1657  QString encoding; // only used to store the encoding
1658  Standalone standalone; // used to store the value of the standalone declaration
1659 
1660  QString publicId; // used by parseExternalID() to store the public ID
1661  QString systemId; // used by parseExternalID() to store the system ID
1662  QString attDeclEName; // use by parseAttlistDecl()
1663  QString attDeclAName; // use by parseAttlistDecl()
1664 
1665  // flags for some features support
1669 
1670  // used to build the attribute list
1672 
1673  // helper classes
1676 
1677  // error string
1679 
1680  // friend declarations
1681  friend class QXmlSimpleReader;
1682 };
1683 
1684 
1685 /*********************************************
1686  *
1687  * QXmlSimpleReader
1688  *
1689  *********************************************/
1690 
1691 /*!
1692  \class QXmlReader qxml.h
1693  \brief The QXmlReader class provides an interface for XML readers (i.e.
1694  parsers).
1695 
1696  \module XML
1697 
1698  This abstract class describes an interface for all XML readers in Qt. At the
1699  moment there is only one implementation of a reader included in the XML
1700  module of Qt (QXmlSimpleReader). In future releases there might be more
1701  readers with different properties available (e.g. a validating parser).
1702 
1703  The design of the XML classes follow the
1704  <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>.
1705  It was adopted to fit into the Qt naming conventions; so it should be very
1706  easy for anybody who has worked with SAX2 to get started with the Qt XML
1707  classes.
1708 
1709  All readers use the class QXmlInputSource to read the input document from.
1710  Since you are normally interested in certain contents of the XML document,
1711  the reader reports those contents through special handler classes
1712  (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
1713  QXmlErrorHandler and QXmlLexicalHandler).
1714 
1715  You have to subclass these classes. Since the handler classes describe only
1716  interfaces you must implement all functions; there is a class
1717  (QXmlDefaultHandler) to make this easier; it implements a default behaviour
1718  (do nothing) for all functions.
1719 
1720  For getting started see also the
1721  <a href="xml-sax.html#quickStart">Quick start</a>.
1722 
1723  \sa QXmlSimpleReader
1724 */
1725 /*!
1726  \fn bool QXmlReader::feature( const QString& name, bool *ok ) const
1727 
1728  If the reader has the feature \a name, this function returns the value of the
1729  feature.
1730 
1731  If the reader has not the feature \a name, the return value may be anything.
1732 
1733  If \a ok is not 0, then \a ok is set to TRUE if the reader has the feature
1734  \a name, otherwise \a ok is set to FALSE.
1735 
1736  \sa setFeature() hasFeature()
1737 */
1738 /*!
1739  \fn void QXmlReader::setFeature( const QString& name, bool value )
1740 
1741  Sets the feature \a name to \a value. If the reader has not the feature \a
1742  name, this value is ignored.
1743 
1744  \sa feature() hasFeature()
1745 */
1746 /*!
1747  \fn bool QXmlReader::hasFeature( const QString& name ) const
1748 
1749  Returns \c TRUE if the reader has the feature \a name, otherwise FALSE.
1750 
1751  \sa feature() setFeature()
1752 */
1753 /*!
1754  \fn void* QXmlReader::property( const QString& name, bool *ok ) const
1755 
1756  If the reader has the property \a name, this function returns the value of
1757  the property.
1758 
1759  If the reader has not the property \a name, the return value is 0.
1760 
1761  If \a ok is not 0, then \a ok is set to TRUE if the reader has the property
1762  \a name, otherwise \a ok is set to FALSE.
1763 
1764  \sa setProperty() hasProperty()
1765 */
1766 /*!
1767  \fn void QXmlReader::setProperty( const QString& name, void* value )
1768 
1769  Sets the property \a name to \a value. If the reader has not the property \a
1770  name, this value is ignored.
1771 
1772  \sa property() hasProperty()
1773 */
1774 /*!
1775  \fn bool QXmlReader::hasProperty( const QString& name ) const
1776 
1777  Returns TRUE if the reader has the property \a name, otherwise FALSE.
1778 
1779  \sa property() setProperty()
1780 */
1781 /*!
1782  \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
1783 
1784  Sets the entity resolver to \a handler.
1785 
1786  \sa entityResolver()
1787 */
1788 /*!
1789  \fn QXmlEntityResolver* QXmlReader::entityResolver() const
1790 
1791  Returns the entity resolver or 0 if none was set.
1792 
1793  \sa setEntityResolver()
1794 */
1795 /*!
1796  \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
1797 
1798  Sets the DTD handler to \a handler.
1799 
1800  \sa DTDHandler()
1801 */
1802 /*!
1803  \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
1804 
1805  Returns the DTD handler or 0 if none was set.
1806 
1807  \sa setDTDHandler()
1808 */
1809 /*!
1810  \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
1811 
1812  Sets the content handler to \a handler.
1813 
1814  \sa contentHandler()
1815 */
1816 /*!
1817  \fn QXmlContentHandler* QXmlReader::contentHandler() const
1818 
1819  Returns the content handler or 0 if none was set.
1820 
1821  \sa setContentHandler()
1822 */
1823 /*!
1824  \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
1825 
1826  Sets the error handler to \a handler.
1827 
1828  \sa errorHandler()
1829 */
1830 /*!
1831  \fn QXmlErrorHandler* QXmlReader::errorHandler() const
1832 
1833  Returns the error handler or 0 if none was set
1834 
1835  \sa setErrorHandler()
1836 */
1837 /*!
1838  \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
1839 
1840  Sets the lexical handler to \a handler.
1841 
1842  \sa lexicalHandler()
1843 */
1844 /*!
1845  \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
1846 
1847  Returns the lexical handler or 0 if none was set.
1848 
1849  \sa setLexicalHandler()
1850 */
1851 /*!
1852  \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
1853 
1854  Sets the declaration handler to \a handler.
1855 
1856  \sa declHandler()
1857 */
1858 /*!
1859  \fn QXmlDeclHandler* QXmlReader::declHandler() const
1860 
1861  Returns the declaration handler or 0 if none was set.
1862 
1863  \sa setDeclHandler()
1864 */
1865 /*!
1866  \fn bool QXmlReader::parse( const QXmlInputSource& input )
1867 
1868  Parses the XML document \a input. Returns TRUE if the parsing was successful,
1869  otherwise FALSE.
1870 */
1871 /*!
1872  \fn bool QXmlReader::parse( const QString& systemId )
1873 
1874  Parses the XML document at the location \a systemId. Returns TRUE if the
1875  parsing was successful, otherwise FALSE.
1876 */
1877 
1878 
1879 /*!
1880  \class QXmlSimpleReader qxml.h
1881  \brief The QXmlSimpleReader class provides an implementation of a simple XML
1882  reader (i.e. parser).
1883 
1884  \module XML
1885 
1886  This XML reader is sufficient for simple parsing tasks. Here is a short list
1887  of the properties of this reader:
1888  <ul>
1889  <li> well-formed parser
1890  <li> does not parse any external entities
1891  <li> can do namespace processing
1892  </ul>
1893 
1894  For getting started see also the
1895  <a href="xml-sax.html#quickStart">Quick start</a>.
1896 */
1897 
1898 //guaranteed not to be a characater
1899 const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff);
1900 
1901 /*!
1902  Constructs a simple XML reader.
1903 */
1905 {
1906  d = new QXmlSimpleReaderPrivate();
1907  d->locator = new QXmlLocator( this );
1908 
1909  entityRes = 0;
1910  dtdHnd = 0;
1911  contentHnd = 0;
1912  errorHnd = 0;
1913  lexicalHnd = 0;
1914  declHnd = 0;
1915 
1916  // default feature settings
1917  d->useNamespaces = TRUE;
1918  d->useNamespacePrefixes = FALSE;
1919  d->reportWhitespaceCharData = TRUE;
1920 }
1921 
1922 /*!
1923  Destroys a simple XML reader.
1924 */
1926 {
1927  delete d->locator;
1928  delete d;
1929 }
1930 
1931 /*!
1932  Gets the state of a feature.
1933 
1934  \sa setFeature() hasFeature()
1935 */
1936 bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
1937 {
1938  if ( ok != 0 )
1939  *ok = TRUE;
1940  if ( name == "http://xml.org/sax/features/namespaces" ) {
1941  return d->useNamespaces;
1942  } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
1943  return d->useNamespacePrefixes;
1944  } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
1945  return d->reportWhitespaceCharData;
1946  } else {
1947  qWarning( "Unknown feature %s", name.ascii() );
1948  if ( ok != 0 )
1949  *ok = FALSE;
1950  }
1951  return FALSE;
1952 }
1953 
1954 /*!
1955  Sets the state of a feature.
1956 
1957  Supported features are:
1958  <ul>
1959  <li> http://xml.org/sax/features/namespaces:
1960  if this feature is TRUE, namespace processing is performed
1961  <li> http://xml.org/sax/features/namespace-prefixes:
1962  if this feature is TRUE, the the original prefixed names and attributes
1963  used for namespace declarations are reported
1964  <li> http://trolltech.com/xml/features/report-whitespace-only-CharData:
1965  if this feature is TRUE, CharData that consists only of whitespace (and
1966  no other characters) is not reported via
1967  QXmlContentHandler::characters()
1968  </ul>
1969 
1970  \sa feature() hasFeature()
1971 */
1973 {
1974  if ( name == "http://xml.org/sax/features/namespaces" ) {
1975  d->useNamespaces = value;
1976  } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
1977  d->useNamespacePrefixes = value;
1978  } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
1979  d->reportWhitespaceCharData = value;
1980  } else {
1981  qWarning( "Unknown feature %s", name.ascii() );
1982  }
1983 }
1984 
1985 /*!
1986  Returns TRUE if the class has a feature named \a feature, otherwise FALSE.
1987 
1988  \sa setFeature() feature()
1989 */
1991 {
1992  if ( name == "http://xml.org/sax/features/namespaces" ||
1993  name == "http://xml.org/sax/features/namespace-prefixes" ||
1994  name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
1995  return TRUE;
1996  } else {
1997  return FALSE;
1998  }
1999 }
2000 
2001 /*!
2002  Returns 0 since this class does not support any properties.
2003 */
2004 void* QXmlSimpleReader::property( const QString&, bool *ok ) const
2005 {
2006  if ( ok != 0 )
2007  *ok = FALSE;
2008  return 0;
2009 }
2010 
2011 /*!
2012  Does nothing since this class does not support any properties.
2013 */
2015 {
2016 }
2017 
2018 /*!
2019  Returns FALSE since this class does not support any properties.
2020 */
2022 {
2023  return FALSE;
2024 }
2025 
2026 /*! \reimp */
2028 { entityRes = handler; }
2029 
2030 /*! \reimp */
2032 { return entityRes; }
2033 
2034 /*! \reimp */
2036 { dtdHnd = handler; }
2037 
2038 /*! \reimp */
2040 { return dtdHnd; }
2041 
2042 /*! \reimp */
2044 { contentHnd = handler; }
2045 
2046 /*! \reimp */
2048 { return contentHnd; }
2049 
2050 /*! \reimp */
2052 { errorHnd = handler; }
2053 
2054 /*! \reimp */
2056 { return errorHnd; }
2057 
2058 /*! \reimp */
2060 { lexicalHnd = handler; }
2061 
2062 /*! \reimp */
2064 { return lexicalHnd; }
2065 
2066 /*! \reimp */
2068 { declHnd = handler; }
2069 
2070 /*! \reimp */
2072 { return declHnd; }
2073 
2074 
2075 
2076 /*! \reimp */
2078 {
2079  init( input );
2080  // call the handler
2081  if ( contentHnd ) {
2082  contentHnd->setDocumentLocator( d->locator );
2083  if ( !contentHnd->startDocument() ) {
2084  d->error = contentHnd->errorString();
2085  goto parseError;
2086  }
2087  }
2088  // parse prolog
2089  if ( !parseProlog() ) {
2090  d->error = XMLERR_ERRORPARSINGPROLOG;
2091  goto parseError;
2092  }
2093  // parse element
2094  if ( !parseElement() ) {
2096  goto parseError;
2097  }
2098  // parse Misc*
2099  while ( !atEnd() ) {
2100  if ( !parseMisc() ) {
2101  d->error = XMLERR_ERRORPARSINGMISC;
2102  goto parseError;
2103  }
2104  }
2105  // is stack empty?
2106  if ( !tags.isEmpty() ) {
2107  d->error = XMLERR_UNEXPECTEDEOF;
2108  goto parseError;
2109  }
2110  // call the handler
2111  if ( contentHnd ) {
2112  if ( !contentHnd->endDocument() ) {
2113  d->error = contentHnd->errorString();
2114  goto parseError;
2115  }
2116  }
2117 
2118  return TRUE;
2119 
2120  // error handling
2121 
2122 parseError:
2123  reportParseError();
2124  tags.clear();
2125  return FALSE;
2126 }
2127 
2128 /*!
2129  Parses the prolog [22].
2130 */
2132 {
2133  bool xmldecl_possible = TRUE;
2134  bool doctype_read = FALSE;
2135 
2136  const signed char Init = 0;
2137  const signed char EatWS = 1; // eat white spaces
2138  const signed char Lt = 2; // '<' read
2139  const signed char Em = 3; // '!' read
2140  const signed char DocType = 4; // read doctype
2141  const signed char Comment = 5; // read comment
2142  const signed char PI = 6; // read PI
2143  const signed char Done = 7;
2144 
2145  const signed char InpWs = 0;
2146  const signed char InpLt = 1; // <
2147  const signed char InpQm = 2; // ?
2148  const signed char InpEm = 3; // !
2149  const signed char InpD = 4; // D
2150  const signed char InpDash = 5; // -
2151  const signed char InpUnknown = 6;
2152 
2153  // use some kind of state machine for parsing
2154  static signed char table[7][7] = {
2155  /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
2156  { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
2157  { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
2158  { -1, -1, PI, Em, Done, -1, Done }, // Lt
2159  { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
2160  { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
2161  { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
2162  { EatWS, Lt, -1, -1, -1, -1, -1 } // PI
2163  };
2164  signed char state = Init;
2165  signed char input;
2166  bool parseOk = TRUE;
2167 
2168  while ( TRUE ) {
2169 
2170  // read input
2171  if ( atEnd() ) {
2172  d->error = XMLERR_UNEXPECTEDEOF;
2173  goto parseError;
2174  }
2175  if ( is_S(c) ) {
2176  input = InpWs;
2177  } else if ( c == '<' ) {
2178  input = InpLt;
2179  } else if ( c == '?' ) {
2180  input = InpQm;
2181  } else if ( c == '!' ) {
2182  input = InpEm;
2183  } else if ( c == 'D' ) {
2184  input = InpD;
2185  } else if ( c == '-' ) {
2186  input = InpDash;
2187  } else {
2188  input = InpUnknown;
2189  }
2190  // get new state
2191  state = table[state][input];
2192 
2193  // in some cases do special actions depending on state
2194  switch ( state ) {
2195  case EatWS:
2196  // XML declaration only on first position possible
2197  xmldecl_possible = FALSE;
2198  // eat white spaces
2199  eat_ws();
2200  break;
2201  case Lt:
2202  // next character
2203  next();
2204  break;
2205  case Em:
2206  // XML declaration only on first position possible
2207  xmldecl_possible = FALSE;
2208  // next character
2209  next();
2210  break;
2211  case DocType:
2212  parseOk = parseDoctype();
2213  break;
2214  case Comment:
2215  parseOk = parseComment();
2216  break;
2217  case PI:
2218  parseOk = parsePI( xmldecl_possible );
2219  break;
2220  }
2221  // no input is read after this
2222  switch ( state ) {
2223  case DocType:
2224  if ( !parseOk ) {
2225  d->error = XMLERR_ERRORPARSINGPROLOG;
2226  goto parseError;
2227  }
2228  if ( doctype_read ) {
2229  d->error = XMLERR_MORETHANONEDOCTYPE;
2230  goto parseError;
2231  } else {
2232  doctype_read = FALSE;
2233  }
2234  break;
2235  case Comment:
2236  if ( !parseOk ) {
2237  d->error = XMLERR_ERRORPARSINGPROLOG;
2238  goto parseError;
2239  }
2240  if ( lexicalHnd ) {
2241  if ( !lexicalHnd->comment( string() ) ) {
2242  d->error = lexicalHnd->errorString();
2243  goto parseError;
2244  }
2245  }
2246  break;
2247  case PI:
2248  if ( !parseOk ) {
2249  d->error = XMLERR_ERRORPARSINGPROLOG;
2250  goto parseError;
2251  }
2252  // call the handler
2253  if ( contentHnd ) {
2254  if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) {
2255  QString value( "version = '" );
2256  value += d->xmlVersion;
2257  value += "'";
2258  if ( !d->encoding.isEmpty() ) {
2259  value += " encoding = '";
2260  value += d->encoding;
2261  value += "'";
2262  }
2263  if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
2264  value += " standalone = 'yes'";
2265  } else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
2266  value += " standalone = 'no'";
2267  }
2268  if ( !contentHnd->processingInstruction( "xml", value ) ) {
2269  d->error = contentHnd->errorString();
2270  goto parseError;
2271  }
2272  } else {
2273  if ( !contentHnd->processingInstruction( name(), string() ) ) {
2274  d->error = contentHnd->errorString();
2275  goto parseError;
2276  }
2277  }
2278  }
2279  // XML declaration only on first position possible
2280  xmldecl_possible = FALSE;
2281  break;
2282  case Done:
2283  return TRUE;
2284  case -1:
2285  d->error = XMLERR_ERRORPARSINGELEMENT;
2286  goto parseError;
2287  }
2288 
2289  }
2290 
2291  return TRUE;
2292 
2293 parseError:
2294  reportParseError();
2295  return FALSE;
2296 }
2297 
2298 /*!
2299  Parse an element [39].
2300 
2301  Precondition: the opening '<' is already read.
2302 */
2304 {
2305  static QString uri, lname, prefix;
2306  static bool t;
2307 
2308  const signed char Init = 0;
2309  const signed char ReadName = 1;
2310  const signed char Ws1 = 2;
2311  const signed char STagEnd = 3;
2312  const signed char STagEnd2 = 4;
2313  const signed char ETagBegin = 5;
2314  const signed char ETagBegin2 = 6;
2315  const signed char Ws2 = 7;
2316  const signed char EmptyTag = 8;
2317  const signed char Attribute = 9;
2318  const signed char Ws3 = 10;
2319  const signed char Done = 11;
2320 
2321  const signed char InpWs = 0; // whitespace
2322  const signed char InpNameBe = 1; // is_NameBeginning()
2323  const signed char InpGt = 2; // >
2324  const signed char InpSlash = 3; // /
2325  const signed char InpUnknown = 4;
2326 
2327  // use some kind of state machine for parsing
2328  static signed char table[11][5] = {
2329  /* InpWs InpNameBe InpGt InpSlash InpUnknown */
2330  { -1, ReadName, -1, -1, -1 }, // Init
2331  { Ws1, Attribute, STagEnd, EmptyTag, -1 }, // ReadName
2332  { -1, Attribute, STagEnd, EmptyTag, -1 }, // Ws1
2333  { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
2334  { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
2335  { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
2336  { Ws2, -1, Done, -1, -1 }, // ETagBegin2
2337  { -1, -1, Done, -1, -1 }, // Ws2
2338  { -1, -1, Done, -1, -1 }, // EmptyTag
2339  { Ws3, Attribute, STagEnd, EmptyTag, -1 }, // Attribute
2340  { -1, Attribute, STagEnd, EmptyTag, -1 } // Ws3
2341  };
2342  signed char state = Init;
2343  signed char input;
2344  bool parseOk = TRUE;
2345 
2346  while ( TRUE ) {
2347 
2348  // read input
2349  if ( atEnd() ) {
2350  d->error = XMLERR_UNEXPECTEDEOF;
2351  goto parseError;
2352  }
2353  if ( is_S(c) ) {
2354  input = InpWs;
2355  } else if ( is_NameBeginning(c) ) {
2356  input = InpNameBe;
2357  } else if ( c == '>' ) {
2358  input = InpGt;
2359  } else if ( c == '/' ) {
2360  input = InpSlash;
2361  } else {
2362  input = InpUnknown;
2363  }
2364  // get new state
2365 //qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
2366  state = table[state][input];
2367 
2368  // in some cases do special actions depending on state
2369  switch ( state ) {
2370  case ReadName:
2371  parseOk = parseName();
2372  break;
2373  case Ws1:
2374  case Ws2:
2375  case Ws3:
2376  eat_ws();
2377  break;
2378  case STagEnd:
2379  // call the handler
2380  if ( contentHnd ) {
2381  if ( d->useNamespaces ) {
2382  d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
2383  t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
2384  } else {
2385  t = contentHnd->startElement( "", "", tags.top(), d->attList );
2386  }
2387  if ( !t ) {
2388  d->error = contentHnd->errorString();
2389  goto parseError;
2390  }
2391  }
2392  next();
2393  break;
2394  case STagEnd2:
2395  parseOk = parseContent();
2396  break;
2397  case ETagBegin:
2398  next();
2399  break;
2400  case ETagBegin2:
2401  // get the name of the tag
2402  parseOk = parseName();
2403  break;
2404  case EmptyTag:
2405  if ( tags.isEmpty() ) {
2406  d->error = XMLERR_TAGMISMATCH;
2407  goto parseError;
2408  }
2409  if ( !parseElementEmptyTag( t, uri, lname ) )
2410  goto parseError;
2411  // next character
2412  next();
2413  break;
2414  case Attribute:
2415  // get name and value of attribute
2416  parseOk = parseAttribute();
2417  break;
2418  case Done:
2419  next();
2420  break;
2421  }
2422  // no input is read after this
2423  switch ( state ) {
2424  case ReadName:
2425  if ( !parseOk ) {
2426  d->error = XMLERR_ERRORPARSINGNAME;
2427  goto parseError;
2428  }
2429  // store it on the stack
2430  tags.push( name() );
2431  // empty the attributes
2432  d->attList.qnameList.clear();
2433  d->attList.uriList.clear();
2434  d->attList.localnameList.clear();
2435  d->attList.valueList.clear();
2436  // namespace support?
2437  if ( d->useNamespaces ) {
2438  d->namespaceSupport.pushContext();
2439  }
2440  break;
2441  case STagEnd2:
2442  if ( !parseOk ) {
2443  d->error = XMLERR_ERRORPARSINGCONTENT;
2444  goto parseError;
2445  }
2446  break;
2447  case ETagBegin2:
2448  if ( !parseOk ) {
2449  d->error = XMLERR_ERRORPARSINGNAME;
2450  goto parseError;
2451  }
2452  if ( !parseElementETagBegin2( uri, lname ) )
2453  goto parseError;
2454  break;
2455  case Attribute:
2456  if ( !parseOk ) {
2458  goto parseError;
2459  }
2460  if ( !parseElementAttribute( prefix, uri, lname ) )
2461  goto parseError;
2462  break;
2463  case Done:
2464  return TRUE;
2465  case -1:
2466  d->error = XMLERR_ERRORPARSINGELEMENT;
2467  goto parseError;
2468  }
2469 
2470  }
2471 
2472  return TRUE;
2473 
2474 parseError:
2475  reportParseError();
2476  return FALSE;
2477 }
2478 /*!
2479  Helper to break down the size of the code in the case statement.
2480  Return FALSE on error, otherwise TRUE.
2481 */
2483 {
2484  // pop the stack and call the handler
2485  if ( contentHnd ) {
2486  // report startElement first...
2487  if ( d->useNamespaces ) {
2488  d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
2489  t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
2490  } else {
2491  t = contentHnd->startElement( "", "", tags.top(), d->attList );
2492  }
2493  if ( !t ) {
2494  d->error = contentHnd->errorString();
2495  return FALSE;
2496  }
2497  // ... followed by endElement
2498  if ( d->useNamespaces ) {
2499  if ( !contentHnd->endElement( uri, lname,tags.pop() ) ) {
2500  d->error = contentHnd->errorString();
2501  return FALSE;
2502  }
2503  }
2504  else {
2505  if ( !contentHnd->endElement( "","",tags.pop() ) ) {
2506  d->error = contentHnd->errorString();
2507  return FALSE;
2508  }
2509  }
2510  // namespace support?
2511  if ( d->useNamespaces ) {
2512  QStringList prefixesBefore, prefixesAfter;
2513  if ( contentHnd ) {
2514  prefixesBefore = d->namespaceSupport.prefixes();
2515  }
2516  d->namespaceSupport.popContext();
2517  // call the handler for prefix mapping
2518  if ( contentHnd ) {
2519  prefixesAfter = d->namespaceSupport.prefixes();
2520  for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
2521  if ( prefixesAfter.contains(*it) == 0 ) {
2522  if ( !contentHnd->endPrefixMapping( *it ) ) {
2523  d->error = contentHnd->errorString();
2524  return FALSE;
2525  }
2526  }
2527  }
2528  }
2529  }
2530  } else {
2531  tags.pop();
2532  }
2533  return TRUE;
2534 }
2535 /*!
2536  Helper to break down the size of the code in the case statement.
2537  Return FALSE on error, otherwise TRUE.
2538 */
2540 {
2541 
2542  // pop the stack and compare it with the name
2543  if ( tags.pop() != name() ) {
2544  d->error = XMLERR_TAGMISMATCH;
2545  return FALSE;
2546  }
2547  // call the handler
2548  if ( contentHnd ) {
2549  if ( d->useNamespaces ) {
2550  d->namespaceSupport.processName( name(), FALSE, uri, lname );
2551  if ( !contentHnd->endElement(uri,lname,name()) ) {
2552  d->error = contentHnd->errorString();
2553  return FALSE;
2554  }
2555  }
2556  else {
2557  if ( !contentHnd->endElement("","",name()) ) {
2558  d->error = contentHnd->errorString();
2559  return FALSE;
2560  }
2561  }
2562  }
2563  // namespace support?
2564  if ( d->useNamespaces ) {
2565  QStringList prefixesBefore, prefixesAfter;
2566  if ( contentHnd ) {
2567  prefixesBefore = d->namespaceSupport.prefixes();
2568  }
2569  d->namespaceSupport.popContext();
2570  // call the handler for prefix mapping
2571  if ( contentHnd ) {
2572  prefixesAfter = d->namespaceSupport.prefixes();
2573  for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
2574  if ( prefixesAfter.contains(*it) == 0 ) {
2575  if ( !contentHnd->endPrefixMapping( *it ) ) {
2576  d->error = contentHnd->errorString();
2577  return FALSE;
2578  }
2579  }
2580  }
2581  }
2582  }
2583  return TRUE;
2584 }
2585 /*!
2586  Helper to break down the size of the code in the case statement.
2587  Return FALSE on error, otherwise TRUE.
2588 */
2590 {
2591  // add the attribute to the list
2592  if ( d->useNamespaces ) {
2593  // is it a namespace declaration?
2594  d->namespaceSupport.splitName( name(), prefix, lname );
2595  if ( prefix == "xmlns" ) {
2596  // namespace declaration
2597  d->namespaceSupport.setPrefix( lname, string() );
2598  if ( d->useNamespacePrefixes ) {
2599  d->attList.qnameList.append( name() );
2600  d->attList.uriList.append( "" );
2601  d->attList.localnameList.append( "" );
2602  d->attList.valueList.append( string() );
2603  }
2604  // call the handler for prefix mapping
2605  if ( contentHnd ) {
2606  if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
2607  d->error = contentHnd->errorString();
2608  return FALSE;
2609  }
2610  }
2611  } else {
2612  // no namespace delcaration
2613  d->namespaceSupport.processName( name(), TRUE, uri, lname );
2614  d->attList.qnameList.append( name() );
2615  d->attList.uriList.append( uri );
2616  d->attList.localnameList.append( lname );
2617  d->attList.valueList.append( string() );
2618  }
2619  } else {
2620  // no namespace support
2621  d->attList.qnameList.append( name() );
2622  d->attList.uriList.append( "" );
2623  d->attList.localnameList.append( "" );
2624  d->attList.valueList.append( string() );
2625  }
2626  return TRUE;
2627 }
2628 
2629 /*!
2630  Parse a content [43].
2631 
2632  A content is only used between tags. If a end tag is found the < is already
2633  read and the head stand on the '/' of the end tag '</name>'.
2634 */
2636 {
2637  bool charDataRead = FALSE;
2638 
2639  const signed char Init = 0;
2640  const signed char ChD = 1; // CharData
2641  const signed char ChD1 = 2; // CharData help state
2642  const signed char ChD2 = 3; // CharData help state
2643  const signed char Ref = 4; // Reference
2644  const signed char Lt = 5; // '<' read
2645  const signed char PI = 6; // PI
2646  const signed char Elem = 7; // Element
2647  const signed char Em = 8; // '!' read
2648  const signed char Com = 9; // Comment
2649  const signed char CDS = 10; // CDSect
2650  const signed char CDS1 = 11; // read a CDSect
2651  const signed char CDS2 = 12; // read a CDSect (help state)
2652  const signed char CDS3 = 13; // read a CDSect (help state)
2653  const signed char Done = 14; // finished reading content
2654 
2655  const signed char InpLt = 0; // <
2656  const signed char InpGt = 1; // >
2657  const signed char InpSlash = 2; // /
2658  const signed char InpQMark = 3; // ?
2659  const signed char InpEMark = 4; // !
2660  const signed char InpAmp = 5; // &
2661  const signed char InpDash = 6; // -
2662  const signed char InpOpenB = 7; // [
2663  const signed char InpCloseB = 8; // ]
2664  const signed char InpUnknown = 9;
2665 
2666  static signed char mapCLT2FSMChar[] = {
2667  InpUnknown, // white space
2668  InpUnknown, // %
2669  InpAmp, // &
2670  InpGt, // >
2671  InpLt, // <
2672  InpSlash, // /
2673  InpQMark, // ?
2674  InpEMark, // !
2675  InpDash, // -
2676  InpCloseB, // ]
2677  InpOpenB, // [
2678  InpUnknown, // =
2679  InpUnknown, // "
2680  InpUnknown, // '
2681  InpUnknown // unknown
2682  };
2683 
2684  // use some kind of state machine for parsing
2685  static signed char const table[14][10] = {
2686  /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
2687  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
2688  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
2689  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
2690  { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
2691  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
2692  { -1, -1, Done, PI, Em, -1, -1, -1, -1, Elem }, // Lt
2693  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PI (same as Init)
2694  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
2695  { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
2696  { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
2697  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
2698  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
2699  { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
2700  { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
2701  };
2702  signed char state = Init;
2703  signed char input;
2704  bool parseOk = TRUE;
2705 
2706  while ( TRUE ) {
2707 
2708  // get input (use lookup-table instead of nested ifs for performance
2709  // reasons)
2710  if ( atEnd() ) {
2711  d->error = XMLERR_UNEXPECTEDEOF;
2712  goto parseError;
2713  }
2714  if ( c.row() ) {
2715  input = InpUnknown;
2716  } else {
2717  input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
2718  }
2719 
2720  // set state according to input
2721  state = table[state][input];
2722 
2723  // do some actions according to state
2724  switch ( state ) {
2725  case Init:
2726  // next character
2727  next();
2728  break;
2729  case ChD:
2730  // on first call: clear string
2731  if ( !charDataRead ) {
2732  charDataRead = TRUE;
2733  stringClear();
2734  }
2735  stringAddC();
2736  next();
2737  break;
2738  case ChD1:
2739  // on first call: clear string
2740  if ( !charDataRead ) {
2741  charDataRead = TRUE;
2742  stringClear();
2743  }
2744  stringAddC();
2745  next();
2746  break;
2747  case ChD2:
2748  stringAddC();
2749  next();
2750  break;
2751  case Ref:
2752  if ( !charDataRead) {
2753  // reference may be CharData; so clear string to be safe
2754  stringClear();
2755  parseOk = parseReference( charDataRead, InContent );
2756  } else {
2757  bool tmp;
2758  parseOk = parseReference( tmp, InContent );
2759  }
2760  break;
2761  case Lt:
2762  // call the handler for CharData
2763  if ( contentHnd ) {
2764  if ( charDataRead ) {
2765  if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
2766  if ( !contentHnd->characters( string() ) ) {
2767  d->error = contentHnd->errorString();
2768  goto parseError;
2769  }
2770  }
2771  }
2772  }
2773  charDataRead = FALSE;
2774  // next character
2775  next();
2776  break;
2777  case PI:
2778  parseOk = parsePI();
2779  break;
2780  case Elem:
2781  parseOk = parseElement();
2782  break;
2783  case Em:
2784  // next character
2785  next();
2786  break;
2787  case Com:
2788  parseOk = parseComment();
2789  break;
2790  case CDS:
2791  parseOk = parseString( "[CDATA[" );
2792  break;
2793  case CDS1:
2794  // read one character and add it
2795  stringAddC();
2796  next();
2797  break;
2798  case CDS2:
2799  // skip ']'
2800  next();
2801  break;
2802  case CDS3:
2803  // skip ']'...
2804  next();
2805  break;
2806  }
2807  // no input is read after this
2808  switch ( state ) {
2809  case Ref:
2810  if ( !parseOk ) {
2812  goto parseError;
2813  }
2814  break;
2815  case PI:
2816  if ( !parseOk ) {
2817  d->error = XMLERR_ERRORPARSINGPI;
2818  goto parseError;
2819  }
2820  // call the handler
2821  if ( contentHnd ) {
2822  if ( !contentHnd->processingInstruction(name(),string()) ) {
2823  d->error = contentHnd->errorString();
2824  goto parseError;
2825  }
2826  }
2827  break;
2828  case Elem:
2829  if ( !parseOk ) {
2830  d->error = XMLERR_ERRORPARSINGELEMENT;
2831  goto parseError;
2832  }
2833  break;
2834  case Com:
2835  if ( !parseOk ) {
2836  d->error = XMLERR_ERRORPARSINGCOMMENT;
2837  goto parseError;
2838  }
2839  if ( lexicalHnd ) {
2840  if ( !lexicalHnd->comment( string() ) ) {
2841  d->error = lexicalHnd->errorString();
2842  goto parseError;
2843  }
2844  }
2845  break;
2846  case CDS:
2847  if( !parseOk ) {
2848  d->error = XMLERR_CDSECTHEADEREXPECTED;
2849  goto parseError;
2850  }
2851  // empty string
2852  stringClear();
2853  break;
2854  case CDS2:
2855  if (c != ']') {
2856  stringAddC( ']' );
2857  }
2858  break;
2859  case CDS3:
2860  // test if this skipping was legal
2861  if ( c == '>' ) {
2862  // the end of the CDSect
2863  if ( lexicalHnd ) {
2864  if ( !lexicalHnd->startCDATA() ) {
2865  d->error = lexicalHnd->errorString();
2866  goto parseError;
2867  }
2868  }
2869  if ( contentHnd ) {
2870  if ( !contentHnd->characters( string() ) ) {
2871  d->error = contentHnd->errorString();
2872  goto parseError;
2873  }
2874  }
2875  if ( lexicalHnd ) {
2876  if ( !lexicalHnd->endCDATA() ) {
2877  d->error = lexicalHnd->errorString();
2878  goto parseError;
2879  }
2880  }
2881  } else if (c == ']') {
2882  // three or more ']'
2883  stringAddC( ']' );
2884  } else {
2885  // after ']]' comes another character
2886  stringAddC( ']' );
2887  stringAddC( ']' );
2888  }
2889  break;
2890  case Done:
2891  // call the handler for CharData
2892  if ( contentHnd ) {
2893  if ( charDataRead ) {
2894  if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
2895  if ( !contentHnd->characters( string() ) ) {
2896  d->error = contentHnd->errorString();
2897  goto parseError;
2898  }
2899  }
2900  }
2901  }
2902  // Done
2903  return TRUE;
2904  case -1:
2905  // Error
2906  d->error = XMLERR_ERRORPARSINGCONTENT;
2907  goto parseError;
2908  }
2909 
2910  }
2911 
2912  return TRUE;
2913 
2914 parseError:
2915  reportParseError();
2916  return FALSE;
2917 }
2918 
2919 /*!
2920  Parse Misc [27].
2921 */
2923 {
2924  const signed char Init = 0;
2925  const signed char Lt = 1; // '<' was read
2926  const signed char Comment = 2; // read comment
2927  const signed char eatWS = 3; // eat whitespaces
2928  const signed char PI = 4; // read PI
2929  const signed char Comment2 = 5; // read comment
2930 
2931  const signed char InpWs = 0; // S
2932  const signed char InpLt = 1; // <
2933  const signed char InpQm = 2; // ?
2934  const signed char InpEm = 3; // !
2935  const signed char InpUnknown = 4;
2936 
2937  // use some kind of state machine for parsing
2938  static signed char table[3][5] = {
2939  /* InpWs InpLt InpQm InpEm InpUnknown */
2940  { eatWS, Lt, -1, -1, -1 }, // Init
2941  { -1, -1, PI, Comment, -1 }, // Lt
2942  { -1, -1, -1, -1, Comment2 } // Comment
2943  };
2944  signed char state = Init;
2945  signed char input;
2946  bool parseOk = TRUE;
2947 
2948  while ( TRUE ) {
2949 
2950  // get input
2951  if ( atEnd() ) {
2952  d->error = XMLERR_UNEXPECTEDEOF;
2953  goto parseError;
2954  }
2955  if ( is_S(c) ) {
2956  input = InpWs;
2957  } else if ( c == '<' ) {
2958  input = InpLt;
2959  } else if ( c == '?' ) {
2960  input = InpQm;
2961  } else if ( c == '!' ) {
2962  input = InpEm;
2963  } else {
2964  input = InpUnknown;
2965  }
2966 
2967  // set state according to input
2968  state = table[state][input];
2969 
2970  // do some actions according to state
2971  switch ( state ) {
2972  case eatWS:
2973  eat_ws();
2974  break;
2975  case Lt:
2976  next();
2977  break;
2978  case PI:
2979  parseOk = parsePI();
2980  break;
2981  case Comment:
2982  next();
2983  break;
2984  case Comment2:
2985  parseOk = parseComment();
2986  break;
2987  }
2988  // no input is read after this
2989  switch ( state ) {
2990  case eatWS:
2991  return TRUE;
2992  case PI:
2993  if ( !parseOk ) {
2994  d->error = XMLERR_ERRORPARSINGPI;
2995  goto parseError;
2996  }
2997  if ( contentHnd ) {
2998  if ( !contentHnd->processingInstruction(name(),string()) ) {
2999  d->error = contentHnd->errorString();
3000  goto parseError;
3001  }
3002  }
3003  return TRUE;
3004  case Comment2:
3005  if ( !parseOk ) {
3006  d->error = XMLERR_ERRORPARSINGCOMMENT;
3007  goto parseError;
3008  }
3009  if ( lexicalHnd ) {
3010  if ( !lexicalHnd->comment( string() ) ) {
3011  d->error = lexicalHnd->errorString();
3012  goto parseError;
3013  }
3014  }
3015  return TRUE;
3016  case -1:
3017  // Error
3018  d->error = XMLERR_UNEXPECTEDCHARACTER;
3019  goto parseError;
3020  }
3021 
3022  }
3023 
3024  return TRUE;
3025 
3026 parseError:
3027  reportParseError();
3028  return FALSE;
3029 }
3030 
3031 /*!
3032  Parse a processing instruction [16].
3033 
3034  If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
3035 
3036  Precondition: the beginning '<' of the PI is already read and the head stand
3037  on the '?' of '<?'.
3038 
3039  If this funktion was successful, the head-position is on the first
3040  character after the PI.
3041 */
3042 bool QXmlSimpleReader::parsePI( bool xmldecl )
3043 {
3044  const signed char Init = 0;
3045  const signed char QmI = 1; // ? was read
3046  const signed char Name = 2; // read Name
3047  const signed char XMLDecl = 3; // read XMLDecl
3048  const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
3049  const signed char PI = 5; // read PI
3050  const signed char Ws2 = 6; // eat ws after Name of PI
3051  const signed char Version = 7; // read versionInfo
3052  const signed char Ws3 = 8; // eat ws after versionInfo
3053  const signed char EorSD = 9; // read EDecl or SDDecl
3054  const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
3055  const signed char SD = 11; // read SDDecl
3056  const signed char Ws5 = 12; // eat ws after SDDecl
3057  const signed char ADone = 13; // almost done
3058  const signed char Char = 14; // Char was read
3059  const signed char Qm = 15; // Qm was read
3060  const signed char Done = 16; // finished reading content
3061 
3062  const signed char InpWs = 0; // whitespace
3063  const signed char InpNameBe = 1; // is_nameBeginning()
3064  const signed char InpGt = 2; // >
3065  const signed char InpQm = 3; // ?
3066  const signed char InpUnknown = 4;
3067 
3068  // use some kind of state machine for parsing
3069  static signed char table[16][5] = {
3070  /* InpWs, InpNameBe InpGt InpQm InpUnknown */
3071  { -1, -1, -1, QmI, -1 }, // Init
3072  { -1, Name, -1, -1, -1 }, // QmI
3073  { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
3074  { Ws1, -1, -1, -1, -1 }, // XMLDecl
3075  { -1, Version, -1, -1, -1 }, // Ws1
3076  { Ws2, -1, -1, Qm, -1 }, // PI
3077  { Char, Char, Char, Qm, Char }, // Ws2
3078  { Ws3, -1, -1, ADone, -1 }, // Version
3079  { -1, EorSD, -1, ADone, -1 }, // Ws3
3080  { Ws4, -1, -1, ADone, -1 }, // EorSD
3081  { -1, SD, -1, ADone, -1 }, // Ws4
3082  { Ws5, -1, -1, ADone, -1 }, // SD
3083  { -1, -1, -1, ADone, -1 }, // Ws5
3084  { -1, -1, Done, -1, -1 }, // ADone
3085  { Char, Char, Char, Qm, Char }, // Char
3086  { Char, Char, Done, Qm, Char }, // Qm
3087  };
3088  signed char state = Init;
3089  signed char input;
3090  bool parseOk = TRUE;
3091 
3092  while ( TRUE ) {
3093 
3094  // get input
3095  if ( atEnd() ) {
3096  d->error = XMLERR_UNEXPECTEDEOF;
3097  goto parseError;
3098  }
3099  if ( is_S(c) ) {
3100  input = InpWs;
3101  } else if ( is_NameBeginning(c) ) {
3102  input = InpNameBe;
3103  } else if ( c == '>' ) {
3104  input = InpGt;
3105  } else if ( c == '?' ) {
3106  input = InpQm;
3107  } else {
3108  input = InpUnknown;
3109  }
3110 
3111  // set state according to input
3112  state = table[state][input];
3113 
3114  // do some actions according to state
3115  switch ( state ) {
3116  case QmI:
3117  next();
3118  break;
3119  case Name:
3120  parseOk = parseName();
3121  break;
3122  case Ws1:
3123  case Ws2:
3124  case Ws3:
3125  case Ws4:
3126  case Ws5:
3127  eat_ws();
3128  break;
3129  case Version:
3130  parseOk = parseAttribute();
3131  break;
3132  case EorSD:
3133  parseOk = parseAttribute();
3134  break;
3135  case SD:
3136  // get the SDDecl (syntax like an attribute)
3137  if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
3138  // already parsed the standalone declaration
3139  d->error = XMLERR_UNEXPECTEDCHARACTER;
3140  goto parseError;
3141  }
3142  parseOk = parseAttribute();
3143  break;
3144  case ADone:
3145  next();
3146  break;
3147  case Char:
3148  stringAddC();
3149  next();
3150  break;
3151  case Qm:
3152  // skip the '?'
3153  next();
3154  break;
3155  case Done:
3156  next();
3157  break;
3158  }
3159  // no input is read after this
3160  switch ( state ) {
3161  case Name:
3162  if ( !parseOk ) {
3163  d->error = XMLERR_ERRORPARSINGNAME;
3164  goto parseError;
3165  }
3166  // test what name was read and determine the next state
3167  // (not very beautiful, I admit)
3168  if ( name().lower() == "xml" ) {
3169  if ( xmldecl && name()=="xml" ) {
3170  state = XMLDecl;
3171  } else {
3172  d->error = XMLERR_INVALIDNAMEFORPI;
3173  goto parseError;
3174  }
3175  } else {
3176  state = PI;
3177  stringClear();
3178  }
3179  break;
3180  case Version:
3181  // get version (syntax like an attribute)
3182  if ( !parseOk ) {
3183  d->error = XMLERR_VERSIONEXPECTED;
3184  goto parseError;
3185  }
3186  if ( name() != "version" ) {
3187  d->error = XMLERR_VERSIONEXPECTED;
3188  goto parseError;
3189  }
3190  d->xmlVersion = string();
3191  break;
3192  case EorSD:
3193  // get the EDecl or SDDecl (syntax like an attribute)
3194  if ( !parseOk ) {
3196  goto parseError;
3197  }
3198  if ( name() == "standalone" ) {
3199  if ( string()=="yes" ) {
3200  d->standalone = QXmlSimpleReaderPrivate::Yes;
3201  } else if ( string()=="no" ) {
3202  d->standalone = QXmlSimpleReaderPrivate::No;
3203  } else {
3204  d->error = XMLERR_WRONGVALUEFORSDECL;
3205  goto parseError;
3206  }
3207  } else if ( name() == "encoding" ) {
3208  d->encoding = string();
3209  } else {
3211  goto parseError;
3212  }
3213  break;
3214  case SD:
3215  if ( !parseOk ) {
3216  d->error = XMLERR_SDDECLEXPECTED;
3217  goto parseError;
3218  }
3219  if ( name() != "standalone" ) {
3220  d->error = XMLERR_SDDECLEXPECTED;
3221  goto parseError;
3222  }
3223  if ( string()=="yes" ) {
3224  d->standalone = QXmlSimpleReaderPrivate::Yes;
3225  } else if ( string()=="no" ) {
3226  d->standalone = QXmlSimpleReaderPrivate::No;
3227  } else {
3228  d->error = XMLERR_WRONGVALUEFORSDECL;
3229  goto parseError;
3230  }
3231  break;
3232  case Qm:
3233  // test if the skipping was legal
3234  if ( c != '>' ) {
3235  stringAddC( '?' );
3236  }
3237  break;
3238  case Done:
3239  return TRUE;
3240  case -1:
3241  // Error
3242  d->error = XMLERR_UNEXPECTEDCHARACTER;
3243  goto parseError;
3244  }
3245 
3246  }
3247 
3248  return TRUE;
3249 
3250 parseError:
3251  reportParseError();
3252  return FALSE;
3253 }
3254 
3255 /*!
3256  Parse a document type definition (doctypedecl [28]).
3257 
3258  Precondition: the beginning '<!' of the doctype is already read the head
3259  stands on the 'D' of '<!DOCTYPE'.
3260 
3261  If this funktion was successful, the head-position is on the first
3262  character after the document type definition.
3263 */
3265 {
3266  // some init-stuff
3267  d->systemId = QString::null;
3268  d->publicId = QString::null;
3269 
3270  const signed char Init = 0;
3271  const signed char Doctype = 1; // read the doctype
3272  const signed char Ws1 = 2; // eat_ws
3273  const signed char Doctype2 = 3; // read the doctype, part 2
3274  const signed char Ws2 = 4; // eat_ws
3275  const signed char Sys = 5; // read SYSTEM
3276  const signed char Ws3 = 6; // eat_ws
3277  const signed char MP = 7; // markupdecl or PEReference
3278  const signed char PER = 8; // PERReference
3279  const signed char Mup = 9; // markupdecl
3280  const signed char Ws4 = 10; // eat_ws
3281  const signed char MPE = 11; // end of markupdecl or PEReference
3282  const signed char Done = 12;
3283 
3284  const signed char InpWs = 0;
3285  const signed char InpD = 1; // 'D'
3286  const signed char InpS = 2; // 'S' or 'P'
3287  const signed char InpOB = 3; // [
3288  const signed char InpCB = 4; // ]
3289  const signed char InpPer = 5; // %
3290  const signed char InpGt = 6; // >
3291  const signed char InpUnknown = 7;
3292 
3293  // use some kind of state machine for parsing
3294  static signed char table[12][8] = {
3295  /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
3296  { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
3297  { Ws1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Doctype
3298  { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
3299  { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
3300  { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
3301  { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
3302  { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
3303  { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
3304  { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
3305  { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
3306  { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
3307  { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
3308  };
3309  signed char state = Init;
3310  signed char input;
3311  bool parseOk = TRUE;
3312 
3313  while ( TRUE ) {
3314 
3315  // get input
3316  if ( atEnd() ) {
3317  d->error = XMLERR_UNEXPECTEDEOF;
3318  goto parseError;
3319  }
3320  if ( is_S(c) ) {
3321  input = InpWs;
3322  } else if ( c == 'D' ) {
3323  input = InpD;
3324  } else if ( c == 'S' ) {
3325  input = InpS;
3326  } else if ( c == 'P' ) {
3327  input = InpS;
3328  } else if ( c == '[' ) {
3329  input = InpOB;
3330  } else if ( c == ']' ) {
3331  input = InpCB;
3332  } else if ( c == '%' ) {
3333  input = InpPer;
3334  } else if ( c == '>' ) {
3335  input = InpGt;
3336  } else {
3337  input = InpUnknown;
3338  }
3339 
3340  // set state according to input
3341  state = table[state][input];
3342 
3343  // do some actions according to state
3344  switch ( state ) {
3345  case Doctype:
3346  parseOk = parseString( "DOCTYPE" );
3347  break;
3348  case Ws1:
3349  case Ws2:
3350  case Ws3:
3351  case Ws4:
3352  eat_ws();
3353  break;
3354  case Doctype2:
3355  parseName();
3356  break;
3357  case Sys:
3358  parseOk = parseExternalID();
3359  break;
3360  case MP:
3361  next_eat_ws();
3362  break;
3363  case PER:
3364  parseOk = parsePEReference( InDTD );
3365  break;
3366  case Mup:
3367  parseOk = parseMarkupdecl();
3368  break;
3369  case MPE:
3370  next_eat_ws();
3371  break;
3372  case Done:
3373  if ( lexicalHnd ) {
3374  if ( !lexicalHnd->endDTD() ) {
3375  d->error = lexicalHnd->errorString();
3376  goto parseError;
3377  }
3378  }
3379  next();
3380  break;
3381  }
3382  // no input is read after this
3383  switch ( state ) {
3384  case Doctype:
3385  if ( !parseOk ) {
3386  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3387  goto parseError;
3388  }
3389  if ( !is_S(c) ) {
3390  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3391  goto parseError;
3392  }
3393  break;
3394  case Doctype2:
3395  d->doctype = name();
3396  if ( lexicalHnd ) {
3397  if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
3398  d->error = lexicalHnd->errorString();
3399  goto parseError;
3400  }
3401  }
3402  break;
3403  case Sys:
3404  if ( !parseOk ) {
3405  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3406  goto parseError;
3407  }
3408  break;
3409  case PER:
3410  if ( !parseOk ) {
3411  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3412  goto parseError;
3413  }
3414  break;
3415  case Mup:
3416  if ( !parseOk ) {
3417  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3418  goto parseError;
3419  }
3420  break;
3421  case Done:
3422  return TRUE;
3423  case -1:
3424  // Error
3425  d->error = XMLERR_ERRORPARSINGDOCTYPE;
3426  goto parseError;
3427  }
3428 
3429  }
3430 
3431  return TRUE;
3432 
3433 parseError:
3434  reportParseError();
3435  return FALSE;
3436 }
3437 
3438 /*!
3439  Parse a ExternalID [75].
3440 
3441  If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
3442 */
3443 bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
3444 {
3445  // some init-stuff
3446  d->systemId = QString::null;
3447  d->publicId = QString::null;
3448 
3449  const signed char Init = 0;
3450  const signed char Sys = 1; // parse 'SYSTEM'
3451  const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
3452  const signed char SysSQ = 3; // parse SystemLiteral with '
3453  const signed char SysSQ2 = 4; // parse SystemLiteral with '
3454  const signed char SysDQ = 5; // parse SystemLiteral with "
3455  const signed char SysDQ2 = 6; // parse SystemLiteral with "
3456  const signed char Pub = 7; // parse 'PUBLIC'
3457  const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
3458  const signed char PubSQ = 9; // parse PubidLiteral with '
3459  const signed char PubSQ2 = 10; // parse PubidLiteral with '
3460  const signed char PubDQ = 11; // parse PubidLiteral with "
3461  const signed char PubDQ2 = 12; // parse PubidLiteral with "
3462  const signed char PubE = 13; // finished parsing the PubidLiteral
3463  const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
3464  const signed char PDone = 15; // done if allowPublicID is TRUE
3465  const signed char Done = 16;
3466 
3467  const signed char InpSQ = 0; // '
3468  const signed char InpDQ = 1; // "
3469  const signed char InpS = 2; // S
3470  const signed char InpP = 3; // P
3471  const signed char InpWs = 4; // white space
3472  const signed char InpUnknown = 5;
3473 
3474  // use some kind of state machine for parsing
3475  static signed char table[15][6] = {
3476  /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
3477  { -1, -1, Sys, Pub, -1, -1 }, // Init
3478  { -1, -1, -1, -1, SysWS, -1 }, // Sys
3479  { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
3480  { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
3481  { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
3482  { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
3483  { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
3484  { -1, -1, -1, -1, PubWS, -1 }, // Pub
3485  { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
3486  { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
3487  { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
3488  { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
3489  { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
3490  { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
3491  { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
3492  };
3493  signed char state = Init;
3494  signed char input;
3495  bool parseOk = TRUE;
3496 
3497  while ( TRUE ) {
3498 
3499  // get input
3500  if ( atEnd() ) {
3501  d->error = XMLERR_UNEXPECTEDEOF;
3502  goto parseError;
3503  }
3504  if ( is_S(c) ) {
3505  input = InpWs;
3506  } else if ( c == '\'' ) {
3507  input = InpSQ;
3508  } else if ( c == '"' ) {
3509  input = InpDQ;
3510  } else if ( c == 'S' ) {
3511  input = InpS;
3512  } else if ( c == 'P' ) {
3513  input = InpP;
3514  } else {
3515  input = InpUnknown;
3516  }
3517 
3518  // set state according to input
3519  state = table[state][input];
3520 
3521  // do some actions according to state
3522  switch ( state ) {
3523  case Sys:
3524  parseOk = parseString( "SYSTEM" );
3525  break;
3526  case SysWS:
3527  eat_ws();
3528  break;
3529  case SysSQ:
3530  case SysDQ:
3531  stringClear();
3532  next();
3533  break;
3534  case SysSQ2:
3535  case SysDQ2:
3536  stringAddC();
3537  next();
3538  break;
3539  case Pub:
3540  parseOk = parseString( "PUBLIC" );
3541  break;
3542  case PubWS:
3543  eat_ws();
3544  break;
3545  case PubSQ:
3546  case PubDQ:
3547  stringClear();
3548  next();
3549  break;
3550  case PubSQ2:
3551  case PubDQ2:
3552  stringAddC();
3553  next();
3554  break;
3555  case PubE:
3556  next();
3557  break;
3558  case PubWS2:
3559  d->publicId = string();
3560  eat_ws();
3561  break;
3562  case Done:
3563  d->systemId = string();
3564  next();
3565  break;
3566  }
3567  // no input is read after this
3568  switch ( state ) {
3569  case Sys:
3570  if( !parseOk ) {
3571  d->error = XMLERR_UNEXPECTEDCHARACTER;
3572  goto parseError;
3573  }
3574  break;
3575  case Pub:
3576  if( !parseOk ) {
3577  d->error = XMLERR_UNEXPECTEDCHARACTER;
3578  goto parseError;
3579  }
3580  break;
3581  case PDone:
3582  if ( allowPublicID ) {
3583  d->publicId = string();
3584  return TRUE;
3585  } else {
3586  d->error = XMLERR_UNEXPECTEDCHARACTER;
3587  goto parseError;
3588  }
3589  break;
3590  case Done:
3591  return TRUE;
3592  case -1:
3593  // Error
3594  d->error = XMLERR_UNEXPECTEDCHARACTER;
3595  goto parseError;
3596  }
3597 
3598  }
3599 
3600  return TRUE;
3601 
3602 parseError:
3603  reportParseError();
3604  return FALSE;
3605 }
3606 
3607 /*!
3608  Parse a markupdecl [29].
3609 */
3611 {
3612  const signed char Init = 0;
3613  const signed char Lt = 1; // < was read
3614  const signed char Em = 2; // ! was read
3615  const signed char CE = 3; // E was read
3616  const signed char Qm = 4; // ? was read
3617  const signed char Dash = 5; // - was read
3618  const signed char CA = 6; // A was read
3619  const signed char CEL = 7; // EL was read
3620  const signed char CEN = 8; // EN was read
3621  const signed char CN = 9; // N was read
3622  const signed char Done = 10;
3623 
3624  const signed char InpLt = 0; // <
3625  const signed char InpQm = 1; // ?
3626  const signed char InpEm = 2; // !
3627  const signed char InpDash = 3; // -
3628  const signed char InpA = 4; // A
3629  const signed char InpE = 5; // E
3630  const signed char InpL = 6; // L
3631  const signed char InpN = 7; // N
3632  const signed char InpUnknown = 8;
3633 
3634  // use some kind of state machine for parsing
3635  static signed char table[4][9] = {
3636  /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
3637  { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
3638  { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
3639  { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
3640  { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
3641  };
3642  signed char state = Init;
3643  signed char input;
3644  bool parseOk = TRUE;
3645 
3646  while ( TRUE ) {
3647 
3648  // get input
3649  if ( atEnd() ) {
3650  d->error = XMLERR_UNEXPECTEDEOF;
3651  goto parseError;
3652  }
3653  if ( c == '<' ) {
3654  input = InpLt;
3655  } else if ( c == '?' ) {
3656  input = InpQm;
3657  } else if ( c == '!' ) {
3658  input = InpEm;
3659  } else if ( c == '-' ) {
3660  input = InpDash;
3661  } else if ( c == 'A' ) {
3662  input = InpA;
3663  } else if ( c == 'E' ) {
3664  input = InpE;
3665  } else if ( c == 'L' ) {
3666  input = InpL;
3667  } else if ( c == 'N' ) {
3668  input = InpN;
3669  } else {
3670  input = InpUnknown;
3671  }
3672 
3673  // set state according to input
3674  state = table[state][input];
3675 
3676  // do some actions according to state
3677  switch ( state ) {
3678  case Lt:
3679  next();
3680  break;
3681  case Em:
3682  next();
3683  break;
3684  case CE:
3685  next();
3686  break;
3687  case Qm:
3688  parseOk = parsePI();
3689  break;
3690  case Dash:
3691  parseOk = parseComment();
3692  break;
3693  case CA:
3694  parseOk = parseAttlistDecl();
3695  break;
3696  case CEL:
3697  parseOk = parseElementDecl();
3698  break;
3699  case CEN:
3700  parseOk = parseEntityDecl();
3701  break;
3702  case CN:
3703  parseOk = parseNotationDecl();
3704  break;
3705  }
3706  // no input is read after this
3707  switch ( state ) {
3708  case Qm:
3709  if ( !parseOk ) {
3710  d->error = XMLERR_ERRORPARSINGPI;
3711  goto parseError;
3712  }
3713  if ( contentHnd ) {
3714  if ( !contentHnd->processingInstruction(name(),string()) ) {
3715  d->error = contentHnd->errorString();
3716  goto parseError;
3717  }
3718  }
3719  return TRUE;
3720  case Dash:
3721  if ( !parseOk ) {
3722  d->error = XMLERR_ERRORPARSINGCOMMENT;
3723  goto parseError;
3724  }
3725  if ( lexicalHnd ) {
3726  if ( !lexicalHnd->comment( string() ) ) {
3727  d->error = lexicalHnd->errorString();
3728  goto parseError;
3729  }
3730  }
3731  return TRUE;
3732  case CA:
3733  if ( !parseOk ) {
3735  goto parseError;
3736  }
3737  return TRUE;
3738  case CEL:
3739  if ( !parseOk ) {
3741  goto parseError;
3742  }
3743  return TRUE;
3744  case CEN:
3745  if ( !parseOk ) {
3747  goto parseError;
3748  }
3749  return TRUE;
3750  case CN:
3751  if ( !parseOk ) {
3753  goto parseError;
3754  }
3755  return TRUE;
3756  case Done:
3757  return TRUE;
3758  case -1:
3759  // Error
3760  d->error = XMLERR_LETTEREXPECTED;
3761  goto parseError;
3762  }
3763 
3764  }
3765 
3766  return TRUE;
3767 
3768 parseError:
3769  reportParseError();
3770  return FALSE;
3771 }
3772 
3773 /*!
3774  Parse a PEReference [69]
3775 */
3777 {
3778  const signed char Init = 0;
3779  const signed char Next = 1;
3780  const signed char Name = 2;
3781  const signed char Done = 3;
3782 
3783  const signed char InpSemi = 0; // ;
3784  const signed char InpPer = 1; // %
3785  const signed char InpUnknown = 2;
3786 
3787  // use some kind of state machine for parsing
3788  static signed char table[3][3] = {
3789  /* InpSemi InpPer InpUnknown */
3790  { -1, Next, -1 }, // Init
3791  { -1, -1, Name }, // Next
3792  { Done, -1, -1 } // Name
3793  };
3794  signed char state = Init;
3795  signed char input;
3796  bool parseOk = TRUE;
3797 
3798  while ( TRUE ) {
3799 
3800  // get input
3801  if ( atEnd() ) {
3802  d->error = XMLERR_UNEXPECTEDEOF;
3803  goto parseError;
3804  }
3805  if ( c == ';' ) {
3806  input = InpSemi;
3807  } else if ( c == '%' ) {
3808  input = InpPer;
3809  } else {
3810  input = InpUnknown;
3811  }
3812 
3813  // set state according to input
3814  state = table[state][input];
3815 
3816  // do some actions according to state
3817  switch ( state ) {
3818  case Next:
3819  next();
3820  break;
3821  case Name:
3822  parseOk = parseName( TRUE );
3823  break;
3824  case Done:
3825  next();
3826  break;
3827  }
3828  // no input is read after this
3829  switch ( state ) {
3830  case Name:
3831  if ( !parseOk ) {
3832  d->error = XMLERR_ERRORPARSINGNAME;
3833  goto parseError;
3834  }
3835  if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) {
3836  // ### skip it???
3837  if ( contentHnd ) {
3838  if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
3839  d->error = contentHnd->errorString();
3840  goto parseError;
3841  }
3842  }
3843  } else {
3844  if ( context == InEntityValue ) {
3845  // Included in literal
3846  xmlRef = d->parameterEntities.find( ref() )
3847  .data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
3848  + xmlRef;
3849  } else if ( context == InDTD ) {
3850  // Included as PE
3851  xmlRef = QString(" ") +
3852  d->parameterEntities.find( ref() ).data() +
3853  QString(" ") + xmlRef;
3854  }
3855  }
3856  break;
3857  case Done:
3858  return TRUE;
3859  case -1:
3860  // Error
3861  d->error = XMLERR_LETTEREXPECTED;
3862  goto parseError;
3863  }
3864 
3865  }
3866 
3867  return TRUE;
3868 
3869 parseError:
3870  reportParseError();
3871  return FALSE;
3872 }
3873 
3874 /*!
3875  Parse a AttlistDecl [52].
3876 
3877  Precondition: the beginning '<!' is already read and the head
3878  stands on the 'A' of '<!ATTLIST'
3879 */
3881 {
3882  const signed char Init = 0;
3883  const signed char Attlist = 1; // parse the string "ATTLIST"
3884  const signed char Ws = 2; // whitespace read
3885  const signed char Name = 3; // parse name
3886  const signed char Ws1 = 4; // whitespace read
3887  const signed char Attdef = 5; // parse the AttDef
3888  const signed char Ws2 = 6; // whitespace read
3889  const signed char Atttype = 7; // parse the AttType
3890  const signed char Ws3 = 8; // whitespace read
3891  const signed char DDecH = 9; // DefaultDecl with #
3892  const signed char DefReq = 10; // parse the string "REQUIRED"
3893  const signed char DefImp = 11; // parse the string "IMPLIED"
3894  const signed char DefFix = 12; // parse the string "FIXED"
3895  const signed char Attval = 13; // parse the AttValue
3896  const signed char Ws4 = 14; // whitespace read
3897  const signed char Done = 15;
3898 
3899  const signed char InpWs = 0; // white space
3900  const signed char InpGt = 1; // >
3901  const signed char InpHash = 2; // #
3902  const signed char InpA = 3; // A
3903  const signed char InpI = 4; // I
3904  const signed char InpF = 5; // F
3905  const signed char InpR = 6; // R
3906  const signed char InpUnknown = 7;
3907 
3908  // use some kind of state machine for parsing
3909  static signed char table[15][8] = {
3910  /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
3911  { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
3912  { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
3913  { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
3914  { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
3915  { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
3916  { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
3917  { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
3918  { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
3919  { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
3920  { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
3921  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
3922  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
3923  { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
3924  { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
3925  { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
3926  };
3927  signed char state = Init;
3928  signed char input;
3929  bool parseOk = TRUE;
3930 
3931  while ( TRUE ) {
3932 
3933  // get input
3934  if ( atEnd() ) {
3935  d->error = XMLERR_UNEXPECTEDEOF;
3936  goto parseError;
3937  }
3938  if ( is_S(c) ) {
3939  input = InpWs;
3940  } else if ( c == '>' ) {
3941  input = InpGt;
3942  } else if ( c == '#' ) {
3943  input = InpHash;
3944  } else if ( c == 'A' ) {
3945  input = InpA;
3946  } else if ( c == 'I' ) {
3947  input = InpI;
3948  } else if ( c == 'F' ) {
3949  input = InpF;
3950  } else if ( c == 'R' ) {
3951  input = InpR;
3952  } else {
3953  input = InpUnknown;
3954  }
3955 
3956  // set state according to input
3957  state = table[state][input];
3958 
3959  // do some actions according to state
3960  switch ( state ) {
3961  case Attlist:
3962  parseOk = parseString( "ATTLIST" );
3963  break;
3964  case Ws:
3965  case Ws1:
3966  case Ws2:
3967  case Ws3:
3968  eat_ws();
3969  break;
3970  case Name:
3971  parseOk = parseName();
3972  break;
3973  case Attdef:
3974  parseOk = parseName();
3975  break;
3976  case Atttype:
3977  parseOk = parseAttType();
3978  break;
3979  case DDecH:
3980  next();
3981  break;
3982  case DefReq:
3983  parseOk = parseString( "REQUIRED" );
3984  break;
3985  case DefImp:
3986  parseOk = parseString( "IMPLIED" );
3987  break;
3988  case DefFix:
3989  parseOk = parseString( "FIXED" );
3990  break;
3991  case Attval:
3992  parseOk = parseAttValue();
3993  break;
3994  case Ws4:
3995  if ( declHnd ) {
3996  // TODO: not all values are computed yet...
3997  if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
3998  d->error = declHnd->errorString();
3999  goto parseError;
4000  }
4001  }
4002  eat_ws();
4003  break;
4004  case Done:
4005  next();
4006  break;
4007  }
4008  // no input is read after this
4009  switch ( state ) {
4010  case Attlist:
4011  if( !parseOk ) {
4012  d->error = XMLERR_UNEXPECTEDCHARACTER;
4013  goto parseError;
4014  }
4015  break;
4016  case Name:
4017  if ( !parseOk ) {
4018  d->error = XMLERR_ERRORPARSINGNAME;
4019  goto parseError;
4020  }
4021  d->attDeclEName = name();
4022  break;
4023  case Attdef:
4024  if ( !parseOk ) {
4025  d->error = XMLERR_ERRORPARSINGNAME;
4026  goto parseError;
4027  }
4028  d->attDeclAName = name();
4029  break;
4030  case Atttype:
4031  if ( !parseOk ) {
4032  d->error = XMLERR_ERRORPARSINGATTTYPE;
4033  goto parseError;
4034  }
4035  break;
4036  case DefReq:
4037  if( !parseOk ) {
4038  d->error = XMLERR_UNEXPECTEDCHARACTER;
4039  goto parseError;
4040  }
4041  break;
4042  case DefImp:
4043  if( !parseOk ) {
4044  d->error = XMLERR_UNEXPECTEDCHARACTER;
4045  goto parseError;
4046  }
4047  break;
4048  case DefFix:
4049  if( !parseOk ) {
4050  d->error = XMLERR_UNEXPECTEDCHARACTER;
4051  goto parseError;
4052  }
4053  break;
4054  case Attval:
4055  if ( !parseOk ) {
4056  d->error = XMLERR_ERRORPARSINGATTVALUE;
4057  goto parseError;
4058  }
4059  break;
4060  case Done:
4061  return TRUE;
4062  case -1:
4063  // Error
4064  d->error = XMLERR_LETTEREXPECTED;
4065  goto parseError;
4066  }
4067 
4068  }
4069 
4070  return TRUE;
4071 
4072 parseError:
4073  reportParseError();
4074  return FALSE;
4075 }
4076 
4077 /*!
4078  Parse a AttType [54]
4079 */
4081 {
4082  const signed char Init = 0;
4083  const signed char ST = 1; // StringType
4084  const signed char TTI = 2; // TokenizedType starting with 'I'
4085  const signed char TTI2 = 3; // TokenizedType helpstate
4086  const signed char TTI3 = 4; // TokenizedType helpstate
4087  const signed char TTE = 5; // TokenizedType starting with 'E'
4088  const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
4089  const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
4090  const signed char N = 8; // N read (TokenizedType or Notation)
4091  const signed char TTNM = 9; // TokenizedType starting with 'NM'
4092  const signed char TTNM2 = 10; // TokenizedType helpstate
4093  const signed char NO = 11; // Notation
4094  const signed char NO2 = 12; // Notation helpstate
4095  const signed char NO3 = 13; // Notation helpstate
4096  const signed char NOName = 14; // Notation, read name
4097  const signed char NO4 = 15; // Notation helpstate
4098  const signed char EN = 16; // Enumeration
4099  const signed char ENNmt = 17; // Enumeration, read Nmtoken
4100  const signed char EN2 = 18; // Enumeration helpstate
4101  const signed char ADone = 19; // almost done (make next and accept)
4102  const signed char Done = 20;
4103 
4104  const signed char InpWs = 0; // whitespace
4105  const signed char InpOp = 1; // (
4106  const signed char InpCp = 2; // )
4107  const signed char InpPipe = 3; // |
4108  const signed char InpC = 4; // C
4109  const signed char InpE = 5; // E
4110  const signed char InpI = 6; // I
4111  const signed char InpM = 7; // M
4112  const signed char InpN = 8; // N
4113  const signed char InpO = 9; // O
4114  const signed char InpR = 10; // R
4115  const signed char InpS = 11; // S
4116  const signed char InpY = 12; // Y
4117  const signed char InpUnknown = 13;
4118 
4119  // use some kind of state machine for parsing
4120  static signed char table[19][14] = {
4121  /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
4122  { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
4123  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
4124  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
4125  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
4126  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
4127  { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
4128  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
4129  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
4130  { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
4131  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
4132  { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
4133  { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
4134  { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
4135  { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
4136  { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
4137  { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
4138  { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
4139  { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
4140  { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
4141  };
4142  signed char state = Init;
4143  signed char input;
4144  bool parseOk = TRUE;
4145 
4146  while ( TRUE ) {
4147 
4148  // get input
4149  if ( atEnd() ) {
4150  d->error = XMLERR_UNEXPECTEDEOF;
4151  goto parseError;
4152  }
4153  if ( is_S(c) ) {
4154  input = InpWs;
4155  } else if ( c == '(' ) {
4156  input = InpOp;
4157  } else if ( c == ')' ) {
4158  input = InpCp;
4159  } else if ( c == '|' ) {
4160  input = InpPipe;
4161  } else if ( c == 'C' ) {
4162  input = InpC;
4163  } else if ( c == 'E' ) {
4164  input = InpE;
4165  } else if ( c == 'I' ) {
4166  input = InpI;
4167  } else if ( c == 'M' ) {
4168  input = InpM;
4169  } else if ( c == 'N' ) {
4170  input = InpN;
4171  } else if ( c == 'O' ) {
4172  input = InpO;
4173  } else if ( c == 'R' ) {
4174  input = InpR;
4175  } else if ( c == 'S' ) {
4176  input = InpS;
4177  } else if ( c == 'Y' ) {
4178  input = InpY;
4179  } else {
4180  input = InpUnknown;
4181  }
4182 
4183  // set state according to input
4184  state = table[state][input];
4185 
4186  // do some actions according to state
4187  switch ( state ) {
4188  case ST:
4189  parseOk = parseString( "CDATA" );
4190  break;
4191  case TTI:
4192  parseOk = parseString( "ID" );
4193  break;
4194  case TTI2:
4195  parseOk = parseString( "REF" );
4196  break;
4197  case TTI3:
4198  next(); // S
4199  break;
4200  case TTE:
4201  parseOk = parseString( "ENTIT" );
4202  break;
4203  case TTEY:
4204  next(); // Y
4205  break;
4206  case TTEI:
4207  parseOk = parseString( "IES" );
4208  break;
4209  case N:
4210  next(); // N
4211  break;
4212  case TTNM:
4213  parseOk = parseString( "MTOKEN" );
4214  break;
4215  case TTNM2:
4216  next(); // S
4217  break;
4218  case NO:
4219  parseOk = parseString( "OTATION" );
4220  break;
4221  case NO2:
4222  eat_ws();
4223  break;
4224  case NO3:
4225  next_eat_ws();
4226  break;
4227  case NOName:
4228  parseOk = parseName();
4229  break;
4230  case NO4:
4231  eat_ws();
4232  break;
4233  case EN:
4234  next_eat_ws();
4235  break;
4236  case ENNmt:
4237  parseOk = parseNmtoken();
4238  break;
4239  case EN2:
4240  eat_ws();
4241  break;
4242  case ADone:
4243  next();
4244  break;
4245  }
4246  // no input is read after this
4247  switch ( state ) {
4248  case ST:
4249  if( !parseOk ) {
4250  d->error = XMLERR_UNEXPECTEDCHARACTER;
4251  goto parseError;
4252  }
4253  break;
4254  case TTI:
4255  if( !parseOk ) {
4256  d->error = XMLERR_UNEXPECTEDCHARACTER;
4257  goto parseError;
4258  }
4259  break;
4260  case TTI2:
4261  if( !parseOk ) {
4262  d->error = XMLERR_UNEXPECTEDCHARACTER;
4263  goto parseError;
4264  }
4265  break;
4266  case TTE:
4267  if( !parseOk ) {
4268  d->error = XMLERR_UNEXPECTEDCHARACTER;
4269  goto parseError;
4270  }
4271  break;
4272  case TTEI:
4273  if( !parseOk ) {
4274  d->error = XMLERR_UNEXPECTEDCHARACTER;
4275  goto parseError;
4276  }
4277  break;
4278  case TTNM:
4279  if( !parseOk ) {
4280  d->error = XMLERR_UNEXPECTEDCHARACTER;
4281  goto parseError;
4282  }
4283  break;
4284  case NO:
4285  if( !parseOk ) {
4286  d->error = XMLERR_UNEXPECTEDCHARACTER;
4287  goto parseError;
4288  }
4289  break;
4290  case NOName:
4291  if ( !parseOk ) {
4292  d->error = XMLERR_ERRORPARSINGNAME;
4293  goto parseError;
4294  }
4295  break;
4296  case ENNmt:
4297  if ( !parseOk ) {
4298  d->error = XMLERR_ERRORPARSINGNMTOKEN;
4299  goto parseError;
4300  }
4301  break;
4302  case ADone:
4303  return TRUE;
4304  case Done:
4305  return TRUE;
4306  case -1:
4307  // Error
4308  d->error = XMLERR_LETTEREXPECTED;
4309  goto parseError;
4310  }
4311 
4312  }
4313 
4314  return TRUE;
4315 
4316 parseError:
4317  reportParseError();
4318  return FALSE;
4319 }
4320 
4321 /*!
4322  Parse a AttValue [10]
4323 
4324  Precondition: the head stands on the beginning " or '
4325 
4326  If this function was successful, the head stands on the first
4327  character after the closing " or ' and the value of the attribute
4328  is in string().
4329 */
4331 {
4332  bool tmp;
4333 
4334  const signed char Init = 0;
4335  const signed char Dq = 1; // double quotes were read
4336  const signed char DqRef = 2; // read references in double quotes
4337  const signed char DqC = 3; // signed character read in double quotes
4338  const signed char Sq = 4; // single quotes were read
4339  const signed char SqRef = 5; // read references in single quotes
4340  const signed char SqC = 6; // signed character read in single quotes
4341  const signed char Done = 7;
4342 
4343  const signed char InpDq = 0; // "
4344  const signed char InpSq = 1; // '
4345  const signed char InpAmp = 2; // &
4346  const signed char InpLt = 3; // <
4347  const signed char InpUnknown = 4;
4348 
4349  // use some kind of state machine for parsing
4350  static signed char table[7][5] = {
4351  /* InpDq InpSq InpAmp InpLt InpUnknown */
4352  { Dq, Sq, -1, -1, -1 }, // Init
4353  { Done, DqC, DqRef, -1, DqC }, // Dq
4354  { Done, DqC, DqRef, -1, DqC }, // DqRef
4355  { Done, DqC, DqRef, -1, DqC }, // DqC
4356  { SqC, Done, SqRef, -1, SqC }, // Sq
4357  { SqC, Done, SqRef, -1, SqC }, // SqRef
4358  { SqC, Done, SqRef, -1, SqC } // SqRef
4359  };
4360  signed char state = Init;
4361  signed char input;
4362  bool parseOk = TRUE;
4363 
4364  while ( TRUE ) {
4365 
4366  // get input
4367  if ( atEnd() ) {
4368  d->error = XMLERR_UNEXPECTEDEOF;
4369  goto parseError;
4370  }
4371  if ( c == '"' ) {
4372  input = InpDq;
4373  } else if ( c == '\'' ) {
4374  input = InpSq;
4375  } else if ( c == '&' ) {
4376  input = InpAmp;
4377  } else if ( c == '<' ) {
4378  input = InpLt;
4379  } else {
4380  input = InpUnknown;
4381  }
4382 
4383  // set state according to input
4384  state = table[state][input];
4385 
4386  // do some actions according to state
4387  switch ( state ) {
4388  case Dq:
4389  case Sq:
4390  stringClear();
4391  next();
4392  break;
4393  case DqRef:
4394  case SqRef:
4395  parseOk = parseReference( tmp, InAttributeValue );
4396  break;
4397  case DqC:
4398  case SqC:
4399  stringAddC();
4400  next();
4401  break;
4402  case Done:
4403  next();
4404  break;
4405  }
4406  // no input is read after this
4407  switch ( state ) {
4408  case DqRef:
4409  case SqRef:
4410  if ( !parseOk ) {
4412  goto parseError;
4413  }
4414  break;
4415  case Done:
4416  return TRUE;
4417  case -1:
4418  // Error
4419  d->error = XMLERR_UNEXPECTEDCHARACTER;
4420  goto parseError;
4421  }
4422 
4423  }
4424 
4425  return TRUE;
4426 
4427 parseError:
4428  reportParseError();
4429  return FALSE;
4430 }
4431 
4432 /*!
4433  Parse a elementdecl [45].
4434 
4435  Precondition: the beginning '<!E' is already read and the head
4436  stands on the 'L' of '<!ELEMENT'
4437 */
4439 {
4440  const signed char Init = 0;
4441  const signed char Elem = 1; // parse the beginning string
4442  const signed char Ws1 = 2; // whitespace required
4443  const signed char Nam = 3; // parse Name
4444  const signed char Ws2 = 4; // whitespace required
4445  const signed char Empty = 5; // read EMPTY
4446  const signed char Any = 6; // read ANY
4447  const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
4448  const signed char Mix = 8; // read Mixed
4449  const signed char Mix2 = 9; //
4450  const signed char Mix3 = 10; //
4451  const signed char MixN1 = 11; //
4452  const signed char MixN2 = 12; //
4453  const signed char MixN3 = 13; //
4454  const signed char MixN4 = 14; //
4455  const signed char Cp = 15; // parse cp
4456  const signed char Cp2 = 16; //
4457  const signed char WsD = 17; // eat whitespace before Done
4458  const signed char Done = 18;
4459 
4460  const signed char InpWs = 0;
4461  const signed char InpGt = 1; // >
4462  const signed char InpPipe = 2; // |
4463  const signed char InpOp = 3; // (
4464  const signed char InpCp = 4; // )
4465  const signed char InpHash = 5; // #
4466  const signed char InpQm = 6; // ?
4467  const signed char InpAst = 7; // *
4468  const signed char InpPlus = 8; // +
4469  const signed char InpA = 9; // A
4470  const signed char InpE = 10; // E
4471  const signed char InpL = 11; // L
4472  const signed char InpUnknown = 12;
4473 
4474  // use some kind of state machine for parsing
4475  static signed char table[18][13] = {
4476  /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
4477  { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
4478  { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
4479  { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
4480  { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
4481  { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
4482  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
4483  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
4484  { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
4485  { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
4486  { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
4487  { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
4488  { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
4489  { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
4490  { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
4491  { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
4492  { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
4493  { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
4494  { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
4495  };
4496  signed char state = Init;
4497  signed char input;
4498  bool parseOk = TRUE;
4499 
4500  while ( TRUE ) {
4501 
4502  // read input
4503  if ( atEnd() ) {
4504  d->error = XMLERR_UNEXPECTEDEOF;
4505  goto parseError;
4506  }
4507  if ( is_S(c) ) {
4508  input = InpWs;
4509  } else if ( c == '>' ) {
4510  input = InpGt;
4511  } else if ( c == '|' ) {
4512  input = InpPipe;
4513  } else if ( c == '(' ) {
4514  input = InpOp;
4515  } else if ( c == ')' ) {
4516  input = InpCp;
4517  } else if ( c == '#' ) {
4518  input = InpHash;
4519  } else if ( c == '?' ) {
4520  input = InpQm;
4521  } else if ( c == '*' ) {
4522  input = InpAst;
4523  } else if ( c == '+' ) {
4524  input = InpPlus;
4525  } else if ( c == 'A' ) {
4526  input = InpA;
4527  } else if ( c == 'E' ) {
4528  input = InpE;
4529  } else if ( c == 'L' ) {
4530  input = InpL;
4531  } else {
4532  input = InpUnknown;
4533  }
4534  // get new state
4535 //qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
4536  state = table[state][input];
4537 
4538  // in some cases do special actions depending on state
4539  switch ( state ) {
4540  case Elem:
4541  parseOk = parseString( "LEMENT" );
4542  break;
4543  case Ws1:
4544  eat_ws();
4545  break;
4546  case Nam:
4547  parseOk = parseName();
4548  break;
4549  case Ws2:
4550  eat_ws();
4551  break;
4552  case Empty:
4553  parseOk = parseString( "EMPTY" );
4554  break;
4555  case Any:
4556  parseOk = parseString( "ANY" );
4557  break;
4558  case Cont:
4559  next_eat_ws();
4560  break;
4561  case Mix:
4562  parseOk = parseString( "#PCDATA" );
4563  break;
4564  case Mix2:
4565  eat_ws();
4566  break;
4567  case Mix3:
4568  next();
4569  break;
4570  case MixN1:
4571  next_eat_ws();
4572  break;
4573  case MixN2:
4574  parseOk = parseName();
4575  break;
4576  case MixN3:
4577  eat_ws();
4578  break;
4579  case MixN4:
4580  next();
4581  break;
4582  case Cp:
4583  parseOk = parseChoiceSeq();
4584  break;
4585  case Cp2:
4586  next();
4587  break;
4588  case WsD:
4589  next_eat_ws();
4590  break;
4591  case Done:
4592  next();
4593  break;
4594  }
4595  // no input is read after this
4596  switch ( state ) {
4597  case Elem:
4598  if( !parseOk ) {
4599  d->error = XMLERR_UNEXPECTEDCHARACTER;
4600  goto parseError;
4601  }
4602  break;
4603  case Nam:
4604  if ( !parseOk ) {
4605  d->error = XMLERR_ERRORPARSINGNAME;
4606  goto parseError;
4607  }
4608  break;
4609  case Empty:
4610  if( !parseOk ) {
4611  d->error = XMLERR_UNEXPECTEDCHARACTER;
4612  goto parseError;
4613  }
4614  break;
4615  case Any:
4616  if( !parseOk ) {
4617  d->error = XMLERR_UNEXPECTEDCHARACTER;
4618  goto parseError;
4619  }
4620  break;
4621  case Mix:
4622  if( !parseOk ) {
4623  d->error = XMLERR_UNEXPECTEDCHARACTER;
4624  goto parseError;
4625  }
4626  break;
4627  case MixN2:
4628  if ( !parseOk ) {
4629  d->error = XMLERR_ERRORPARSINGNAME;
4630  goto parseError;
4631  }
4632  break;
4633  case Cp:
4634  if ( !parseOk ) {
4635  d->error = XMLERR_ERRORPARSINGCHOICE;
4636  goto parseError;
4637  }
4638  break;
4639  case Done:
4640  return TRUE;
4641  case -1:
4642  d->error = XMLERR_UNEXPECTEDCHARACTER;
4643  goto parseError;
4644  }
4645 
4646  }
4647 
4648  return TRUE;
4649 
4650 parseError:
4651  reportParseError();
4652  return FALSE;
4653 }
4654 
4655 /*!
4656  Parse a NotationDecl [82].
4657 
4658  Precondition: the beginning '<!' is already read and the head
4659  stands on the 'N' of '<!NOTATION'
4660 */
4662 {
4663  const signed char Init = 0;
4664  const signed char Not = 1; // read NOTATION
4665  const signed char Ws1 = 2; // eat whitespaces
4666  const signed char Nam = 3; // read Name
4667  const signed char Ws2 = 4; // eat whitespaces
4668  const signed char ExtID = 5; // parse ExternalID
4669  const signed char Ws3 = 6; // eat whitespaces
4670  const signed char Done = 7;
4671 
4672  const signed char InpWs = 0;
4673  const signed char InpGt = 1; // >
4674  const signed char InpN = 2; // N
4675  const signed char InpUnknown = 3;
4676 
4677  // use some kind of state machine for parsing
4678  static signed char table[7][4] = {
4679  /* InpWs InpGt InpN InpUnknown */
4680  { -1, -1, Not, -1 }, // Init
4681  { Ws1, -1, -1, -1 }, // Not
4682  { -1, -1, Nam, Nam }, // Ws1
4683  { Ws2, Done, -1, -1 }, // Nam
4684  { -1, Done, ExtID, ExtID }, // Ws2
4685  { Ws3, Done, -1, -1 }, // ExtID
4686  { -1, Done, -1, -1 } // Ws3
4687  };
4688  signed char state = Init;
4689  signed char input;
4690  bool parseOk = TRUE;
4691 
4692  while ( TRUE ) {
4693 
4694  // get input
4695  if ( atEnd() ) {
4696  d->error = XMLERR_UNEXPECTEDEOF;
4697  goto parseError;
4698  }
4699  if ( is_S(c) ) {
4700  input = InpWs;
4701  } else if ( c == '>' ) {
4702  input = InpGt;
4703  } else if ( c == 'N' ) {
4704  input = InpN;
4705  } else {
4706  input = InpUnknown;
4707  }
4708 
4709  // set state according to input
4710  state = table[state][input];
4711 
4712  // do some actions according to state
4713  switch ( state ) {
4714  case Not:
4715  parseOk = parseString( "NOTATION" );
4716  break;
4717  case Ws1:
4718  eat_ws();
4719  break;
4720  case Nam:
4721  parseOk = parseName();
4722  break;
4723  case Ws2:
4724  eat_ws();
4725  break;
4726  case ExtID:
4727  parseOk = parseExternalID( TRUE );
4728  break;
4729  case Ws3:
4730  eat_ws();
4731  break;
4732  case Done:
4733  next();
4734  break;
4735  }
4736  // no input is read after this
4737  switch ( state ) {
4738  case Not:
4739  if ( !parseOk ) {
4740  d->error = XMLERR_UNEXPECTEDCHARACTER;
4741  goto parseError;
4742  }
4743  break;
4744  case Nam:
4745  if ( !parseOk ) {
4746  d->error = XMLERR_ERRORPARSINGNAME;
4747  goto parseError;
4748  }
4749  break;
4750  case ExtID:
4751  if ( !parseOk ) {
4753  goto parseError;
4754  }
4755  // call the handler
4756  if ( dtdHnd ) {
4757  if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
4758  d->error = dtdHnd->errorString();
4759  goto parseError;
4760  }
4761  }
4762  break;
4763  case Done:
4764  return TRUE;
4765  case -1:
4766  // Error
4767  d->error = XMLERR_UNEXPECTEDCHARACTER;
4768  goto parseError;
4769  }
4770 
4771  }
4772 
4773  return TRUE;
4774 
4775 parseError:
4776  reportParseError();
4777  return FALSE;
4778 }
4779 
4780 /*!
4781  Parse choice [49] or seq [50].
4782 
4783  Precondition: the beginning '('S? is already read and the head
4784  stands on the first non-whitespace character after it.
4785 */
4787 {
4788  const signed char Init = 0;
4789  const signed char Ws1 = 1; // eat whitespace
4790  const signed char CS_ = 2; // choice or set
4791  const signed char Ws2 = 3; // eat whitespace
4792  const signed char More = 4; // more cp to read
4793  const signed char Name = 5; // read name
4794  const signed char Done = 6; //
4795 
4796  const signed char InpWs = 0; // S
4797  const signed char InpOp = 1; // (
4798  const signed char InpCp = 2; // )
4799  const signed char InpQm = 3; // ?
4800  const signed char InpAst = 4; // *
4801  const signed char InpPlus = 5; // +
4802  const signed char InpPipe = 6; // |
4803  const signed char InpComm = 7; // ,
4804  const signed char InpUnknown = 8;
4805 
4806  // use some kind of state machine for parsing
4807  static signed char table[6][9] = {
4808  /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
4809  { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
4810  { -1, CS_, -1, -1, -1, -1, -1, -1, CS_ }, // Ws1
4811  { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS_
4812  { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
4813  { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
4814  { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS_)
4815  };
4816  signed char state = Init;
4817  signed char input;
4818  bool parseOk = TRUE;
4819 
4820  while ( TRUE ) {
4821 
4822  // get input
4823  if ( atEnd() ) {
4824  d->error = XMLERR_UNEXPECTEDEOF;
4825  goto parseError;
4826  }
4827  if ( is_S(c) ) {
4828  input = InpWs;
4829  } else if ( c == '(' ) {
4830  input = InpOp;
4831  } else if ( c == ')' ) {
4832  input = InpCp;
4833  } else if ( c == '?' ) {
4834  input = InpQm;
4835  } else if ( c == '*' ) {
4836  input = InpAst;
4837  } else if ( c == '+' ) {
4838  input = InpPlus;
4839  } else if ( c == '|' ) {
4840  input = InpPipe;
4841  } else if ( c == ',' ) {
4842  input = InpComm;
4843  } else {
4844  input = InpUnknown;
4845  }
4846 
4847  // set state according to input
4848  state = table[state][input];
4849 
4850  // do some actions according to state
4851  switch ( state ) {
4852  case Ws1:
4853  next_eat_ws();
4854  break;
4855  case CS_:
4856  parseOk = parseChoiceSeq();
4857  break;
4858  case Ws2:
4859  next_eat_ws();
4860  break;
4861  case More:
4862  next_eat_ws();
4863  break;
4864  case Name:
4865  parseOk = parseName();
4866  break;
4867  case Done:
4868  next();
4869  break;
4870  }
4871  // no input is read after this
4872  switch ( state ) {
4873  case CS_:
4874  if ( !parseOk ) {
4875  d->error = XMLERR_ERRORPARSINGCHOICE;
4876  goto parseError;
4877  }
4878  break;
4879  case Name:
4880  if ( !parseOk ) {
4881  d->error = XMLERR_ERRORPARSINGNAME;
4882  goto parseError;
4883  }
4884  break;
4885  case Done:
4886  return TRUE;
4887  case -1:
4888  // Error
4889  d->error = XMLERR_UNEXPECTEDCHARACTER;
4890  goto parseError;
4891  }
4892 
4893  }
4894 
4895  return TRUE;
4896 
4897 parseError:
4898  reportParseError();
4899  return FALSE;
4900 }
4901 
4902 /*!
4903  Parse a EntityDecl [70].
4904 
4905  Precondition: the beginning '<!E' is already read and the head
4906  stand on the 'N' of '<!ENTITY'
4907 */
4909 {
4910  const signed char Init = 0;
4911  const signed char Ent = 1; // parse "ENTITY"
4912  const signed char Ws1 = 2; // white space read
4913  const signed char Name = 3; // parse name
4914  const signed char Ws2 = 4; // white space read
4915  const signed char EValue = 5; // parse entity value
4916  const signed char ExtID = 6; // parse ExternalID
4917  const signed char Ws3 = 7; // white space read
4918  const signed char Ndata = 8; // parse "NDATA"
4919  const signed char Ws4 = 9; // white space read
4920  const signed char NNam = 10; // parse name
4921  const signed char PEDec = 11; // parse PEDecl
4922  const signed char Ws6 = 12; // white space read
4923  const signed char PENam = 13; // parse name
4924  const signed char Ws7 = 14; // white space read
4925  const signed char PEVal = 15; // parse entity value
4926  const signed char PEEID = 16; // parse ExternalID
4927  const signed char WsE = 17; // white space read
4928  const signed char EDDone = 19; // done, but also report an external, unparsed entity decl
4929  const signed char Done = 18;
4930 
4931  const signed char InpWs = 0; // white space
4932  const signed char InpPer = 1; // %
4933  const signed char InpQuot = 2; // " or '
4934  const signed char InpGt = 3; // >
4935  const signed char InpN = 4; // N
4936  const signed char InpUnknown = 5;
4937 
4938  // use some kind of state machine for parsing
4939  static signed char table[18][6] = {
4940  /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
4941  { -1, -1, -1, -1, Ent, -1 }, // Init
4942  { Ws1, -1, -1, -1, -1, -1 }, // Ent
4943  { -1, PEDec, -1, -1, Name, Name }, // Ws1
4944  { Ws2, -1, -1, -1, -1, -1 }, // Name
4945  { -1, -1, EValue, -1, -1, ExtID }, // Ws2
4946  { WsE, -1, -1, Done, -1, -1 }, // EValue
4947  { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
4948  { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
4949  { Ws4, -1, -1, -1, -1, -1 }, // Ndata
4950  { -1, -1, -1, -1, NNam, NNam }, // Ws4
4951  { WsE, -1, -1, Done, -1, -1 }, // NNam
4952  { Ws6, -1, -1, -1, -1, -1 }, // PEDec
4953  { -1, -1, -1, -1, PENam, PENam }, // Ws6
4954  { Ws7, -1, -1, -1, -1, -1 }, // PENam
4955  { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
4956  { WsE, -1, -1, Done, -1, -1 }, // PEVal
4957  { WsE, -1, -1, Done, -1, -1 }, // PEEID
4958  { -1, -1, -1, Done, -1, -1 } // WsE
4959  };
4960  signed char state = Init;
4961  signed char input;
4962  bool parseOk = TRUE;
4963 
4964  while ( TRUE ) {
4965 
4966  // get input
4967  if ( atEnd() ) {
4968  d->error = XMLERR_UNEXPECTEDEOF;
4969  goto parseError;
4970  }
4971  if ( is_S(c) ) {
4972  input = InpWs;
4973  } else if ( c == '%' ) {
4974  input = InpPer;
4975  } else if ( c == '"' || c == '\'' ) {
4976  input = InpQuot;
4977  } else if ( c == '>' ) {
4978  input = InpGt;
4979  } else if ( c == 'N' ) {
4980  input = InpN;
4981  } else {
4982  input = InpUnknown;
4983  }
4984 
4985  // set state according to input
4986  state = table[state][input];
4987 
4988  // do some actions according to state
4989  switch ( state ) {
4990  case Ent:
4991  parseOk = parseString( "NTITY" );
4992  break;
4993  case Ws1:
4994  eat_ws();
4995  break;
4996  case Name:
4997  parseOk = parseName();
4998  break;
4999  case Ws2:
5000  eat_ws();
5001  break;
5002  case EValue:
5003  parseOk = parseEntityValue();
5004  break;
5005  case ExtID:
5006  parseOk = parseExternalID();
5007  break;
5008  case Ws3:
5009  eat_ws();
5010  break;
5011  case Ndata:
5012  parseOk = parseString( "NDATA" );
5013  break;
5014  case Ws4:
5015  eat_ws();
5016  break;
5017  case NNam:
5018  parseOk = parseName( TRUE );
5019  break;
5020  case PEDec:
5021  next();
5022  break;
5023  case Ws6:
5024  eat_ws();
5025  break;
5026  case PENam:
5027  parseOk = parseName();
5028  break;
5029  case Ws7:
5030  eat_ws();
5031  break;
5032  case PEVal:
5033  parseOk = parseEntityValue();
5034  break;
5035  case PEEID:
5036  parseOk = parseExternalID();
5037  break;
5038  case WsE:
5039  eat_ws();
5040  break;
5041  case EDDone:
5042  next();
5043  break;
5044  case Done:
5045  next();
5046  break;
5047  }
5048  // no input is read after this
5049  switch ( state ) {
5050  case Ent:
5051  if ( !parseOk ) {
5052  d->error = XMLERR_UNEXPECTEDCHARACTER;
5053  goto parseError;
5054  }
5055  break;
5056  case Name:
5057  if ( !parseOk ) {
5058  d->error = XMLERR_ERRORPARSINGNAME;
5059  goto parseError;
5060  }
5061  break;
5062  case EValue:
5063  if ( !parseOk ) {
5065  goto parseError;
5066  }
5067  if ( !entityExist( name() ) ) {
5068  d->entities.insert( name(), string() );
5069  if ( declHnd ) {
5070  if ( !declHnd->internalEntityDecl( name(), string() ) ) {
5071  d->error = declHnd->errorString();
5072  goto parseError;
5073  }
5074  }
5075  }
5076  break;
5077  case ExtID:
5078  if ( !parseOk ) {
5080  goto parseError;
5081  }
5082  break;
5083  case Ndata:
5084  if ( !parseOk ) {
5085  d->error = XMLERR_UNEXPECTEDCHARACTER;
5086  goto parseError;
5087  }
5088  break;
5089  case NNam:
5090  if ( !parseOk ) {
5091  d->error = XMLERR_ERRORPARSINGNAME;
5092  goto parseError;
5093  }
5094  if ( !entityExist( name() ) ) {
5095  d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
5096  if ( dtdHnd ) {
5097  if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
5098  d->error = declHnd->errorString();
5099  goto parseError;
5100  }
5101  }
5102  }
5103  break;
5104  case PENam:
5105  if ( !parseOk ) {
5106  d->error = XMLERR_ERRORPARSINGNAME;
5107  goto parseError;
5108  }
5109  break;
5110  case PEVal:
5111  if ( !parseOk ) {
5113  goto parseError;
5114  }
5115  if ( !entityExist( name() ) ) {
5116  d->parameterEntities.insert( name(), string() );
5117  if ( declHnd ) {
5118  if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
5119  d->error = declHnd->errorString();
5120  goto parseError;
5121  }
5122  }
5123  }
5124  break;
5125  case PEEID:
5126  if ( !parseOk ) {
5128  goto parseError;
5129  }
5130  if ( !entityExist( name() ) ) {
5131  d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
5132  if ( declHnd ) {
5133  if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
5134  d->error = declHnd->errorString();
5135  goto parseError;
5136  }
5137  }
5138  }
5139  break;
5140  case EDDone:
5141  if ( !entityExist( name() ) ) {
5142  d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) );
5143  if ( declHnd ) {
5144  if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
5145  d->error = declHnd->errorString();
5146  goto parseError;
5147  }
5148  }
5149  }
5150  return TRUE;
5151  case Done:
5152  return TRUE;
5153  case -1:
5154  // Error
5155  d->error = XMLERR_LETTEREXPECTED;
5156  goto parseError;
5157  }
5158 
5159  }
5160 
5161  return TRUE;
5162 
5163 parseError:
5164  reportParseError();
5165  return FALSE;
5166 }
5167 
5168 /*!
5169  Parse a EntityValue [9]
5170 */
5172 {
5173  bool tmp;
5174 
5175  const signed char Init = 0;
5176  const signed char Dq = 1; // EntityValue is double quoted
5177  const signed char DqC = 2; // signed character
5178  const signed char DqPER = 3; // PERefence
5179  const signed char DqRef = 4; // Reference
5180  const signed char Sq = 5; // EntityValue is double quoted
5181  const signed char SqC = 6; // signed character
5182  const signed char SqPER = 7; // PERefence
5183  const signed char SqRef = 8; // Reference
5184  const signed char Done = 9;
5185 
5186  const signed char InpDq = 0; // "
5187  const signed char InpSq = 1; // '
5188  const signed char InpAmp = 2; // &
5189  const signed char InpPer = 3; // %
5190  const signed char InpUnknown = 4;
5191 
5192  // use some kind of state machine for parsing
5193  static signed char table[9][5] = {
5194  /* InpDq InpSq InpAmp InpPer InpUnknown */
5195  { Dq, Sq, -1, -1, -1 }, // Init
5196  { Done, DqC, DqRef, DqPER, DqC }, // Dq
5197  { Done, DqC, DqRef, DqPER, DqC }, // DqC
5198  { Done, DqC, DqRef, DqPER, DqC }, // DqPER
5199  { Done, DqC, DqRef, DqPER, DqC }, // DqRef
5200  { SqC, Done, SqRef, SqPER, SqC }, // Sq
5201  { SqC, Done, SqRef, SqPER, SqC }, // SqC
5202  { SqC, Done, SqRef, SqPER, SqC }, // SqPER
5203  { SqC, Done, SqRef, SqPER, SqC } // SqRef
5204  };
5205  signed char state = Init;
5206  signed char input;
5207  bool parseOk = TRUE;
5208 
5209  while ( TRUE ) {
5210 
5211  // get input
5212  if ( atEnd() ) {
5213  d->error = XMLERR_UNEXPECTEDEOF;
5214  goto parseError;
5215  }
5216  if ( c == '"' ) {
5217  input = InpDq;
5218  } else if ( c == '\'' ) {
5219  input = InpSq;
5220  } else if ( c == '&' ) {
5221  input = InpAmp;
5222  } else if ( c == '%' ) {
5223  input = InpPer;
5224  } else {
5225  input = InpUnknown;
5226  }
5227 
5228  // set state according to input
5229  state = table[state][input];
5230 
5231  // do some actions according to state
5232  switch ( state ) {
5233  case Dq:
5234  case Sq:
5235  stringClear();
5236  next();
5237  break;
5238  case DqC:
5239  case SqC:
5240  stringAddC();
5241  next();
5242  break;
5243  case DqPER:
5244  case SqPER:
5245  parseOk = parsePEReference( InEntityValue );
5246  break;
5247  case DqRef:
5248  case SqRef:
5249  parseOk = parseReference( tmp, InEntityValue );
5250  break;
5251  case Done:
5252  next();
5253  break;
5254  }
5255  // no input is read after this
5256  switch ( state ) {
5257  case DqPER:
5258  case SqPER:
5259  if ( !parseOk ) {
5260  d->error = XMLERR_ERRORPARSINGDOCTYPE;
5261  goto parseError;
5262  }
5263  break;
5264  case DqRef:
5265  case SqRef:
5266  if ( !parseOk ) {
5268  goto parseError;
5269  }
5270  break;
5271  case Done:
5272  return TRUE;
5273  case -1:
5274  // Error
5275  d->error = XMLERR_LETTEREXPECTED;
5276  goto parseError;
5277  }
5278 
5279  }
5280 
5281  return TRUE;
5282 
5283 parseError:
5284  reportParseError();
5285  return FALSE;
5286 }
5287 
5288 /*!
5289  Parse a comment [15].
5290 
5291  Precondition: the beginning '<!' of the comment is already read and the head
5292  stands on the first '-' of '<!--'.
5293 
5294  If this funktion was successful, the head-position is on the first
5295  character after the comment.
5296 */
5298 {
5299  const signed char Init = 0;
5300  const signed char Dash1 = 1; // the first dash was read
5301  const signed char Dash2 = 2; // the second dash was read
5302  const signed char Com = 3; // read comment
5303  const signed char Com2 = 4; // read comment (help state)
5304  const signed char ComE = 5; // finished reading comment
5305  const signed char Done = 6;
5306 
5307  const signed char InpDash = 0; // -
5308  const signed char InpGt = 1; // >
5309  const signed char InpUnknown = 2;
5310 
5311  // use some kind of state machine for parsing
5312  static signed char table[6][3] = {
5313  /* InpDash InpGt InpUnknown */
5314  { Dash1, -1, -1 }, // Init
5315  { Dash2, -1, -1 }, // Dash1
5316  { Com2, Com, Com }, // Dash2
5317  { Com2, Com, Com }, // Com
5318  { ComE, Com, Com }, // Com2
5319  { -1, Done, -1 } // ComE
5320  };
5321  signed char state = Init;
5322  signed char input;
5323 
5324  while ( TRUE ) {
5325 
5326  // get input
5327  if ( atEnd() ) {
5328  d->error = XMLERR_UNEXPECTEDEOF;
5329  goto parseError;
5330  }
5331  if ( c == '-' ) {
5332  input = InpDash;
5333  } else if ( c == '>' ) {
5334  input = InpGt;
5335  } else {
5336  input = InpUnknown;
5337  }
5338 
5339  // set state according to input
5340  state = table[state][input];
5341 
5342  // do some actions according to state
5343  switch ( state ) {
5344  case Dash1:
5345  next();
5346  break;
5347  case Dash2:
5348  next();
5349  break;
5350  case Com:
5351  stringAddC();
5352  next();
5353  break;
5354  case Com2:
5355  next();
5356  break;
5357  case ComE:
5358  next();
5359  break;
5360  case Done:
5361  next();
5362  break;
5363  }
5364  // no input is read after this
5365  switch ( state ) {
5366  case Dash2:
5367  stringClear();
5368  break;
5369  case Com2:
5370  // if next character is not a dash than don't skip it
5371  if ( c != '-' ) {
5372  stringAddC( '-' );
5373  }
5374  break;
5375  case Done:
5376  return TRUE;
5377  case -1:
5378  // Error
5379  d->error = XMLERR_ERRORPARSINGCOMMENT;
5380  goto parseError;
5381  }
5382 
5383  }
5384 
5385  return TRUE;
5386 
5387 parseError:
5388  reportParseError();
5389  return FALSE;
5390 }
5391 
5392 /*!
5393  Parse a Attribute [41].
5394 
5395  Precondition: the head stands on the first character of the name of the
5396  attribute (i.e. all whitespaces are already parsed).
5397 
5398  The head stand on the next character after the end quotes. The variable name
5399  contains the name of the attribute and the variable string contains the value
5400  of the attribute.
5401 */
5403 {
5404  const signed char Init = 0;
5405  const signed char PName = 1; // parse name
5406  const signed char Ws = 2; // eat ws
5407  const signed char Eq = 3; // the '=' was read
5408  const signed char Quotes = 4; // " or ' were read
5409 
5410  const signed char InpNameBe = 0;
5411  const signed char InpEq = 1; // =
5412  const signed char InpDq = 2; // "
5413  const signed char InpSq = 3; // '
5414  const signed char InpUnknown = 4;
5415 
5416  // use some kind of state machine for parsing
5417  static signed char table[4][5] = {
5418  /* InpNameBe InpEq InpDq InpSq InpUnknown */
5419  { PName, -1, -1, -1, -1 }, // Init
5420  { -1, Eq, -1, -1, Ws }, // PName
5421  { -1, Eq, -1, -1, -1 }, // Ws
5422  { -1, -1, Quotes, Quotes, -1 } // Eq
5423  };
5424  signed char state = Init;
5425  signed char input;
5426  bool parseOk = TRUE;
5427 
5428  while ( TRUE ) {
5429 
5430  // get input
5431  if ( atEnd() ) {
5432  d->error = XMLERR_UNEXPECTEDEOF;
5433  goto parseError;
5434  }
5435  if ( is_NameBeginning(c) ) {
5436  input = InpNameBe;
5437  } else if ( c == '=' ) {
5438  input = InpEq;
5439  } else if ( c == '"' ) {
5440  input = InpDq;
5441  } else if ( c == '\'' ) {
5442  input = InpSq;
5443  } else {
5444  input = InpUnknown;
5445  }
5446 
5447  // set state according to input
5448  state = table[state][input];
5449 
5450  // do some actions according to state
5451  switch ( state ) {
5452  case PName:
5453  parseOk = parseName();
5454  break;
5455  case Ws:
5456  eat_ws();
5457  break;
5458  case Eq:
5459  next_eat_ws();
5460  break;
5461  case Quotes:
5462  parseOk = parseAttValue();
5463  break;
5464  }
5465  // no input is read after this
5466  switch ( state ) {
5467  case PName:
5468  if ( !parseOk ) {
5469  d->error = XMLERR_ERRORPARSINGNAME;
5470  goto parseError;
5471  }
5472  break;
5473  case Quotes:
5474  if ( !parseOk ) {
5475  d->error = XMLERR_ERRORPARSINGATTVALUE;
5476  goto parseError;
5477  }
5478  // Done
5479  return TRUE;
5480  case -1:
5481  // Error
5482  d->error = XMLERR_UNEXPECTEDCHARACTER;
5483  goto parseError;
5484  }
5485 
5486  }
5487 
5488  return TRUE;
5489 
5490 parseError:
5491  reportParseError();
5492  return FALSE;
5493 }
5494 
5495 /*!
5496  Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
5497 */
5498 bool QXmlSimpleReader::parseName( bool useRef )
5499 {
5500  const signed char Init = 0;
5501  const signed char Name1 = 1; // parse first signed character of the name
5502  const signed char Name = 2; // parse name
5503  const signed char Done = 3;
5504 
5505  const signed char InpNameBe = 0; // name beginning signed characters
5506  const signed char InpNameCh = 1; // NameChar without InpNameBe
5507  const signed char InpUnknown = 2;
5508 
5509  // use some kind of state machine for parsing
5510  static signed char table[3][3] = {
5511  /* InpNameBe InpNameCh InpUnknown */
5512  { Name1, -1, -1 }, // Init
5513  { Name, Name, Done }, // Name1
5514  { Name, Name, Done } // Name
5515  };
5516  signed char state = Init;
5517  signed char input;
5518 
5519  while ( TRUE ) {
5520 
5521  // get input
5522  if ( atEnd() ) {
5523  d->error = XMLERR_UNEXPECTEDEOF;
5524  goto parseError;
5525  }
5526  if ( is_NameBeginning(c) ) {
5527  input = InpNameBe;
5528  } else if ( is_NameChar(c) ) {
5529  input = InpNameCh;
5530  } else {
5531  input = InpUnknown;
5532  }
5533 
5534  // set state according to input
5535  state = table[state][input];
5536 
5537  // do some actions according to state
5538  switch ( state ) {
5539  case Name1:
5540  if ( useRef ) {
5541  refClear();
5542  refAddC();
5543  } else {
5544  nameClear();
5545  nameAddC();
5546  }
5547  next();
5548  break;
5549  case Name:
5550  if ( useRef ) {
5551  refAddC();
5552  } else {
5553  nameAddC();
5554  }
5555  next();
5556  break;
5557  }
5558  // no input is read after this
5559  switch ( state ) {
5560  case Done:
5561  return TRUE;
5562  case -1:
5563  // Error
5564  d->error = XMLERR_LETTEREXPECTED;
5565  goto parseError;
5566  }
5567 
5568  }
5569 
5570  return TRUE;
5571 
5572 parseError:
5573  reportParseError();
5574  return FALSE;
5575 }
5576 
5577 /*!
5578  Parse a Nmtoken [7] and store the name in name.
5579 */
5581 {
5582  const signed char Init = 0;
5583  const signed char NameF = 1;
5584  const signed char Name = 2;
5585  const signed char Done = 3;
5586 
5587  const signed char InpNameCh = 0; // NameChar without InpNameBe
5588  const signed char InpUnknown = 1;
5589 
5590  // use some kind of state machine for parsing
5591  static signed char table[3][2] = {
5592  /* InpNameCh InpUnknown */
5593  { NameF, -1 }, // Init
5594  { Name, Done }, // NameF
5595  { Name, Done } // Name
5596  };
5597  signed char state = Init;
5598  signed char input;
5599 
5600  while ( TRUE ) {
5601 
5602  // get input
5603  if ( atEnd() ) {
5604  d->error = XMLERR_UNEXPECTEDEOF;
5605  goto parseError;
5606  }
5607  if ( is_NameChar(c) ) {
5608  input = InpNameCh;
5609  } else {
5610  input = InpUnknown;
5611  }
5612 
5613  // set state according to input
5614  state = table[state][input];
5615 
5616  // do some actions according to state
5617  switch ( state ) {
5618  case NameF:
5619  nameClear();
5620  nameAddC();
5621  next();
5622  break;
5623  case Name:
5624  nameAddC();
5625  next();
5626  break;
5627  }
5628  // no input is read after this
5629  switch ( state ) {
5630  case Done:
5631  return TRUE;
5632  case -1:
5633  // Error
5634  d->error = XMLERR_LETTEREXPECTED;
5635  goto parseError;
5636  }
5637 
5638  }
5639 
5640  return TRUE;
5641 
5642 parseError:
5643  reportParseError();
5644  return FALSE;
5645 }
5646 
5647 /*!
5648  Parse a Reference [67].
5649 
5650  charDataRead is set to TRUE if the reference must not be parsed. The
5651  character(s) which the reference mapped to are appended to string. The
5652  head stands on the first character after the reference.
5653 
5654  charDataRead is set to FALSE if the reference must be parsed. The
5655  charachter(s) which the reference mapped to are inserted at the reference
5656  position. The head stands on the first character of the replacement).
5657 */
5659 {
5660  // temporary variables
5661  uint tmp;
5662  bool ok;
5663 
5664  const signed char Init = 0;
5665  const signed char SRef = 1; // start of a reference
5666  const signed char ChRef = 2; // parse CharRef
5667  const signed char ChDec = 3; // parse CharRef decimal
5668  const signed char ChHexS = 4; // start CharRef hexadecimal
5669  const signed char ChHex = 5; // parse CharRef hexadecimal
5670  const signed char Name = 6; // parse name
5671  const signed char DoneD = 7; // done CharRef decimal
5672  const signed char DoneH = 8; // done CharRef hexadecimal
5673  const signed char DoneN = 9; // done EntityRef
5674 
5675  const signed char InpAmp = 0; // &
5676  const signed char InpSemi = 1; // ;
5677  const signed char InpHash = 2; // #
5678  const signed char InpX = 3; // x
5679  const signed char InpNum = 4; // 0-9
5680  const signed char InpHex = 5; // a-f A-F
5681  const signed char InpUnknown = 6;
5682 
5683  // use some kind of state machine for parsing
5684  static signed char table[8][7] = {
5685  /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
5686  { SRef, -1, -1, -1, -1, -1, -1 }, // Init
5687  { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
5688  { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
5689  { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
5690  { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
5691  { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
5692  { -1, DoneN, -1, -1, -1, -1, -1 } // Name
5693  };
5694  signed char state = Init;
5695  signed char input;
5696 
5697  while ( TRUE ) {
5698 
5699  // get input
5700  if ( atEnd() ) {
5701  d->error = XMLERR_UNEXPECTEDEOF;
5702  goto parseError;
5703  }
5704  if ( c.row() ) {
5705  input = InpUnknown;
5706  } else if ( c.cell() == '&' ) {
5707  input = InpAmp;
5708  } else if ( c.cell() == ';' ) {
5709  input = InpSemi;
5710  } else if ( c.cell() == '#' ) {
5711  input = InpHash;
5712  } else if ( c.cell() == 'x' ) {
5713  input = InpX;
5714  } else if ( '0' <= c.cell() && c.cell() <= '9' ) {
5715  input = InpNum;
5716  } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
5717  input = InpHex;
5718  } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
5719  input = InpHex;
5720  } else {
5721  input = InpUnknown;
5722  }
5723 
5724  // set state according to input
5725  state = table[state][input];
5726 
5727  // do some actions according to state
5728  switch ( state ) {
5729  case SRef:
5730  refClear();
5731  next();
5732  break;
5733  case ChRef:
5734  next();
5735  break;
5736  case ChDec:
5737  refAddC();
5738  next();
5739  break;
5740  case ChHexS:
5741  next();
5742  break;
5743  case ChHex:
5744  refAddC();
5745  next();
5746  break;
5747  case Name:
5748  // read the name into the ref
5749  parseName( TRUE );
5750  break;
5751  case DoneD:
5752  tmp = ref().toUInt( &ok, 10 );
5753  if ( ok ) {
5754  stringAddC( QChar(tmp) );
5755  } else {
5757  goto parseError;
5758  }
5759  charDataRead = TRUE;
5760  next();
5761  break;
5762  case DoneH:
5763  tmp = ref().toUInt( &ok, 16 );
5764  if ( ok ) {
5765  stringAddC( QChar(tmp) );
5766  } else {
5768  goto parseError;
5769  }
5770  charDataRead = TRUE;
5771  next();
5772  break;
5773  case DoneN:
5774  if ( !processReference( charDataRead, context ) )
5775  goto parseError;
5776  next();
5777  break;
5778  }
5779  // no input is read after this
5780  switch ( state ) {
5781  case DoneD:
5782  return TRUE;
5783  case DoneH:
5784  return TRUE;
5785  case DoneN:
5786  return TRUE;
5787  case -1:
5788  // Error
5790  goto parseError;
5791  }
5792 
5793  }
5794 
5795  return TRUE;
5796 
5797 parseError:
5798  reportParseError();
5799  return FALSE;
5800 }
5801 
5802 /*!
5803  Helper function for parseReference()
5804 */
5806 {
5807  QString reference = ref();
5808  if ( reference == "amp" ) {
5809  if ( context == InEntityValue ) {
5810  // Bypassed
5811  stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
5812  } else {
5813  // Included or Included in literal
5814  stringAddC( '&' );
5815  }
5816  charDataRead = TRUE;
5817  } else if ( reference == "lt" ) {
5818  if ( context == InEntityValue ) {
5819  // Bypassed
5820  stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
5821  } else {
5822  // Included or Included in literal
5823  stringAddC( '<' );
5824  }
5825  charDataRead = TRUE;
5826  } else if ( reference == "gt" ) {
5827  if ( context == InEntityValue ) {
5828  // Bypassed
5829  stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
5830  } else {
5831  // Included or Included in literal
5832  stringAddC( '>' );
5833  }
5834  charDataRead = TRUE;
5835  } else if ( reference == "apos" ) {
5836  if ( context == InEntityValue ) {
5837  // Bypassed
5838  stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
5839  } else {
5840  // Included or Included in literal
5841  stringAddC( '\'' );
5842  }
5843  charDataRead = TRUE;
5844  } else if ( reference == "quot" ) {
5845  if ( context == InEntityValue ) {
5846  // Bypassed
5847  stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
5848  } else {
5849  // Included or Included in literal
5850  stringAddC( '"' );
5851  }
5852  charDataRead = TRUE;
5853  } else {
5855  it = d->entities.find( reference );
5856  if ( it != d->entities.end() ) {
5857  // "Internal General"
5858  switch ( context ) {
5859  case InContent:
5860  // Included
5861  xmlRef = it.data() + xmlRef;
5862  charDataRead = FALSE;
5863  break;
5864  case InAttributeValue:
5865  // Included in literal
5866  xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
5867  + xmlRef;
5868  charDataRead = FALSE;
5869  break;
5870  case InEntityValue:
5871  {
5872  // Bypassed
5873  stringAddC( '&' );
5874  for ( int i=0; i<(int)reference.length(); i++ ) {
5875  stringAddC( reference[i] );
5876  }
5877  stringAddC( ';');
5878  charDataRead = TRUE;
5879  }
5880  break;
5881  case InDTD:
5882  // Forbidden
5884  charDataRead = FALSE;
5885  break;
5886  }
5887  } else {
5889  itExtern = d->externEntities.find( reference );
5890  if ( itExtern == d->externEntities.end() ) {
5891  // entity not declared
5892  // ### check this case for conformance
5893  if ( context == InEntityValue ) {
5894  // Bypassed
5895  stringAddC( '&' );
5896  for ( int i=0; i<(int)reference.length(); i++ ) {
5897  stringAddC( reference[i] );
5898  }
5899  stringAddC( ';');
5900  charDataRead = TRUE;
5901  } else {
5902  if ( contentHnd ) {
5903  if ( !contentHnd->skippedEntity( reference ) ) {
5904  d->error = contentHnd->errorString();
5905  return FALSE; // error
5906  }
5907  }
5908  }
5909  } else if ( (*itExtern).notation.isNull() ) {
5910  // "External Parsed General"
5911  switch ( context ) {
5912  case InContent:
5913  // Included if validating
5914  if ( contentHnd ) {
5915  if ( !contentHnd->skippedEntity( reference ) ) {
5916  d->error = contentHnd->errorString();
5917  return FALSE; // error
5918  }
5919  }
5920  charDataRead = FALSE;
5921  break;
5922  case InAttributeValue:
5923  // Forbidden
5925  charDataRead = FALSE;
5926  break;
5927  case InEntityValue:
5928  {
5929  // Bypassed
5930  stringAddC( '&' );
5931  for ( int i=0; i<(int)reference.length(); i++ ) {
5932  stringAddC( reference[i] );
5933  }
5934  stringAddC( ';');
5935  charDataRead = TRUE;
5936  }
5937  break;
5938  case InDTD:
5939  // Forbidden
5941  charDataRead = FALSE;
5942  break;
5943  }
5944  } else {
5945  // "Unparsed"
5946  // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
5947  // Forbidden
5949  charDataRead = FALSE;
5950  return FALSE; // error
5951  }
5952  }
5953  }
5954  return TRUE; // no error
5955 }
5956 
5957 
5958 /*!
5959  Parse over a simple string.
5960 
5961  After the string was successfully parsed, the head is on the first
5962  character after the string.
5963 */
5965 {
5966  signed char Done = s.length();
5967 
5968  const signed char InpCharExpected = 0; // the character that was expected
5969  const signed char InpUnknown = 1;
5970 
5971  signed char state = 0; // state in this function is the position in the string s
5972  signed char input;
5973 
5974  while ( TRUE ) {
5975 
5976  // get input
5977  if ( atEnd() ) {
5978  d->error = XMLERR_UNEXPECTEDEOF;
5979  goto parseError;
5980  }
5981  if ( c == s[(int)state] ) {
5982  input = InpCharExpected;
5983  } else {
5984  input = InpUnknown;
5985  }
5986 
5987  // set state according to input
5988  if ( input == InpCharExpected ) {
5989  state++;
5990  } else {
5991  // Error
5992  d->error = XMLERR_UNEXPECTEDCHARACTER;
5993  goto parseError;
5994  }
5995 
5996  // do some actions according to state
5997  next();
5998  // no input is read after this
5999  if ( state == Done ) {
6000  return TRUE;
6001  }
6002 
6003  }
6004 
6005  return TRUE;
6006 
6007 parseError:
6008  reportParseError();
6009  return FALSE;
6010 }
6011 
6012 
6013 /*!
6014  Inits the data values.
6015 */
6017 {
6018  xml = i.data();
6019  xmlLength = xml.length();
6020  xmlRef = "";
6021 
6022  d->externParameterEntities.clear();
6023  d->parameterEntities.clear();
6024  d->externEntities.clear();
6025  d->entities.clear();
6026 
6027  tags.clear();
6028 
6029  d->doctype = "";
6030  d->xmlVersion = "";
6031  d->encoding = "";
6032  d->standalone = QXmlSimpleReaderPrivate::Unknown;
6033 
6034  lineNr = 0;
6035  columnNr = -1;
6036  pos = 0;
6037  next();
6038  d->error = XMLERR_OK;
6039 }
6040 
6041 /*!
6042  Returns TRUE if a entity with the name \a e exists,
6043  otherwise returns FALSE.
6044 */
6046 {
6047  if ( d->parameterEntities.find(e) == d->parameterEntities.end() &&
6048  d->externParameterEntities.find(e) == d->externParameterEntities.end() ) {
6049  return FALSE;
6050  } else {
6051  return TRUE;
6052  }
6053 }
6054 
6056 {
6057  if ( errorHnd )
6058  errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
6059 }
6060 
6061 #endif //QT_NO_XML
void nameClear()
Definition: qxml.h:607
static QCString name
Definition: declinfo.cpp:673
static const signed char cltLt
Definition: qxml.cpp:95
void setDeclHandler(QXmlDeclHandler *handler)
Definition: qxml.cpp:2067
bool parseReference(bool &charDataRead, EntityRecognitionContext context)
Definition: qxml.cpp:5658
QString xml
Definition: qxml.h:291
bool isEmpty() const
Definition: qmap.h:543
virtual bool is_S(const QChar &)
Definition: qxml.h:530
QString errorString()
Definition: qxml.cpp:1527
QXmlEntityResolver * entityRes
Definition: qxml.h:272
uint toUInt(bool *ok=0, int base=10) const
Definition: qstring.cpp:14058
void setCodec(QTextCodec *)
The QXmlLocator class provides the XML handler classes with information about the actual parsing posi...
Definition: qxml.h:379
bool parseProlog()
Definition: qxml.cpp:2131
QMap< QString, QString > entities
Definition: qxml.cpp:1650
bool hasFeature(const QString &name) const
Definition: qxml.cpp:1990
QXmlLexicalHandler * lexicalHnd
Definition: qxml.h:273
The QXmlLexicalHandler class provides an interface to report lexical content of XML data...
Definition: qxml.h:447
virtual bool skippedEntity(const QString &name)=0
bool endPrefixMapping(const QString &prefix)
Definition: qxml.cpp:1415
bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)
Definition: qxml.cpp:1507
#define XMLERR_UNEXPECTEDCHARACTER
Definition: qxml.cpp:62
#define XMLERR_OK
Definition: qxml.cpp:47
QValueStack< QString > tags
Definition: qxml.h:295
Iterator append(const T &x)
Definition: qvaluelist.h:372
virtual ~QXmlSimpleReader()
Definition: qxml.cpp:1925
#define XMLERR_ERRORPARSINGENTITYDECL
Definition: qxml.cpp:71
The QRegExp class provides pattern matching using regular expressions or wildcards.
Definition: qregexp.h:46
void msg(const char *fmt,...)
Definition: message.cpp:107
bool parseElement()
Definition: qxml.cpp:2303
#define XMLERR_ERRORPARSINGATTTYPE
Definition: qxml.cpp:68
virtual QString errorString()=0
virtual bool startDocument()=0
static const signed char cltEm
Definition: qxml.cpp:98
#define XMLERR_ERRORPARSINGDOCTYPE
Definition: qxml.cpp:78
Iterator end()
Definition: qvaluelist.h:363
std::string string
Definition: nybbler.cc:12
ExternEntity(const QString &p, const QString &s, const QString &n)
Definition: qxml.cpp:1641
bool resize(uint size)
Definition: qarray.h:69
bool notationDecl(const QString &name, const QString &publicId, const QString &systemId)
Definition: qxml.cpp:1498
void insert(const char *k, const type *d)
Definition: qasciidict.h:59
void close()
Definition: qbuffer.cpp:217
QString mid(uint index, uint len=0xffffffff) const
Definition: qstring.cpp:13265
#define XMLERR_ERRORPARSINGNOTATIONDECL
Definition: qxml.cpp:72
QXmlAttributes attList
Definition: qxml.cpp:1671
bool parseExternalID(bool allowPublicID=FALSE)
Definition: qxml.cpp:3443
bool parse(const QXmlInputSource &input)
Definition: qxml.cpp:2077
#define XMLERR_ERRORPARSINGCHOICE
Definition: qxml.cpp:60
void setEncoding(Encoding)
static const signed char cltSlash
Definition: qxml.cpp:96
virtual bool atEnd() const
Definition: qiodevice.cpp:498
static const signed char cltOB
Definition: qxml.cpp:101
virtual int readBlock(char *data, uint maxlen)=0
void processName(const QString &, bool, QString &, QString &) const
Definition: qxml.cpp:421
Iterator replace(const Key &k, const T &v)
Definition: qmap.h:560
bool parseElementETagBegin2(QString &uri, QString &lname)
Definition: qxml.cpp:2539
void clear()
Definition: qvaluelist.h:396
static const signed char cltWS
Definition: qxml.cpp:91
const bool FALSE
Definition: qglobal.h:370
The QXmlNamespaceSupport class is a helper class for XML readers which want to include namespace supp...
Definition: qxml.h:98
ChannelGroupService::Name Name
#define XMLERR_TAGMISMATCH
Definition: qxml.cpp:48
int columnNumber() const
Definition: qxml.cpp:231
bool parseAttValue()
Definition: qxml.cpp:4330
#define XMLERR_VERSIONEXPECTED
Definition: qxml.cpp:80
#define XMLERR_ERRORPARSINGELEMENT
Definition: qxml.cpp:52
virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)=0
bool parseNotationDecl()
Definition: qxml.cpp:4661
bool parseAttribute()
Definition: qxml.cpp:5402
#define XMLERR_INTERNALGENERALENTITYINDTD
Definition: qxml.cpp:85
void nameAddC()
Definition: qxml.h:620
The QBuffer class is an I/O device that operates on a QByteArray.
Definition: qbuffer.h:47
The QString class provides an abstraction of Unicode text and the classic C null-terminated char arra...
Definition: qstring.h:350
#define XMLERR_CDSECTHEADEREXPECTED
Definition: qxml.cpp:76
void setProperty(const QString &name, void *value)
Definition: qxml.cpp:2014
bool skippedEntity(const QString &name)
Definition: qxml.cpp:1466
void qWarning(const char *msg,...)
Definition: qglobal.cpp:409
#define XMLERR_ERRORPARSINGPROLOG
Definition: qxml.cpp:53
virtual const QString & data() const
Definition: qxml.cpp:717
static const QChar QEOF
Definition: qxml.h:299
void setErrorHandler(QXmlErrorHandler *handler)
Definition: qxml.cpp:2051
int columnNr
Definition: qxml.h:278
virtual bool startDTD(const QString &name, const QString &publicId, const QString &systemId)=0
The QXmlErrorHandler class provides an interface to report errors in XML data.
Definition: qxml.h:420
QString message() const
Definition: qxml.cpp:224
#define XMLERR_ERRORPARSINGMISC
Definition: qxml.cpp:59
init
Definition: train.py:42
QString publicId() const
Definition: qxml.cpp:245
QXmlDeclHandler * declHandler() const
Definition: qxml.cpp:2071
#define XMLERR_MORETHANONEDOCTYPE
Definition: qxml.cpp:77
The QXmlDTDHandler class provides an interface to report DTD content of XML data. ...
Definition: qxml.h:430
static const signed char cltQm
Definition: qxml.cpp:97
#define XMLERR_UNPARSEDENTITYREFERENCE
Definition: qxml.cpp:84
QXmlLexicalHandler * lexicalHandler() const
Definition: qxml.cpp:2063
#define XMLERR_SDDECLEXPECTED
Definition: qxml.cpp:82
The QChar class provides a light-weight Unicode character.
Definition: qstring.h:56
QString value(int index) const
Definition: qxml.cpp:664
QXmlContentHandler * contentHnd
Definition: qxml.h:269
void splitName(const QString &, QString &, QString &) const
Definition: qxml.cpp:387
#define XMLERR_ERRORPARSINGMAINELEMENT
Definition: qxml.cpp:54
bool parseChoiceSeq()
Definition: qxml.cpp:4786
constexpr double PI
void setLexicalHandler(QXmlLexicalHandler *handler)
Definition: qxml.cpp:2059
static const signed char cltAmp
Definition: qxml.cpp:93
static const signed char cltSq
Definition: qxml.cpp:104
void refAddC()
Definition: qxml.h:628
QString uri(const QString &) const
Definition: qxml.cpp:378
QXmlDeclHandler * declHnd
Definition: qxml.h:274
QXmlEntityResolver * entityResolver() const
Definition: qxml.cpp:2031
void eat_ws()
Definition: qxml.h:578
void stringClear()
Definition: qxml.h:605
bool parsePEReference(EntityRecognitionContext context)
Definition: qxml.cpp:3776
bool characters(const QString &ch)
Definition: qxml.cpp:1441
#define IO_ReadOnly
Definition: qiodevice.h:61
The QXmlSimpleReader class provides an implementation of a simple XML reader (i.e. parser).
Definition: qxml.h:238
#define XMLERR_ERRORPARSINGEXTERNALID
Definition: qxml.cpp:73
bool parseEntityDecl()
Definition: qxml.cpp:4908
virtual ~QXmlInputSource()
Definition: qxml.cpp:768
static const signed char cltUnknown
Definition: qxml.cpp:105
type * data() const
Definition: qarray.h:63
#define XMLERR_LETTEREXPECTED
Definition: qxml.cpp:51
bool parseMarkupdecl()
Definition: qxml.cpp:3610
virtual bool attributeDecl(const QString &eName, const QString &aName, const QString &type, const QString &valueDefault, const QString &value)=0
void push(const T &d)
Definition: qvaluestack.h:52
bool startCDATA()
Definition: qxml.cpp:1569
QTextStream & reset(QTextStream &s)
#define XMLERR_ERRORPARSINGATTRIBUTE
Definition: qxml.cpp:58
#define XMLERR_ERRORPARSINGREFERENCE
Definition: qxml.cpp:65
void setContentHandler(QXmlContentHandler *handler)
Definition: qxml.cpp:2043
virtual bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)=0
bool parseElementAttribute(QString &prefix, QString &uri, QString &lname)
Definition: qxml.cpp:2589
bool parseElementDecl()
Definition: qxml.cpp:4438
const double e
#define XMLERR_ERRORPARSINGCOMMENT
Definition: qxml.cpp:74
int lineNumber()
Definition: qxml.cpp:292
static int input(void)
Definition: code.cpp:15695
Standalone standalone
Definition: qxml.cpp:1658
QChar at(uint i) const
Definition: qstring.h:492
const char * ascii() const
Definition: qstring.cpp:14494
#define XMLERR_ERRORPARSINGCONTENT
Definition: qxml.cpp:55
void next()
Definition: qxml.h:555
A list of strings.
Definition: qstringlist.h:51
QString left(uint len) const
Definition: qstring.cpp:13199
friend class QXmlSimpleReaderPrivate
Definition: qxml.h:371
#define XMLERR_INVALIDNAMEFORPI
Definition: qxml.cpp:79
uint length() const
Definition: qstring.h:679
std::void_t< T > n
friend class QXmlLocator
Definition: qxml.h:372
virtual void setData(const QString &d)
Definition: qxml.cpp:775
bool open(int)
Definition: qfile_unix.cpp:134
bool open(int)
Definition: qbuffer.cpp:187
QMap< QString, ExternParameterEntity > externParameterEntities
Definition: qxml.cpp:1647
virtual bool comment(const QString &ch)=0
bool parseNmtoken()
Definition: qxml.cpp:5580
The QXmlContentHandler class provides an interface to report logical content of XML data...
Definition: qxml.h:402
bool internalEntityDecl(const QString &name, const QString &value)
Definition: qxml.cpp:1601
p
Definition: test.py:223
bool startPrefixMapping(const QString &prefix, const QString &uri)
Definition: qxml.cpp:1407
void setEntityResolver(QXmlEntityResolver *handler)
Definition: qxml.cpp:2027
bool processingInstruction(const QString &target, const QString &data)
Definition: qxml.cpp:1457
QStringList prefixes() const
Definition: qxml.cpp:453
#define XMLERR_EXTERNALGENERALENTITYINDTD
Definition: qxml.cpp:86
QString xmlRef
Definition: qxml.h:293
void clear()
Definition: qasciidict.h:70
static const signed char cltPer
Definition: qxml.cpp:92
bool processReference(bool &charDataRead, EntityRecognitionContext context)
Definition: qxml.cpp:5805
#define XMLERR_ERRORPARSINGNAME
Definition: qxml.cpp:56
virtual bool notationDecl(const QString &name, const QString &publicId, const QString &systemId)=0
string tmp
Definition: languages.py:63
void readInput(QByteArray &rawData)
Definition: qxml.cpp:784
virtual bool processingInstruction(const QString &target, const QString &data)=0
bool startDTD(const QString &name, const QString &publicId, const QString &systemId)
Definition: qxml.cpp:1535
bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)
Definition: qxml.cpp:1609
int xmlLength
Definition: qxml.h:292
void next_eat_ws()
Definition: qxml.h:581
#define XMLERR_ERRORPARSINGATTLISTDECL
Definition: qxml.cpp:67
QXmlDTDHandler * DTDHandler() const
Definition: qxml.cpp:2039
bool entityExist(const QString &) const
Definition: qxml.cpp:6045
void setDTDHandler(QXmlDTDHandler *handler)
Definition: qxml.cpp:2035
virtual bool endDocument()=0
bool comment(const QString &ch)
Definition: qxml.cpp:1585
bool parseComment()
Definition: qxml.cpp:5297
virtual bool startCDATA()=0
void Init(void)
Definition: gXSecComp.cxx:138
QXmlNamespaceSupport namespaceSupport
Definition: qxml.cpp:1675
static const signed char cltDash
Definition: qxml.cpp:99
QString uri(int index) const
Definition: qxml.cpp:622
bool parseAttType()
Definition: qxml.cpp:4080
QString localName(int index) const
Definition: qxml.cpp:602
uint contains(const T &x) const
Definition: qvaluelist.h:392
QString systemId() const
Definition: qxml.cpp:252
virtual bool endPrefixMapping(const QString &prefix)=0
ExternParameterEntity(const QString &p, const QString &s)
Definition: qxml.cpp:1633
bool parseName(bool useRef=FALSE)
Definition: qxml.cpp:5498
void stringAddC()
Definition: qxml.h:612
int columnNumber()
Definition: qxml.cpp:284
QMap< QString, QString > parameterEntities
Definition: qxml.cpp:1648
QString read()
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
static const signed char cltGt
Definition: qxml.cpp:94
#define XMLERR_EXTERNALGENERALENTITYINAV
Definition: qxml.cpp:87
bool isDirectAccess() const
Definition: qiodevice.h:98
QString & ref()
Definition: qxml.h:598
void reportParseError()
Definition: qxml.cpp:6055
QXmlDTDHandler * dtdHnd
Definition: qxml.h:271
The QTextStream class provides basic functions for reading and writing text using a QIODevice...
Definition: qtextstream.h:53
static QTextCodec * codecForName(const char *hint, int accuracy=0)
Definition: qtextcodec.cpp:626
unsigned short ushort
Definition: qglobal.h:350
static const signed char cltDq
Definition: qxml.cpp:103
#define XMLERR_ERRORPARSINGENTITYVALUE
Definition: qxml.cpp:75
#define Comment
QXmlLocator * locator
Definition: qxml.cpp:1674
QXmlContentHandler * contentHandler() const
Definition: qxml.cpp:2047
bool parseAttlistDecl()
Definition: qxml.cpp:3880
bool parseMisc()
Definition: qxml.cpp:2922
QXmlErrorHandler * errorHandler() const
Definition: qxml.cpp:2055
bool warning(const QXmlParseException &exception)
Definition: qxml.cpp:1474
static QCString encoding
Definition: config.cpp:1052
virtual bool characters(const QString &ch)=0
virtual bool endCDATA()=0
virtual QString errorString()=0
bool parseEntityValue()
Definition: qxml.cpp:5171
bool reset()
Definition: qiodevice.h:123
bool parseString(const QString &s)
Definition: qxml.cpp:5964
QByteArray readAll()
Definition: qiodevice.cpp:535
bool fatalError(const QXmlParseException &exception)
Definition: qxml.cpp:1490
void line(double t, double *p, double &x, double &y, double &z)
bool resolveEntity(const QString &publicId, const QString &systemId, QXmlInputSource *&ret)
Definition: qxml.cpp:1517
static const signed char cltEq
Definition: qxml.cpp:102
std::vector< std::string > column
bool parseDoctype()
Definition: qxml.cpp:3264
virtual bool endDTD()=0
bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
Definition: qxml.cpp:1423
Iterator begin()
Definition: qvaluelist.h:361
QString type(int index) const
Definition: qxml.cpp:632
The QXmlAttributes class provides XML attributes.
Definition: qxml.h:128
bool isNull() const
Definition: qstring.h:379
QIODevice * device() const
Definition: qtextstream.h:223
static msg_handler handler
Definition: qglobal.cpp:234
bool error(const QXmlParseException &exception)
Definition: qxml.cpp:1482
virtual QString errorString()=0
QString prefix(const QString &) const
Definition: qxml.cpp:363
#define XMLERR_ERRORPARSINGELEMENTDECL
Definition: qxml.cpp:70
The QXmlEntityResolver class provides an interface to resolve extern entities contained in XML data...
Definition: qxml.h:439
bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
Definition: qxml.cpp:1432
int index(const QString &qName) const
Definition: qxml.cpp:563
The QXmlDeclHandler class provides an interface to report declaration content of XML data...
Definition: qxml.h:461
void * property(const QString &name, bool *ok=0) const
Definition: qxml.cpp:2004
void init(const QXmlInputSource &i)
Definition: qxml.cpp:6016
static const Null null
Definition: qstring.h:376
bool isEmpty() const
Definition: qvaluelist.h:368
static const signed char charLookupTable[256]
Definition: qxml.cpp:108
bool parseContent()
Definition: qxml.cpp:2635
EntityRecognitionContext
Definition: qxml.h:324
void setPrefix(const QString &, const QString &)
Definition: qxml.cpp:344
int length() const
Definition: qxml.cpp:592
static const signed char cltCB
Definition: qxml.cpp:100
The QXmlInputSource class is the source where XML data is read from.
Definition: qxml.h:162
#define XMLERR_UNEXPECTEDEOF
Definition: qxml.cpp:49
bool hasProperty(const QString &name) const
Definition: qxml.cpp:2021
#define XMLERR_WRONGVALUEFORSDECL
Definition: qxml.cpp:83
void close()
Definition: qfile_unix.cpp:614
QCString utf8() const
Definition: qstring.cpp:14507
void setFeature(const QString &name, bool value)
Definition: qxml.cpp:1972
bool startDocument()
Definition: qxml.cpp:1391
bool endDocument()
Definition: qxml.cpp:1399
bool feature(const QString &name, bool *ok=0) const
Definition: qxml.cpp:1936
virtual bool is_NameChar(const QChar &)
Definition: qxml.h:548
#define XMLERR_ERRORPARSINGNMTOKEN
Definition: qxml.cpp:57
unsigned uint
Definition: qglobal.h:351
bool atEnd()
Definition: qxml.h:575
QAsciiDict< Entry > ns
virtual QString errorString()=0
#define XMLERR_ERRORPARSINGPI
Definition: qxml.cpp:66
bool parsePI(bool xmldecl=FALSE)
Definition: qxml.cpp:3042
bool ignorableWhitespace(const QString &ch)
Definition: qxml.cpp:1449
int lineNumber() const
Definition: qxml.cpp:238
virtual bool internalEntityDecl(const QString &name, const QString &value)=0
virtual bool startPrefixMapping(const QString &prefix, const QString &uri)=0
QMap< QString, ExternEntity > externEntities
Definition: qxml.cpp:1649
virtual void setDocumentLocator(QXmlLocator *locator)=0
static QCString * s
Definition: config.cpp:1042
const bool TRUE
Definition: qglobal.h:371
void refClear()
Definition: qxml.h:609
bool parseElementEmptyTag(bool &t, QString &uri, QString &lname)
Definition: qxml.cpp:2482
void setDocumentLocator(QXmlLocator *locator)
Definition: qxml.cpp:1384
#define XMLERR_ERRORPARSINGATTVALUE
Definition: qxml.cpp:69
QString qName(int index) const
Definition: qxml.cpp:612
The QXmlParseException class is used to report errors with the QXmlErrorHandler interface.
Definition: qxml.h:185
virtual bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)=0
virtual bool is_NameBeginning(const QChar &)
Definition: qxml.h:536
#define XMLERR_EDECLORSDDECLEXPECTED
Definition: qxml.cpp:81
bool attributeDecl(const QString &eName, const QString &aName, const QString &type, const QString &valueDefault, const QString &value)
Definition: qxml.cpp:1593
bool operator==(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept
QXmlErrorHandler * errorHnd
Definition: qxml.h:270
virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)=0
void pushContext()
Definition: qxml.cpp:498
virtual bool fatalError(const QXmlParseException &exception)=0
#define XMLERR_ERRORBYCONSUMER
Definition: qxml.cpp:61