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

« back to all changes in this revision

Viewing changes to 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