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