~ubuntu-branches/ubuntu/karmic/psi/karmic

« back to all changes in this revision

Viewing changes to src/tools/qxml/qxml.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2006-01-20 00:20:36 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060120002036-7nw6yo6totip0ee5
Tags: 0.10-2
* Added upstream changelog (Closes: Bug#327748)
* Mention --no-gpg and --no-gpg-agent in manpage (Closes: Bug#204416)

Show diffs side-by-side

added added

removed removed

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