|
1 /* Copyright (c) 1998, 1999, 2000,Thai Open Source Software Center Ltd |
|
2 See the file COPYING for copying permission. |
|
3 Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
4 */ |
|
5 |
|
6 // This file produces 9 "unreferenced formal parameter" warnings on MS and CW |
|
7 #if defined(__VC32__) |
|
8 #pragma warning ( disable : 4100 ) |
|
9 |
|
10 #if !defined(_DEBUG) |
|
11 // This file produces 1 "unreachable code" warning on MS for UREL builds |
|
12 #pragma warning ( disable : 4702 ) |
|
13 #endif // _DEBUG |
|
14 |
|
15 #elif defined(__CW32__) |
|
16 #pragma warn_unusedarg off |
|
17 #endif |
|
18 |
|
19 #include <stddef.h> |
|
20 #include <string.h> /* memset(), memcpy() */ |
|
21 |
|
22 #include "expat_config.h" |
|
23 #include "expat.h" |
|
24 |
|
25 #ifdef XML_UNICODE |
|
26 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX |
|
27 #define XmlConvert XmlUtf16Convert |
|
28 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding |
|
29 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS |
|
30 #define XmlEncode XmlUtf16Encode |
|
31 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) |
|
32 typedef unsigned short ICHAR; |
|
33 #else |
|
34 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX |
|
35 #define XmlConvert XmlUtf8Convert |
|
36 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding |
|
37 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS |
|
38 #define XmlEncode XmlUtf8Encode |
|
39 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8) |
|
40 typedef char ICHAR; |
|
41 #endif |
|
42 |
|
43 |
|
44 #ifndef XML_NS |
|
45 |
|
46 #define XmlInitEncodingNS XmlInitEncoding |
|
47 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding |
|
48 #undef XmlGetInternalEncodingNS |
|
49 #define XmlGetInternalEncodingNS XmlGetInternalEncoding |
|
50 #define XmlParseXmlDeclNS XmlParseXmlDecl |
|
51 |
|
52 #endif |
|
53 |
|
54 #ifdef XML_UNICODE |
|
55 |
|
56 #ifdef XML_UNICODE_WCHAR_T |
|
57 #define XML_T(x) (wchar_t)x |
|
58 #define XML_L(x) L ## x |
|
59 #else |
|
60 #define XML_T(x) (unsigned short)x |
|
61 #define XML_L(x) x |
|
62 #endif |
|
63 |
|
64 #else |
|
65 |
|
66 #define XML_T(x) x |
|
67 #define XML_L(x) x |
|
68 |
|
69 #endif |
|
70 |
|
71 /* Round up n to be a multiple of sz, where sz is a power of 2. */ |
|
72 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) |
|
73 |
|
74 /* Handle the case where memmove() doesn't exist. */ |
|
75 #ifndef HAVE_MEMMOVE |
|
76 #ifdef HAVE_BCOPY |
|
77 #define memmove(d,s,l) bcopy((s),(d),(l)) |
|
78 #else |
|
79 #error memmove does not exist on this platform, nor is a substitute available |
|
80 #endif /* HAVE_BCOPY */ |
|
81 #endif /* HAVE_MEMMOVE */ |
|
82 |
|
83 #include "internal.h" |
|
84 #include "xmltok.h" |
|
85 #include "xmlrole.h" |
|
86 |
|
87 typedef const XML_Char *KEY; |
|
88 |
|
89 typedef struct { |
|
90 KEY name; |
|
91 } NAMED; |
|
92 |
|
93 typedef struct { |
|
94 NAMED **v; |
|
95 size_t size; |
|
96 size_t used; |
|
97 size_t usedLim; |
|
98 XML_Memory_Handling_Suite *mem; |
|
99 } HASH_TABLE; |
|
100 |
|
101 typedef struct { |
|
102 NAMED **p; |
|
103 NAMED **end; |
|
104 } HASH_TABLE_ITER; |
|
105 |
|
106 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ |
|
107 #define INIT_DATA_BUF_SIZE 1024 |
|
108 #define INIT_ATTS_SIZE 16 |
|
109 #define INIT_BLOCK_SIZE 1024 |
|
110 #define INIT_BUFFER_SIZE 1024 |
|
111 |
|
112 #define EXPAND_SPARE 24 |
|
113 |
|
114 typedef struct binding { |
|
115 struct prefix *prefix; |
|
116 struct binding *nextTagBinding; |
|
117 struct binding *prevPrefixBinding; |
|
118 const struct attribute_id *attId; |
|
119 XML_Char *uri; |
|
120 int uriLen; |
|
121 int uriAlloc; |
|
122 } BINDING; |
|
123 |
|
124 typedef struct prefix { |
|
125 const XML_Char *name; |
|
126 BINDING *binding; |
|
127 } PREFIX; |
|
128 |
|
129 typedef struct { |
|
130 const XML_Char *str; |
|
131 const XML_Char *localPart; |
|
132 const XML_Char *prefix; |
|
133 int strLen; |
|
134 int uriLen; |
|
135 int prefixLen; |
|
136 } TAG_NAME; |
|
137 |
|
138 /* TAG represents an open element. |
|
139 The name of the element is stored in both the document and API |
|
140 encodings. The memory buffer 'buf' is a separately-allocated |
|
141 memory area which stores the name. During the XML_Parse()/ |
|
142 XMLParseBuffer() when the element is open, the memory for the 'raw' |
|
143 version of the name (in the document encoding) is shared with the |
|
144 document buffer. If the element is open across calls to |
|
145 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to |
|
146 contain the 'raw' name as well. |
|
147 |
|
148 A parser re-uses these structures, maintaining a list of allocated |
|
149 TAG objects in a free list. |
|
150 */ |
|
151 typedef struct tag { |
|
152 struct tag *parent; /* parent of this element */ |
|
153 const char *rawName; /* tagName in the original encoding */ |
|
154 int rawNameLength; |
|
155 TAG_NAME name; /* tagName in the API encoding */ |
|
156 char *buf; /* buffer for name components */ |
|
157 char *bufEnd; /* end of the buffer */ |
|
158 BINDING *bindings; |
|
159 } TAG; |
|
160 |
|
161 typedef struct { |
|
162 const XML_Char *name; |
|
163 const XML_Char *textPtr; |
|
164 int textLen; |
|
165 const XML_Char *systemId; |
|
166 const XML_Char *base; |
|
167 const XML_Char *publicId; |
|
168 const XML_Char *notation; |
|
169 XML_Bool open; |
|
170 XML_Bool is_param; |
|
171 XML_Bool is_internal; /* true if declared in internal subset outside PE */ |
|
172 } ENTITY; |
|
173 |
|
174 typedef struct { |
|
175 enum XML_Content_Type type; |
|
176 enum XML_Content_Quant quant; |
|
177 const XML_Char * name; |
|
178 int firstchild; |
|
179 int lastchild; |
|
180 int childcnt; |
|
181 int nextsib; |
|
182 } CONTENT_SCAFFOLD; |
|
183 |
|
184 #define INIT_SCAFFOLD_ELEMENTS 32 |
|
185 |
|
186 typedef struct block { |
|
187 struct block *next; |
|
188 int size; |
|
189 XML_Char s[1]; |
|
190 } BLOCK; |
|
191 |
|
192 typedef struct { |
|
193 BLOCK *blocks; |
|
194 BLOCK *freeBlocks; |
|
195 const XML_Char *end; |
|
196 XML_Char *ptr; |
|
197 XML_Char *start; |
|
198 XML_Memory_Handling_Suite *mem; |
|
199 } STRING_POOL; |
|
200 |
|
201 /* The XML_Char before the name is used to determine whether |
|
202 an attribute has been specified. */ |
|
203 typedef struct attribute_id { |
|
204 XML_Char *name; |
|
205 PREFIX *prefix; |
|
206 XML_Bool maybeTokenized; |
|
207 XML_Bool xmlns; |
|
208 } ATTRIBUTE_ID; |
|
209 |
|
210 typedef struct { |
|
211 const ATTRIBUTE_ID *id; |
|
212 XML_Bool isCdata; |
|
213 const XML_Char *value; |
|
214 } DEFAULT_ATTRIBUTE; |
|
215 |
|
216 typedef struct { |
|
217 const XML_Char *name; |
|
218 PREFIX *prefix; |
|
219 const ATTRIBUTE_ID *idAtt; |
|
220 int nDefaultAtts; |
|
221 int allocDefaultAtts; |
|
222 DEFAULT_ATTRIBUTE *defaultAtts; |
|
223 } ELEMENT_TYPE; |
|
224 |
|
225 typedef struct { |
|
226 HASH_TABLE generalEntities; |
|
227 HASH_TABLE elementTypes; |
|
228 HASH_TABLE attributeIds; |
|
229 HASH_TABLE prefixes; |
|
230 STRING_POOL pool; |
|
231 STRING_POOL entityValuePool; |
|
232 /* false once a parameter entity reference has been skipped */ |
|
233 XML_Bool keepProcessing; |
|
234 /* true once an internal or external PE reference has been encountered; |
|
235 any external subset is considered an external PE reference */ |
|
236 XML_Bool hasParamEntityRefs; |
|
237 XML_Bool standalone; |
|
238 #ifdef XML_DTD |
|
239 /* indicates if external PE has been read */ |
|
240 XML_Bool paramEntityRead; |
|
241 HASH_TABLE paramEntities; |
|
242 #endif /* XML_DTD */ |
|
243 PREFIX defaultPrefix; |
|
244 /* === scaffolding for building content model === */ |
|
245 XML_Bool in_eldecl; |
|
246 CONTENT_SCAFFOLD *scaffold; |
|
247 unsigned contentStringLen; |
|
248 unsigned scaffSize; |
|
249 unsigned scaffCount; |
|
250 int scaffLevel; |
|
251 int *scaffIndex; |
|
252 } DTD; |
|
253 |
|
254 typedef struct open_internal_entity { |
|
255 const char *internalEventPtr; |
|
256 const char *internalEventEndPtr; |
|
257 struct open_internal_entity *next; |
|
258 ENTITY *entity; |
|
259 } OPEN_INTERNAL_ENTITY; |
|
260 |
|
261 typedef enum XML_Error FASTCALL Processor(XML_Parser parser, |
|
262 const char *start, |
|
263 const char *end, |
|
264 const char **endPtr); |
|
265 |
|
266 static Processor prologProcessor; |
|
267 static Processor prologInitProcessor; |
|
268 static Processor contentProcessor; |
|
269 static Processor cdataSectionProcessor; |
|
270 #ifdef XML_DTD |
|
271 static Processor ignoreSectionProcessor; |
|
272 static Processor externalParEntProcessor; |
|
273 static Processor externalParEntInitProcessor; |
|
274 static Processor entityValueProcessor; |
|
275 static Processor entityValueInitProcessor; |
|
276 #endif /* XML_DTD */ |
|
277 static Processor epilogProcessor; |
|
278 static Processor errorProcessor; |
|
279 #ifndef SYMBIAN_MIN_SIZE |
|
280 static Processor externalEntityInitProcessor; |
|
281 static Processor externalEntityInitProcessor2; |
|
282 static Processor externalEntityInitProcessor3; |
|
283 #endif // SYMBIAN_MIN_SIZE |
|
284 static Processor externalEntityContentProcessor; |
|
285 |
|
286 static enum XML_Error FASTCALL |
|
287 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); |
|
288 static enum XML_Error FASTCALL |
|
289 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, |
|
290 const char *, const char *); |
|
291 static enum XML_Error FASTCALL |
|
292 initializeEncoding(XML_Parser parser); |
|
293 static enum XML_Error FASTCALL |
|
294 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, |
|
295 const char *end, int tok, const char *next, const char **nextPtr); |
|
296 |
|
297 #ifdef XML_DTD |
|
298 static enum XML_Error FASTCALL |
|
299 processInternalParamEntity(XML_Parser parser, ENTITY *entity); |
|
300 #endif |
|
301 |
|
302 static enum XML_Error FASTCALL |
|
303 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, |
|
304 const char *start, const char *end, const char **endPtr); |
|
305 static enum XML_Error FASTCALL |
|
306 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, |
|
307 const char *end, const char **nextPtr); |
|
308 #ifdef XML_DTD |
|
309 static enum XML_Error FASTCALL |
|
310 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, |
|
311 const char *end, const char **nextPtr); |
|
312 #endif /* XML_DTD */ |
|
313 static enum XML_Error FASTCALL |
|
314 storeAtts(XML_Parser parser, const ENCODING *, |
|
315 const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); |
|
316 static int FASTCALL |
|
317 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, |
|
318 const XML_Char *uri, BINDING **bindingsPtr); |
|
319 |
|
320 static int FASTCALL |
|
321 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, |
|
322 XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue, |
|
323 XML_Parser parser); |
|
324 |
|
325 static enum XML_Error FASTCALL |
|
326 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, |
|
327 const char *, const char *, STRING_POOL *); |
|
328 static enum XML_Error FASTCALL |
|
329 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, |
|
330 const char *, const char *, STRING_POOL *); |
|
331 static ATTRIBUTE_ID * FASTCALL |
|
332 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, |
|
333 const char *end); |
|
334 static int FASTCALL |
|
335 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); |
|
336 static enum XML_Error FASTCALL |
|
337 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, |
|
338 const char *end); |
|
339 static int FASTCALL |
|
340 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, |
|
341 const char *start, const char *end); |
|
342 static int FASTCALL |
|
343 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, |
|
344 const char *end); |
|
345 static void FASTCALL |
|
346 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, |
|
347 const char *end); |
|
348 |
|
349 static const XML_Char * FASTCALL getContext(XML_Parser parser); |
|
350 static XML_Bool FASTCALL |
|
351 setContext(XML_Parser parser, const XML_Char *context); |
|
352 static void FASTCALL normalizePublicId(XML_Char *s); |
|
353 static void FASTCALL dtdInit(DTD *, XML_Parser parser); |
|
354 |
|
355 /* do not call if parentParser != NULL */ |
|
356 static void FASTCALL dtdReset(DTD *, XML_Parser parser); |
|
357 static void FASTCALL dtdDestroy(DTD *, XML_Parser parser); |
|
358 |
|
359 #ifndef SYMBIAN_MIN_SIZE |
|
360 static int FASTCALL dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser); |
|
361 static int FASTCALL copyEntityTable(HASH_TABLE *, STRING_POOL *, |
|
362 const HASH_TABLE *, XML_Parser parser); |
|
363 #endif // SYMBIAN_MIN_SIZE |
|
364 |
|
365 #ifdef XML_DTD |
|
366 static void FASTCALL dtdSwap(DTD *, DTD *); |
|
367 #endif /* XML_DTD */ |
|
368 |
|
369 static NAMED * FASTCALL |
|
370 lookup(HASH_TABLE *table, KEY name, size_t createSize); |
|
371 |
|
372 static void FASTCALL |
|
373 hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms); |
|
374 |
|
375 static void FASTCALL hashTableClear(HASH_TABLE *); |
|
376 static void FASTCALL hashTableDestroy(HASH_TABLE *); |
|
377 static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); |
|
378 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); |
|
379 static void FASTCALL poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms); |
|
380 static void FASTCALL poolClear(STRING_POOL *); |
|
381 static void FASTCALL poolDestroy(STRING_POOL *); |
|
382 static XML_Char * FASTCALL |
|
383 poolAppend(STRING_POOL *pool, const ENCODING *enc, |
|
384 const char *ptr, const char *end); |
|
385 static XML_Char * FASTCALL |
|
386 poolStoreString(STRING_POOL *pool, const ENCODING *enc, |
|
387 const char *ptr, const char *end); |
|
388 |
|
389 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); |
|
390 |
|
391 static int FASTCALL nextScaffoldPart(XML_Parser parser); |
|
392 static XML_Content * FASTCALL build_model(XML_Parser parser); |
|
393 |
|
394 static const XML_Char * FASTCALL |
|
395 poolCopyString(STRING_POOL *pool, const XML_Char *s); |
|
396 |
|
397 #ifndef SYMBIAN_MIN_SIZE |
|
398 static const XML_Char * FASTCALL |
|
399 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); |
|
400 static const XML_Char * FASTCALL |
|
401 poolAppendString(STRING_POOL *pool, const XML_Char *s); |
|
402 #endif // SYMBIAN_MIN_SIZE |
|
403 |
|
404 static ELEMENT_TYPE * FASTCALL |
|
405 getElementType(XML_Parser Paraser, const ENCODING *enc, |
|
406 const char *ptr, const char *end); |
|
407 |
|
408 static void FASTCALL |
|
409 parserInit(XML_Parser parser, const XML_Char *encodingName); |
|
410 |
|
411 #define poolStart(pool) ((pool)->start) |
|
412 #define poolEnd(pool) ((pool)->ptr) |
|
413 #define poolLength(pool) ((pool)->ptr - (pool)->start) |
|
414 #define poolChop(pool) ((void)--(pool->ptr)) |
|
415 #define poolLastChar(pool) (((pool)->ptr)[-1]) |
|
416 #define poolDiscard(pool) ((pool)->ptr = (pool)->start) |
|
417 #define poolFinish(pool) ((pool)->start = (pool)->ptr) |
|
418 #define poolAppendChar(pool, c) \ |
|
419 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ |
|
420 ? 0 \ |
|
421 : ((*((pool)->ptr)++ = c), 1)) |
|
422 |
|
423 struct XML_ParserStruct { |
|
424 /* The first member must be userData so that the XML_GetUserData |
|
425 macro works. */ |
|
426 void *m_userData; |
|
427 void *m_handlerArg; |
|
428 char *m_buffer; |
|
429 XML_Memory_Handling_Suite m_mem; |
|
430 /* first character to be parsed */ |
|
431 const char *m_bufferPtr; |
|
432 /* past last character to be parsed */ |
|
433 char *m_bufferEnd; |
|
434 /* allocated end of buffer */ |
|
435 const char *m_bufferLim; |
|
436 long m_parseEndByteIndex; |
|
437 const char *m_parseEndPtr; |
|
438 XML_Char *m_dataBuf; |
|
439 XML_Char *m_dataBufEnd; |
|
440 XML_StartElementHandler m_startElementHandler; |
|
441 XML_EndElementHandler m_endElementHandler; |
|
442 XML_CharacterDataHandler m_characterDataHandler; |
|
443 XML_ProcessingInstructionHandler m_processingInstructionHandler; |
|
444 XML_CommentHandler m_commentHandler; |
|
445 XML_StartCdataSectionHandler m_startCdataSectionHandler; |
|
446 XML_EndCdataSectionHandler m_endCdataSectionHandler; |
|
447 XML_DefaultHandler m_defaultHandler; |
|
448 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; |
|
449 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; |
|
450 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; |
|
451 XML_NotationDeclHandler m_notationDeclHandler; |
|
452 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; |
|
453 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; |
|
454 XML_NotStandaloneHandler m_notStandaloneHandler; |
|
455 XML_ExternalEntityRefHandler m_externalEntityRefHandler; |
|
456 void *m_externalEntityRefHandlerArg; |
|
457 XML_SkippedEntityHandler m_skippedEntityHandler; |
|
458 XML_UnknownEncodingHandler m_unknownEncodingHandler; |
|
459 XML_ElementDeclHandler m_elementDeclHandler; |
|
460 XML_AttlistDeclHandler m_attlistDeclHandler; |
|
461 XML_EntityDeclHandler m_entityDeclHandler; |
|
462 XML_XmlDeclHandler m_xmlDeclHandler; |
|
463 const ENCODING *m_encoding; |
|
464 INIT_ENCODING m_initEncoding; |
|
465 const ENCODING *m_internalEncoding; |
|
466 const XML_Char *m_protocolEncodingName; |
|
467 XML_Bool m_ns; |
|
468 XML_Bool m_ns_triplets; |
|
469 void *m_unknownEncodingMem; |
|
470 void *m_unknownEncodingData; |
|
471 void *m_unknownEncodingHandlerData; |
|
472 void (*m_unknownEncodingRelease)(void *); |
|
473 PROLOG_STATE m_prologState; |
|
474 Processor *m_processor; |
|
475 enum XML_Error m_errorCode; |
|
476 const char *m_eventPtr; |
|
477 const char *m_eventEndPtr; |
|
478 const char *m_positionPtr; |
|
479 OPEN_INTERNAL_ENTITY *m_openInternalEntities; |
|
480 XML_Bool m_defaultExpandInternalEntities; |
|
481 int m_tagLevel; |
|
482 ENTITY *m_declEntity; |
|
483 const XML_Char *m_doctypeName; |
|
484 const XML_Char *m_doctypeSysid; |
|
485 const XML_Char *m_doctypePubid; |
|
486 const XML_Char *m_declAttributeType; |
|
487 const XML_Char *m_declNotationName; |
|
488 const XML_Char *m_declNotationPublicId; |
|
489 ELEMENT_TYPE *m_declElementType; |
|
490 ATTRIBUTE_ID *m_declAttributeId; |
|
491 XML_Bool m_declAttributeIsCdata; |
|
492 XML_Bool m_declAttributeIsId; |
|
493 DTD m_dtd; |
|
494 const XML_Char *m_curBase; |
|
495 TAG *m_tagStack; |
|
496 TAG *m_freeTagList; |
|
497 BINDING *m_inheritedBindings; |
|
498 BINDING *m_freeBindingList; |
|
499 int m_attsSize; |
|
500 int m_nSpecifiedAtts; |
|
501 int m_idAttIndex; |
|
502 ATTRIBUTE *m_atts; |
|
503 POSITION m_position; |
|
504 STRING_POOL m_tempPool; |
|
505 STRING_POOL m_temp2Pool; |
|
506 char *m_groupConnector; |
|
507 unsigned m_groupSize; |
|
508 XML_Char m_namespaceSeparator; |
|
509 XML_Parser m_parentParser; |
|
510 #ifdef XML_DTD |
|
511 XML_Bool m_isParamEntity; |
|
512 XML_Bool m_useForeignDTD; |
|
513 enum XML_ParamEntityParsing m_paramEntityParsing; |
|
514 #endif |
|
515 }; |
|
516 |
|
517 #define MALLOC(s) ( (parser)->m_mem.malloc_fcn ( ((parser)->m_mem.allocData), (s) ) ) |
|
518 #define REALLOC(p,s) ( (parser)->m_mem.realloc_fcn ( ((parser)->m_mem.allocData), (p), (s) ) ) |
|
519 #define FREE(p) ( (parser)->m_mem.free_fcn ( ((parser)->m_mem.allocData), (p) ) ) |
|
520 |
|
521 #define userData (parser->m_userData) |
|
522 #define handlerArg (parser->m_handlerArg) |
|
523 #define startElementHandler (parser->m_startElementHandler) |
|
524 #define endElementHandler (parser->m_endElementHandler) |
|
525 #define characterDataHandler (parser->m_characterDataHandler) |
|
526 #define processingInstructionHandler \ |
|
527 (parser->m_processingInstructionHandler) |
|
528 #define commentHandler (parser->m_commentHandler) |
|
529 #define startCdataSectionHandler \ |
|
530 (parser->m_startCdataSectionHandler) |
|
531 #define endCdataSectionHandler (parser->m_endCdataSectionHandler) |
|
532 #define defaultHandler (parser->m_defaultHandler) |
|
533 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) |
|
534 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) |
|
535 #define unparsedEntityDeclHandler \ |
|
536 (parser->m_unparsedEntityDeclHandler) |
|
537 #define notationDeclHandler (parser->m_notationDeclHandler) |
|
538 #define startNamespaceDeclHandler \ |
|
539 (parser->m_startNamespaceDeclHandler) |
|
540 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) |
|
541 #define notStandaloneHandler (parser->m_notStandaloneHandler) |
|
542 #define externalEntityRefHandler \ |
|
543 (parser->m_externalEntityRefHandler) |
|
544 #define externalEntityRefHandlerArg \ |
|
545 (parser->m_externalEntityRefHandlerArg) |
|
546 #define internalEntityRefHandler \ |
|
547 (parser->m_internalEntityRefHandler) |
|
548 #define skippedEntityHandler (parser->m_skippedEntityHandler) |
|
549 #define unknownEncodingHandler (parser->m_unknownEncodingHandler) |
|
550 #define elementDeclHandler (parser->m_elementDeclHandler) |
|
551 #define attlistDeclHandler (parser->m_attlistDeclHandler) |
|
552 #define entityDeclHandler (parser->m_entityDeclHandler) |
|
553 #define xmlDeclHandler (parser->m_xmlDeclHandler) |
|
554 #define encoding (parser->m_encoding) |
|
555 #define initEncoding (parser->m_initEncoding) |
|
556 #define internalEncoding (parser->m_internalEncoding) |
|
557 #define unknownEncodingMem (parser->m_unknownEncodingMem) |
|
558 #define unknownEncodingData (parser->m_unknownEncodingData) |
|
559 #define unknownEncodingHandlerData \ |
|
560 (parser->m_unknownEncodingHandlerData) |
|
561 #define unknownEncodingRelease (parser->m_unknownEncodingRelease) |
|
562 #define protocolEncodingName (parser->m_protocolEncodingName) |
|
563 #define ns (parser->m_ns) |
|
564 #define ns_triplets (parser->m_ns_triplets) |
|
565 #define prologState (parser->m_prologState) |
|
566 #define processor (parser->m_processor) |
|
567 #define errorCode (parser->m_errorCode) |
|
568 #define eventPtr (parser->m_eventPtr) |
|
569 #define eventEndPtr (parser->m_eventEndPtr) |
|
570 #define positionPtr (parser->m_positionPtr) |
|
571 #define position (parser->m_position) |
|
572 #define openInternalEntities (parser->m_openInternalEntities) |
|
573 #define defaultExpandInternalEntities \ |
|
574 (parser->m_defaultExpandInternalEntities) |
|
575 #define tagLevel (parser->m_tagLevel) |
|
576 #define buffer (parser->m_buffer) |
|
577 #define bufferPtr (parser->m_bufferPtr) |
|
578 #define bufferEnd (parser->m_bufferEnd) |
|
579 #define parseEndByteIndex (parser->m_parseEndByteIndex) |
|
580 #define parseEndPtr (parser->m_parseEndPtr) |
|
581 #define bufferLim (parser->m_bufferLim) |
|
582 #define dataBuf (parser->m_dataBuf) |
|
583 #define dataBufEnd (parser->m_dataBufEnd) |
|
584 #define dtd (parser->m_dtd) |
|
585 #define curBase (parser->m_curBase) |
|
586 #define declEntity (parser->m_declEntity) |
|
587 #define doctypeName (parser->m_doctypeName) |
|
588 #define doctypeSysid (parser->m_doctypeSysid) |
|
589 #define doctypePubid (parser->m_doctypePubid) |
|
590 #define declAttributeType (parser->m_declAttributeType) |
|
591 #define declNotationName (parser->m_declNotationName) |
|
592 #define declNotationPublicId (parser->m_declNotationPublicId) |
|
593 #define declElementType (parser->m_declElementType) |
|
594 #define declAttributeId (parser->m_declAttributeId) |
|
595 #define declAttributeIsCdata (parser->m_declAttributeIsCdata) |
|
596 #define declAttributeIsId (parser->m_declAttributeIsId) |
|
597 #define freeTagList (parser->m_freeTagList) |
|
598 #define freeBindingList (parser->m_freeBindingList) |
|
599 #define inheritedBindings (parser->m_inheritedBindings) |
|
600 #define tagStack (parser->m_tagStack) |
|
601 #define atts (parser->m_atts) |
|
602 #define attsSize (parser->m_attsSize) |
|
603 #define nSpecifiedAtts (parser->m_nSpecifiedAtts) |
|
604 #define idAttIndex (parser->m_idAttIndex) |
|
605 #define tempPool (parser->m_tempPool) |
|
606 #define temp2Pool (parser->m_temp2Pool) |
|
607 #define groupConnector (parser->m_groupConnector) |
|
608 #define groupSize (parser->m_groupSize) |
|
609 #define namespaceSeparator (parser->m_namespaceSeparator) |
|
610 #define parentParser (parser->m_parentParser) |
|
611 #ifdef XML_DTD |
|
612 #define isParamEntity (parser->m_isParamEntity) |
|
613 #define useForeignDTD (parser->m_useForeignDTD) |
|
614 #define paramEntityParsing (parser->m_paramEntityParsing) |
|
615 #endif /* XML_DTD */ |
|
616 |
|
617 #define parsing (processor != prologInitProcessor) |
|
618 |
|
619 #ifndef SYMBIAN_MIN_SIZE |
|
620 XML_Parser |
|
621 XML_ParserCreate(const XML_Char *encodingName) |
|
622 { |
|
623 return XML_ParserCreate_MM(encodingName, NULL, NULL); |
|
624 } |
|
625 #endif // SYMBIAN_MIN_SIZE |
|
626 |
|
627 #ifndef SYMBIAN_MIN_SIZE |
|
628 XML_Parser |
|
629 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) |
|
630 { |
|
631 XML_Char tmp[2]; |
|
632 *tmp = nsSep; |
|
633 return XML_ParserCreate_MM(encodingName, NULL, tmp); |
|
634 } |
|
635 #endif // SYMBIAN_MIN_SIZE |
|
636 |
|
637 inline void* internal_malloc(void* allocData, size_t size) |
|
638 { return malloc(size); } |
|
639 |
|
640 inline void* internal_realloc(void* allocData, void* ptr, size_t size) |
|
641 { return realloc(ptr, size); } |
|
642 |
|
643 inline void internal_free(void* allocData, void* ptr) |
|
644 { free(ptr); } |
|
645 |
|
646 XML_Parser |
|
647 XML_ParserCreate_MM(const XML_Char *encodingName, |
|
648 const XML_Memory_Handling_Suite *memsuite, |
|
649 const XML_Char *nameSep) { |
|
650 XML_Parser parser; |
|
651 static const XML_Char implicitContext[] = { |
|
652 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/', |
|
653 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/', |
|
654 'X', 'M', 'L', '/', '1', '9', '9', '8', '/', |
|
655 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0' |
|
656 }; |
|
657 |
|
658 |
|
659 if (memsuite) { |
|
660 XML_Memory_Handling_Suite *mtemp; |
|
661 parser = (XML_Parser)memsuite->malloc_fcn(memsuite->allocData, sizeof(struct XML_ParserStruct)); |
|
662 if (parser != NULL) { |
|
663 mtemp = &(parser->m_mem); |
|
664 mtemp->malloc_fcn = memsuite->malloc_fcn; |
|
665 mtemp->realloc_fcn = memsuite->realloc_fcn; |
|
666 mtemp->free_fcn = memsuite->free_fcn; |
|
667 mtemp->allocData = memsuite->allocData; |
|
668 |
|
669 } |
|
670 } |
|
671 else { |
|
672 XML_Memory_Handling_Suite *mtemp; |
|
673 parser = (XML_Parser)internal_malloc(0, sizeof(struct XML_ParserStruct)); |
|
674 if (parser != NULL) { |
|
675 mtemp = &(parser->m_mem); |
|
676 mtemp->malloc_fcn = internal_malloc; |
|
677 mtemp->realloc_fcn = internal_realloc; |
|
678 mtemp->free_fcn = internal_free; |
|
679 mtemp->allocData = 0; |
|
680 } |
|
681 } |
|
682 |
|
683 if (!parser) |
|
684 return parser; |
|
685 |
|
686 buffer = NULL; |
|
687 bufferLim = NULL; |
|
688 |
|
689 attsSize = INIT_ATTS_SIZE; |
|
690 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); |
|
691 if (atts == NULL) { |
|
692 FREE(parser); |
|
693 return NULL; |
|
694 } |
|
695 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); |
|
696 if (dataBuf == NULL) { |
|
697 FREE(atts); |
|
698 FREE(parser); |
|
699 return NULL; |
|
700 } |
|
701 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; |
|
702 |
|
703 freeBindingList = NULL; |
|
704 freeTagList = NULL; |
|
705 |
|
706 groupSize = 0; |
|
707 groupConnector = NULL; |
|
708 |
|
709 unknownEncodingHandler = NULL; |
|
710 unknownEncodingHandlerData = NULL; |
|
711 |
|
712 namespaceSeparator = '!'; |
|
713 ns = XML_FALSE; |
|
714 ns_triplets = XML_FALSE; |
|
715 |
|
716 poolInit(&tempPool, &(parser->m_mem)); |
|
717 poolInit(&temp2Pool, &(parser->m_mem)); |
|
718 parserInit(parser, encodingName); |
|
719 dtdInit(&dtd, parser); |
|
720 |
|
721 if (!atts || !dataBuf || (encodingName && !protocolEncodingName)) { |
|
722 XML_ParserFree(parser); |
|
723 return NULL; |
|
724 } |
|
725 |
|
726 if (nameSep) { |
|
727 ns = XML_TRUE; |
|
728 internalEncoding = XmlGetInternalEncodingNS(); |
|
729 namespaceSeparator = *nameSep; |
|
730 |
|
731 if (!setContext(parser, implicitContext)) { |
|
732 XML_ParserFree(parser); |
|
733 return NULL; |
|
734 } |
|
735 } |
|
736 else { |
|
737 internalEncoding = XmlGetInternalEncoding(); |
|
738 } |
|
739 |
|
740 return parser; |
|
741 } |
|
742 |
|
743 static void FASTCALL |
|
744 parserInit(XML_Parser parser, const XML_Char *encodingName) |
|
745 { |
|
746 processor = prologInitProcessor; |
|
747 XmlPrologStateInit(&prologState); |
|
748 protocolEncodingName = (encodingName != NULL |
|
749 ? poolCopyString(&tempPool, encodingName) |
|
750 : NULL); |
|
751 curBase = NULL; |
|
752 XmlInitEncoding(&initEncoding, &encoding, 0); |
|
753 userData = NULL; |
|
754 handlerArg = NULL; |
|
755 startElementHandler = NULL; |
|
756 endElementHandler = NULL; |
|
757 characterDataHandler = NULL; |
|
758 processingInstructionHandler = NULL; |
|
759 commentHandler = NULL; |
|
760 startCdataSectionHandler = NULL; |
|
761 endCdataSectionHandler = NULL; |
|
762 defaultHandler = NULL; |
|
763 startDoctypeDeclHandler = NULL; |
|
764 endDoctypeDeclHandler = NULL; |
|
765 unparsedEntityDeclHandler = NULL; |
|
766 notationDeclHandler = NULL; |
|
767 startNamespaceDeclHandler = NULL; |
|
768 endNamespaceDeclHandler = NULL; |
|
769 notStandaloneHandler = NULL; |
|
770 externalEntityRefHandler = NULL; |
|
771 externalEntityRefHandlerArg = parser; |
|
772 skippedEntityHandler = NULL; |
|
773 elementDeclHandler = NULL; |
|
774 attlistDeclHandler = NULL; |
|
775 entityDeclHandler = NULL; |
|
776 xmlDeclHandler = NULL; |
|
777 bufferPtr = buffer; |
|
778 bufferEnd = buffer; |
|
779 parseEndByteIndex = 0; |
|
780 parseEndPtr = NULL; |
|
781 declElementType = NULL; |
|
782 declAttributeId = NULL; |
|
783 declEntity = NULL; |
|
784 doctypeName = NULL; |
|
785 doctypeSysid = NULL; |
|
786 doctypePubid = NULL; |
|
787 declAttributeType = NULL; |
|
788 declNotationName = NULL; |
|
789 declNotationPublicId = NULL; |
|
790 declAttributeIsCdata = XML_FALSE; |
|
791 declAttributeIsId = XML_FALSE; |
|
792 memset(&position, 0, sizeof(POSITION)); |
|
793 errorCode = XML_ERROR_NONE; |
|
794 eventPtr = NULL; |
|
795 eventEndPtr = NULL; |
|
796 positionPtr = NULL; |
|
797 openInternalEntities = 0; |
|
798 defaultExpandInternalEntities = XML_TRUE; |
|
799 tagLevel = 0; |
|
800 tagStack = NULL; |
|
801 inheritedBindings = NULL; |
|
802 nSpecifiedAtts = 0; |
|
803 unknownEncodingMem = NULL; |
|
804 unknownEncodingRelease = NULL; |
|
805 unknownEncodingData = NULL; |
|
806 parentParser = NULL; |
|
807 #ifdef XML_DTD |
|
808 isParamEntity = XML_FALSE; |
|
809 useForeignDTD = XML_FALSE; |
|
810 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; |
|
811 #endif |
|
812 } |
|
813 |
|
814 /* moves list of bindings to freeBindingList */ |
|
815 static void FASTCALL |
|
816 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) |
|
817 { |
|
818 while (bindings) { |
|
819 BINDING *b = bindings; |
|
820 bindings = bindings->nextTagBinding; |
|
821 b->nextTagBinding = freeBindingList; |
|
822 freeBindingList = b; |
|
823 } |
|
824 } |
|
825 |
|
826 XML_Bool |
|
827 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) |
|
828 { |
|
829 TAG *tStk; |
|
830 if (parentParser) |
|
831 return XML_FALSE; |
|
832 /* move tagStack to freeTagList */ |
|
833 tStk = tagStack; |
|
834 while (tStk) { |
|
835 TAG *tag = tStk; |
|
836 tStk = tStk->parent; |
|
837 tag->parent = freeTagList; |
|
838 moveToFreeBindingList(parser, tag->bindings); |
|
839 tag->bindings = NULL; |
|
840 freeTagList = tag; |
|
841 } |
|
842 moveToFreeBindingList(parser, inheritedBindings); |
|
843 if (unknownEncodingMem) |
|
844 FREE(unknownEncodingMem); |
|
845 if (unknownEncodingRelease) |
|
846 unknownEncodingRelease(unknownEncodingData); |
|
847 poolClear(&tempPool); |
|
848 poolClear(&temp2Pool); |
|
849 parserInit(parser, encodingName); |
|
850 dtdReset(&dtd, parser); |
|
851 return XML_TRUE; |
|
852 } |
|
853 |
|
854 #ifndef SYMBIAN_MIN_SIZE |
|
855 int |
|
856 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) |
|
857 { |
|
858 /* block after XML_Parse()/XML_ParseBuffer() has been called */ |
|
859 if (parsing) |
|
860 return 0; |
|
861 if (encodingName == NULL) |
|
862 protocolEncodingName = NULL; |
|
863 else { |
|
864 protocolEncodingName = poolCopyString(&tempPool, encodingName); |
|
865 if (!protocolEncodingName) |
|
866 return 0; |
|
867 } |
|
868 return 1; |
|
869 } |
|
870 #endif // SYMBIAN_MIN_SIZE |
|
871 |
|
872 #ifndef SYMBIAN_MIN_SIZE |
|
873 XML_Parser |
|
874 XML_ExternalEntityParserCreate(XML_Parser oldParser, |
|
875 const XML_Char *context, |
|
876 const XML_Char *encodingName) |
|
877 { |
|
878 XML_Parser parser = oldParser; |
|
879 DTD *oldDtd = &dtd; |
|
880 XML_StartElementHandler oldStartElementHandler = startElementHandler; |
|
881 XML_EndElementHandler oldEndElementHandler = endElementHandler; |
|
882 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; |
|
883 XML_ProcessingInstructionHandler oldProcessingInstructionHandler |
|
884 = processingInstructionHandler; |
|
885 XML_CommentHandler oldCommentHandler = commentHandler; |
|
886 XML_StartCdataSectionHandler oldStartCdataSectionHandler |
|
887 = startCdataSectionHandler; |
|
888 XML_EndCdataSectionHandler oldEndCdataSectionHandler |
|
889 = endCdataSectionHandler; |
|
890 XML_DefaultHandler oldDefaultHandler = defaultHandler; |
|
891 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler |
|
892 = unparsedEntityDeclHandler; |
|
893 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; |
|
894 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler |
|
895 = startNamespaceDeclHandler; |
|
896 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler |
|
897 = endNamespaceDeclHandler; |
|
898 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; |
|
899 XML_ExternalEntityRefHandler oldExternalEntityRefHandler |
|
900 = externalEntityRefHandler; |
|
901 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; |
|
902 XML_UnknownEncodingHandler oldUnknownEncodingHandler |
|
903 = unknownEncodingHandler; |
|
904 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; |
|
905 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; |
|
906 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; |
|
907 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; |
|
908 ELEMENT_TYPE * oldDeclElementType = declElementType; |
|
909 |
|
910 void *oldUserData = userData; |
|
911 void *oldHandlerArg = handlerArg; |
|
912 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; |
|
913 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; |
|
914 #ifdef XML_DTD |
|
915 int oldParamEntityParsing = paramEntityParsing; |
|
916 int oldInEntityValue = prologState.inEntityValue; |
|
917 #endif |
|
918 XML_Bool oldns_triplets = ns_triplets; |
|
919 |
|
920 /* Note that the magical uses of the pre-processor to make field |
|
921 access look more like C++ require that `parser' be overwritten |
|
922 here. This makes this function more painful to follow than it |
|
923 would be otherwise. |
|
924 */ |
|
925 if (ns) { |
|
926 XML_Char tmp[2]; |
|
927 |
|
928 *tmp = namespaceSeparator; |
|
929 parser = XML_ParserCreate_MM(encodingName, &parser->m_mem, |
|
930 tmp); |
|
931 } |
|
932 else { |
|
933 parser = XML_ParserCreate_MM(encodingName, &parser->m_mem, |
|
934 NULL); |
|
935 } |
|
936 |
|
937 if (!parser) |
|
938 return NULL; |
|
939 |
|
940 startElementHandler = oldStartElementHandler; |
|
941 endElementHandler = oldEndElementHandler; |
|
942 characterDataHandler = oldCharacterDataHandler; |
|
943 processingInstructionHandler = oldProcessingInstructionHandler; |
|
944 commentHandler = oldCommentHandler; |
|
945 startCdataSectionHandler = oldStartCdataSectionHandler; |
|
946 endCdataSectionHandler = oldEndCdataSectionHandler; |
|
947 defaultHandler = oldDefaultHandler; |
|
948 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; |
|
949 notationDeclHandler = oldNotationDeclHandler; |
|
950 startNamespaceDeclHandler = oldStartNamespaceDeclHandler; |
|
951 endNamespaceDeclHandler = oldEndNamespaceDeclHandler; |
|
952 notStandaloneHandler = oldNotStandaloneHandler; |
|
953 externalEntityRefHandler = oldExternalEntityRefHandler; |
|
954 skippedEntityHandler = oldSkippedEntityHandler; |
|
955 unknownEncodingHandler = oldUnknownEncodingHandler; |
|
956 elementDeclHandler = oldElementDeclHandler; |
|
957 attlistDeclHandler = oldAttlistDeclHandler; |
|
958 entityDeclHandler = oldEntityDeclHandler; |
|
959 xmlDeclHandler = oldXmlDeclHandler; |
|
960 declElementType = oldDeclElementType; |
|
961 userData = oldUserData; |
|
962 if (oldUserData == oldHandlerArg) |
|
963 handlerArg = userData; |
|
964 else |
|
965 handlerArg = parser; |
|
966 if (oldExternalEntityRefHandlerArg != oldParser) |
|
967 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; |
|
968 defaultExpandInternalEntities = oldDefaultExpandInternalEntities; |
|
969 ns_triplets = oldns_triplets; |
|
970 parentParser = oldParser; |
|
971 #ifdef XML_DTD |
|
972 paramEntityParsing = oldParamEntityParsing; |
|
973 prologState.inEntityValue = oldInEntityValue; |
|
974 if (context) { |
|
975 #endif /* XML_DTD */ |
|
976 if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) { |
|
977 XML_ParserFree(parser); |
|
978 return NULL; |
|
979 } |
|
980 processor = externalEntityInitProcessor; |
|
981 #ifdef XML_DTD |
|
982 } |
|
983 else { |
|
984 dtdSwap(&dtd, oldDtd); |
|
985 isParamEntity = XML_TRUE; |
|
986 XmlPrologStateInitExternalEntity(&prologState); |
|
987 processor = externalParEntInitProcessor; |
|
988 } |
|
989 #endif /* XML_DTD */ |
|
990 return parser; |
|
991 } |
|
992 #endif // SYMBIAN_MIN_SIZE |
|
993 |
|
994 static void FASTCALL |
|
995 destroyBindings(BINDING *bindings, XML_Parser parser) |
|
996 { |
|
997 for (;;) { |
|
998 BINDING *b = bindings; |
|
999 if (!b) |
|
1000 break; |
|
1001 bindings = b->nextTagBinding; |
|
1002 FREE(b->uri); |
|
1003 FREE(b); |
|
1004 } |
|
1005 } |
|
1006 |
|
1007 void |
|
1008 XML_ParserFree(XML_Parser parser) |
|
1009 { |
|
1010 for (;;) { |
|
1011 TAG *p; |
|
1012 if (tagStack == 0) { |
|
1013 if (freeTagList == NULL) |
|
1014 break; |
|
1015 tagStack = freeTagList; |
|
1016 freeTagList = NULL; |
|
1017 } |
|
1018 p = tagStack; |
|
1019 tagStack = tagStack->parent; |
|
1020 FREE(p->buf); |
|
1021 destroyBindings(p->bindings, parser); |
|
1022 FREE(p); |
|
1023 } |
|
1024 destroyBindings(freeBindingList, parser); |
|
1025 destroyBindings(inheritedBindings, parser); |
|
1026 poolDestroy(&tempPool); |
|
1027 poolDestroy(&temp2Pool); |
|
1028 #ifdef XML_DTD |
|
1029 if (isParamEntity) |
|
1030 dtdSwap(&dtd, &parentParser->m_dtd); |
|
1031 #endif /* XML_DTD */ |
|
1032 dtdDestroy(&dtd, parser); |
|
1033 FREE((void *)atts); |
|
1034 if (groupConnector) |
|
1035 FREE(groupConnector); |
|
1036 if (buffer) |
|
1037 FREE(buffer); |
|
1038 FREE(dataBuf); |
|
1039 if (unknownEncodingMem) |
|
1040 FREE(unknownEncodingMem); |
|
1041 if (unknownEncodingRelease) |
|
1042 unknownEncodingRelease(unknownEncodingData); |
|
1043 FREE(parser); |
|
1044 } |
|
1045 |
|
1046 #ifndef SYMBIAN_MIN_SIZE |
|
1047 void |
|
1048 XML_UseParserAsHandlerArg(XML_Parser parser) |
|
1049 { |
|
1050 handlerArg = parser; |
|
1051 } |
|
1052 |
|
1053 enum XML_Error |
|
1054 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) |
|
1055 { |
|
1056 #ifdef XML_DTD |
|
1057 /* block after XML_Parse()/XML_ParseBuffer() has been called */ |
|
1058 if (parsing) |
|
1059 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; |
|
1060 useForeignDTD = useDTD; |
|
1061 return XML_ERROR_NONE; |
|
1062 #else |
|
1063 return XML_ERROR_FEATURE_REQUIRES_XML_DTD; |
|
1064 #endif |
|
1065 } |
|
1066 #endif // SYMBIAN_MIN_SIZE |
|
1067 |
|
1068 void |
|
1069 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) |
|
1070 { |
|
1071 /* block after XML_Parse()/XML_ParseBuffer() has been called */ |
|
1072 if (parsing) |
|
1073 return; |
|
1074 ns_triplets = (XML_Bool)(do_nst ? XML_TRUE : XML_FALSE); |
|
1075 } |
|
1076 |
|
1077 void |
|
1078 XML_SetUserData(XML_Parser parser, void *p) |
|
1079 { |
|
1080 if (handlerArg == userData) |
|
1081 handlerArg = userData = p; |
|
1082 else |
|
1083 userData = p; |
|
1084 } |
|
1085 |
|
1086 #ifndef SYMBIAN_MIN_SIZE |
|
1087 int |
|
1088 XML_SetBase(XML_Parser parser, const XML_Char *p) |
|
1089 { |
|
1090 if (p) { |
|
1091 p = poolCopyString(&dtd.pool, p); |
|
1092 if (!p) |
|
1093 return 0; |
|
1094 curBase = p; |
|
1095 } |
|
1096 else |
|
1097 curBase = NULL; |
|
1098 return 1; |
|
1099 } |
|
1100 |
|
1101 const XML_Char * |
|
1102 XML_GetBase(XML_Parser parser) |
|
1103 { |
|
1104 return curBase; |
|
1105 } |
|
1106 |
|
1107 int |
|
1108 XML_GetSpecifiedAttributeCount(XML_Parser parser) |
|
1109 { |
|
1110 return nSpecifiedAtts; |
|
1111 } |
|
1112 |
|
1113 int |
|
1114 XML_GetIdAttributeIndex(XML_Parser parser) |
|
1115 { |
|
1116 return idAttIndex; |
|
1117 } |
|
1118 #endif // SYMBIAN_MIN_SIZE |
|
1119 |
|
1120 void |
|
1121 XML_SetElementHandler(XML_Parser parser, |
|
1122 XML_StartElementHandler start, |
|
1123 XML_EndElementHandler end) |
|
1124 { |
|
1125 startElementHandler = start; |
|
1126 endElementHandler = end; |
|
1127 } |
|
1128 |
|
1129 #ifndef SYMBIAN_MIN_SIZE |
|
1130 void |
|
1131 XML_SetStartElementHandler(XML_Parser parser, |
|
1132 XML_StartElementHandler start) { |
|
1133 startElementHandler = start; |
|
1134 } |
|
1135 |
|
1136 void |
|
1137 XML_SetEndElementHandler(XML_Parser parser, |
|
1138 XML_EndElementHandler end) { |
|
1139 endElementHandler = end; |
|
1140 } |
|
1141 #endif // SYMBIAN_MIN_SIZE |
|
1142 |
|
1143 void |
|
1144 XML_SetCharacterDataHandler(XML_Parser parser, |
|
1145 XML_CharacterDataHandler handler) |
|
1146 { |
|
1147 characterDataHandler = handler; |
|
1148 } |
|
1149 |
|
1150 void |
|
1151 XML_SetProcessingInstructionHandler(XML_Parser parser, |
|
1152 XML_ProcessingInstructionHandler handler) |
|
1153 { |
|
1154 processingInstructionHandler = handler; |
|
1155 } |
|
1156 |
|
1157 #ifndef SYMBIAN_MIN_SIZE |
|
1158 void |
|
1159 XML_SetCommentHandler(XML_Parser parser, |
|
1160 XML_CommentHandler handler) |
|
1161 { |
|
1162 commentHandler = handler; |
|
1163 } |
|
1164 |
|
1165 void |
|
1166 XML_SetCdataSectionHandler(XML_Parser parser, |
|
1167 XML_StartCdataSectionHandler start, |
|
1168 XML_EndCdataSectionHandler end) |
|
1169 { |
|
1170 startCdataSectionHandler = start; |
|
1171 endCdataSectionHandler = end; |
|
1172 } |
|
1173 |
|
1174 void |
|
1175 XML_SetStartCdataSectionHandler(XML_Parser parser, |
|
1176 XML_StartCdataSectionHandler start) { |
|
1177 startCdataSectionHandler = start; |
|
1178 } |
|
1179 |
|
1180 void |
|
1181 XML_SetEndCdataSectionHandler(XML_Parser parser, |
|
1182 XML_EndCdataSectionHandler end) { |
|
1183 endCdataSectionHandler = end; |
|
1184 } |
|
1185 |
|
1186 void |
|
1187 XML_SetDefaultHandler(XML_Parser parser, |
|
1188 XML_DefaultHandler handler) |
|
1189 { |
|
1190 defaultHandler = handler; |
|
1191 defaultExpandInternalEntities = XML_FALSE; |
|
1192 } |
|
1193 |
|
1194 void |
|
1195 XML_SetDefaultHandlerExpand(XML_Parser parser, |
|
1196 XML_DefaultHandler handler) |
|
1197 { |
|
1198 defaultHandler = handler; |
|
1199 defaultExpandInternalEntities = XML_TRUE; |
|
1200 } |
|
1201 |
|
1202 void |
|
1203 XML_SetDoctypeDeclHandler(XML_Parser parser, |
|
1204 XML_StartDoctypeDeclHandler start, |
|
1205 XML_EndDoctypeDeclHandler end) |
|
1206 { |
|
1207 startDoctypeDeclHandler = start; |
|
1208 endDoctypeDeclHandler = end; |
|
1209 } |
|
1210 |
|
1211 void |
|
1212 XML_SetStartDoctypeDeclHandler(XML_Parser parser, |
|
1213 XML_StartDoctypeDeclHandler start) { |
|
1214 startDoctypeDeclHandler = start; |
|
1215 } |
|
1216 |
|
1217 void |
|
1218 XML_SetEndDoctypeDeclHandler(XML_Parser parser, |
|
1219 XML_EndDoctypeDeclHandler end) { |
|
1220 endDoctypeDeclHandler = end; |
|
1221 } |
|
1222 |
|
1223 void |
|
1224 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, |
|
1225 XML_UnparsedEntityDeclHandler handler) |
|
1226 { |
|
1227 unparsedEntityDeclHandler = handler; |
|
1228 } |
|
1229 |
|
1230 void |
|
1231 XML_SetNotationDeclHandler(XML_Parser parser, |
|
1232 XML_NotationDeclHandler handler) |
|
1233 { |
|
1234 notationDeclHandler = handler; |
|
1235 } |
|
1236 #endif // SYMBIAN_MIN_SIZE |
|
1237 |
|
1238 void |
|
1239 XML_SetNamespaceDeclHandler(XML_Parser parser, |
|
1240 XML_StartNamespaceDeclHandler start, |
|
1241 XML_EndNamespaceDeclHandler end) |
|
1242 { |
|
1243 startNamespaceDeclHandler = start; |
|
1244 endNamespaceDeclHandler = end; |
|
1245 } |
|
1246 |
|
1247 #ifndef SYMBIAN_MIN_SIZE |
|
1248 void |
|
1249 XML_SetStartNamespaceDeclHandler(XML_Parser parser, |
|
1250 XML_StartNamespaceDeclHandler start) { |
|
1251 startNamespaceDeclHandler = start; |
|
1252 } |
|
1253 |
|
1254 void |
|
1255 XML_SetEndNamespaceDeclHandler(XML_Parser parser, |
|
1256 XML_EndNamespaceDeclHandler end) { |
|
1257 endNamespaceDeclHandler = end; |
|
1258 } |
|
1259 |
|
1260 void |
|
1261 XML_SetNotStandaloneHandler(XML_Parser parser, |
|
1262 XML_NotStandaloneHandler handler) |
|
1263 { |
|
1264 notStandaloneHandler = handler; |
|
1265 } |
|
1266 #endif // SYMBIAN_MIN_SIZE |
|
1267 |
|
1268 void |
|
1269 XML_SetExternalEntityRefHandler(XML_Parser parser, |
|
1270 XML_ExternalEntityRefHandler handler) |
|
1271 { |
|
1272 externalEntityRefHandler = handler; |
|
1273 } |
|
1274 |
|
1275 #ifndef SYMBIAN_MIN_SIZE |
|
1276 void |
|
1277 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) |
|
1278 { |
|
1279 if (arg) |
|
1280 externalEntityRefHandlerArg = arg; |
|
1281 else |
|
1282 externalEntityRefHandlerArg = parser; |
|
1283 } |
|
1284 #endif // SYMBIAN_MIN_SIZE |
|
1285 |
|
1286 void |
|
1287 XML_SetSkippedEntityHandler(XML_Parser parser, |
|
1288 XML_SkippedEntityHandler handler) |
|
1289 { |
|
1290 skippedEntityHandler = handler; |
|
1291 } |
|
1292 |
|
1293 #ifndef SYMBIAN_MIN_SIZE |
|
1294 void |
|
1295 XML_SetUnknownEncodingHandler(XML_Parser parser, |
|
1296 XML_UnknownEncodingHandler handler, |
|
1297 void *data) |
|
1298 { |
|
1299 unknownEncodingHandler = handler; |
|
1300 unknownEncodingHandlerData = data; |
|
1301 } |
|
1302 |
|
1303 void |
|
1304 XML_SetElementDeclHandler(XML_Parser parser, |
|
1305 XML_ElementDeclHandler eldecl) |
|
1306 { |
|
1307 elementDeclHandler = eldecl; |
|
1308 } |
|
1309 |
|
1310 void |
|
1311 XML_SetAttlistDeclHandler(XML_Parser parser, |
|
1312 XML_AttlistDeclHandler attdecl) |
|
1313 { |
|
1314 attlistDeclHandler = attdecl; |
|
1315 } |
|
1316 |
|
1317 void |
|
1318 XML_SetEntityDeclHandler(XML_Parser parser, |
|
1319 XML_EntityDeclHandler handler) |
|
1320 { |
|
1321 entityDeclHandler = handler; |
|
1322 } |
|
1323 #endif // SYMBIAN_MIN_SIZE |
|
1324 |
|
1325 void |
|
1326 XML_SetXmlDeclHandler(XML_Parser parser, |
|
1327 XML_XmlDeclHandler handler) { |
|
1328 xmlDeclHandler = handler; |
|
1329 } |
|
1330 |
|
1331 #ifndef SYMBIAN_MIN_SIZE |
|
1332 int |
|
1333 XML_SetParamEntityParsing(XML_Parser parser, |
|
1334 enum XML_ParamEntityParsing peParsing) |
|
1335 { |
|
1336 /* block after XML_Parse()/XML_ParseBuffer() has been called */ |
|
1337 if (parsing) |
|
1338 return 0; |
|
1339 #ifdef XML_DTD |
|
1340 paramEntityParsing = peParsing; |
|
1341 return 1; |
|
1342 #else |
|
1343 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; |
|
1344 #endif |
|
1345 } |
|
1346 |
|
1347 enum XML_Status |
|
1348 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) |
|
1349 { |
|
1350 if (len == 0) { |
|
1351 if (!isFinal) |
|
1352 return XML_STATUS_OK; |
|
1353 positionPtr = bufferPtr; |
|
1354 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); |
|
1355 if (errorCode == XML_ERROR_NONE) |
|
1356 return XML_STATUS_OK; |
|
1357 eventEndPtr = eventPtr; |
|
1358 processor = errorProcessor; |
|
1359 return XML_STATUS_ERROR; |
|
1360 } |
|
1361 #ifndef XML_CONTEXT_BYTES |
|
1362 else if (bufferPtr == bufferEnd) { |
|
1363 const char *end; |
|
1364 int nLeftOver; |
|
1365 parseEndByteIndex += len; |
|
1366 positionPtr = s; |
|
1367 if (isFinal) { |
|
1368 errorCode = processor(parser, s, parseEndPtr = s + len, 0); |
|
1369 if (errorCode == XML_ERROR_NONE) |
|
1370 return XML_STATUS_OK; |
|
1371 eventEndPtr = eventPtr; |
|
1372 processor = errorProcessor; |
|
1373 return XML_STATUS_ERROR; |
|
1374 } |
|
1375 errorCode = processor(parser, s, parseEndPtr = s + len, &end); |
|
1376 if (errorCode != XML_ERROR_NONE) { |
|
1377 eventEndPtr = eventPtr; |
|
1378 processor = errorProcessor; |
|
1379 return XML_STATUS_ERROR; |
|
1380 } |
|
1381 XmlUpdatePosition(encoding, positionPtr, end, &position); |
|
1382 nLeftOver = s + len - end; |
|
1383 if (nLeftOver) { |
|
1384 if (buffer == NULL || nLeftOver > bufferLim - buffer) { |
|
1385 /* FIXME avoid integer overflow */ |
|
1386 char *temp; |
|
1387 temp = buffer == NULL ? MALLOC(len * 2) : REALLOC(buffer, len * 2); |
|
1388 if (temp == NULL) { |
|
1389 errorCode = XML_ERROR_NO_MEMORY; |
|
1390 return XML_STATUS_ERROR; |
|
1391 } |
|
1392 buffer = temp; |
|
1393 if (!buffer) { |
|
1394 errorCode = XML_ERROR_NO_MEMORY; |
|
1395 eventPtr = eventEndPtr = NULL; |
|
1396 processor = errorProcessor; |
|
1397 return XML_STATUS_ERROR; |
|
1398 } |
|
1399 bufferLim = buffer + len * 2; |
|
1400 } |
|
1401 memcpy(buffer, end, nLeftOver); |
|
1402 bufferPtr = buffer; |
|
1403 bufferEnd = buffer + nLeftOver; |
|
1404 } |
|
1405 return XML_STATUS_OK; |
|
1406 } |
|
1407 #endif /* not defined XML_CONTEXT_BYTES */ |
|
1408 else { |
|
1409 void *buff = XML_GetBuffer(parser, len); |
|
1410 if (buff == NULL) |
|
1411 return XML_STATUS_ERROR; |
|
1412 else { |
|
1413 memcpy(buff, s, len); |
|
1414 return XML_ParseBuffer(parser, len, isFinal); |
|
1415 } |
|
1416 } |
|
1417 } |
|
1418 #endif // SYMBIAN_MIN_SIZE |
|
1419 |
|
1420 enum XML_Status |
|
1421 XML_ParseBuffer(XML_Parser parser, int len, int isFinal) |
|
1422 { |
|
1423 const char *start = bufferPtr; |
|
1424 positionPtr = start; |
|
1425 bufferEnd += len; |
|
1426 parseEndByteIndex += len; |
|
1427 errorCode = processor(parser, start, parseEndPtr = bufferEnd, |
|
1428 isFinal ? (const char **)NULL : &bufferPtr); |
|
1429 if (errorCode == XML_ERROR_NONE) { |
|
1430 if (!isFinal) |
|
1431 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); |
|
1432 return XML_STATUS_OK; |
|
1433 } |
|
1434 else { |
|
1435 eventEndPtr = eventPtr; |
|
1436 processor = errorProcessor; |
|
1437 return XML_STATUS_ERROR; |
|
1438 } |
|
1439 } |
|
1440 |
|
1441 void * |
|
1442 XML_GetBuffer(XML_Parser parser, int len) |
|
1443 { |
|
1444 if (len > bufferLim - bufferEnd) { |
|
1445 /* FIXME avoid integer overflow */ |
|
1446 int neededSize = len + (bufferEnd - bufferPtr); |
|
1447 #ifdef XML_CONTEXT_BYTES |
|
1448 int keep = bufferPtr - buffer; |
|
1449 |
|
1450 if (keep > XML_CONTEXT_BYTES) |
|
1451 keep = XML_CONTEXT_BYTES; |
|
1452 neededSize += keep; |
|
1453 #endif /* defined XML_CONTEXT_BYTES */ |
|
1454 if (neededSize <= bufferLim - buffer) { |
|
1455 #ifdef XML_CONTEXT_BYTES |
|
1456 if (keep < bufferPtr - buffer) { |
|
1457 int offset = (bufferPtr - buffer) - keep; |
|
1458 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); |
|
1459 bufferEnd -= offset; |
|
1460 bufferPtr -= offset; |
|
1461 } |
|
1462 #else |
|
1463 memmove(buffer, bufferPtr, bufferEnd - bufferPtr); |
|
1464 bufferEnd = buffer + (bufferEnd - bufferPtr); |
|
1465 bufferPtr = buffer; |
|
1466 #endif /* not defined XML_CONTEXT_BYTES */ |
|
1467 } |
|
1468 else { |
|
1469 char *newBuf; |
|
1470 int bufferSize = bufferLim - bufferPtr; |
|
1471 // If the XML file is Very Big and corrupt,then bufferSize would increase drastically |
|
1472 //as the bufferLim incrases and BufferPtr doesnt move.Hence To Avoid XML_ERROR_NO_MEMORY |
|
1473 //the bufferPtr is set to bufferEnd and bufferSize is controlled/Reset.The UpperLimit for bufferSize for |
|
1474 // Wrong Parsed buffer has been set to 8KB. |
|
1475 if(bufferSize>=0X2000) |
|
1476 { |
|
1477 bufferPtr=bufferEnd; |
|
1478 bufferSize=2048; |
|
1479 newBuf = (char *)MALLOC(bufferSize); |
|
1480 if (newBuf == 0) |
|
1481 { |
|
1482 errorCode = XML_ERROR_NO_MEMORY; |
|
1483 return NULL; |
|
1484 } |
|
1485 } |
|
1486 else |
|
1487 { |
|
1488 if (bufferSize == 0) |
|
1489 bufferSize = INIT_BUFFER_SIZE; |
|
1490 do { |
|
1491 bufferSize *= 2; |
|
1492 } while (bufferSize < neededSize); |
|
1493 newBuf = (char *)MALLOC(bufferSize); |
|
1494 if (newBuf == 0) { |
|
1495 errorCode = XML_ERROR_NO_MEMORY; |
|
1496 return NULL; |
|
1497 } |
|
1498 |
|
1499 } |
|
1500 bufferLim = newBuf + bufferSize; |
|
1501 #ifdef XML_CONTEXT_BYTES |
|
1502 if (bufferPtr) { |
|
1503 int keep = bufferPtr - buffer; |
|
1504 if (keep > XML_CONTEXT_BYTES) |
|
1505 keep = XML_CONTEXT_BYTES; |
|
1506 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); |
|
1507 FREE(buffer); |
|
1508 buffer = newBuf; |
|
1509 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; |
|
1510 bufferPtr = buffer + keep; |
|
1511 } |
|
1512 else { |
|
1513 bufferEnd = newBuf + (bufferEnd - bufferPtr); |
|
1514 bufferPtr = buffer = newBuf; |
|
1515 } |
|
1516 #else |
|
1517 if (bufferPtr) { |
|
1518 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); |
|
1519 FREE(buffer); |
|
1520 } |
|
1521 bufferEnd = newBuf + (bufferEnd - bufferPtr); |
|
1522 bufferPtr = buffer = newBuf; |
|
1523 #endif /* not defined XML_CONTEXT_BYTES */ |
|
1524 } |
|
1525 } |
|
1526 return bufferEnd; |
|
1527 } |
|
1528 |
|
1529 enum XML_Error |
|
1530 XML_GetErrorCode(XML_Parser parser) |
|
1531 { |
|
1532 return errorCode; |
|
1533 } |
|
1534 |
|
1535 #ifndef SYMBIAN_MIN_SIZE |
|
1536 long |
|
1537 XML_GetCurrentByteIndex(XML_Parser parser) |
|
1538 { |
|
1539 if (eventPtr) |
|
1540 return parseEndByteIndex - (parseEndPtr - eventPtr); |
|
1541 return -1; |
|
1542 } |
|
1543 |
|
1544 int |
|
1545 XML_GetCurrentByteCount(XML_Parser parser) |
|
1546 { |
|
1547 if (eventEndPtr && eventPtr) |
|
1548 return eventEndPtr - eventPtr; |
|
1549 return 0; |
|
1550 } |
|
1551 |
|
1552 const char * |
|
1553 XML_GetInputContext(XML_Parser parser, int *offset, int *size) |
|
1554 { |
|
1555 #ifdef XML_CONTEXT_BYTES |
|
1556 if (eventPtr && buffer) { |
|
1557 *offset = eventPtr - buffer; |
|
1558 *size = bufferEnd - buffer; |
|
1559 return buffer; |
|
1560 } |
|
1561 #endif /* defined XML_CONTEXT_BYTES */ |
|
1562 return (char *) 0; |
|
1563 } |
|
1564 |
|
1565 int |
|
1566 XML_GetCurrentLineNumber(XML_Parser parser) |
|
1567 { |
|
1568 if (eventPtr) { |
|
1569 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); |
|
1570 positionPtr = eventPtr; |
|
1571 } |
|
1572 return position.lineNumber + 1; |
|
1573 } |
|
1574 |
|
1575 int |
|
1576 XML_GetCurrentColumnNumber(XML_Parser parser) |
|
1577 { |
|
1578 if (eventPtr) { |
|
1579 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); |
|
1580 positionPtr = eventPtr; |
|
1581 } |
|
1582 return position.columnNumber; |
|
1583 } |
|
1584 |
|
1585 void |
|
1586 XML_DefaultCurrent(XML_Parser parser) |
|
1587 { |
|
1588 if (defaultHandler) { |
|
1589 if (openInternalEntities) |
|
1590 reportDefault(parser, |
|
1591 internalEncoding, |
|
1592 openInternalEntities->internalEventPtr, |
|
1593 openInternalEntities->internalEventEndPtr); |
|
1594 else |
|
1595 reportDefault(parser, encoding, eventPtr, eventEndPtr); |
|
1596 } |
|
1597 } |
|
1598 |
|
1599 const XML_LChar * |
|
1600 XML_ErrorString(enum XML_Error code) |
|
1601 { |
|
1602 static const XML_LChar *const message[] = { |
|
1603 0, |
|
1604 XML_L("out of memory"), |
|
1605 XML_L("syntax error"), |
|
1606 XML_L("no element found"), |
|
1607 XML_L("not well-formed (invalid token)"), |
|
1608 XML_L("unclosed token"), |
|
1609 XML_L("partial character"), |
|
1610 XML_L("mismatched tag"), |
|
1611 XML_L("duplicate attribute"), |
|
1612 XML_L("junk after document element"), |
|
1613 XML_L("illegal parameter entity reference"), |
|
1614 XML_L("undefined entity"), |
|
1615 XML_L("recursive entity reference"), |
|
1616 XML_L("asynchronous entity"), |
|
1617 XML_L("reference to invalid character number"), |
|
1618 XML_L("reference to binary entity"), |
|
1619 XML_L("reference to external entity in attribute"), |
|
1620 XML_L("xml declaration not at start of external entity"), |
|
1621 XML_L("unknown encoding"), |
|
1622 XML_L("encoding specified in XML declaration is incorrect"), |
|
1623 XML_L("unclosed CDATA section"), |
|
1624 XML_L("error in processing external entity reference"), |
|
1625 XML_L("document is not standalone"), |
|
1626 XML_L("unexpected parser state - please send a bug report"), |
|
1627 XML_L("entity declared in parameter entity"), |
|
1628 XML_L("requested feature requires XML_DTD support in Expat"), |
|
1629 XML_L("cannot change setting once parsing has begun") |
|
1630 }; |
|
1631 if (code > 0 && code < sizeof(message)/sizeof(message[0])) |
|
1632 return message[code]; |
|
1633 return NULL; |
|
1634 } |
|
1635 |
|
1636 const XML_LChar * |
|
1637 XML_ExpatVersion(void) { |
|
1638 |
|
1639 /* V1 is used to string-ize the version number. However, it would |
|
1640 string-ize the actual version macro *names* unless we get them |
|
1641 substituted before being passed to V1. CPP is defined to expand |
|
1642 a macro, then rescan for more expansions. Thus, we use V2 to expand |
|
1643 the version macros, then CPP will expand the resulting V1() macro |
|
1644 with the correct numerals. */ |
|
1645 /* ### I'm assuming cpp is portable in this respect... */ |
|
1646 |
|
1647 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) |
|
1648 #define V2(a,b,c) XML_L("expat_")V1(a,b,c) |
|
1649 |
|
1650 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); |
|
1651 |
|
1652 #undef V1 |
|
1653 #undef V2 |
|
1654 } |
|
1655 |
|
1656 XML_Expat_Version |
|
1657 XML_ExpatVersionInfo(void) |
|
1658 { |
|
1659 XML_Expat_Version version; |
|
1660 |
|
1661 version.major = XML_MAJOR_VERSION; |
|
1662 version.minor = XML_MINOR_VERSION; |
|
1663 version.micro = XML_MICRO_VERSION; |
|
1664 |
|
1665 return version; |
|
1666 } |
|
1667 |
|
1668 const XML_Feature * |
|
1669 XML_GetFeatureList(void) |
|
1670 { |
|
1671 static const XML_Feature features[] = { |
|
1672 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), sizeof(XML_Char)}, |
|
1673 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), sizeof(XML_LChar)}, |
|
1674 #ifdef XML_UNICODE |
|
1675 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")}, |
|
1676 #endif |
|
1677 #ifdef XML_UNICODE_WCHAR_T |
|
1678 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")}, |
|
1679 #endif |
|
1680 #ifdef XML_DTD |
|
1681 {XML_FEATURE_DTD, XML_L("XML_DTD")}, |
|
1682 #endif |
|
1683 #ifdef XML_CONTEXT_BYTES |
|
1684 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), |
|
1685 XML_CONTEXT_BYTES}, |
|
1686 #endif |
|
1687 #ifdef XML_MIN_SIZE |
|
1688 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")}, |
|
1689 #endif |
|
1690 {XML_FEATURE_END, NULL} |
|
1691 }; |
|
1692 |
|
1693 return features; |
|
1694 } |
|
1695 #endif // SYMBIAN_MIN_SIZE |
|
1696 |
|
1697 /* Initially tag->rawName always points into the parse buffer; |
|
1698 for those TAG instances opened while the current parse buffer was |
|
1699 processed, and not yet closed, we need to store tag->rawName in a more |
|
1700 permanent location, since the parse buffer is about to be discarded. |
|
1701 */ |
|
1702 static XML_Bool FASTCALL |
|
1703 storeRawNames(XML_Parser parser) |
|
1704 { |
|
1705 TAG *tag = tagStack; |
|
1706 while (tag) { |
|
1707 int bufSize; |
|
1708 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); |
|
1709 char *rawNameBuf = tag->buf + nameLen; |
|
1710 /* Stop if already stored. Since tagStack is a stack, we can stop |
|
1711 at the first entry that has already been copied; everything |
|
1712 below it in the stack is already been accounted for in a |
|
1713 previous call to this function. |
|
1714 */ |
|
1715 if (tag->rawName == rawNameBuf) |
|
1716 break; |
|
1717 /* For re-use purposes we need to ensure that the |
|
1718 size of tag->buf is a multiple of sizeof(XML_Char). |
|
1719 */ |
|
1720 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); |
|
1721 if (bufSize > tag->bufEnd - tag->buf) { |
|
1722 char *temp = (char *)REALLOC(tag->buf, bufSize); |
|
1723 if (temp == NULL) |
|
1724 return XML_FALSE; |
|
1725 if(tag->name.str == (XML_Char *)tag->buf) |
|
1726 tag->name.str = (XML_Char *)temp; |
|
1727 if(tag->name.localPart) |
|
1728 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); |
|
1729 tag->buf = temp; |
|
1730 tag->bufEnd = temp + bufSize; |
|
1731 rawNameBuf = temp + nameLen; |
|
1732 } |
|
1733 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); |
|
1734 tag->rawName = rawNameBuf; |
|
1735 tag = tag->parent; |
|
1736 } |
|
1737 return XML_TRUE; |
|
1738 } |
|
1739 |
|
1740 static enum XML_Error FASTCALL |
|
1741 contentProcessor(XML_Parser parser, |
|
1742 const char *start, |
|
1743 const char *end, |
|
1744 const char **endPtr) |
|
1745 { |
|
1746 enum XML_Error result = |
|
1747 doContent(parser, 0, encoding, start, end, endPtr); |
|
1748 if (result != XML_ERROR_NONE) |
|
1749 return result; |
|
1750 if (!storeRawNames(parser)) |
|
1751 return XML_ERROR_NO_MEMORY; |
|
1752 return result; |
|
1753 } |
|
1754 |
|
1755 #ifndef SYMBIAN_MIN_SIZE |
|
1756 static enum XML_Error FASTCALL |
|
1757 externalEntityInitProcessor(XML_Parser parser, |
|
1758 const char *start, |
|
1759 const char *end, |
|
1760 const char **endPtr) |
|
1761 { |
|
1762 enum XML_Error result = initializeEncoding(parser); |
|
1763 if (result != XML_ERROR_NONE) |
|
1764 return result; |
|
1765 processor = externalEntityInitProcessor2; |
|
1766 return externalEntityInitProcessor2(parser, start, end, endPtr); |
|
1767 } |
|
1768 |
|
1769 static enum XML_Error FASTCALL |
|
1770 externalEntityInitProcessor2(XML_Parser parser, |
|
1771 const char *start, |
|
1772 const char *end, |
|
1773 const char **endPtr) |
|
1774 { |
|
1775 const char *next = start; /* XmlContentTok doesn't always set the last arg */ |
|
1776 int tok = XmlContentTok(encoding, start, end, &next); |
|
1777 switch (tok) { |
|
1778 case XML_TOK_BOM: |
|
1779 /* If we are at the end of the buffer, this would cause the next stage, |
|
1780 i.e. externalEntityInitProcessor3, to pass control directly to |
|
1781 doContent (by detecting XML_TOK_NONE) without processing any xml text |
|
1782 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. |
|
1783 */ |
|
1784 if (next == end && endPtr) { |
|
1785 *endPtr = next; |
|
1786 return XML_ERROR_NONE; |
|
1787 } |
|
1788 start = next; |
|
1789 break; |
|
1790 case XML_TOK_PARTIAL: |
|
1791 if (endPtr) { |
|
1792 *endPtr = start; |
|
1793 return XML_ERROR_NONE; |
|
1794 } |
|
1795 eventPtr = start; |
|
1796 return XML_ERROR_UNCLOSED_TOKEN; |
|
1797 case XML_TOK_PARTIAL_CHAR: |
|
1798 if (endPtr) { |
|
1799 *endPtr = start; |
|
1800 return XML_ERROR_NONE; |
|
1801 } |
|
1802 eventPtr = start; |
|
1803 return XML_ERROR_PARTIAL_CHAR; |
|
1804 } |
|
1805 processor = externalEntityInitProcessor3; |
|
1806 return externalEntityInitProcessor3(parser, start, end, endPtr); |
|
1807 } |
|
1808 |
|
1809 static enum XML_Error FASTCALL |
|
1810 externalEntityInitProcessor3(XML_Parser parser, |
|
1811 const char *start, |
|
1812 const char *end, |
|
1813 const char **endPtr) |
|
1814 { |
|
1815 const char *next = start; /* XmlContentTok doesn't always set the last arg */ |
|
1816 int tok = XmlContentTok(encoding, start, end, &next); |
|
1817 switch (tok) { |
|
1818 case XML_TOK_XML_DECL: |
|
1819 { |
|
1820 enum XML_Error result = processXmlDecl(parser, 1, start, next); |
|
1821 if (result != XML_ERROR_NONE) |
|
1822 return result; |
|
1823 start = next; |
|
1824 } |
|
1825 break; |
|
1826 case XML_TOK_PARTIAL: |
|
1827 if (endPtr) { |
|
1828 *endPtr = start; |
|
1829 return XML_ERROR_NONE; |
|
1830 } |
|
1831 eventPtr = start; |
|
1832 return XML_ERROR_UNCLOSED_TOKEN; |
|
1833 case XML_TOK_PARTIAL_CHAR: |
|
1834 if (endPtr) { |
|
1835 *endPtr = start; |
|
1836 return XML_ERROR_NONE; |
|
1837 } |
|
1838 eventPtr = start; |
|
1839 return XML_ERROR_PARTIAL_CHAR; |
|
1840 } |
|
1841 processor = externalEntityContentProcessor; |
|
1842 tagLevel = 1; |
|
1843 return externalEntityContentProcessor(parser, start, end, endPtr); |
|
1844 } |
|
1845 #endif // SYMBIAN_MIN_SIZE |
|
1846 |
|
1847 static enum XML_Error FASTCALL |
|
1848 externalEntityContentProcessor(XML_Parser parser, |
|
1849 const char *start, |
|
1850 const char *end, |
|
1851 const char **endPtr) |
|
1852 { |
|
1853 enum XML_Error result = |
|
1854 doContent(parser, 1, encoding, start, end, endPtr); |
|
1855 if (result != XML_ERROR_NONE) |
|
1856 return result; |
|
1857 if (!storeRawNames(parser)) |
|
1858 return XML_ERROR_NO_MEMORY; |
|
1859 return result; |
|
1860 } |
|
1861 |
|
1862 static enum XML_Error FASTCALL |
|
1863 doContent(XML_Parser parser, |
|
1864 int startTagLevel, |
|
1865 const ENCODING *enc, |
|
1866 const char *s, |
|
1867 const char *end, |
|
1868 const char **nextPtr) |
|
1869 { |
|
1870 const char **eventPP; |
|
1871 const char **eventEndPP; |
|
1872 if (enc == encoding) { |
|
1873 eventPP = &eventPtr; |
|
1874 eventEndPP = &eventEndPtr; |
|
1875 } |
|
1876 else { |
|
1877 eventPP = &(openInternalEntities->internalEventPtr); |
|
1878 eventEndPP = &(openInternalEntities->internalEventEndPtr); |
|
1879 } |
|
1880 *eventPP = s; |
|
1881 for (;;) { |
|
1882 const char *next = s; /* XmlContentTok doesn't always set the last arg */ |
|
1883 int tok = XmlContentTok(enc, s, end, &next); |
|
1884 *eventEndPP = next; |
|
1885 switch (tok) { |
|
1886 case XML_TOK_TRAILING_CR: |
|
1887 if (nextPtr) { |
|
1888 *nextPtr = s; |
|
1889 return XML_ERROR_NONE; |
|
1890 } |
|
1891 *eventEndPP = end; |
|
1892 if (characterDataHandler) { |
|
1893 XML_Char c = 0xA; |
|
1894 characterDataHandler(handlerArg, &c, 1); |
|
1895 } |
|
1896 else if (defaultHandler) |
|
1897 reportDefault(parser, enc, s, end); |
|
1898 if (startTagLevel == 0) |
|
1899 return XML_ERROR_NO_ELEMENTS; |
|
1900 if (tagLevel != startTagLevel) |
|
1901 return XML_ERROR_ASYNC_ENTITY; |
|
1902 return XML_ERROR_NONE; |
|
1903 case XML_TOK_NONE: |
|
1904 if (nextPtr) { |
|
1905 *nextPtr = s; |
|
1906 return XML_ERROR_NONE; |
|
1907 } |
|
1908 if (startTagLevel > 0) { |
|
1909 if (tagLevel != startTagLevel) |
|
1910 return XML_ERROR_ASYNC_ENTITY; |
|
1911 return XML_ERROR_NONE; |
|
1912 } |
|
1913 return XML_ERROR_NO_ELEMENTS; |
|
1914 case XML_TOK_INVALID: |
|
1915 *eventPP = next; |
|
1916 return XML_ERROR_INVALID_TOKEN; |
|
1917 case XML_TOK_PARTIAL: |
|
1918 if (nextPtr) { |
|
1919 *nextPtr = s; |
|
1920 return XML_ERROR_NONE; |
|
1921 } |
|
1922 return XML_ERROR_UNCLOSED_TOKEN; |
|
1923 case XML_TOK_PARTIAL_CHAR: |
|
1924 if (nextPtr) { |
|
1925 *nextPtr = s; |
|
1926 return XML_ERROR_NONE; |
|
1927 } |
|
1928 return XML_ERROR_PARTIAL_CHAR; |
|
1929 case XML_TOK_ENTITY_REF: |
|
1930 { |
|
1931 const XML_Char *name; |
|
1932 ENTITY *entity; |
|
1933 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, |
|
1934 s + enc->minBytesPerChar, |
|
1935 next - enc->minBytesPerChar); |
|
1936 if (ch) { |
|
1937 if (characterDataHandler) |
|
1938 characterDataHandler(handlerArg, &ch, 1); |
|
1939 else if (defaultHandler) |
|
1940 reportDefault(parser, enc, s, next); |
|
1941 break; |
|
1942 } |
|
1943 name = poolStoreString(&dtd.pool, enc, |
|
1944 s + enc->minBytesPerChar, |
|
1945 next - enc->minBytesPerChar); |
|
1946 if (!name) |
|
1947 return XML_ERROR_NO_MEMORY; |
|
1948 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); |
|
1949 poolDiscard(&dtd.pool); |
|
1950 /* First, determine if a check for an existing declaration is needed; |
|
1951 if yes, check that the entity exists, and that it is internal, |
|
1952 otherwise call the skipped entity or default handler. |
|
1953 */ |
|
1954 if (!dtd.hasParamEntityRefs || dtd.standalone) { |
|
1955 if (!entity) |
|
1956 return XML_ERROR_UNDEFINED_ENTITY; |
|
1957 else if (!entity->is_internal) |
|
1958 return XML_ERROR_ENTITY_DECLARED_IN_PE; |
|
1959 } |
|
1960 else if (!entity) { |
|
1961 if (skippedEntityHandler) |
|
1962 skippedEntityHandler(handlerArg, name, 0); |
|
1963 else if (defaultHandler) |
|
1964 reportDefault(parser, enc, s, next); |
|
1965 break; |
|
1966 } |
|
1967 if (entity->open) |
|
1968 return XML_ERROR_RECURSIVE_ENTITY_REF; |
|
1969 if (entity->notation) |
|
1970 return XML_ERROR_BINARY_ENTITY_REF; |
|
1971 if (entity->textPtr) { |
|
1972 enum XML_Error result; |
|
1973 OPEN_INTERNAL_ENTITY openEntity; |
|
1974 if (!defaultExpandInternalEntities) { |
|
1975 if (skippedEntityHandler) |
|
1976 skippedEntityHandler(handlerArg, entity->name, 0); |
|
1977 else if (defaultHandler) |
|
1978 reportDefault(parser, enc, s, next); |
|
1979 break; |
|
1980 } |
|
1981 entity->open = XML_TRUE; |
|
1982 openEntity.next = openInternalEntities; |
|
1983 openInternalEntities = &openEntity; |
|
1984 openEntity.entity = entity; |
|
1985 openEntity.internalEventPtr = NULL; |
|
1986 openEntity.internalEventEndPtr = NULL; |
|
1987 result = doContent(parser, |
|
1988 tagLevel, |
|
1989 internalEncoding, |
|
1990 (char *)entity->textPtr, |
|
1991 (char *)(entity->textPtr + entity->textLen), |
|
1992 0); |
|
1993 entity->open = XML_FALSE; |
|
1994 openInternalEntities = openEntity.next; |
|
1995 if (result) |
|
1996 return result; |
|
1997 } |
|
1998 else if (externalEntityRefHandler) { |
|
1999 const XML_Char *context; |
|
2000 entity->open = XML_TRUE; |
|
2001 context = getContext(parser); |
|
2002 entity->open = XML_FALSE; |
|
2003 if (!context) |
|
2004 return XML_ERROR_NO_MEMORY; |
|
2005 if (!externalEntityRefHandler(handlerArg, name)) |
|
2006 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
|
2007 poolDiscard(&tempPool); |
|
2008 } |
|
2009 else if (defaultHandler) |
|
2010 reportDefault(parser, enc, s, next); |
|
2011 break; |
|
2012 } |
|
2013 case XML_TOK_START_TAG_WITH_ATTS: |
|
2014 if (!startElementHandler) { |
|
2015 enum XML_Error result = storeAtts(parser, enc, s, 0, 0); |
|
2016 if (result) |
|
2017 return result; |
|
2018 } |
|
2019 /* fall through */ |
|
2020 case XML_TOK_START_TAG_NO_ATTS: |
|
2021 { |
|
2022 TAG *tag; |
|
2023 enum XML_Error result; |
|
2024 XML_Char *toPtr; |
|
2025 if (freeTagList) { |
|
2026 tag = freeTagList; |
|
2027 freeTagList = freeTagList->parent; |
|
2028 } |
|
2029 else { |
|
2030 tag = (TAG *)MALLOC(sizeof(TAG)); |
|
2031 if (!tag) |
|
2032 return XML_ERROR_NO_MEMORY; |
|
2033 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); |
|
2034 if (!tag->buf) { |
|
2035 FREE(tag); |
|
2036 return XML_ERROR_NO_MEMORY; |
|
2037 } |
|
2038 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; |
|
2039 } |
|
2040 tag->bindings = NULL; |
|
2041 tag->parent = tagStack; |
|
2042 tagStack = tag; |
|
2043 tag->name.localPart = NULL; |
|
2044 tag->name.prefix = NULL; |
|
2045 tag->rawName = s + enc->minBytesPerChar; |
|
2046 tag->rawNameLength = XmlNameLength(enc, tag->rawName); |
|
2047 ++tagLevel; |
|
2048 { |
|
2049 const char *rawNameEnd = tag->rawName + tag->rawNameLength; |
|
2050 const char *fromPtr = tag->rawName; |
|
2051 toPtr = (XML_Char *)tag->buf; |
|
2052 for (;;) { |
|
2053 int bufSize; |
|
2054 int convLen; |
|
2055 XmlConvert(enc, |
|
2056 &fromPtr, rawNameEnd, |
|
2057 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); |
|
2058 convLen = toPtr - (XML_Char *)tag->buf; |
|
2059 if (fromPtr == rawNameEnd) { |
|
2060 tag->name.strLen = convLen; |
|
2061 break; |
|
2062 } |
|
2063 bufSize = (tag->bufEnd - tag->buf) << 1; |
|
2064 { |
|
2065 char *temp = (char *)REALLOC(tag->buf, bufSize); |
|
2066 if (temp == NULL) |
|
2067 return XML_ERROR_NO_MEMORY; |
|
2068 tag->buf = temp; |
|
2069 tag->bufEnd = temp + bufSize; |
|
2070 toPtr = (XML_Char *)temp + convLen; |
|
2071 } |
|
2072 } |
|
2073 } |
|
2074 tag->name.str = (XML_Char *)tag->buf; |
|
2075 *toPtr = XML_T('\0'); |
|
2076 if (startElementHandler) { |
|
2077 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); |
|
2078 if (result) |
|
2079 return result; |
|
2080 startElementHandler(handlerArg, tag->name.str, |
|
2081 (const XML_Char **)atts); |
|
2082 } |
|
2083 else if (defaultHandler) |
|
2084 reportDefault(parser, enc, s, next); |
|
2085 poolClear(&tempPool); |
|
2086 break; |
|
2087 } |
|
2088 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: |
|
2089 if (!startElementHandler) { |
|
2090 enum XML_Error result = storeAtts(parser, enc, s, 0, 0); |
|
2091 if (result) |
|
2092 return result; |
|
2093 } |
|
2094 /* fall through */ |
|
2095 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: |
|
2096 if (startElementHandler || endElementHandler) { |
|
2097 const char *rawName = s + enc->minBytesPerChar; |
|
2098 enum XML_Error result; |
|
2099 BINDING *bindings = NULL; |
|
2100 TAG_NAME name; |
|
2101 name.str = poolStoreString(&tempPool, enc, rawName, |
|
2102 rawName + XmlNameLength(enc, rawName)); |
|
2103 if (!name.str) |
|
2104 return XML_ERROR_NO_MEMORY; |
|
2105 poolFinish(&tempPool); |
|
2106 result = storeAtts(parser, enc, s, &name, &bindings); |
|
2107 if (result) |
|
2108 return result; |
|
2109 poolFinish(&tempPool); |
|
2110 if (startElementHandler) |
|
2111 startElementHandler(handlerArg, name.str, (const XML_Char **)atts); |
|
2112 if (endElementHandler) { |
|
2113 if (startElementHandler) |
|
2114 *eventPP = *eventEndPP; |
|
2115 endElementHandler(handlerArg, name.str); |
|
2116 } |
|
2117 poolClear(&tempPool); |
|
2118 while (bindings) { |
|
2119 BINDING *b = bindings; |
|
2120 if (endNamespaceDeclHandler) |
|
2121 endNamespaceDeclHandler(handlerArg, b->prefix->name); |
|
2122 bindings = bindings->nextTagBinding; |
|
2123 b->nextTagBinding = freeBindingList; |
|
2124 freeBindingList = b; |
|
2125 b->prefix->binding = b->prevPrefixBinding; |
|
2126 } |
|
2127 } |
|
2128 else if (defaultHandler) |
|
2129 reportDefault(parser, enc, s, next); |
|
2130 if (tagLevel == 0) |
|
2131 return epilogProcessor(parser, next, end, nextPtr); |
|
2132 break; |
|
2133 case XML_TOK_END_TAG: |
|
2134 if (tagLevel == startTagLevel) |
|
2135 return XML_ERROR_ASYNC_ENTITY; |
|
2136 else { |
|
2137 int len; |
|
2138 const char *rawName; |
|
2139 TAG *tag = tagStack; |
|
2140 tagStack = tag->parent; |
|
2141 tag->parent = freeTagList; |
|
2142 freeTagList = tag; |
|
2143 rawName = s + enc->minBytesPerChar*2; |
|
2144 len = XmlNameLength(enc, rawName); |
|
2145 if (len != tag->rawNameLength |
|
2146 || memcmp(tag->rawName, rawName, len) != 0) { |
|
2147 *eventPP = rawName; |
|
2148 return XML_ERROR_TAG_MISMATCH; |
|
2149 } |
|
2150 --tagLevel; |
|
2151 if (endElementHandler) { |
|
2152 const XML_Char *localPart; |
|
2153 const XML_Char *prefix; |
|
2154 XML_Char *uri; |
|
2155 localPart = tag->name.localPart; |
|
2156 if (ns && localPart) { |
|
2157 /* localPart and prefix may have been overwritten in |
|
2158 tag->name.str, since this points to the binding->uri |
|
2159 buffer which gets re-used; so we have to add them again |
|
2160 */ |
|
2161 uri = (XML_Char *)tag->name.str + tag->name.uriLen; |
|
2162 /* don't need to check for space - already done in storeAtts() */ |
|
2163 while (*localPart) *uri++ = *localPart++; |
|
2164 prefix = (XML_Char *)tag->name.prefix; |
|
2165 if (ns_triplets && prefix) { |
|
2166 *uri++ = namespaceSeparator; |
|
2167 while (*prefix) *uri++ = *prefix++; |
|
2168 } |
|
2169 *uri = XML_T('\0'); |
|
2170 } |
|
2171 endElementHandler(handlerArg, tag->name.str); |
|
2172 } |
|
2173 else if (defaultHandler) |
|
2174 reportDefault(parser, enc, s, next); |
|
2175 while (tag->bindings) { |
|
2176 BINDING *b = tag->bindings; |
|
2177 if (endNamespaceDeclHandler) |
|
2178 endNamespaceDeclHandler(handlerArg, b->prefix->name); |
|
2179 tag->bindings = tag->bindings->nextTagBinding; |
|
2180 b->nextTagBinding = freeBindingList; |
|
2181 freeBindingList = b; |
|
2182 b->prefix->binding = b->prevPrefixBinding; |
|
2183 } |
|
2184 if (tagLevel == 0) |
|
2185 return epilogProcessor(parser, next, end, nextPtr); |
|
2186 } |
|
2187 break; |
|
2188 case XML_TOK_CHAR_REF: |
|
2189 { |
|
2190 int n = XmlCharRefNumber(enc, s); |
|
2191 if (n < 0) |
|
2192 return XML_ERROR_BAD_CHAR_REF; |
|
2193 if (characterDataHandler) { |
|
2194 XML_Char buf[XML_ENCODE_MAX]; |
|
2195 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); |
|
2196 } |
|
2197 else if (defaultHandler) |
|
2198 reportDefault(parser, enc, s, next); |
|
2199 } |
|
2200 break; |
|
2201 case XML_TOK_XML_DECL: |
|
2202 return XML_ERROR_MISPLACED_XML_PI; |
|
2203 case XML_TOK_DATA_NEWLINE: |
|
2204 if (characterDataHandler) { |
|
2205 XML_Char c = 0xA; |
|
2206 characterDataHandler(handlerArg, &c, 1); |
|
2207 } |
|
2208 else if (defaultHandler) |
|
2209 reportDefault(parser, enc, s, next); |
|
2210 break; |
|
2211 case XML_TOK_CDATA_SECT_OPEN: |
|
2212 { |
|
2213 enum XML_Error result; |
|
2214 if (startCdataSectionHandler) |
|
2215 startCdataSectionHandler(handlerArg); |
|
2216 #if 0 |
|
2217 /* Suppose you doing a transformation on a document that involves |
|
2218 changing only the character data. You set up a defaultHandler |
|
2219 and a characterDataHandler. The defaultHandler simply copies |
|
2220 characters through. The characterDataHandler does the |
|
2221 transformation and writes the characters out escaping them as |
|
2222 necessary. This case will fail to work if we leave out the |
|
2223 following two lines (because & and < inside CDATA sections will |
|
2224 be incorrectly escaped). |
|
2225 |
|
2226 However, now we have a start/endCdataSectionHandler, so it seems |
|
2227 easier to let the user deal with this. |
|
2228 */ |
|
2229 else if (characterDataHandler) |
|
2230 characterDataHandler(handlerArg, dataBuf, 0); |
|
2231 #endif |
|
2232 else if (defaultHandler) |
|
2233 reportDefault(parser, enc, s, next); |
|
2234 result = doCdataSection(parser, enc, &next, end, nextPtr); |
|
2235 if (!next) { |
|
2236 processor = cdataSectionProcessor; |
|
2237 return result; |
|
2238 } |
|
2239 } |
|
2240 break; |
|
2241 case XML_TOK_TRAILING_RSQB: |
|
2242 if (nextPtr) { |
|
2243 *nextPtr = s; |
|
2244 return XML_ERROR_NONE; |
|
2245 } |
|
2246 if (characterDataHandler) { |
|
2247 if (MUST_CONVERT(enc, s)) { |
|
2248 ICHAR *dataPtr = (ICHAR *)dataBuf; |
|
2249 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); |
|
2250 characterDataHandler(handlerArg, dataBuf, |
|
2251 dataPtr - (ICHAR *)dataBuf); |
|
2252 } |
|
2253 else |
|
2254 characterDataHandler(handlerArg, |
|
2255 (XML_Char *)s, |
|
2256 (XML_Char *)end - (XML_Char *)s); |
|
2257 } |
|
2258 else if (defaultHandler) |
|
2259 reportDefault(parser, enc, s, end); |
|
2260 if (startTagLevel == 0) { |
|
2261 *eventPP = end; |
|
2262 return XML_ERROR_NO_ELEMENTS; |
|
2263 } |
|
2264 if (tagLevel != startTagLevel) { |
|
2265 *eventPP = end; |
|
2266 return XML_ERROR_ASYNC_ENTITY; |
|
2267 } |
|
2268 return XML_ERROR_NONE; |
|
2269 case XML_TOK_DATA_CHARS: |
|
2270 if (characterDataHandler) { |
|
2271 if (MUST_CONVERT(enc, s)) { |
|
2272 for (;;) { |
|
2273 ICHAR *dataPtr = (ICHAR *)dataBuf; |
|
2274 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); |
|
2275 *eventEndPP = s; |
|
2276 characterDataHandler(handlerArg, dataBuf, |
|
2277 dataPtr - (ICHAR *)dataBuf); |
|
2278 if (s == next) |
|
2279 break; |
|
2280 *eventPP = s; |
|
2281 } |
|
2282 } |
|
2283 else |
|
2284 characterDataHandler(handlerArg, |
|
2285 (XML_Char *)s, |
|
2286 (XML_Char *)next - (XML_Char *)s); |
|
2287 } |
|
2288 else if (defaultHandler) |
|
2289 reportDefault(parser, enc, s, next); |
|
2290 break; |
|
2291 case XML_TOK_PI: |
|
2292 if (!reportProcessingInstruction(parser, enc, s, next)) |
|
2293 return XML_ERROR_NO_MEMORY; |
|
2294 break; |
|
2295 case XML_TOK_COMMENT: |
|
2296 if (!reportComment(parser, enc, s, next)) |
|
2297 return XML_ERROR_NO_MEMORY; |
|
2298 break; |
|
2299 default: |
|
2300 if (defaultHandler) |
|
2301 reportDefault(parser, enc, s, next); |
|
2302 break; |
|
2303 } |
|
2304 *eventPP = s = next; |
|
2305 } |
|
2306 /* not reached */ |
|
2307 } |
|
2308 |
|
2309 /* If tagNamePtr is non-null, build a real list of attributes, |
|
2310 otherwise just check the attributes for well-formedness. |
|
2311 */ |
|
2312 static enum XML_Error FASTCALL |
|
2313 storeAtts(XML_Parser parser, const ENCODING *enc, |
|
2314 const char *attStr, TAG_NAME *tagNamePtr, |
|
2315 BINDING **bindingsPtr) |
|
2316 { |
|
2317 ELEMENT_TYPE *elementType = NULL; |
|
2318 int nDefaultAtts = 0; |
|
2319 const XML_Char **appAtts; /* the attribute list for the application */ |
|
2320 int attIndex = 0; |
|
2321 int prefixLen; |
|
2322 int i; |
|
2323 int n; |
|
2324 XML_Char *uri; |
|
2325 int nPrefixes = 0; |
|
2326 BINDING *binding; |
|
2327 const XML_Char *localPart; |
|
2328 |
|
2329 /* SYMBIAN: the following lines have been modified to correct a "Directly dereferenced |
|
2330 pointer 'tagNamePtr' Coverity error. |
|
2331 */ |
|
2332 if (tagNamePtr) { |
|
2333 /* lookup the element type name */ |
|
2334 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0); |
|
2335 if (!elementType) { |
|
2336 const XML_Char* name = poolCopyString(&dtd.pool, tagNamePtr->str); |
|
2337 if (!name) |
|
2338 return XML_ERROR_NO_MEMORY; |
|
2339 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, |
|
2340 sizeof(ELEMENT_TYPE)); |
|
2341 if (!elementType) |
|
2342 return XML_ERROR_NO_MEMORY; |
|
2343 if (ns && !setElementTypePrefix(parser, elementType)) |
|
2344 return XML_ERROR_NO_MEMORY; |
|
2345 |
|
2346 nDefaultAtts = elementType->nDefaultAtts; |
|
2347 } |
|
2348 } |
|
2349 /* SYMBIAN: end */ |
|
2350 |
|
2351 /* get the attributes from the tokenizer */ |
|
2352 n = XmlGetAttributes(enc, attStr, attsSize, atts); |
|
2353 if (n + nDefaultAtts > attsSize) { |
|
2354 int oldAttsSize = attsSize; |
|
2355 ATTRIBUTE *temp; |
|
2356 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; |
|
2357 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); |
|
2358 if (temp == NULL) |
|
2359 return XML_ERROR_NO_MEMORY; |
|
2360 atts = temp; |
|
2361 if (n > oldAttsSize) |
|
2362 XmlGetAttributes(enc, attStr, n, atts); |
|
2363 } |
|
2364 appAtts = (const XML_Char **)atts; |
|
2365 for (i = 0; i < n; i++) { |
|
2366 /* add the name and value to the attribute list */ |
|
2367 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, |
|
2368 atts[i].name |
|
2369 + XmlNameLength(enc, atts[i].name)); |
|
2370 if (!attId) |
|
2371 return XML_ERROR_NO_MEMORY; |
|
2372 /* detect duplicate attributes */ |
|
2373 if ((attId->name)[-1]) { |
|
2374 if (enc == encoding) |
|
2375 eventPtr = atts[i].name; |
|
2376 return XML_ERROR_DUPLICATE_ATTRIBUTE; |
|
2377 } |
|
2378 (attId->name)[-1] = 1; |
|
2379 appAtts[attIndex++] = attId->name; |
|
2380 if (!atts[i].normalized) { |
|
2381 enum XML_Error result; |
|
2382 XML_Bool isCdata = XML_TRUE; |
|
2383 |
|
2384 /* figure out whether declared as other than CDATA */ |
|
2385 if (attId->maybeTokenized) { |
|
2386 int j; |
|
2387 for (j = 0; j < nDefaultAtts; j++) { |
|
2388 if (attId == elementType->defaultAtts[j].id) { |
|
2389 isCdata = elementType->defaultAtts[j].isCdata; |
|
2390 break; |
|
2391 } |
|
2392 } |
|
2393 } |
|
2394 |
|
2395 /* normalize the attribute value */ |
|
2396 result = storeAttributeValue(parser, enc, isCdata, |
|
2397 atts[i].valuePtr, atts[i].valueEnd, |
|
2398 &tempPool); |
|
2399 if (result) |
|
2400 return result; |
|
2401 if (tagNamePtr) { |
|
2402 appAtts[attIndex] = poolStart(&tempPool); |
|
2403 poolFinish(&tempPool); |
|
2404 } |
|
2405 else |
|
2406 poolDiscard(&tempPool); |
|
2407 } |
|
2408 else if (tagNamePtr) { |
|
2409 /* the value did not need normalizing */ |
|
2410 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, |
|
2411 atts[i].valueEnd); |
|
2412 if (appAtts[attIndex] == 0) |
|
2413 return XML_ERROR_NO_MEMORY; |
|
2414 poolFinish(&tempPool); |
|
2415 } |
|
2416 /* handle prefixed attribute names */ |
|
2417 if (attId->prefix && tagNamePtr) { |
|
2418 if (attId->xmlns) { |
|
2419 /* deal with namespace declarations here */ |
|
2420 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], |
|
2421 bindingsPtr)) |
|
2422 return XML_ERROR_NO_MEMORY; |
|
2423 --attIndex; |
|
2424 } |
|
2425 else { |
|
2426 /* deal with other prefixed names later */ |
|
2427 attIndex++; |
|
2428 nPrefixes++; |
|
2429 (attId->name)[-1] = 2; |
|
2430 } |
|
2431 } |
|
2432 else |
|
2433 attIndex++; |
|
2434 } |
|
2435 if (tagNamePtr) { |
|
2436 int j; |
|
2437 nSpecifiedAtts = attIndex; |
|
2438 if (elementType->idAtt && (elementType->idAtt->name)[-1]) { |
|
2439 for (i = 0; i < attIndex; i += 2) |
|
2440 if (appAtts[i] == elementType->idAtt->name) { |
|
2441 idAttIndex = i; |
|
2442 break; |
|
2443 } |
|
2444 } |
|
2445 else |
|
2446 idAttIndex = -1; |
|
2447 /* do attribute defaulting */ |
|
2448 for (j = 0; j < nDefaultAtts; j++) { |
|
2449 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; |
|
2450 if (!(da->id->name)[-1] && da->value) { |
|
2451 if (da->id->prefix) { |
|
2452 if (da->id->xmlns) { |
|
2453 if (!addBinding(parser, da->id->prefix, da->id, da->value, |
|
2454 bindingsPtr)) |
|
2455 return XML_ERROR_NO_MEMORY; |
|
2456 } |
|
2457 else { |
|
2458 (da->id->name)[-1] = 2; |
|
2459 nPrefixes++; |
|
2460 appAtts[attIndex++] = da->id->name; |
|
2461 appAtts[attIndex++] = da->value; |
|
2462 } |
|
2463 } |
|
2464 else { |
|
2465 (da->id->name)[-1] = 1; |
|
2466 appAtts[attIndex++] = da->id->name; |
|
2467 appAtts[attIndex++] = da->value; |
|
2468 } |
|
2469 } |
|
2470 } |
|
2471 appAtts[attIndex] = 0; |
|
2472 } |
|
2473 i = 0; |
|
2474 if (nPrefixes) { |
|
2475 /* expand prefixed attribute names */ |
|
2476 for (; i < attIndex; i += 2) { |
|
2477 if (appAtts[i][-1] == 2) { |
|
2478 ATTRIBUTE_ID *id; |
|
2479 ((XML_Char *)(appAtts[i]))[-1] = 0; |
|
2480 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0); |
|
2481 /* SYMBIAN: the following lines have been added to correct a "Variable 'id' assigned |
|
2482 to NULL return value from 'lookup' " error found by Coverity |
|
2483 */ |
|
2484 if (id == NULL) { |
|
2485 return XML_ERROR_NO_MEMORY; |
|
2486 } |
|
2487 /* SYMBIAN: end */ |
|
2488 if (id->prefix->binding) { |
|
2489 int j; |
|
2490 const BINDING *b = id->prefix->binding; |
|
2491 const XML_Char *s = appAtts[i]; |
|
2492 for (j = 0; j < b->uriLen; j++) { |
|
2493 if (!poolAppendChar(&tempPool, b->uri[j])) |
|
2494 return XML_ERROR_NO_MEMORY; |
|
2495 } |
|
2496 while (*s++ != XML_T(':')) |
|
2497 ; |
|
2498 do { |
|
2499 if (!poolAppendChar(&tempPool, *s)) |
|
2500 return XML_ERROR_NO_MEMORY; |
|
2501 } while (*s++); |
|
2502 if (ns_triplets) { |
|
2503 tempPool.ptr[-1] = namespaceSeparator; |
|
2504 s = b->prefix->name; |
|
2505 do { |
|
2506 if (!poolAppendChar(&tempPool, *s)) |
|
2507 return XML_ERROR_NO_MEMORY; |
|
2508 } while (*s++); |
|
2509 } |
|
2510 |
|
2511 appAtts[i] = poolStart(&tempPool); |
|
2512 poolFinish(&tempPool); |
|
2513 } |
|
2514 if (!--nPrefixes) |
|
2515 break; |
|
2516 } |
|
2517 else |
|
2518 ((XML_Char *)(appAtts[i]))[-1] = 0; |
|
2519 } |
|
2520 } |
|
2521 /* clear the flags that say whether attributes were specified */ |
|
2522 for (; i < attIndex; i += 2) |
|
2523 ((XML_Char *)(appAtts[i]))[-1] = 0; |
|
2524 if (!tagNamePtr) |
|
2525 return XML_ERROR_NONE; |
|
2526 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) |
|
2527 binding->attId->name[-1] = 0; |
|
2528 /* expand the element type name */ |
|
2529 if (elementType->prefix) { |
|
2530 binding = elementType->prefix->binding; |
|
2531 if (!binding) |
|
2532 return XML_ERROR_NONE; |
|
2533 localPart = tagNamePtr->str; |
|
2534 while (*localPart++ != XML_T(':')) |
|
2535 ; |
|
2536 } |
|
2537 else if (dtd.defaultPrefix.binding) { |
|
2538 binding = dtd.defaultPrefix.binding; |
|
2539 localPart = tagNamePtr->str; |
|
2540 } |
|
2541 else |
|
2542 return XML_ERROR_NONE; |
|
2543 prefixLen = 0; |
|
2544 if (ns && ns_triplets && binding->prefix->name) { |
|
2545 for (; binding->prefix->name[prefixLen++];) |
|
2546 ; |
|
2547 } |
|
2548 tagNamePtr->localPart = localPart; |
|
2549 tagNamePtr->uriLen = binding->uriLen; |
|
2550 tagNamePtr->prefix = binding->prefix->name; |
|
2551 tagNamePtr->prefixLen = prefixLen; |
|
2552 for (i = 0; localPart[i++];) |
|
2553 ; |
|
2554 n = i + binding->uriLen + prefixLen; |
|
2555 if (n > binding->uriAlloc) { |
|
2556 TAG *p; |
|
2557 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); |
|
2558 if (!uri) |
|
2559 return XML_ERROR_NO_MEMORY; |
|
2560 binding->uriAlloc = n + EXPAND_SPARE; |
|
2561 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); |
|
2562 for (p = tagStack; p; p = p->parent) |
|
2563 if (p->name.str == binding->uri) |
|
2564 p->name.str = uri; |
|
2565 FREE(binding->uri); |
|
2566 binding->uri = uri; |
|
2567 } |
|
2568 uri = binding->uri + binding->uriLen; |
|
2569 memcpy(uri, localPart, i * sizeof(XML_Char)); |
|
2570 if (prefixLen) { |
|
2571 uri = uri + (i - 1); |
|
2572 if (namespaceSeparator) { *(uri) = namespaceSeparator; } |
|
2573 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); |
|
2574 } |
|
2575 tagNamePtr->str = binding->uri; |
|
2576 return XML_ERROR_NONE; |
|
2577 } |
|
2578 |
|
2579 static int FASTCALL |
|
2580 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, |
|
2581 const XML_Char *uri, BINDING **bindingsPtr) |
|
2582 { |
|
2583 BINDING *b; |
|
2584 int len; |
|
2585 for (len = 0; uri[len]; len++) |
|
2586 ; |
|
2587 if (namespaceSeparator) |
|
2588 len++; |
|
2589 if (freeBindingList) { |
|
2590 b = freeBindingList; |
|
2591 if (len > b->uriAlloc) { |
|
2592 XML_Char *temp = (XML_Char *)REALLOC(b->uri, |
|
2593 sizeof(XML_Char) * (len + EXPAND_SPARE)); |
|
2594 if (temp == NULL) |
|
2595 return 0; |
|
2596 b->uri = temp; |
|
2597 b->uriAlloc = len + EXPAND_SPARE; |
|
2598 } |
|
2599 freeBindingList = b->nextTagBinding; |
|
2600 } |
|
2601 else { |
|
2602 b = (BINDING *)MALLOC(sizeof(BINDING)); |
|
2603 if (!b) |
|
2604 return 0; |
|
2605 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); |
|
2606 if (!b->uri) { |
|
2607 FREE(b); |
|
2608 return 0; |
|
2609 } |
|
2610 b->uriAlloc = len + EXPAND_SPARE; |
|
2611 } |
|
2612 b->uriLen = len; |
|
2613 memcpy(b->uri, uri, len * sizeof(XML_Char)); |
|
2614 if (namespaceSeparator) |
|
2615 b->uri[len - 1] = namespaceSeparator; |
|
2616 b->prefix = prefix; |
|
2617 b->attId = attId; |
|
2618 b->prevPrefixBinding = prefix->binding; |
|
2619 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix) |
|
2620 prefix->binding = NULL; |
|
2621 else |
|
2622 prefix->binding = b; |
|
2623 b->nextTagBinding = *bindingsPtr; |
|
2624 *bindingsPtr = b; |
|
2625 if (startNamespaceDeclHandler) |
|
2626 startNamespaceDeclHandler(handlerArg, prefix->name, |
|
2627 prefix->binding ? uri : 0); |
|
2628 return 1; |
|
2629 } |
|
2630 |
|
2631 /* The idea here is to avoid using stack for each CDATA section when |
|
2632 the whole file is parsed with one call. |
|
2633 */ |
|
2634 static enum XML_Error FASTCALL |
|
2635 cdataSectionProcessor(XML_Parser parser, |
|
2636 const char *start, |
|
2637 const char *end, |
|
2638 const char **endPtr) |
|
2639 { |
|
2640 enum XML_Error result = doCdataSection(parser, encoding, &start, |
|
2641 end, endPtr); |
|
2642 if (start) { |
|
2643 if (parentParser) { /* we are parsing an external entity */ |
|
2644 processor = externalEntityContentProcessor; |
|
2645 return externalEntityContentProcessor(parser, start, end, endPtr); |
|
2646 } |
|
2647 else { |
|
2648 processor = contentProcessor; |
|
2649 return contentProcessor(parser, start, end, endPtr); |
|
2650 } |
|
2651 } |
|
2652 return result; |
|
2653 } |
|
2654 |
|
2655 /* startPtr gets set to non-null is the section is closed, and to null if |
|
2656 the section is not yet closed. |
|
2657 */ |
|
2658 static enum XML_Error FASTCALL |
|
2659 doCdataSection(XML_Parser parser, |
|
2660 const ENCODING *enc, |
|
2661 const char **startPtr, |
|
2662 const char *end, |
|
2663 const char **nextPtr) |
|
2664 { |
|
2665 const char *s = *startPtr; |
|
2666 const char **eventPP; |
|
2667 const char **eventEndPP; |
|
2668 if (enc == encoding) { |
|
2669 eventPP = &eventPtr; |
|
2670 *eventPP = s; |
|
2671 eventEndPP = &eventEndPtr; |
|
2672 } |
|
2673 else { |
|
2674 eventPP = &(openInternalEntities->internalEventPtr); |
|
2675 eventEndPP = &(openInternalEntities->internalEventEndPtr); |
|
2676 } |
|
2677 *eventPP = s; |
|
2678 *startPtr = NULL; |
|
2679 for (;;) { |
|
2680 const char *next; |
|
2681 int tok = XmlCdataSectionTok(enc, s, end, &next); |
|
2682 *eventEndPP = next; |
|
2683 switch (tok) { |
|
2684 case XML_TOK_CDATA_SECT_CLOSE: |
|
2685 if (endCdataSectionHandler) |
|
2686 endCdataSectionHandler(handlerArg); |
|
2687 #if 0 |
|
2688 /* see comment under XML_TOK_CDATA_SECT_OPEN */ |
|
2689 else if (characterDataHandler) |
|
2690 characterDataHandler(handlerArg, dataBuf, 0); |
|
2691 #endif |
|
2692 else if (defaultHandler) |
|
2693 reportDefault(parser, enc, s, next); |
|
2694 *startPtr = next; |
|
2695 return XML_ERROR_NONE; |
|
2696 case XML_TOK_DATA_NEWLINE: |
|
2697 if (characterDataHandler) { |
|
2698 XML_Char c = 0xA; |
|
2699 characterDataHandler(handlerArg, &c, 1); |
|
2700 } |
|
2701 else if (defaultHandler) |
|
2702 reportDefault(parser, enc, s, next); |
|
2703 break; |
|
2704 case XML_TOK_DATA_CHARS: |
|
2705 if (characterDataHandler) { |
|
2706 if (MUST_CONVERT(enc, s)) { |
|
2707 for (;;) { |
|
2708 ICHAR *dataPtr = (ICHAR *)dataBuf; |
|
2709 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); |
|
2710 *eventEndPP = next; |
|
2711 characterDataHandler(handlerArg, dataBuf, |
|
2712 dataPtr - (ICHAR *)dataBuf); |
|
2713 if (s == next) |
|
2714 break; |
|
2715 *eventPP = s; |
|
2716 } |
|
2717 } |
|
2718 else |
|
2719 characterDataHandler(handlerArg, |
|
2720 (XML_Char *)s, |
|
2721 (XML_Char *)next - (XML_Char *)s); |
|
2722 } |
|
2723 else if (defaultHandler) |
|
2724 reportDefault(parser, enc, s, next); |
|
2725 break; |
|
2726 case XML_TOK_INVALID: |
|
2727 *eventPP = next; |
|
2728 return XML_ERROR_INVALID_TOKEN; |
|
2729 case XML_TOK_PARTIAL_CHAR: |
|
2730 if (nextPtr) { |
|
2731 *nextPtr = s; |
|
2732 return XML_ERROR_NONE; |
|
2733 } |
|
2734 return XML_ERROR_PARTIAL_CHAR; |
|
2735 case XML_TOK_PARTIAL: |
|
2736 case XML_TOK_NONE: |
|
2737 if (nextPtr) { |
|
2738 *nextPtr = s; |
|
2739 return XML_ERROR_NONE; |
|
2740 } |
|
2741 return XML_ERROR_UNCLOSED_CDATA_SECTION; |
|
2742 default: |
|
2743 *eventPP = next; |
|
2744 return XML_ERROR_UNEXPECTED_STATE; |
|
2745 } |
|
2746 *eventPP = s = next; |
|
2747 } |
|
2748 /* not reached */ |
|
2749 } |
|
2750 |
|
2751 #ifdef XML_DTD |
|
2752 |
|
2753 /* The idea here is to avoid using stack for each IGNORE section when |
|
2754 the whole file is parsed with one call. |
|
2755 */ |
|
2756 static enum XML_Error FASTCALL |
|
2757 ignoreSectionProcessor(XML_Parser parser, |
|
2758 const char *start, |
|
2759 const char *end, |
|
2760 const char **endPtr) |
|
2761 { |
|
2762 enum XML_Error result = doIgnoreSection(parser, encoding, &start, |
|
2763 end, endPtr); |
|
2764 if (start) { |
|
2765 processor = prologProcessor; |
|
2766 return prologProcessor(parser, start, end, endPtr); |
|
2767 } |
|
2768 return result; |
|
2769 } |
|
2770 |
|
2771 /* startPtr gets set to non-null is the section is closed, and to null |
|
2772 if the section is not yet closed. |
|
2773 */ |
|
2774 static enum XML_Error FASTCALL |
|
2775 doIgnoreSection(XML_Parser parser, |
|
2776 const ENCODING *enc, |
|
2777 const char **startPtr, |
|
2778 const char *end, |
|
2779 const char **nextPtr) |
|
2780 { |
|
2781 const char *next; |
|
2782 int tok; |
|
2783 const char *s = *startPtr; |
|
2784 const char **eventPP; |
|
2785 const char **eventEndPP; |
|
2786 if (enc == encoding) { |
|
2787 eventPP = &eventPtr; |
|
2788 *eventPP = s; |
|
2789 eventEndPP = &eventEndPtr; |
|
2790 } |
|
2791 else { |
|
2792 eventPP = &(openInternalEntities->internalEventPtr); |
|
2793 eventEndPP = &(openInternalEntities->internalEventEndPtr); |
|
2794 } |
|
2795 *eventPP = s; |
|
2796 *startPtr = NULL; |
|
2797 tok = XmlIgnoreSectionTok(enc, s, end, &next); |
|
2798 *eventEndPP = next; |
|
2799 switch (tok) { |
|
2800 case XML_TOK_IGNORE_SECT: |
|
2801 if (defaultHandler) |
|
2802 reportDefault(parser, enc, s, next); |
|
2803 *startPtr = next; |
|
2804 return XML_ERROR_NONE; |
|
2805 case XML_TOK_INVALID: |
|
2806 *eventPP = next; |
|
2807 return XML_ERROR_INVALID_TOKEN; |
|
2808 case XML_TOK_PARTIAL_CHAR: |
|
2809 if (nextPtr) { |
|
2810 *nextPtr = s; |
|
2811 return XML_ERROR_NONE; |
|
2812 } |
|
2813 return XML_ERROR_PARTIAL_CHAR; |
|
2814 case XML_TOK_PARTIAL: |
|
2815 case XML_TOK_NONE: |
|
2816 if (nextPtr) { |
|
2817 *nextPtr = s; |
|
2818 return XML_ERROR_NONE; |
|
2819 } |
|
2820 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ |
|
2821 default: |
|
2822 *eventPP = next; |
|
2823 return XML_ERROR_UNEXPECTED_STATE; |
|
2824 } |
|
2825 /* not reached */ |
|
2826 } |
|
2827 |
|
2828 #endif /* XML_DTD */ |
|
2829 |
|
2830 static enum XML_Error FASTCALL |
|
2831 initializeEncoding(XML_Parser parser) |
|
2832 { |
|
2833 const char *s; |
|
2834 #ifdef XML_UNICODE |
|
2835 char encodingBuf[128]; |
|
2836 if (!protocolEncodingName) |
|
2837 s = NULL; |
|
2838 else { |
|
2839 int i; |
|
2840 for (i = 0; protocolEncodingName[i]; i++) { |
|
2841 if (i == sizeof(encodingBuf) - 1 |
|
2842 || (protocolEncodingName[i] & ~0x7f) != 0) { |
|
2843 encodingBuf[0] = '\0'; |
|
2844 break; |
|
2845 } |
|
2846 encodingBuf[i] = (char)protocolEncodingName[i]; |
|
2847 } |
|
2848 encodingBuf[i] = '\0'; |
|
2849 s = encodingBuf; |
|
2850 } |
|
2851 #else |
|
2852 s = protocolEncodingName; |
|
2853 #endif |
|
2854 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) |
|
2855 return XML_ERROR_NONE; |
|
2856 return handleUnknownEncoding(parser, protocolEncodingName); |
|
2857 } |
|
2858 |
|
2859 static enum XML_Error FASTCALL |
|
2860 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, |
|
2861 const char *s, const char *next) |
|
2862 { |
|
2863 const char *encodingName = NULL; |
|
2864 const XML_Char *storedEncName = NULL; |
|
2865 const ENCODING *newEncoding = NULL; |
|
2866 const char *version = NULL; |
|
2867 const char *versionend; |
|
2868 const XML_Char *storedversion = NULL; |
|
2869 int standalone = -1; |
|
2870 if (!(ns |
|
2871 ? XmlParseXmlDeclNS |
|
2872 : XmlParseXmlDecl)(isGeneralTextEntity, |
|
2873 encoding, |
|
2874 s, |
|
2875 next, |
|
2876 &eventPtr, |
|
2877 &version, |
|
2878 &versionend, |
|
2879 &encodingName, |
|
2880 &newEncoding, |
|
2881 &standalone)) |
|
2882 return XML_ERROR_SYNTAX; |
|
2883 if (!isGeneralTextEntity && standalone == 1) { |
|
2884 dtd.standalone = XML_TRUE; |
|
2885 #ifdef XML_DTD |
|
2886 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) |
|
2887 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; |
|
2888 #endif /* XML_DTD */ |
|
2889 } |
|
2890 if (xmlDeclHandler) { |
|
2891 if (encodingName != NULL) { |
|
2892 storedEncName = poolStoreString(&temp2Pool, |
|
2893 encoding, |
|
2894 encodingName, |
|
2895 encodingName |
|
2896 + XmlNameLength(encoding, encodingName)); |
|
2897 if (!storedEncName) |
|
2898 return XML_ERROR_NO_MEMORY; |
|
2899 poolFinish(&temp2Pool); |
|
2900 } |
|
2901 if (version) { |
|
2902 storedversion = poolStoreString(&temp2Pool, |
|
2903 encoding, |
|
2904 version, |
|
2905 versionend - encoding->minBytesPerChar); |
|
2906 if (!storedversion) |
|
2907 return XML_ERROR_NO_MEMORY; |
|
2908 } |
|
2909 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); |
|
2910 } |
|
2911 else if (defaultHandler) |
|
2912 reportDefault(parser, encoding, s, next); |
|
2913 if (protocolEncodingName == NULL) { |
|
2914 if (newEncoding) { |
|
2915 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { |
|
2916 eventPtr = encodingName; |
|
2917 return XML_ERROR_INCORRECT_ENCODING; |
|
2918 } |
|
2919 encoding = newEncoding; |
|
2920 } |
|
2921 else if (encodingName) { |
|
2922 enum XML_Error result; |
|
2923 if (!storedEncName) { |
|
2924 storedEncName = poolStoreString( |
|
2925 &temp2Pool, encoding, encodingName, |
|
2926 encodingName + XmlNameLength(encoding, encodingName)); |
|
2927 if (!storedEncName) |
|
2928 return XML_ERROR_NO_MEMORY; |
|
2929 } |
|
2930 result = handleUnknownEncoding(parser, storedEncName); |
|
2931 poolClear(&temp2Pool); |
|
2932 if (result == XML_ERROR_UNKNOWN_ENCODING) |
|
2933 eventPtr = encodingName; |
|
2934 return result; |
|
2935 } |
|
2936 } |
|
2937 |
|
2938 if (storedEncName || storedversion) |
|
2939 poolClear(&temp2Pool); |
|
2940 |
|
2941 return XML_ERROR_NONE; |
|
2942 } |
|
2943 |
|
2944 static enum XML_Error FASTCALL |
|
2945 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) |
|
2946 { |
|
2947 #ifndef SYMBIAN_MIN_SIZE |
|
2948 if (unknownEncodingHandler) { |
|
2949 XML_Encoding info; |
|
2950 int i; |
|
2951 for (i = 0; i < 256; i++) |
|
2952 info.map[i] = -1; |
|
2953 info.convert = NULL; |
|
2954 info.data = NULL; |
|
2955 info.release = NULL; |
|
2956 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, |
|
2957 &info)) { |
|
2958 ENCODING *enc; |
|
2959 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); |
|
2960 if (!unknownEncodingMem) { |
|
2961 if (info.release) |
|
2962 info.release(info.data); |
|
2963 return XML_ERROR_NO_MEMORY; |
|
2964 } |
|
2965 enc = (ns |
|
2966 ? XmlInitUnknownEncodingNS |
|
2967 : XmlInitUnknownEncoding)(unknownEncodingMem, |
|
2968 info.map, |
|
2969 info.convert, |
|
2970 info.data); |
|
2971 if (enc) { |
|
2972 unknownEncodingData = info.data; |
|
2973 unknownEncodingRelease = info.release; |
|
2974 encoding = enc; |
|
2975 return XML_ERROR_NONE; |
|
2976 } |
|
2977 } |
|
2978 if (info.release != NULL) |
|
2979 info.release(info.data); |
|
2980 } |
|
2981 #endif // SYMBIAN_MIN_SIZE |
|
2982 return XML_ERROR_UNKNOWN_ENCODING; |
|
2983 } |
|
2984 |
|
2985 static enum XML_Error FASTCALL |
|
2986 prologInitProcessor(XML_Parser parser, |
|
2987 const char *s, |
|
2988 const char *end, |
|
2989 const char **nextPtr) |
|
2990 { |
|
2991 enum XML_Error result = initializeEncoding(parser); |
|
2992 if (result != XML_ERROR_NONE) |
|
2993 return result; |
|
2994 processor = prologProcessor; |
|
2995 return prologProcessor(parser, s, end, nextPtr); |
|
2996 } |
|
2997 |
|
2998 #ifdef XML_DTD |
|
2999 |
|
3000 static enum XML_Error FASTCALL |
|
3001 externalParEntInitProcessor(XML_Parser parser, |
|
3002 const char *s, |
|
3003 const char *end, |
|
3004 const char **nextPtr) |
|
3005 { |
|
3006 enum XML_Error result = initializeEncoding(parser); |
|
3007 if (result != XML_ERROR_NONE) |
|
3008 return result; |
|
3009 |
|
3010 /* we know now that XML_Parse(Buffer) has been called, |
|
3011 so we consider the external parameter entity read */ |
|
3012 dtd.paramEntityRead = XML_TRUE; |
|
3013 |
|
3014 if (prologState.inEntityValue) { |
|
3015 processor = entityValueInitProcessor; |
|
3016 return entityValueInitProcessor(parser, s, end, nextPtr); |
|
3017 } |
|
3018 else { |
|
3019 processor = externalParEntProcessor; |
|
3020 return externalParEntProcessor(parser, s, end, nextPtr); |
|
3021 } |
|
3022 } |
|
3023 |
|
3024 static enum XML_Error FASTCALL |
|
3025 entityValueInitProcessor(XML_Parser parser, |
|
3026 const char *s, |
|
3027 const char *end, |
|
3028 const char **nextPtr) |
|
3029 { |
|
3030 const char *start = s; |
|
3031 const char *next = s; |
|
3032 int tok; |
|
3033 |
|
3034 for (;;) { |
|
3035 tok = XmlPrologTok(encoding, start, end, &next); |
|
3036 if (tok <= 0) { |
|
3037 if (nextPtr != 0 && tok != XML_TOK_INVALID) { |
|
3038 *nextPtr = s; |
|
3039 return XML_ERROR_NONE; |
|
3040 } |
|
3041 switch (tok) { |
|
3042 case XML_TOK_INVALID: |
|
3043 return XML_ERROR_INVALID_TOKEN; |
|
3044 case XML_TOK_PARTIAL: |
|
3045 return XML_ERROR_UNCLOSED_TOKEN; |
|
3046 case XML_TOK_PARTIAL_CHAR: |
|
3047 return XML_ERROR_PARTIAL_CHAR; |
|
3048 case XML_TOK_NONE: /* start == end */ |
|
3049 default: |
|
3050 break; |
|
3051 } |
|
3052 return storeEntityValue(parser, encoding, s, end); |
|
3053 } |
|
3054 else if (tok == XML_TOK_XML_DECL) { |
|
3055 enum XML_Error result = processXmlDecl(parser, 0, start, next); |
|
3056 if (result != XML_ERROR_NONE) |
|
3057 return result; |
|
3058 if (nextPtr) *nextPtr = next; |
|
3059 /* stop scanning for text declaration - we found one */ |
|
3060 processor = entityValueProcessor; |
|
3061 return entityValueProcessor(parser, next, end, nextPtr); |
|
3062 } |
|
3063 /* If we are at the end of the buffer, this would cause XmlPrologTok to |
|
3064 return XML_TOK_NONE on the next call, which would then cause the |
|
3065 function to exit with *nextPtr set to s - that is what we want for other |
|
3066 tokens, but not for the BOM - we would rather like to skip it; |
|
3067 then, when this routine is entered the next time, XmlPrologTok will |
|
3068 return XML_TOK_INVALID, since the BOM is still in the buffer |
|
3069 */ |
|
3070 else if (tok == XML_TOK_BOM && next == end && nextPtr) { |
|
3071 *nextPtr = next; |
|
3072 return XML_ERROR_NONE; |
|
3073 } |
|
3074 start = next; |
|
3075 } |
|
3076 } |
|
3077 |
|
3078 static enum XML_Error FASTCALL |
|
3079 externalParEntProcessor(XML_Parser parser, |
|
3080 const char *s, |
|
3081 const char *end, |
|
3082 const char **nextPtr) |
|
3083 { |
|
3084 const char *start = s; |
|
3085 const char *next = s; |
|
3086 int tok; |
|
3087 |
|
3088 tok = XmlPrologTok(encoding, start, end, &next); |
|
3089 if (tok <= 0) { |
|
3090 if (nextPtr != 0 && tok != XML_TOK_INVALID) { |
|
3091 *nextPtr = s; |
|
3092 return XML_ERROR_NONE; |
|
3093 } |
|
3094 switch (tok) { |
|
3095 case XML_TOK_INVALID: |
|
3096 return XML_ERROR_INVALID_TOKEN; |
|
3097 case XML_TOK_PARTIAL: |
|
3098 return XML_ERROR_UNCLOSED_TOKEN; |
|
3099 case XML_TOK_PARTIAL_CHAR: |
|
3100 return XML_ERROR_PARTIAL_CHAR; |
|
3101 case XML_TOK_NONE: /* start == end */ |
|
3102 default: |
|
3103 break; |
|
3104 } |
|
3105 } |
|
3106 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. |
|
3107 However, when parsing an external subset, doProlog will not accept a BOM |
|
3108 as valid, and report a syntax error, so we have to skip the BOM |
|
3109 */ |
|
3110 else if (tok == XML_TOK_BOM) { |
|
3111 s = next; |
|
3112 tok = XmlPrologTok(encoding, s, end, &next); |
|
3113 } |
|
3114 |
|
3115 processor = prologProcessor; |
|
3116 return doProlog(parser, encoding, s, end, tok, next, nextPtr); |
|
3117 } |
|
3118 |
|
3119 static enum XML_Error FASTCALL |
|
3120 entityValueProcessor(XML_Parser parser, |
|
3121 const char *s, |
|
3122 const char *end, |
|
3123 const char **nextPtr) |
|
3124 { |
|
3125 const char *start = s; |
|
3126 const char *next = s; |
|
3127 const ENCODING *enc = encoding; |
|
3128 int tok; |
|
3129 |
|
3130 for (;;) { |
|
3131 tok = XmlPrologTok(enc, start, end, &next); |
|
3132 if (tok <= 0) { |
|
3133 if (nextPtr != 0 && tok != XML_TOK_INVALID) { |
|
3134 *nextPtr = s; |
|
3135 return XML_ERROR_NONE; |
|
3136 } |
|
3137 switch (tok) { |
|
3138 case XML_TOK_INVALID: |
|
3139 return XML_ERROR_INVALID_TOKEN; |
|
3140 case XML_TOK_PARTIAL: |
|
3141 return XML_ERROR_UNCLOSED_TOKEN; |
|
3142 case XML_TOK_PARTIAL_CHAR: |
|
3143 return XML_ERROR_PARTIAL_CHAR; |
|
3144 case XML_TOK_NONE: /* start == end */ |
|
3145 default: |
|
3146 break; |
|
3147 } |
|
3148 return storeEntityValue(parser, enc, s, end); |
|
3149 } |
|
3150 start = next; |
|
3151 } |
|
3152 } |
|
3153 |
|
3154 #endif /* XML_DTD */ |
|
3155 |
|
3156 static enum XML_Error FASTCALL |
|
3157 prologProcessor(XML_Parser parser, |
|
3158 const char *s, |
|
3159 const char *end, |
|
3160 const char **nextPtr) |
|
3161 { |
|
3162 const char *next = s; |
|
3163 int tok = XmlPrologTok(encoding, s, end, &next); |
|
3164 return doProlog(parser, encoding, s, end, tok, next, nextPtr); |
|
3165 } |
|
3166 |
|
3167 static enum XML_Error FASTCALL |
|
3168 doProlog(XML_Parser parser, |
|
3169 const ENCODING *enc, |
|
3170 const char *s, |
|
3171 const char *end, |
|
3172 int tok, |
|
3173 const char *next, |
|
3174 const char **nextPtr) |
|
3175 { |
|
3176 #ifdef XML_DTD |
|
3177 static const XML_Char externalSubsetName[] = { '#' , '\0' }; |
|
3178 #endif /* XML_DTD */ |
|
3179 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' }; |
|
3180 static const XML_Char atypeID[] = { 'I', 'D', '\0' }; |
|
3181 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' }; |
|
3182 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' }; |
|
3183 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' }; |
|
3184 static const XML_Char atypeENTITIES[] = |
|
3185 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' }; |
|
3186 static const XML_Char atypeNMTOKEN[] = { |
|
3187 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' }; |
|
3188 static const XML_Char atypeNMTOKENS[] = { |
|
3189 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' }; |
|
3190 |
|
3191 #ifndef SYMBIAN_MIN_SIZE |
|
3192 static const XML_Char notationPrefix[] = { |
|
3193 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' }; |
|
3194 static const XML_Char enumValueSep[] = { '|', '\0' }; |
|
3195 static const XML_Char enumValueStart[] = { '(', '\0' }; |
|
3196 #endif // SYMBIAN_MIN_SIZE |
|
3197 |
|
3198 const char **eventPP; |
|
3199 const char **eventEndPP; |
|
3200 enum XML_Content_Quant quant; |
|
3201 |
|
3202 if (enc == encoding) { |
|
3203 eventPP = &eventPtr; |
|
3204 eventEndPP = &eventEndPtr; |
|
3205 } |
|
3206 else { |
|
3207 eventPP = &(openInternalEntities->internalEventPtr); |
|
3208 eventEndPP = &(openInternalEntities->internalEventEndPtr); |
|
3209 } |
|
3210 for (;;) { |
|
3211 int role; |
|
3212 XML_Bool handleDefault = XML_TRUE; |
|
3213 *eventPP = s; |
|
3214 *eventEndPP = next; |
|
3215 if (tok <= 0) { |
|
3216 if (nextPtr != 0 && tok != XML_TOK_INVALID) { |
|
3217 *nextPtr = s; |
|
3218 return XML_ERROR_NONE; |
|
3219 } |
|
3220 switch (tok) { |
|
3221 case XML_TOK_INVALID: |
|
3222 *eventPP = next; |
|
3223 return XML_ERROR_INVALID_TOKEN; |
|
3224 case XML_TOK_PARTIAL: |
|
3225 return XML_ERROR_UNCLOSED_TOKEN; |
|
3226 case XML_TOK_PARTIAL_CHAR: |
|
3227 return XML_ERROR_PARTIAL_CHAR; |
|
3228 case XML_TOK_NONE: |
|
3229 #ifdef XML_DTD |
|
3230 if (enc != encoding) |
|
3231 return XML_ERROR_NONE; |
|
3232 if (isParamEntity) { |
|
3233 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) |
|
3234 == XML_ROLE_ERROR) |
|
3235 return XML_ERROR_SYNTAX; |
|
3236 return XML_ERROR_NONE; |
|
3237 } |
|
3238 #endif /* XML_DTD */ |
|
3239 return XML_ERROR_NO_ELEMENTS; |
|
3240 default: |
|
3241 tok = -tok; |
|
3242 next = end; |
|
3243 break; |
|
3244 } |
|
3245 } |
|
3246 role = XmlTokenRole(&prologState, tok, s, next, enc); |
|
3247 switch (role) { |
|
3248 case XML_ROLE_XML_DECL: |
|
3249 { |
|
3250 enum XML_Error result = processXmlDecl(parser, 0, s, next); |
|
3251 if (result != XML_ERROR_NONE) |
|
3252 return result; |
|
3253 enc = encoding; |
|
3254 handleDefault = XML_FALSE; |
|
3255 } |
|
3256 break; |
|
3257 case XML_ROLE_DOCTYPE_NAME: |
|
3258 #ifndef SYMBIAN_MIN_SIZE |
|
3259 if (startDoctypeDeclHandler) { |
|
3260 doctypeName = poolStoreString(&tempPool, enc, s, next); |
|
3261 if (!doctypeName) |
|
3262 return XML_ERROR_NO_MEMORY; |
|
3263 poolFinish(&tempPool); |
|
3264 doctypePubid = NULL; |
|
3265 handleDefault = XML_FALSE; |
|
3266 } |
|
3267 #endif // SYMBIAN_MIN_SIZE |
|
3268 doctypeSysid = NULL; /* always initialize to NULL */ |
|
3269 break; |
|
3270 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: |
|
3271 #ifndef SYMBIAN_MIN_SIZE |
|
3272 if (startDoctypeDeclHandler) { |
|
3273 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, |
|
3274 doctypePubid, 1); |
|
3275 doctypeName = NULL; |
|
3276 poolClear(&tempPool); |
|
3277 handleDefault = XML_FALSE; |
|
3278 } |
|
3279 #endif // SYMBIAN_MIN_SIZE |
|
3280 break; |
|
3281 #ifdef XML_DTD |
|
3282 case XML_ROLE_TEXT_DECL: |
|
3283 { |
|
3284 enum XML_Error result = processXmlDecl(parser, 1, s, next); |
|
3285 if (result != XML_ERROR_NONE) |
|
3286 return result; |
|
3287 enc = encoding; |
|
3288 handleDefault = XML_FALSE; |
|
3289 } |
|
3290 break; |
|
3291 #endif /* XML_DTD */ |
|
3292 case XML_ROLE_DOCTYPE_PUBLIC_ID: |
|
3293 #ifdef XML_DTD |
|
3294 useForeignDTD = XML_FALSE; |
|
3295 #endif /* XML_DTD */ |
|
3296 dtd.hasParamEntityRefs = XML_TRUE; |
|
3297 #ifndef SYMBIAN_MIN_SIZE |
|
3298 if (startDoctypeDeclHandler) { |
|
3299 doctypePubid = poolStoreString(&tempPool, enc, |
|
3300 s + enc->minBytesPerChar, |
|
3301 next - enc->minBytesPerChar); |
|
3302 if (!doctypePubid) |
|
3303 return XML_ERROR_NO_MEMORY; |
|
3304 poolFinish(&tempPool); |
|
3305 handleDefault = XML_FALSE; |
|
3306 } |
|
3307 #endif // SYMBIAN_MIN_SIZE |
|
3308 #ifdef XML_DTD |
|
3309 declEntity = (ENTITY *)lookup(&dtd.paramEntities, |
|
3310 externalSubsetName, |
|
3311 sizeof(ENTITY)); |
|
3312 if (!declEntity) |
|
3313 return XML_ERROR_NO_MEMORY; |
|
3314 #endif /* XML_DTD */ |
|
3315 /* fall through */ |
|
3316 case XML_ROLE_ENTITY_PUBLIC_ID: |
|
3317 if (!XmlIsPublicId(enc, s, next, eventPP)) |
|
3318 return XML_ERROR_SYNTAX; |
|
3319 if (dtd.keepProcessing && declEntity) { |
|
3320 XML_Char *tem = poolStoreString(&dtd.pool, |
|
3321 enc, |
|
3322 s + enc->minBytesPerChar, |
|
3323 next - enc->minBytesPerChar); |
|
3324 if (!tem) |
|
3325 return XML_ERROR_NO_MEMORY; |
|
3326 normalizePublicId(tem); |
|
3327 declEntity->publicId = tem; |
|
3328 poolFinish(&dtd.pool); |
|
3329 if (entityDeclHandler) |
|
3330 handleDefault = XML_FALSE; |
|
3331 } |
|
3332 break; |
|
3333 case XML_ROLE_DOCTYPE_CLOSE: |
|
3334 if (doctypeName) { |
|
3335 startDoctypeDeclHandler(handlerArg, doctypeName, |
|
3336 doctypeSysid, doctypePubid, 0); |
|
3337 poolClear(&tempPool); |
|
3338 handleDefault = XML_FALSE; |
|
3339 } |
|
3340 /* doctypeSysid will be non-NULL in the case of a previous |
|
3341 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler |
|
3342 was not set, indicating an external subset |
|
3343 */ |
|
3344 #ifdef XML_DTD |
|
3345 if (doctypeSysid || useForeignDTD) { |
|
3346 dtd.hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */ |
|
3347 if (paramEntityParsing && externalEntityRefHandler) { |
|
3348 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities, |
|
3349 externalSubsetName, |
|
3350 sizeof(ENTITY)); |
|
3351 if (!entity) |
|
3352 return XML_ERROR_NO_MEMORY; |
|
3353 if (useForeignDTD) |
|
3354 entity->base = curBase; |
|
3355 dtd.paramEntityRead = XML_FALSE; |
|
3356 if (!externalEntityRefHandler(handlerArg, name)) |
|
3357 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
|
3358 if (dtd.paramEntityRead && |
|
3359 !dtd.standalone && |
|
3360 notStandaloneHandler && |
|
3361 !notStandaloneHandler(handlerArg)) |
|
3362 return XML_ERROR_NOT_STANDALONE; |
|
3363 /* end of DTD - no need to update dtd.keepProcessing */ |
|
3364 } |
|
3365 useForeignDTD = XML_FALSE; |
|
3366 } |
|
3367 #endif /* XML_DTD */ |
|
3368 #ifndef SYMBIAN_MIN_SIZE |
|
3369 if (endDoctypeDeclHandler) { |
|
3370 endDoctypeDeclHandler(handlerArg); |
|
3371 handleDefault = XML_FALSE; |
|
3372 } |
|
3373 #endif // SYMBIAN_MIN_SIZE |
|
3374 break; |
|
3375 case XML_ROLE_INSTANCE_START: |
|
3376 #ifdef XML_DTD |
|
3377 /* if there is no DOCTYPE declaration then now is the |
|
3378 last chance to read the foreign DTD |
|
3379 */ |
|
3380 if (useForeignDTD) { |
|
3381 dtd.hasParamEntityRefs = XML_TRUE; |
|
3382 if (paramEntityParsing && externalEntityRefHandler) { |
|
3383 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities, |
|
3384 externalSubsetName, |
|
3385 sizeof(ENTITY)); |
|
3386 if (!entity) |
|
3387 return XML_ERROR_NO_MEMORY; |
|
3388 entity->base = curBase; |
|
3389 dtd.paramEntityRead = XML_FALSE; |
|
3390 if (!externalEntityRefHandler(handlerArg, name)) |
|
3391 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
|
3392 if (dtd.paramEntityRead && |
|
3393 !dtd.standalone && |
|
3394 notStandaloneHandler && |
|
3395 !notStandaloneHandler(handlerArg)) |
|
3396 return XML_ERROR_NOT_STANDALONE; |
|
3397 /* end of DTD - no need to update dtd.keepProcessing */ |
|
3398 } |
|
3399 } |
|
3400 #endif /* XML_DTD */ |
|
3401 processor = contentProcessor; |
|
3402 return contentProcessor(parser, s, end, nextPtr); |
|
3403 case XML_ROLE_ATTLIST_ELEMENT_NAME: |
|
3404 declElementType = getElementType(parser, enc, s, next); |
|
3405 if (!declElementType) |
|
3406 return XML_ERROR_NO_MEMORY; |
|
3407 goto checkAttListDeclHandler; |
|
3408 case XML_ROLE_ATTRIBUTE_NAME: |
|
3409 declAttributeId = getAttributeId(parser, enc, s, next); |
|
3410 if (!declAttributeId) |
|
3411 return XML_ERROR_NO_MEMORY; |
|
3412 declAttributeIsCdata = XML_FALSE; |
|
3413 declAttributeType = NULL; |
|
3414 declAttributeIsId = XML_FALSE; |
|
3415 goto checkAttListDeclHandler; |
|
3416 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: |
|
3417 declAttributeIsCdata = XML_TRUE; |
|
3418 declAttributeType = atypeCDATA; |
|
3419 goto checkAttListDeclHandler; |
|
3420 case XML_ROLE_ATTRIBUTE_TYPE_ID: |
|
3421 declAttributeIsId = XML_TRUE; |
|
3422 declAttributeType = atypeID; |
|
3423 goto checkAttListDeclHandler; |
|
3424 case XML_ROLE_ATTRIBUTE_TYPE_IDREF: |
|
3425 declAttributeType = atypeIDREF; |
|
3426 goto checkAttListDeclHandler; |
|
3427 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: |
|
3428 declAttributeType = atypeIDREFS; |
|
3429 goto checkAttListDeclHandler; |
|
3430 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: |
|
3431 declAttributeType = atypeENTITY; |
|
3432 goto checkAttListDeclHandler; |
|
3433 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: |
|
3434 declAttributeType = atypeENTITIES; |
|
3435 goto checkAttListDeclHandler; |
|
3436 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: |
|
3437 declAttributeType = atypeNMTOKEN; |
|
3438 goto checkAttListDeclHandler; |
|
3439 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: |
|
3440 declAttributeType = atypeNMTOKENS; |
|
3441 checkAttListDeclHandler: |
|
3442 if (dtd.keepProcessing && attlistDeclHandler) |
|
3443 handleDefault = XML_FALSE; |
|
3444 break; |
|
3445 case XML_ROLE_ATTRIBUTE_ENUM_VALUE: |
|
3446 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: |
|
3447 #ifndef SYMBIAN_MIN_SIZE |
|
3448 if (dtd.keepProcessing && attlistDeclHandler) { |
|
3449 const XML_Char *prefix; |
|
3450 if (declAttributeType) { |
|
3451 prefix = enumValueSep; |
|
3452 } |
|
3453 else { |
|
3454 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE |
|
3455 ? notationPrefix |
|
3456 : enumValueStart); |
|
3457 } |
|
3458 if (!poolAppendString(&tempPool, prefix)) |
|
3459 return XML_ERROR_NO_MEMORY; |
|
3460 if (!poolAppend(&tempPool, enc, s, next)) |
|
3461 return XML_ERROR_NO_MEMORY; |
|
3462 declAttributeType = tempPool.start; |
|
3463 handleDefault = XML_FALSE; |
|
3464 } |
|
3465 #endif // SYMBIAN_MIN_SIZE |
|
3466 break; |
|
3467 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: |
|
3468 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: |
|
3469 if (dtd.keepProcessing) { |
|
3470 if (!defineAttribute(declElementType, declAttributeId, |
|
3471 declAttributeIsCdata, declAttributeIsId, 0, |
|
3472 parser)) |
|
3473 return XML_ERROR_NO_MEMORY; |
|
3474 #ifndef SYMBIAN_MIN_SIZE |
|
3475 if (attlistDeclHandler && declAttributeType) { |
|
3476 if (*declAttributeType == XML_T('(') |
|
3477 || (*declAttributeType == XML_T('N') |
|
3478 && declAttributeType[1] == XML_T('O'))) { |
|
3479 /* Enumerated or Notation type */ |
|
3480 if (!poolAppendChar(&tempPool, XML_T(')')) |
|
3481 || !poolAppendChar(&tempPool, XML_T('\0'))) |
|
3482 return XML_ERROR_NO_MEMORY; |
|
3483 declAttributeType = tempPool.start; |
|
3484 poolFinish(&tempPool); |
|
3485 } |
|
3486 *eventEndPP = s; |
|
3487 attlistDeclHandler(handlerArg, declElementType->name, |
|
3488 declAttributeId->name, declAttributeType, |
|
3489 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); |
|
3490 poolClear(&tempPool); |
|
3491 handleDefault = XML_FALSE; |
|
3492 } |
|
3493 #endif // SYMBIAN_MIN_SIZE |
|
3494 } |
|
3495 break; |
|
3496 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: |
|
3497 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: |
|
3498 if (dtd.keepProcessing) { |
|
3499 const XML_Char *attVal; |
|
3500 enum XML_Error result |
|
3501 = storeAttributeValue(parser, enc, declAttributeIsCdata, |
|
3502 s + enc->minBytesPerChar, |
|
3503 next - enc->minBytesPerChar, |
|
3504 &dtd.pool); |
|
3505 if (result) |
|
3506 return result; |
|
3507 attVal = poolStart(&dtd.pool); |
|
3508 poolFinish(&dtd.pool); |
|
3509 /* ID attributes aren't allowed to have a default */ |
|
3510 if (!defineAttribute(declElementType, declAttributeId, |
|
3511 declAttributeIsCdata, XML_FALSE, attVal, parser)) |
|
3512 return XML_ERROR_NO_MEMORY; |
|
3513 #ifndef SYMBIAN_MIN_SIZE |
|
3514 if (attlistDeclHandler && declAttributeType) { |
|
3515 if (*declAttributeType == XML_T('(') |
|
3516 || (*declAttributeType == XML_T('N') |
|
3517 && declAttributeType[1] == XML_T('O'))) { |
|
3518 /* Enumerated or Notation type */ |
|
3519 if (!poolAppendChar(&tempPool, XML_T(')')) |
|
3520 || !poolAppendChar(&tempPool, XML_T('\0'))) |
|
3521 return XML_ERROR_NO_MEMORY; |
|
3522 declAttributeType = tempPool.start; |
|
3523 poolFinish(&tempPool); |
|
3524 } |
|
3525 *eventEndPP = s; |
|
3526 attlistDeclHandler(handlerArg, declElementType->name, |
|
3527 declAttributeId->name, declAttributeType, |
|
3528 attVal, |
|
3529 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); |
|
3530 poolClear(&tempPool); |
|
3531 handleDefault = XML_FALSE; |
|
3532 } |
|
3533 #endif // SYMBIAN_MIN_SIZE |
|
3534 } |
|
3535 break; |
|
3536 case XML_ROLE_ENTITY_VALUE: |
|
3537 if (dtd.keepProcessing) { |
|
3538 enum XML_Error result = storeEntityValue(parser, enc, |
|
3539 s + enc->minBytesPerChar, |
|
3540 next - enc->minBytesPerChar); |
|
3541 if (declEntity) { |
|
3542 declEntity->textPtr = poolStart(&dtd.entityValuePool); |
|
3543 declEntity->textLen = poolLength(&dtd.entityValuePool); |
|
3544 poolFinish(&dtd.entityValuePool); |
|
3545 #ifndef SYMBIAN_MIN_SIZE |
|
3546 if (entityDeclHandler) { |
|
3547 *eventEndPP = s; |
|
3548 entityDeclHandler(handlerArg, |
|
3549 declEntity->name, |
|
3550 declEntity->is_param, |
|
3551 declEntity->textPtr, |
|
3552 declEntity->textLen, |
|
3553 curBase, 0, 0, 0); |
|
3554 handleDefault = XML_FALSE; |
|
3555 } |
|
3556 #endif // SYMBIAN_MIN_SIZE |
|
3557 } |
|
3558 else |
|
3559 poolDiscard(&dtd.entityValuePool); |
|
3560 if (result != XML_ERROR_NONE) |
|
3561 return result; |
|
3562 } |
|
3563 break; |
|
3564 case XML_ROLE_DOCTYPE_SYSTEM_ID: |
|
3565 #ifdef XML_DTD |
|
3566 useForeignDTD = XML_FALSE; |
|
3567 #endif /* XML_DTD */ |
|
3568 dtd.hasParamEntityRefs = XML_TRUE; |
|
3569 #ifndef SYMBIAN_MIN_SIZE |
|
3570 if (startDoctypeDeclHandler) { |
|
3571 doctypeSysid = poolStoreString(&tempPool, enc, |
|
3572 s + enc->minBytesPerChar, |
|
3573 next - enc->minBytesPerChar); |
|
3574 if (doctypeSysid == NULL) |
|
3575 return XML_ERROR_NO_MEMORY; |
|
3576 poolFinish(&tempPool); |
|
3577 handleDefault = XML_FALSE; |
|
3578 } |
|
3579 #endif // SYMBIAN_MIN_SIZE |
|
3580 #ifdef XML_DTD |
|
3581 else |
|
3582 /* use externalSubsetName to make doctypeSysid non-NULL |
|
3583 for the case where no startDoctypeDeclHandler is set */ |
|
3584 doctypeSysid = externalSubsetName; |
|
3585 #endif /* XML_DTD */ |
|
3586 if (!dtd.standalone |
|
3587 #ifdef XML_DTD |
|
3588 && !paramEntityParsing |
|
3589 #endif /* XML_DTD */ |
|
3590 && notStandaloneHandler |
|
3591 && !notStandaloneHandler(handlerArg)) |
|
3592 return XML_ERROR_NOT_STANDALONE; |
|
3593 #ifndef XML_DTD |
|
3594 break; |
|
3595 #else /* XML_DTD */ |
|
3596 if (!declEntity) { |
|
3597 declEntity = (ENTITY *)lookup(&dtd.paramEntities, |
|
3598 externalSubsetName, |
|
3599 sizeof(ENTITY)); |
|
3600 if (!declEntity) |
|
3601 return XML_ERROR_NO_MEMORY; |
|
3602 declEntity->publicId = NULL; |
|
3603 } |
|
3604 /* fall through */ |
|
3605 #endif /* XML_DTD */ |
|
3606 case XML_ROLE_ENTITY_SYSTEM_ID: |
|
3607 if (dtd.keepProcessing && declEntity) { |
|
3608 declEntity->systemId = poolStoreString(&dtd.pool, enc, |
|
3609 s + enc->minBytesPerChar, |
|
3610 next - enc->minBytesPerChar); |
|
3611 if (!declEntity->systemId) |
|
3612 return XML_ERROR_NO_MEMORY; |
|
3613 declEntity->base = curBase; |
|
3614 poolFinish(&dtd.pool); |
|
3615 if (entityDeclHandler) |
|
3616 handleDefault = XML_FALSE; |
|
3617 } |
|
3618 break; |
|
3619 case XML_ROLE_ENTITY_COMPLETE: |
|
3620 #ifndef SYMBIAN_MIN_SIZE |
|
3621 if (dtd.keepProcessing && declEntity && entityDeclHandler) { |
|
3622 *eventEndPP = s; |
|
3623 entityDeclHandler(handlerArg, |
|
3624 declEntity->name, |
|
3625 declEntity->is_param, |
|
3626 0,0, |
|
3627 declEntity->base, |
|
3628 declEntity->systemId, |
|
3629 declEntity->publicId, |
|
3630 0); |
|
3631 handleDefault = XML_FALSE; |
|
3632 } |
|
3633 #endif // SYMBIAN_MIN_SIZE |
|
3634 break; |
|
3635 case XML_ROLE_ENTITY_NOTATION_NAME: |
|
3636 if (dtd.keepProcessing && declEntity) { |
|
3637 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); |
|
3638 if (!declEntity->notation) |
|
3639 return XML_ERROR_NO_MEMORY; |
|
3640 poolFinish(&dtd.pool); |
|
3641 #ifndef SYMBIAN_MIN_SIZE |
|
3642 if (unparsedEntityDeclHandler) { |
|
3643 *eventEndPP = s; |
|
3644 unparsedEntityDeclHandler(handlerArg, |
|
3645 declEntity->name, |
|
3646 declEntity->base, |
|
3647 declEntity->systemId, |
|
3648 declEntity->publicId, |
|
3649 declEntity->notation); |
|
3650 handleDefault = XML_FALSE; |
|
3651 } |
|
3652 else if (entityDeclHandler) { |
|
3653 *eventEndPP = s; |
|
3654 entityDeclHandler(handlerArg, |
|
3655 declEntity->name, |
|
3656 0,0,0, |
|
3657 declEntity->base, |
|
3658 declEntity->systemId, |
|
3659 declEntity->publicId, |
|
3660 declEntity->notation); |
|
3661 handleDefault = XML_FALSE; |
|
3662 } |
|
3663 #endif // SYMBIAN_MIN_SIZE |
|
3664 } |
|
3665 break; |
|
3666 case XML_ROLE_GENERAL_ENTITY_NAME: |
|
3667 { |
|
3668 if (XmlPredefinedEntityName(enc, s, next)) { |
|
3669 declEntity = NULL; |
|
3670 break; |
|
3671 } |
|
3672 if (dtd.keepProcessing) { |
|
3673 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); |
|
3674 if (!name) |
|
3675 return XML_ERROR_NO_MEMORY; |
|
3676 declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, |
|
3677 sizeof(ENTITY)); |
|
3678 if (!declEntity) |
|
3679 return XML_ERROR_NO_MEMORY; |
|
3680 if (declEntity->name != name) { |
|
3681 poolDiscard(&dtd.pool); |
|
3682 declEntity = NULL; |
|
3683 } |
|
3684 else { |
|
3685 poolFinish(&dtd.pool); |
|
3686 declEntity->publicId = NULL; |
|
3687 declEntity->is_param = XML_FALSE; |
|
3688 /* if we have a parent parser or are reading an internal parameter |
|
3689 entity, then the entity declaration is not considered "internal" |
|
3690 */ |
|
3691 declEntity->is_internal = (XML_Bool)!(parentParser || openInternalEntities); |
|
3692 if (entityDeclHandler) |
|
3693 handleDefault = XML_FALSE; |
|
3694 } |
|
3695 } |
|
3696 else { |
|
3697 poolDiscard(&dtd.pool); |
|
3698 declEntity = NULL; |
|
3699 } |
|
3700 } |
|
3701 break; |
|
3702 case XML_ROLE_PARAM_ENTITY_NAME: |
|
3703 #ifdef XML_DTD |
|
3704 if (dtd.keepProcessing) { |
|
3705 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); |
|
3706 if (!name) |
|
3707 return XML_ERROR_NO_MEMORY; |
|
3708 declEntity = (ENTITY *)lookup(&dtd.paramEntities, |
|
3709 name, sizeof(ENTITY)); |
|
3710 if (!declEntity) |
|
3711 return XML_ERROR_NO_MEMORY; |
|
3712 if (declEntity->name != name) { |
|
3713 poolDiscard(&dtd.pool); |
|
3714 declEntity = NULL; |
|
3715 } |
|
3716 else { |
|
3717 poolFinish(&dtd.pool); |
|
3718 declEntity->publicId = NULL; |
|
3719 declEntity->is_param = XML_TRUE; |
|
3720 /* if we have a parent parser or are reading an internal parameter |
|
3721 entity, then the entity declaration is not considered "internal" |
|
3722 */ |
|
3723 declEntity->is_internal = (XML_Bool)!(parentParser || openInternalEntities); |
|
3724 if (entityDeclHandler) |
|
3725 handleDefault = XML_FALSE; |
|
3726 } |
|
3727 } |
|
3728 else { |
|
3729 poolDiscard(&dtd.pool); |
|
3730 declEntity = NULL; |
|
3731 } |
|
3732 #else /* not XML_DTD */ |
|
3733 declEntity = NULL; |
|
3734 #endif /* XML_DTD */ |
|
3735 break; |
|
3736 case XML_ROLE_NOTATION_NAME: |
|
3737 declNotationPublicId = NULL; |
|
3738 declNotationName = NULL; |
|
3739 #ifndef SYMBIAN_MIN_SIZE |
|
3740 if (notationDeclHandler) { |
|
3741 declNotationName = poolStoreString(&tempPool, enc, s, next); |
|
3742 if (!declNotationName) |
|
3743 return XML_ERROR_NO_MEMORY; |
|
3744 poolFinish(&tempPool); |
|
3745 handleDefault = XML_FALSE; |
|
3746 } |
|
3747 #endif // SYMBIAN_MIN_SIZE |
|
3748 break; |
|
3749 case XML_ROLE_NOTATION_PUBLIC_ID: |
|
3750 if (!XmlIsPublicId(enc, s, next, eventPP)) |
|
3751 return XML_ERROR_SYNTAX; |
|
3752 if (declNotationName) { /* means notationDeclHandler != NULL */ |
|
3753 XML_Char *tem = poolStoreString(&tempPool, |
|
3754 enc, |
|
3755 s + enc->minBytesPerChar, |
|
3756 next - enc->minBytesPerChar); |
|
3757 if (!tem) |
|
3758 return XML_ERROR_NO_MEMORY; |
|
3759 normalizePublicId(tem); |
|
3760 declNotationPublicId = tem; |
|
3761 poolFinish(&tempPool); |
|
3762 handleDefault = XML_FALSE; |
|
3763 } |
|
3764 break; |
|
3765 case XML_ROLE_NOTATION_SYSTEM_ID: |
|
3766 #ifndef SYMBIAN_MIN_SIZE |
|
3767 if (declNotationName && notationDeclHandler) { |
|
3768 const XML_Char *systemId |
|
3769 = poolStoreString(&tempPool, enc, |
|
3770 s + enc->minBytesPerChar, |
|
3771 next - enc->minBytesPerChar); |
|
3772 if (!systemId) |
|
3773 return XML_ERROR_NO_MEMORY; |
|
3774 *eventEndPP = s; |
|
3775 notationDeclHandler(handlerArg, |
|
3776 declNotationName, |
|
3777 curBase, |
|
3778 systemId, |
|
3779 declNotationPublicId); |
|
3780 handleDefault = XML_FALSE; |
|
3781 } |
|
3782 #endif // SYMBIAN_MIN_SIZE |
|
3783 poolClear(&tempPool); |
|
3784 break; |
|
3785 case XML_ROLE_NOTATION_NO_SYSTEM_ID: |
|
3786 #ifndef SYMBIAN_MIN_SIZE |
|
3787 if (declNotationPublicId && notationDeclHandler) { |
|
3788 *eventEndPP = s; |
|
3789 notationDeclHandler(handlerArg, |
|
3790 declNotationName, |
|
3791 curBase, |
|
3792 0, |
|
3793 declNotationPublicId); |
|
3794 handleDefault = XML_FALSE; |
|
3795 } |
|
3796 #endif // SYMBIAN_MIN_SIZE |
|
3797 poolClear(&tempPool); |
|
3798 break; |
|
3799 case XML_ROLE_ERROR: |
|
3800 switch (tok) { |
|
3801 case XML_TOK_PARAM_ENTITY_REF: |
|
3802 return XML_ERROR_PARAM_ENTITY_REF; |
|
3803 case XML_TOK_XML_DECL: |
|
3804 return XML_ERROR_MISPLACED_XML_PI; |
|
3805 default: |
|
3806 return XML_ERROR_SYNTAX; |
|
3807 } |
|
3808 #ifdef XML_DTD |
|
3809 case XML_ROLE_IGNORE_SECT: |
|
3810 { |
|
3811 enum XML_Error result; |
|
3812 if (defaultHandler) |
|
3813 reportDefault(parser, enc, s, next); |
|
3814 handleDefault = XML_FALSE; |
|
3815 result = doIgnoreSection(parser, enc, &next, end, nextPtr); |
|
3816 if (!next) { |
|
3817 processor = ignoreSectionProcessor; |
|
3818 return result; |
|
3819 } |
|
3820 } |
|
3821 break; |
|
3822 #endif /* XML_DTD */ |
|
3823 case XML_ROLE_GROUP_OPEN: |
|
3824 if (prologState.level >= groupSize) { |
|
3825 if (groupSize) { |
|
3826 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); |
|
3827 if (temp == NULL) |
|
3828 return XML_ERROR_NO_MEMORY; |
|
3829 groupConnector = temp; |
|
3830 if (dtd.scaffIndex) { |
|
3831 int *temp = (int *)REALLOC(dtd.scaffIndex, groupSize * sizeof(int)); |
|
3832 if (temp == NULL) |
|
3833 return XML_ERROR_NO_MEMORY; |
|
3834 dtd.scaffIndex = temp; |
|
3835 } |
|
3836 } |
|
3837 else { |
|
3838 groupConnector = (char *)MALLOC(groupSize = 32); |
|
3839 if (!groupConnector) |
|
3840 return XML_ERROR_NO_MEMORY; |
|
3841 } |
|
3842 } |
|
3843 groupConnector[prologState.level] = 0; |
|
3844 if (dtd.in_eldecl) { |
|
3845 int myindex = nextScaffoldPart(parser); |
|
3846 if (myindex < 0) |
|
3847 return XML_ERROR_NO_MEMORY; |
|
3848 if(dtd.scaffIndex != NULL) |
|
3849 { |
|
3850 dtd.scaffIndex[dtd.scaffLevel] = myindex; |
|
3851 dtd.scaffLevel++; |
|
3852 dtd.scaffold[myindex].type = XML_CTYPE_SEQ; |
|
3853 if (elementDeclHandler) |
|
3854 handleDefault = XML_FALSE; |
|
3855 } |
|
3856 } |
|
3857 break; |
|
3858 case XML_ROLE_GROUP_SEQUENCE: |
|
3859 if (groupConnector[prologState.level] == '|') |
|
3860 return XML_ERROR_SYNTAX; |
|
3861 groupConnector[prologState.level] = ','; |
|
3862 if (dtd.in_eldecl && elementDeclHandler) |
|
3863 handleDefault = XML_FALSE; |
|
3864 break; |
|
3865 case XML_ROLE_GROUP_CHOICE: |
|
3866 if (groupConnector[prologState.level] == ',') |
|
3867 return XML_ERROR_SYNTAX; |
|
3868 if (dtd.in_eldecl |
|
3869 && !groupConnector[prologState.level] |
|
3870 && (dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type |
|
3871 != XML_CTYPE_MIXED) |
|
3872 ) { |
|
3873 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type |
|
3874 = XML_CTYPE_CHOICE; |
|
3875 if (elementDeclHandler) |
|
3876 handleDefault = XML_FALSE; |
|
3877 } |
|
3878 groupConnector[prologState.level] = '|'; |
|
3879 break; |
|
3880 case XML_ROLE_PARAM_ENTITY_REF: |
|
3881 #ifdef XML_DTD |
|
3882 case XML_ROLE_INNER_PARAM_ENTITY_REF: |
|
3883 /* PE references in internal subset are |
|
3884 not allowed within declarations */ |
|
3885 if (prologState.documentEntity && |
|
3886 role == XML_ROLE_INNER_PARAM_ENTITY_REF) |
|
3887 return XML_ERROR_PARAM_ENTITY_REF; |
|
3888 dtd.hasParamEntityRefs = XML_TRUE; |
|
3889 if (!paramEntityParsing) |
|
3890 dtd.keepProcessing = dtd.standalone; |
|
3891 else { |
|
3892 const XML_Char *name; |
|
3893 ENTITY *entity; |
|
3894 name = poolStoreString(&dtd.pool, enc, |
|
3895 s + enc->minBytesPerChar, |
|
3896 next - enc->minBytesPerChar); |
|
3897 if (!name) |
|
3898 return XML_ERROR_NO_MEMORY; |
|
3899 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); |
|
3900 poolDiscard(&dtd.pool); |
|
3901 /* first, determine if a check for an existing declaration is needed; |
|
3902 if yes, check that the entity exists, and that it is internal, |
|
3903 otherwise call the skipped entity handler |
|
3904 */ |
|
3905 if (prologState.documentEntity && |
|
3906 (dtd.standalone |
|
3907 ? !openInternalEntities |
|
3908 : !dtd.hasParamEntityRefs)) { |
|
3909 if (!entity) |
|
3910 return XML_ERROR_UNDEFINED_ENTITY; |
|
3911 else if (!entity->is_internal) |
|
3912 return XML_ERROR_ENTITY_DECLARED_IN_PE; |
|
3913 } |
|
3914 else if (!entity) { |
|
3915 dtd.keepProcessing = dtd.standalone; |
|
3916 /* cannot report skipped entities in declarations */ |
|
3917 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { |
|
3918 skippedEntityHandler(handlerArg, name, 1); |
|
3919 handleDefault = XML_FALSE; |
|
3920 } |
|
3921 break; |
|
3922 } |
|
3923 if (entity->open) |
|
3924 return XML_ERROR_RECURSIVE_ENTITY_REF; |
|
3925 if (entity->textPtr) { |
|
3926 enum XML_Error result; |
|
3927 result = processInternalParamEntity(parser, entity); |
|
3928 if (result != XML_ERROR_NONE) |
|
3929 return result; |
|
3930 handleDefault = XML_FALSE; |
|
3931 break; |
|
3932 } |
|
3933 if (externalEntityRefHandler) { |
|
3934 dtd.paramEntityRead = XML_FALSE; |
|
3935 entity->open = XML_TRUE; |
|
3936 if (!externalEntityRefHandler(handlerArg, name)) { |
|
3937 entity->open = XML_FALSE; |
|
3938 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
|
3939 } |
|
3940 entity->open = XML_FALSE; |
|
3941 handleDefault = XML_FALSE; |
|
3942 if (!dtd.paramEntityRead) { |
|
3943 dtd.keepProcessing = dtd.standalone; |
|
3944 break; |
|
3945 } |
|
3946 } |
|
3947 else { |
|
3948 dtd.keepProcessing = dtd.standalone; |
|
3949 break; |
|
3950 } |
|
3951 } |
|
3952 #endif /* XML_DTD */ |
|
3953 if (!dtd.standalone && |
|
3954 notStandaloneHandler && |
|
3955 !notStandaloneHandler(handlerArg)) |
|
3956 return XML_ERROR_NOT_STANDALONE; |
|
3957 break; |
|
3958 |
|
3959 /* Element declaration stuff */ |
|
3960 |
|
3961 case XML_ROLE_ELEMENT_NAME: |
|
3962 #ifndef SYMBIAN_MIN_SIZE |
|
3963 if (elementDeclHandler) { |
|
3964 declElementType = getElementType(parser, enc, s, next); |
|
3965 if (!declElementType) |
|
3966 return XML_ERROR_NO_MEMORY; |
|
3967 dtd.scaffLevel = 0; |
|
3968 dtd.scaffCount = 0; |
|
3969 dtd.in_eldecl = XML_TRUE; |
|
3970 handleDefault = XML_FALSE; |
|
3971 } |
|
3972 #endif // SYMBIAN_MIN_SIZE |
|
3973 break; |
|
3974 |
|
3975 case XML_ROLE_CONTENT_ANY: |
|
3976 case XML_ROLE_CONTENT_EMPTY: |
|
3977 if (dtd.in_eldecl) { |
|
3978 #ifndef SYMBIAN_MIN_SIZE |
|
3979 if (elementDeclHandler) { |
|
3980 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); |
|
3981 if (!content) |
|
3982 return XML_ERROR_NO_MEMORY; |
|
3983 content->quant = XML_CQUANT_NONE; |
|
3984 content->name = NULL; |
|
3985 content->numchildren = 0; |
|
3986 content->children = NULL; |
|
3987 content->type = ((role == XML_ROLE_CONTENT_ANY) ? |
|
3988 XML_CTYPE_ANY : |
|
3989 XML_CTYPE_EMPTY); |
|
3990 *eventEndPP = s; |
|
3991 elementDeclHandler(handlerArg, declElementType->name, content); |
|
3992 handleDefault = XML_FALSE; |
|
3993 } |
|
3994 #endif // SYMBIAN_MIN_SIZE |
|
3995 dtd.in_eldecl = XML_FALSE; |
|
3996 } |
|
3997 break; |
|
3998 |
|
3999 case XML_ROLE_CONTENT_PCDATA: |
|
4000 if (dtd.in_eldecl) { |
|
4001 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type |
|
4002 = XML_CTYPE_MIXED; |
|
4003 if (elementDeclHandler) |
|
4004 handleDefault = XML_FALSE; |
|
4005 } |
|
4006 break; |
|
4007 |
|
4008 case XML_ROLE_CONTENT_ELEMENT: |
|
4009 quant = XML_CQUANT_NONE; |
|
4010 goto elementContent; |
|
4011 case XML_ROLE_CONTENT_ELEMENT_OPT: |
|
4012 quant = XML_CQUANT_OPT; |
|
4013 goto elementContent; |
|
4014 case XML_ROLE_CONTENT_ELEMENT_REP: |
|
4015 quant = XML_CQUANT_REP; |
|
4016 goto elementContent; |
|
4017 case XML_ROLE_CONTENT_ELEMENT_PLUS: |
|
4018 quant = XML_CQUANT_PLUS; |
|
4019 elementContent: |
|
4020 if (dtd.in_eldecl) { |
|
4021 ELEMENT_TYPE *el; |
|
4022 const XML_Char *name; |
|
4023 int nameLen; |
|
4024 const char *nxt = (quant == XML_CQUANT_NONE |
|
4025 ? next |
|
4026 : next - enc->minBytesPerChar); |
|
4027 int myindex = nextScaffoldPart(parser); |
|
4028 if (myindex < 0) |
|
4029 return XML_ERROR_NO_MEMORY; |
|
4030 dtd.scaffold[myindex].type = XML_CTYPE_NAME; |
|
4031 dtd.scaffold[myindex].quant = quant; |
|
4032 el = getElementType(parser, enc, s, nxt); |
|
4033 if (!el) |
|
4034 return XML_ERROR_NO_MEMORY; |
|
4035 name = el->name; |
|
4036 dtd.scaffold[myindex].name = name; |
|
4037 nameLen = 0; |
|
4038 for (; name[nameLen++]; ) |
|
4039 ; |
|
4040 dtd.contentStringLen += nameLen; |
|
4041 if (elementDeclHandler) |
|
4042 handleDefault = XML_FALSE; |
|
4043 } |
|
4044 break; |
|
4045 |
|
4046 case XML_ROLE_GROUP_CLOSE: |
|
4047 quant = XML_CQUANT_NONE; |
|
4048 goto closeGroup; |
|
4049 case XML_ROLE_GROUP_CLOSE_OPT: |
|
4050 quant = XML_CQUANT_OPT; |
|
4051 goto closeGroup; |
|
4052 case XML_ROLE_GROUP_CLOSE_REP: |
|
4053 quant = XML_CQUANT_REP; |
|
4054 goto closeGroup; |
|
4055 case XML_ROLE_GROUP_CLOSE_PLUS: |
|
4056 quant = XML_CQUANT_PLUS; |
|
4057 closeGroup: |
|
4058 if (dtd.in_eldecl) { |
|
4059 if (elementDeclHandler) |
|
4060 handleDefault = XML_FALSE; |
|
4061 dtd.scaffLevel--; |
|
4062 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant; |
|
4063 if (dtd.scaffLevel == 0) { |
|
4064 if (!handleDefault) { |
|
4065 XML_Content *model = build_model(parser); |
|
4066 if (!model) |
|
4067 return XML_ERROR_NO_MEMORY; |
|
4068 *eventEndPP = s; |
|
4069 elementDeclHandler(handlerArg, declElementType->name, model); |
|
4070 } |
|
4071 dtd.in_eldecl = XML_FALSE; |
|
4072 dtd.contentStringLen = 0; |
|
4073 } |
|
4074 } |
|
4075 break; |
|
4076 /* End element declaration stuff */ |
|
4077 |
|
4078 case XML_ROLE_PI: |
|
4079 if (!reportProcessingInstruction(parser, enc, s, next)) |
|
4080 return XML_ERROR_NO_MEMORY; |
|
4081 handleDefault = XML_FALSE; |
|
4082 break; |
|
4083 case XML_ROLE_COMMENT: |
|
4084 if (!reportComment(parser, enc, s, next)) |
|
4085 return XML_ERROR_NO_MEMORY; |
|
4086 handleDefault = XML_FALSE; |
|
4087 break; |
|
4088 case XML_ROLE_NONE: |
|
4089 switch (tok) { |
|
4090 case XML_TOK_BOM: |
|
4091 handleDefault = XML_FALSE; |
|
4092 break; |
|
4093 } |
|
4094 break; |
|
4095 case XML_ROLE_DOCTYPE_NONE: |
|
4096 if (startDoctypeDeclHandler) |
|
4097 handleDefault = XML_FALSE; |
|
4098 break; |
|
4099 case XML_ROLE_ENTITY_NONE: |
|
4100 if (dtd.keepProcessing && entityDeclHandler) |
|
4101 handleDefault = XML_FALSE; |
|
4102 break; |
|
4103 case XML_ROLE_NOTATION_NONE: |
|
4104 if (notationDeclHandler) |
|
4105 handleDefault = XML_FALSE; |
|
4106 break; |
|
4107 case XML_ROLE_ATTLIST_NONE: |
|
4108 if (dtd.keepProcessing && attlistDeclHandler) |
|
4109 handleDefault = XML_FALSE; |
|
4110 break; |
|
4111 case XML_ROLE_ELEMENT_NONE: |
|
4112 if (elementDeclHandler) |
|
4113 handleDefault = XML_FALSE; |
|
4114 break; |
|
4115 } /* end of big switch */ |
|
4116 |
|
4117 if (handleDefault && defaultHandler) |
|
4118 reportDefault(parser, enc, s, next); |
|
4119 |
|
4120 s = next; |
|
4121 tok = XmlPrologTok(enc, s, end, &next); |
|
4122 } |
|
4123 /* not reached */ |
|
4124 } |
|
4125 |
|
4126 static enum XML_Error FASTCALL |
|
4127 epilogProcessor(XML_Parser parser, |
|
4128 const char *s, |
|
4129 const char *end, |
|
4130 const char **nextPtr) |
|
4131 { |
|
4132 processor = epilogProcessor; |
|
4133 eventPtr = s; |
|
4134 for (;;) { |
|
4135 const char *next = NULL; |
|
4136 int tok = XmlPrologTok(encoding, s, end, &next); |
|
4137 eventEndPtr = next; |
|
4138 switch (tok) { |
|
4139 /* report partial linebreak - it might be the last token */ |
|
4140 case -XML_TOK_PROLOG_S: |
|
4141 if (defaultHandler) { |
|
4142 eventEndPtr = next; |
|
4143 reportDefault(parser, encoding, s, next); |
|
4144 } |
|
4145 if (nextPtr) |
|
4146 *nextPtr = next; |
|
4147 return XML_ERROR_NONE; |
|
4148 case XML_TOK_NONE: |
|
4149 if (nextPtr) |
|
4150 *nextPtr = s; |
|
4151 return XML_ERROR_NONE; |
|
4152 case XML_TOK_PROLOG_S: |
|
4153 if (defaultHandler) |
|
4154 reportDefault(parser, encoding, s, next); |
|
4155 break; |
|
4156 case XML_TOK_PI: |
|
4157 if (!reportProcessingInstruction(parser, encoding, s, next)) |
|
4158 return XML_ERROR_NO_MEMORY; |
|
4159 break; |
|
4160 case XML_TOK_COMMENT: |
|
4161 if (!reportComment(parser, encoding, s, next)) |
|
4162 return XML_ERROR_NO_MEMORY; |
|
4163 break; |
|
4164 case XML_TOK_INVALID: |
|
4165 eventPtr = next; |
|
4166 return XML_ERROR_INVALID_TOKEN; |
|
4167 case XML_TOK_PARTIAL: |
|
4168 if (nextPtr) { |
|
4169 *nextPtr = s; |
|
4170 return XML_ERROR_NONE; |
|
4171 } |
|
4172 return XML_ERROR_UNCLOSED_TOKEN; |
|
4173 case XML_TOK_PARTIAL_CHAR: |
|
4174 if (nextPtr) { |
|
4175 *nextPtr = s; |
|
4176 return XML_ERROR_NONE; |
|
4177 } |
|
4178 return XML_ERROR_PARTIAL_CHAR; |
|
4179 default: |
|
4180 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; |
|
4181 } |
|
4182 eventPtr = s = next; |
|
4183 } |
|
4184 } |
|
4185 |
|
4186 #ifdef XML_DTD |
|
4187 |
|
4188 static enum XML_Error FASTCALL |
|
4189 processInternalParamEntity(XML_Parser parser, ENTITY *entity) |
|
4190 { |
|
4191 const char *s, *end, *next; |
|
4192 int tok; |
|
4193 enum XML_Error result; |
|
4194 OPEN_INTERNAL_ENTITY openEntity; |
|
4195 entity->open = XML_TRUE; |
|
4196 openEntity.next = openInternalEntities; |
|
4197 openInternalEntities = &openEntity; |
|
4198 openEntity.entity = entity; |
|
4199 openEntity.internalEventPtr = NULL; |
|
4200 openEntity.internalEventEndPtr = NULL; |
|
4201 s = (char *)entity->textPtr; |
|
4202 end = (char *)(entity->textPtr + entity->textLen); |
|
4203 tok = XmlPrologTok(internalEncoding, s, end, &next); |
|
4204 result = doProlog(parser, internalEncoding, s, end, tok, next, 0); |
|
4205 entity->open = XML_FALSE; |
|
4206 openInternalEntities = openEntity.next; |
|
4207 return result; |
|
4208 } |
|
4209 |
|
4210 #endif /* XML_DTD */ |
|
4211 |
|
4212 static enum XML_Error FASTCALL |
|
4213 errorProcessor(XML_Parser parser, |
|
4214 const char *s, |
|
4215 const char *end, |
|
4216 const char **nextPtr) |
|
4217 { |
|
4218 return errorCode; |
|
4219 } |
|
4220 |
|
4221 static enum XML_Error FASTCALL |
|
4222 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, |
|
4223 const char *ptr, const char *end, |
|
4224 STRING_POOL *pool) |
|
4225 { |
|
4226 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, |
|
4227 end, pool); |
|
4228 if (result) |
|
4229 return result; |
|
4230 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) |
|
4231 poolChop(pool); |
|
4232 if (!poolAppendChar(pool, XML_T('\0'))) |
|
4233 return XML_ERROR_NO_MEMORY; |
|
4234 return XML_ERROR_NONE; |
|
4235 } |
|
4236 |
|
4237 static enum XML_Error FASTCALL |
|
4238 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, |
|
4239 const char *ptr, const char *end, |
|
4240 STRING_POOL *pool) |
|
4241 { |
|
4242 for (;;) { |
|
4243 const char *next; |
|
4244 int tok = XmlAttributeValueTok(enc, ptr, end, &next); |
|
4245 switch (tok) { |
|
4246 case XML_TOK_NONE: |
|
4247 return XML_ERROR_NONE; |
|
4248 case XML_TOK_INVALID: |
|
4249 if (enc == encoding) |
|
4250 eventPtr = next; |
|
4251 return XML_ERROR_INVALID_TOKEN; |
|
4252 case XML_TOK_PARTIAL: |
|
4253 if (enc == encoding) |
|
4254 eventPtr = ptr; |
|
4255 return XML_ERROR_INVALID_TOKEN; |
|
4256 case XML_TOK_CHAR_REF: |
|
4257 { |
|
4258 XML_Char buf[XML_ENCODE_MAX]; |
|
4259 int i; |
|
4260 int n = XmlCharRefNumber(enc, ptr); |
|
4261 if (n < 0) { |
|
4262 if (enc == encoding) |
|
4263 eventPtr = ptr; |
|
4264 return XML_ERROR_BAD_CHAR_REF; |
|
4265 } |
|
4266 if (!isCdata |
|
4267 && n == 0x20 /* space */ |
|
4268 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) |
|
4269 break; |
|
4270 n = XmlEncode(n, (ICHAR *)buf); |
|
4271 if (!n) { |
|
4272 if (enc == encoding) |
|
4273 eventPtr = ptr; |
|
4274 return XML_ERROR_BAD_CHAR_REF; |
|
4275 } |
|
4276 for (i = 0; i < n; i++) { |
|
4277 if (!poolAppendChar(pool, buf[i])) |
|
4278 return XML_ERROR_NO_MEMORY; |
|
4279 } |
|
4280 } |
|
4281 break; |
|
4282 case XML_TOK_DATA_CHARS: |
|
4283 if (!poolAppend(pool, enc, ptr, next)) |
|
4284 return XML_ERROR_NO_MEMORY; |
|
4285 break; |
|
4286 case XML_TOK_TRAILING_CR: |
|
4287 next = ptr + enc->minBytesPerChar; |
|
4288 /* fall through */ |
|
4289 case XML_TOK_ATTRIBUTE_VALUE_S: |
|
4290 case XML_TOK_DATA_NEWLINE: |
|
4291 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) |
|
4292 break; |
|
4293 if (!poolAppendChar(pool, 0x20)) |
|
4294 return XML_ERROR_NO_MEMORY; |
|
4295 break; |
|
4296 case XML_TOK_ENTITY_REF: |
|
4297 { |
|
4298 const XML_Char *name; |
|
4299 ENTITY *entity; |
|
4300 char checkEntityDecl; |
|
4301 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, |
|
4302 ptr + enc->minBytesPerChar, |
|
4303 next - enc->minBytesPerChar); |
|
4304 if (ch) { |
|
4305 if (!poolAppendChar(pool, ch)) |
|
4306 return XML_ERROR_NO_MEMORY; |
|
4307 break; |
|
4308 } |
|
4309 name = poolStoreString(&temp2Pool, enc, |
|
4310 ptr + enc->minBytesPerChar, |
|
4311 next - enc->minBytesPerChar); |
|
4312 if (!name) |
|
4313 return XML_ERROR_NO_MEMORY; |
|
4314 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); |
|
4315 poolDiscard(&temp2Pool); |
|
4316 /* first, determine if a check for an existing declaration is needed; |
|
4317 if yes, check that the entity exists, and that it is internal, |
|
4318 otherwise call the default handler (if called from content) |
|
4319 */ |
|
4320 if (pool == &dtd.pool) /* are we called from prolog? */ |
|
4321 checkEntityDecl = (char)( |
|
4322 #ifdef XML_DTD |
|
4323 prologState.documentEntity && |
|
4324 #endif /* XML_DTD */ |
|
4325 (dtd.standalone |
|
4326 ? !openInternalEntities |
|
4327 : !dtd.hasParamEntityRefs)); |
|
4328 else /* if (pool == &tempPool): we are called from content */ |
|
4329 checkEntityDecl = (char)(!dtd.hasParamEntityRefs || dtd.standalone); |
|
4330 if (checkEntityDecl) { |
|
4331 if (!entity) |
|
4332 return XML_ERROR_UNDEFINED_ENTITY; |
|
4333 else if (!entity->is_internal) |
|
4334 return XML_ERROR_ENTITY_DECLARED_IN_PE; |
|
4335 } |
|
4336 else if (!entity) { |
|
4337 /* cannot report skipped entity here - see comments on |
|
4338 skippedEntityHandler |
|
4339 if (skippedEntityHandler) |
|
4340 skippedEntityHandler(handlerArg, name, 0); |
|
4341 */ |
|
4342 if ((pool == &tempPool) && defaultHandler) |
|
4343 reportDefault(parser, enc, ptr, next); |
|
4344 break; |
|
4345 } |
|
4346 if (entity->open) { |
|
4347 if (enc == encoding) |
|
4348 eventPtr = ptr; |
|
4349 return XML_ERROR_RECURSIVE_ENTITY_REF; |
|
4350 } |
|
4351 if (entity->notation) { |
|
4352 if (enc == encoding) |
|
4353 eventPtr = ptr; |
|
4354 return XML_ERROR_BINARY_ENTITY_REF; |
|
4355 } |
|
4356 if (!entity->textPtr) { |
|
4357 if (enc == encoding) |
|
4358 eventPtr = ptr; |
|
4359 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; |
|
4360 } |
|
4361 else { |
|
4362 enum XML_Error result; |
|
4363 const XML_Char *textEnd = entity->textPtr + entity->textLen; |
|
4364 entity->open = XML_TRUE; |
|
4365 result = appendAttributeValue(parser, internalEncoding, isCdata, |
|
4366 (char *)entity->textPtr, |
|
4367 (char *)textEnd, pool); |
|
4368 entity->open = XML_FALSE; |
|
4369 if (result) |
|
4370 return result; |
|
4371 } |
|
4372 } |
|
4373 break; |
|
4374 default: |
|
4375 if (enc == encoding) |
|
4376 eventPtr = ptr; |
|
4377 return XML_ERROR_UNEXPECTED_STATE; |
|
4378 } |
|
4379 ptr = next; |
|
4380 } |
|
4381 /* not reached */ |
|
4382 } |
|
4383 |
|
4384 static enum XML_Error FASTCALL |
|
4385 storeEntityValue(XML_Parser parser, |
|
4386 const ENCODING *enc, |
|
4387 const char *entityTextPtr, |
|
4388 const char *entityTextEnd) |
|
4389 { |
|
4390 STRING_POOL *pool = &(dtd.entityValuePool); |
|
4391 enum XML_Error result = XML_ERROR_NONE; |
|
4392 #ifdef XML_DTD |
|
4393 int oldInEntityValue = prologState.inEntityValue; |
|
4394 prologState.inEntityValue = 1; |
|
4395 #endif /* XML_DTD */ |
|
4396 /* never return Null for the value argument in EntityDeclHandler, |
|
4397 since this would indicate an external entity; therefore we |
|
4398 have to make sure that entityValuePool.start is not null */ |
|
4399 if (!pool->blocks) { |
|
4400 if (!poolGrow(pool)) |
|
4401 return XML_ERROR_NO_MEMORY; |
|
4402 } |
|
4403 |
|
4404 for (;;) { |
|
4405 const char *next; |
|
4406 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); |
|
4407 switch (tok) { |
|
4408 case XML_TOK_PARAM_ENTITY_REF: |
|
4409 #ifdef XML_DTD |
|
4410 if (isParamEntity || enc != encoding) { |
|
4411 const XML_Char *name; |
|
4412 ENTITY *entity; |
|
4413 name = poolStoreString(&tempPool, enc, |
|
4414 entityTextPtr + enc->minBytesPerChar, |
|
4415 next - enc->minBytesPerChar); |
|
4416 if (!name) { |
|
4417 result = XML_ERROR_NO_MEMORY; |
|
4418 goto endEntityValue; |
|
4419 } |
|
4420 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); |
|
4421 poolDiscard(&tempPool); |
|
4422 if (!entity) { |
|
4423 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ |
|
4424 /* cannot report skipped entity here - see comments on |
|
4425 skippedEntityHandler |
|
4426 if (skippedEntityHandler) |
|
4427 skippedEntityHandler(handlerArg, name, 0); |
|
4428 */ |
|
4429 dtd.keepProcessing = dtd.standalone; |
|
4430 goto endEntityValue; |
|
4431 } |
|
4432 if (entity->open) { |
|
4433 if (enc == encoding) |
|
4434 eventPtr = entityTextPtr; |
|
4435 result = XML_ERROR_RECURSIVE_ENTITY_REF; |
|
4436 goto endEntityValue; |
|
4437 } |
|
4438 if (entity->systemId) { |
|
4439 if (externalEntityRefHandler) { |
|
4440 dtd.paramEntityRead = XML_FALSE; |
|
4441 entity->open = XML_TRUE; |
|
4442 if (!externalEntityRefHandler(handlerArg, name)) { |
|
4443 entity->open = XML_FALSE; |
|
4444 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
|
4445 goto endEntityValue; |
|
4446 } |
|
4447 entity->open = XML_FALSE; |
|
4448 if (!dtd.paramEntityRead) |
|
4449 dtd.keepProcessing = dtd.standalone; |
|
4450 } |
|
4451 else |
|
4452 dtd.keepProcessing = dtd.standalone; |
|
4453 } |
|
4454 else { |
|
4455 entity->open = XML_TRUE; |
|
4456 result = storeEntityValue(parser, |
|
4457 internalEncoding, |
|
4458 (char *)entity->textPtr, |
|
4459 (char *)(entity->textPtr |
|
4460 + entity->textLen)); |
|
4461 entity->open = XML_FALSE; |
|
4462 if (result) |
|
4463 goto endEntityValue; |
|
4464 } |
|
4465 break; |
|
4466 } |
|
4467 #endif /* XML_DTD */ |
|
4468 /* in the internal subset, PE references are not legal |
|
4469 within markup declarations, e.g entity values in this case */ |
|
4470 eventPtr = entityTextPtr; |
|
4471 result = XML_ERROR_PARAM_ENTITY_REF; |
|
4472 goto endEntityValue; |
|
4473 case XML_TOK_NONE: |
|
4474 result = XML_ERROR_NONE; |
|
4475 goto endEntityValue; |
|
4476 case XML_TOK_ENTITY_REF: |
|
4477 case XML_TOK_DATA_CHARS: |
|
4478 if (!poolAppend(pool, enc, entityTextPtr, next)) { |
|
4479 result = XML_ERROR_NO_MEMORY; |
|
4480 goto endEntityValue; |
|
4481 } |
|
4482 break; |
|
4483 case XML_TOK_TRAILING_CR: |
|
4484 next = entityTextPtr + enc->minBytesPerChar; |
|
4485 /* fall through */ |
|
4486 case XML_TOK_DATA_NEWLINE: |
|
4487 if (pool->end == pool->ptr && !poolGrow(pool)) { |
|
4488 result = XML_ERROR_NO_MEMORY; |
|
4489 goto endEntityValue; |
|
4490 } |
|
4491 *(pool->ptr)++ = 0xA; |
|
4492 break; |
|
4493 case XML_TOK_CHAR_REF: |
|
4494 { |
|
4495 XML_Char buf[XML_ENCODE_MAX]; |
|
4496 int i; |
|
4497 int n = XmlCharRefNumber(enc, entityTextPtr); |
|
4498 if (n < 0) { |
|
4499 if (enc == encoding) |
|
4500 eventPtr = entityTextPtr; |
|
4501 result = XML_ERROR_BAD_CHAR_REF; |
|
4502 goto endEntityValue; |
|
4503 } |
|
4504 n = XmlEncode(n, (ICHAR *)buf); |
|
4505 if (!n) { |
|
4506 if (enc == encoding) |
|
4507 eventPtr = entityTextPtr; |
|
4508 result = XML_ERROR_BAD_CHAR_REF; |
|
4509 goto endEntityValue; |
|
4510 } |
|
4511 for (i = 0; i < n; i++) { |
|
4512 if (pool->end == pool->ptr && !poolGrow(pool)) { |
|
4513 result = XML_ERROR_NO_MEMORY; |
|
4514 goto endEntityValue; |
|
4515 } |
|
4516 *(pool->ptr)++ = buf[i]; |
|
4517 } |
|
4518 } |
|
4519 break; |
|
4520 case XML_TOK_PARTIAL: |
|
4521 if (enc == encoding) |
|
4522 eventPtr = entityTextPtr; |
|
4523 result = XML_ERROR_INVALID_TOKEN; |
|
4524 goto endEntityValue; |
|
4525 case XML_TOK_INVALID: |
|
4526 if (enc == encoding) |
|
4527 eventPtr = next; |
|
4528 result = XML_ERROR_INVALID_TOKEN; |
|
4529 goto endEntityValue; |
|
4530 default: |
|
4531 if (enc == encoding) |
|
4532 eventPtr = entityTextPtr; |
|
4533 result = XML_ERROR_UNEXPECTED_STATE; |
|
4534 goto endEntityValue; |
|
4535 } |
|
4536 entityTextPtr = next; |
|
4537 } |
|
4538 endEntityValue: |
|
4539 #ifdef XML_DTD |
|
4540 prologState.inEntityValue = oldInEntityValue; |
|
4541 #endif /* XML_DTD */ |
|
4542 return result; |
|
4543 } |
|
4544 |
|
4545 static void FASTCALL |
|
4546 normalizeLines(XML_Char *s) |
|
4547 { |
|
4548 XML_Char *p; |
|
4549 for (;; s++) { |
|
4550 if (*s == XML_T('\0')) |
|
4551 return; |
|
4552 if (*s == 0xD) |
|
4553 break; |
|
4554 } |
|
4555 p = s; |
|
4556 do { |
|
4557 if (*s == 0xD) { |
|
4558 *p++ = 0xA; |
|
4559 if (*++s == 0xA) |
|
4560 s++; |
|
4561 } |
|
4562 else |
|
4563 *p++ = *s++; |
|
4564 } while (*s); |
|
4565 *p = XML_T('\0'); |
|
4566 } |
|
4567 |
|
4568 static int FASTCALL |
|
4569 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, |
|
4570 const char *start, const char *end) |
|
4571 { |
|
4572 const XML_Char *target; |
|
4573 XML_Char *data; |
|
4574 const char *tem; |
|
4575 if (!processingInstructionHandler) { |
|
4576 if (defaultHandler) |
|
4577 reportDefault(parser, enc, start, end); |
|
4578 return 1; |
|
4579 } |
|
4580 start += enc->minBytesPerChar * 2; |
|
4581 tem = start + XmlNameLength(enc, start); |
|
4582 target = poolStoreString(&tempPool, enc, start, tem); |
|
4583 if (!target) |
|
4584 return 0; |
|
4585 poolFinish(&tempPool); |
|
4586 data = poolStoreString(&tempPool, enc, |
|
4587 XmlSkipS(enc, tem), |
|
4588 end - enc->minBytesPerChar*2); |
|
4589 if (!data) |
|
4590 return 0; |
|
4591 normalizeLines(data); |
|
4592 processingInstructionHandler(handlerArg, target, data); |
|
4593 poolClear(&tempPool); |
|
4594 return 1; |
|
4595 } |
|
4596 |
|
4597 static int FASTCALL |
|
4598 reportComment(XML_Parser parser, const ENCODING *enc, |
|
4599 const char *start, const char *end) |
|
4600 { |
|
4601 #ifndef SYMBIAN_MIN_SIZE |
|
4602 XML_Char *data; |
|
4603 if (!commentHandler) { |
|
4604 if (defaultHandler) |
|
4605 reportDefault(parser, enc, start, end); |
|
4606 return 1; |
|
4607 } |
|
4608 data = poolStoreString(&tempPool, |
|
4609 enc, |
|
4610 start + enc->minBytesPerChar * 4, |
|
4611 end - enc->minBytesPerChar * 3); |
|
4612 if (!data) |
|
4613 return 0; |
|
4614 normalizeLines(data); |
|
4615 commentHandler(handlerArg, data); |
|
4616 poolClear(&tempPool); |
|
4617 #endif // SYMBIAN_MIN_SIZE |
|
4618 return 1; |
|
4619 } |
|
4620 |
|
4621 static void FASTCALL |
|
4622 reportDefault(XML_Parser parser, const ENCODING *enc, |
|
4623 const char *s, const char *end) |
|
4624 { |
|
4625 #ifndef SYMBIAN_MIN_SIZE |
|
4626 if (MUST_CONVERT(enc, s)) { |
|
4627 const char **eventPP; |
|
4628 const char **eventEndPP; |
|
4629 if (enc == encoding) { |
|
4630 eventPP = &eventPtr; |
|
4631 eventEndPP = &eventEndPtr; |
|
4632 } |
|
4633 else { |
|
4634 eventPP = &(openInternalEntities->internalEventPtr); |
|
4635 eventEndPP = &(openInternalEntities->internalEventEndPtr); |
|
4636 } |
|
4637 do { |
|
4638 ICHAR *dataPtr = (ICHAR *)dataBuf; |
|
4639 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); |
|
4640 *eventEndPP = s; |
|
4641 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); |
|
4642 *eventPP = s; |
|
4643 } while (s != end); |
|
4644 } |
|
4645 else |
|
4646 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); |
|
4647 #endif // SYMBIAN_MIN_SIZE |
|
4648 } |
|
4649 |
|
4650 |
|
4651 static int FASTCALL |
|
4652 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, |
|
4653 XML_Bool isId, const XML_Char *value, XML_Parser parser) |
|
4654 { |
|
4655 DEFAULT_ATTRIBUTE *att; |
|
4656 if (value || isId) { |
|
4657 /* The handling of default attributes gets messed up if we have |
|
4658 a default which duplicates a non-default. */ |
|
4659 int i; |
|
4660 for (i = 0; i < type->nDefaultAtts; i++) |
|
4661 if (attId == type->defaultAtts[i].id) |
|
4662 return 1; |
|
4663 if (isId && !type->idAtt && !attId->xmlns) |
|
4664 type->idAtt = attId; |
|
4665 } |
|
4666 if (type->nDefaultAtts == type->allocDefaultAtts) { |
|
4667 if (type->allocDefaultAtts == 0) { |
|
4668 type->allocDefaultAtts = 8; |
|
4669 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts |
|
4670 * sizeof(DEFAULT_ATTRIBUTE)); |
|
4671 if (!type->defaultAtts) |
|
4672 return 0; |
|
4673 } |
|
4674 else { |
|
4675 DEFAULT_ATTRIBUTE *temp; |
|
4676 int count = type->allocDefaultAtts * 2; |
|
4677 temp = (DEFAULT_ATTRIBUTE *)REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); |
|
4678 if (temp == NULL) |
|
4679 return 0; |
|
4680 type->allocDefaultAtts = count; |
|
4681 type->defaultAtts = temp; |
|
4682 } |
|
4683 } |
|
4684 att = type->defaultAtts + type->nDefaultAtts; |
|
4685 att->id = attId; |
|
4686 att->value = value; |
|
4687 att->isCdata = isCdata; |
|
4688 if (!isCdata) |
|
4689 attId->maybeTokenized = XML_TRUE; |
|
4690 type->nDefaultAtts += 1; |
|
4691 return 1; |
|
4692 } |
|
4693 |
|
4694 static int FASTCALL |
|
4695 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) |
|
4696 { |
|
4697 const XML_Char *name; |
|
4698 for (name = elementType->name; *name; name++) { |
|
4699 if (*name == XML_T(':')) { |
|
4700 PREFIX *prefix; |
|
4701 const XML_Char *s; |
|
4702 for (s = elementType->name; s != name; s++) { |
|
4703 if (!poolAppendChar(&dtd.pool, *s)) |
|
4704 return 0; |
|
4705 } |
|
4706 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) |
|
4707 return 0; |
|
4708 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), |
|
4709 sizeof(PREFIX)); |
|
4710 if (!prefix) |
|
4711 return 0; |
|
4712 if (prefix->name == poolStart(&dtd.pool)) |
|
4713 poolFinish(&dtd.pool); |
|
4714 else |
|
4715 poolDiscard(&dtd.pool); |
|
4716 elementType->prefix = prefix; |
|
4717 |
|
4718 } |
|
4719 } |
|
4720 return 1; |
|
4721 } |
|
4722 |
|
4723 static ATTRIBUTE_ID * FASTCALL |
|
4724 getAttributeId(XML_Parser parser, const ENCODING *enc, |
|
4725 const char *start, const char *end) |
|
4726 { |
|
4727 ATTRIBUTE_ID *id; |
|
4728 const XML_Char *name; |
|
4729 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) |
|
4730 return NULL; |
|
4731 name = poolStoreString(&dtd.pool, enc, start, end); |
|
4732 if (!name) |
|
4733 return NULL; |
|
4734 ++name; |
|
4735 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID)); |
|
4736 if (!id) |
|
4737 return NULL; |
|
4738 if (id->name != name) |
|
4739 poolDiscard(&dtd.pool); |
|
4740 else { |
|
4741 poolFinish(&dtd.pool); |
|
4742 if (!ns) |
|
4743 ; |
|
4744 else if (name[0] == 'x' |
|
4745 && name[1] == 'm' |
|
4746 && name[2] == 'l' |
|
4747 && name[3] == 'n' |
|
4748 && name[4] == 's' |
|
4749 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { |
|
4750 if (name[5] == '\0') |
|
4751 id->prefix = &dtd.defaultPrefix; |
|
4752 else |
|
4753 id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX)); |
|
4754 id->xmlns = XML_TRUE; |
|
4755 } |
|
4756 else { |
|
4757 int i; |
|
4758 for (i = 0; name[i]; i++) { |
|
4759 if (name[i] == XML_T(':')) { |
|
4760 int j; |
|
4761 for (j = 0; j < i; j++) { |
|
4762 if (!poolAppendChar(&dtd.pool, name[j])) |
|
4763 return NULL; |
|
4764 } |
|
4765 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) |
|
4766 return NULL; |
|
4767 id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), |
|
4768 sizeof(PREFIX)); |
|
4769 if (id->prefix && id->prefix->name == poolStart(&dtd.pool)) |
|
4770 poolFinish(&dtd.pool); |
|
4771 else |
|
4772 poolDiscard(&dtd.pool); |
|
4773 break; |
|
4774 } |
|
4775 } |
|
4776 } |
|
4777 } |
|
4778 return id; |
|
4779 } |
|
4780 |
|
4781 #define CONTEXT_SEP XML_T('\f') |
|
4782 |
|
4783 static const XML_Char * FASTCALL |
|
4784 getContext(XML_Parser parser) |
|
4785 { |
|
4786 HASH_TABLE_ITER iter; |
|
4787 XML_Bool needSep = XML_FALSE; |
|
4788 |
|
4789 if (dtd.defaultPrefix.binding) { |
|
4790 int i; |
|
4791 int len; |
|
4792 if (!poolAppendChar(&tempPool, XML_T('='))) |
|
4793 return NULL; |
|
4794 len = dtd.defaultPrefix.binding->uriLen; |
|
4795 if (namespaceSeparator != XML_T('\0')) |
|
4796 len--; |
|
4797 for (i = 0; i < len; i++) |
|
4798 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i])) |
|
4799 return NULL; |
|
4800 needSep = XML_TRUE; |
|
4801 } |
|
4802 |
|
4803 hashTableIterInit(&iter, &(dtd.prefixes)); |
|
4804 for (;;) { |
|
4805 int i; |
|
4806 int len; |
|
4807 const XML_Char *s; |
|
4808 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); |
|
4809 if (!prefix) |
|
4810 break; |
|
4811 if (!prefix->binding) |
|
4812 continue; |
|
4813 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) |
|
4814 return NULL; |
|
4815 for (s = prefix->name; *s; s++) |
|
4816 if (!poolAppendChar(&tempPool, *s)) |
|
4817 return NULL; |
|
4818 if (!poolAppendChar(&tempPool, XML_T('='))) |
|
4819 return NULL; |
|
4820 len = prefix->binding->uriLen; |
|
4821 if (namespaceSeparator != XML_T('\0')) |
|
4822 len--; |
|
4823 for (i = 0; i < len; i++) |
|
4824 if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) |
|
4825 return NULL; |
|
4826 needSep = XML_TRUE; |
|
4827 } |
|
4828 |
|
4829 |
|
4830 hashTableIterInit(&iter, &(dtd.generalEntities)); |
|
4831 for (;;) { |
|
4832 const XML_Char *s; |
|
4833 ENTITY *e = (ENTITY *)hashTableIterNext(&iter); |
|
4834 if (!e) |
|
4835 break; |
|
4836 if (!e->open) |
|
4837 continue; |
|
4838 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) |
|
4839 return NULL; |
|
4840 for (s = e->name; *s; s++) |
|
4841 if (!poolAppendChar(&tempPool, *s)) |
|
4842 return 0; |
|
4843 needSep = XML_TRUE; |
|
4844 } |
|
4845 |
|
4846 if (!poolAppendChar(&tempPool, XML_T('\0'))) |
|
4847 return NULL; |
|
4848 return tempPool.start; |
|
4849 } |
|
4850 |
|
4851 static XML_Bool FASTCALL |
|
4852 setContext(XML_Parser parser, const XML_Char *context) |
|
4853 { |
|
4854 const XML_Char *s = context; |
|
4855 |
|
4856 while (*context != XML_T('\0')) { |
|
4857 if (*s == CONTEXT_SEP || *s == XML_T('\0')) { |
|
4858 ENTITY *e; |
|
4859 if (!poolAppendChar(&tempPool, XML_T('\0'))) |
|
4860 return XML_FALSE; |
|
4861 e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0); |
|
4862 if (e) |
|
4863 e->open = XML_TRUE; |
|
4864 if (*s != XML_T('\0')) |
|
4865 s++; |
|
4866 context = s; |
|
4867 poolDiscard(&tempPool); |
|
4868 } |
|
4869 else if (*s == XML_T('=')) { |
|
4870 PREFIX *prefix; |
|
4871 if (poolLength(&tempPool) == 0) |
|
4872 prefix = &dtd.defaultPrefix; |
|
4873 else { |
|
4874 if (!poolAppendChar(&tempPool, XML_T('\0'))) |
|
4875 return XML_FALSE; |
|
4876 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), |
|
4877 sizeof(PREFIX)); |
|
4878 if (!prefix) |
|
4879 return XML_FALSE; |
|
4880 if (prefix->name == poolStart(&tempPool)) { |
|
4881 prefix->name = poolCopyString(&dtd.pool, prefix->name); |
|
4882 if (!prefix->name) |
|
4883 return XML_FALSE; |
|
4884 } |
|
4885 poolDiscard(&tempPool); |
|
4886 } |
|
4887 for (context = s + 1; |
|
4888 *context != CONTEXT_SEP && *context != XML_T('\0'); |
|
4889 context++) |
|
4890 if (!poolAppendChar(&tempPool, *context)) |
|
4891 return XML_FALSE; |
|
4892 if (!poolAppendChar(&tempPool, XML_T('\0'))) |
|
4893 return XML_FALSE; |
|
4894 if (!addBinding(parser, prefix, 0, poolStart(&tempPool), |
|
4895 &inheritedBindings)) |
|
4896 return XML_FALSE; |
|
4897 poolDiscard(&tempPool); |
|
4898 if (*context != XML_T('\0')) |
|
4899 ++context; |
|
4900 s = context; |
|
4901 } |
|
4902 else { |
|
4903 if (!poolAppendChar(&tempPool, *s)) |
|
4904 return XML_FALSE; |
|
4905 s++; |
|
4906 } |
|
4907 } |
|
4908 return XML_TRUE; |
|
4909 } |
|
4910 |
|
4911 static void FASTCALL |
|
4912 normalizePublicId(XML_Char *publicId) |
|
4913 { |
|
4914 XML_Char *p = publicId; |
|
4915 XML_Char *s; |
|
4916 for (s = publicId; *s; s++) { |
|
4917 switch (*s) { |
|
4918 case 0x20: |
|
4919 case 0xD: |
|
4920 case 0xA: |
|
4921 if (p != publicId && p[-1] != 0x20) |
|
4922 *p++ = 0x20; |
|
4923 break; |
|
4924 default: |
|
4925 *p++ = *s; |
|
4926 } |
|
4927 } |
|
4928 if (p != publicId && p[-1] == 0x20) |
|
4929 --p; |
|
4930 *p = XML_T('\0'); |
|
4931 } |
|
4932 |
|
4933 static void FASTCALL |
|
4934 dtdInit(DTD *p, XML_Parser parser) |
|
4935 { |
|
4936 XML_Memory_Handling_Suite *ms = &parser->m_mem; |
|
4937 poolInit(&(p->pool), ms); |
|
4938 poolInit(&(p->entityValuePool), ms); |
|
4939 hashTableInit(&(p->generalEntities), ms); |
|
4940 hashTableInit(&(p->elementTypes), ms); |
|
4941 hashTableInit(&(p->attributeIds), ms); |
|
4942 hashTableInit(&(p->prefixes), ms); |
|
4943 #ifdef XML_DTD |
|
4944 p->paramEntityRead = XML_FALSE; |
|
4945 hashTableInit(&(p->paramEntities), ms); |
|
4946 #endif /* XML_DTD */ |
|
4947 p->defaultPrefix.name = NULL; |
|
4948 p->defaultPrefix.binding = NULL; |
|
4949 |
|
4950 p->in_eldecl = XML_FALSE; |
|
4951 p->scaffIndex = NULL; |
|
4952 p->scaffold = NULL; |
|
4953 p->scaffLevel = 0; |
|
4954 p->scaffSize = 0; |
|
4955 p->scaffCount = 0; |
|
4956 p->contentStringLen = 0; |
|
4957 |
|
4958 p->keepProcessing = XML_TRUE; |
|
4959 p->hasParamEntityRefs = XML_FALSE; |
|
4960 p->standalone = XML_FALSE; |
|
4961 } |
|
4962 |
|
4963 #ifdef XML_DTD |
|
4964 |
|
4965 static void FASTCALL |
|
4966 dtdSwap(DTD *p1, DTD *p2) |
|
4967 { |
|
4968 DTD tem; |
|
4969 memcpy(&tem, p1, sizeof(DTD)); |
|
4970 memcpy(p1, p2, sizeof(DTD)); |
|
4971 memcpy(p2, &tem, sizeof(DTD)); |
|
4972 } |
|
4973 |
|
4974 #endif /* XML_DTD */ |
|
4975 |
|
4976 static void FASTCALL |
|
4977 dtdReset(DTD *p, XML_Parser parser) |
|
4978 { |
|
4979 HASH_TABLE_ITER iter; |
|
4980 hashTableIterInit(&iter, &(p->elementTypes)); |
|
4981 for (;;) { |
|
4982 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
|
4983 if (!e) |
|
4984 break; |
|
4985 if (e->allocDefaultAtts != 0) |
|
4986 FREE(e->defaultAtts); |
|
4987 } |
|
4988 hashTableClear(&(p->generalEntities)); |
|
4989 #ifdef XML_DTD |
|
4990 p->paramEntityRead = XML_FALSE; |
|
4991 hashTableClear(&(p->paramEntities)); |
|
4992 #endif /* XML_DTD */ |
|
4993 hashTableClear(&(p->elementTypes)); |
|
4994 hashTableClear(&(p->attributeIds)); |
|
4995 hashTableClear(&(p->prefixes)); |
|
4996 poolClear(&(p->pool)); |
|
4997 poolClear(&(p->entityValuePool)); |
|
4998 p->defaultPrefix.name = NULL; |
|
4999 p->defaultPrefix.binding = NULL; |
|
5000 |
|
5001 p->in_eldecl = XML_FALSE; |
|
5002 if (p->scaffIndex) { |
|
5003 FREE(p->scaffIndex); |
|
5004 p->scaffIndex = NULL; |
|
5005 } |
|
5006 if (p->scaffold) { |
|
5007 FREE(p->scaffold); |
|
5008 p->scaffold = NULL; |
|
5009 } |
|
5010 p->scaffLevel = 0; |
|
5011 p->scaffSize = 0; |
|
5012 p->scaffCount = 0; |
|
5013 p->contentStringLen = 0; |
|
5014 |
|
5015 p->keepProcessing = XML_TRUE; |
|
5016 p->hasParamEntityRefs = XML_FALSE; |
|
5017 p->standalone = XML_FALSE; |
|
5018 } |
|
5019 |
|
5020 static void FASTCALL |
|
5021 dtdDestroy(DTD *p, XML_Parser parser) |
|
5022 { |
|
5023 HASH_TABLE_ITER iter; |
|
5024 hashTableIterInit(&iter, &(p->elementTypes)); |
|
5025 for (;;) { |
|
5026 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
|
5027 if (!e) |
|
5028 break; |
|
5029 if (e->allocDefaultAtts != 0) |
|
5030 FREE(e->defaultAtts); |
|
5031 } |
|
5032 hashTableDestroy(&(p->generalEntities)); |
|
5033 #ifdef XML_DTD |
|
5034 hashTableDestroy(&(p->paramEntities)); |
|
5035 #endif /* XML_DTD */ |
|
5036 hashTableDestroy(&(p->elementTypes)); |
|
5037 hashTableDestroy(&(p->attributeIds)); |
|
5038 hashTableDestroy(&(p->prefixes)); |
|
5039 poolDestroy(&(p->pool)); |
|
5040 poolDestroy(&(p->entityValuePool)); |
|
5041 if (!parentParser) { |
|
5042 if (p->scaffIndex) |
|
5043 FREE(p->scaffIndex); |
|
5044 if (p->scaffold) |
|
5045 FREE(p->scaffold); |
|
5046 } |
|
5047 } |
|
5048 |
|
5049 #ifndef SYMBIAN_MIN_SIZE |
|
5050 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. |
|
5051 The new DTD has already been initialized. |
|
5052 */ |
|
5053 static int FASTCALL |
|
5054 dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser) |
|
5055 { |
|
5056 HASH_TABLE_ITER iter; |
|
5057 |
|
5058 /* Copy the prefix table. */ |
|
5059 |
|
5060 hashTableIterInit(&iter, &(oldDtd->prefixes)); |
|
5061 for (;;) { |
|
5062 const XML_Char *name; |
|
5063 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); |
|
5064 if (!oldP) |
|
5065 break; |
|
5066 name = poolCopyString(&(newDtd->pool), oldP->name); |
|
5067 if (!name) |
|
5068 return 0; |
|
5069 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) |
|
5070 return 0; |
|
5071 } |
|
5072 |
|
5073 hashTableIterInit(&iter, &(oldDtd->attributeIds)); |
|
5074 |
|
5075 /* Copy the attribute id table. */ |
|
5076 |
|
5077 for (;;) { |
|
5078 ATTRIBUTE_ID *newA; |
|
5079 const XML_Char *name; |
|
5080 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); |
|
5081 |
|
5082 if (!oldA) |
|
5083 break; |
|
5084 /* Remember to allocate the scratch byte before the name. */ |
|
5085 if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) |
|
5086 return 0; |
|
5087 name = poolCopyString(&(newDtd->pool), oldA->name); |
|
5088 if (!name) |
|
5089 return 0; |
|
5090 ++name; |
|
5091 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, |
|
5092 sizeof(ATTRIBUTE_ID)); |
|
5093 if (!newA) |
|
5094 return 0; |
|
5095 newA->maybeTokenized = oldA->maybeTokenized; |
|
5096 if (oldA->prefix) { |
|
5097 newA->xmlns = oldA->xmlns; |
|
5098 if (oldA->prefix == &oldDtd->defaultPrefix) |
|
5099 newA->prefix = &newDtd->defaultPrefix; |
|
5100 else |
|
5101 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), |
|
5102 oldA->prefix->name, 0); |
|
5103 } |
|
5104 } |
|
5105 |
|
5106 /* Copy the element type table. */ |
|
5107 |
|
5108 hashTableIterInit(&iter, &(oldDtd->elementTypes)); |
|
5109 |
|
5110 for (;;) { |
|
5111 int i; |
|
5112 ELEMENT_TYPE *newE; |
|
5113 const XML_Char *name; |
|
5114 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
|
5115 if (!oldE) |
|
5116 break; |
|
5117 name = poolCopyString(&(newDtd->pool), oldE->name); |
|
5118 if (!name) |
|
5119 return 0; |
|
5120 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, |
|
5121 sizeof(ELEMENT_TYPE)); |
|
5122 if (!newE) |
|
5123 return 0; |
|
5124 if (oldE->nDefaultAtts) { |
|
5125 newE->defaultAtts = (DEFAULT_ATTRIBUTE *) |
|
5126 MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); |
|
5127 if (!newE->defaultAtts) { |
|
5128 FREE(newE); |
|
5129 return 0; |
|
5130 } |
|
5131 } |
|
5132 if (oldE->idAtt) |
|
5133 newE->idAtt = (ATTRIBUTE_ID *) |
|
5134 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); |
|
5135 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; |
|
5136 if (oldE->prefix) |
|
5137 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), |
|
5138 oldE->prefix->name, 0); |
|
5139 for (i = 0; i < newE->nDefaultAtts; i++) { |
|
5140 newE->defaultAtts[i].id = (ATTRIBUTE_ID *) |
|
5141 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); |
|
5142 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; |
|
5143 if (oldE->defaultAtts[i].value) { |
|
5144 newE->defaultAtts[i].value |
|
5145 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); |
|
5146 if (!newE->defaultAtts[i].value) |
|
5147 return 0; |
|
5148 } |
|
5149 else |
|
5150 newE->defaultAtts[i].value = NULL; |
|
5151 } |
|
5152 } |
|
5153 |
|
5154 /* Copy the entity tables. */ |
|
5155 if (!copyEntityTable(&(newDtd->generalEntities), |
|
5156 &(newDtd->pool), |
|
5157 &(oldDtd->generalEntities), parser)) |
|
5158 return 0; |
|
5159 |
|
5160 #ifdef XML_DTD |
|
5161 if (!copyEntityTable(&(newDtd->paramEntities), |
|
5162 &(newDtd->pool), |
|
5163 &(oldDtd->paramEntities), parser)) |
|
5164 return 0; |
|
5165 newDtd->paramEntityRead = oldDtd->paramEntityRead; |
|
5166 #endif /* XML_DTD */ |
|
5167 |
|
5168 newDtd->keepProcessing = oldDtd->keepProcessing; |
|
5169 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; |
|
5170 newDtd->standalone = oldDtd->standalone; |
|
5171 |
|
5172 /* Don't want deep copying for scaffolding */ |
|
5173 newDtd->in_eldecl = oldDtd->in_eldecl; |
|
5174 newDtd->scaffold = oldDtd->scaffold; |
|
5175 newDtd->contentStringLen = oldDtd->contentStringLen; |
|
5176 newDtd->scaffSize = oldDtd->scaffSize; |
|
5177 newDtd->scaffLevel = oldDtd->scaffLevel; |
|
5178 newDtd->scaffIndex = oldDtd->scaffIndex; |
|
5179 |
|
5180 return 1; |
|
5181 } /* End dtdCopy */ |
|
5182 |
|
5183 static int FASTCALL |
|
5184 copyEntityTable(HASH_TABLE *newTable, |
|
5185 STRING_POOL *newPool, |
|
5186 const HASH_TABLE *oldTable, |
|
5187 XML_Parser parser) |
|
5188 { |
|
5189 HASH_TABLE_ITER iter; |
|
5190 const XML_Char *cachedOldBase = NULL; |
|
5191 const XML_Char *cachedNewBase = NULL; |
|
5192 |
|
5193 hashTableIterInit(&iter, oldTable); |
|
5194 |
|
5195 for (;;) { |
|
5196 ENTITY *newE; |
|
5197 const XML_Char *name; |
|
5198 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); |
|
5199 if (!oldE) |
|
5200 break; |
|
5201 name = poolCopyString(newPool, oldE->name); |
|
5202 if (!name) |
|
5203 return 0; |
|
5204 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); |
|
5205 if (!newE) |
|
5206 return 0; |
|
5207 if (oldE->systemId) { |
|
5208 const XML_Char *tem = poolCopyString(newPool, oldE->systemId); |
|
5209 if (!tem) |
|
5210 return 0; |
|
5211 newE->systemId = tem; |
|
5212 if (oldE->base) { |
|
5213 if (oldE->base == cachedOldBase) |
|
5214 newE->base = cachedNewBase; |
|
5215 else { |
|
5216 cachedOldBase = oldE->base; |
|
5217 tem = poolCopyString(newPool, cachedOldBase); |
|
5218 if (!tem) |
|
5219 return 0; |
|
5220 cachedNewBase = newE->base = tem; |
|
5221 } |
|
5222 } |
|
5223 if (oldE->publicId) { |
|
5224 tem = poolCopyString(newPool, oldE->publicId); |
|
5225 if (!tem) |
|
5226 return 0; |
|
5227 newE->publicId = tem; |
|
5228 } |
|
5229 } |
|
5230 else { |
|
5231 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, |
|
5232 oldE->textLen); |
|
5233 if (!tem) |
|
5234 return 0; |
|
5235 newE->textPtr = tem; |
|
5236 newE->textLen = oldE->textLen; |
|
5237 } |
|
5238 if (oldE->notation) { |
|
5239 const XML_Char *tem = poolCopyString(newPool, oldE->notation); |
|
5240 if (!tem) |
|
5241 return 0; |
|
5242 newE->notation = tem; |
|
5243 } |
|
5244 newE->is_param = oldE->is_param; |
|
5245 newE->is_internal = oldE->is_internal; |
|
5246 } |
|
5247 return 1; |
|
5248 } |
|
5249 #endif // SYMBIAN_MIN_SIZE |
|
5250 |
|
5251 #define INIT_SIZE 64 |
|
5252 |
|
5253 static int FASTCALL |
|
5254 keyeq(KEY s1, KEY s2) |
|
5255 { |
|
5256 for (; *s1 == *s2; s1++, s2++) |
|
5257 if (*s1 == 0) |
|
5258 return 1; |
|
5259 return 0; |
|
5260 } |
|
5261 |
|
5262 static unsigned long FASTCALL |
|
5263 hash(KEY s) |
|
5264 { |
|
5265 unsigned long h = 0; |
|
5266 while (*s) |
|
5267 h = (h << 5) + h + (unsigned char)*s++; |
|
5268 return h; |
|
5269 } |
|
5270 |
|
5271 static NAMED * FASTCALL |
|
5272 lookup(HASH_TABLE *table, KEY name, size_t createSize) |
|
5273 { |
|
5274 size_t i; |
|
5275 if (table->size == 0) { |
|
5276 size_t tsize; |
|
5277 |
|
5278 if (!createSize) |
|
5279 return NULL; |
|
5280 tsize = INIT_SIZE * sizeof(NAMED *); |
|
5281 table->v = (NAMED **)table->mem->malloc_fcn(table->mem->allocData, tsize); |
|
5282 if (!table->v) |
|
5283 return NULL; |
|
5284 memset(table->v, 0, tsize); |
|
5285 table->size = INIT_SIZE; |
|
5286 table->usedLim = INIT_SIZE / 2; |
|
5287 i = hash(name) & (table->size - 1); |
|
5288 } |
|
5289 else { |
|
5290 unsigned long h = hash(name); |
|
5291 for (i = h & (table->size - 1); |
|
5292 table->v[i]; |
|
5293 i == 0 ? i = table->size - 1 : --i) { |
|
5294 if (keyeq(name, table->v[i]->name)) |
|
5295 return table->v[i]; |
|
5296 } |
|
5297 if (!createSize) |
|
5298 return NULL; |
|
5299 if (table->used == table->usedLim) { |
|
5300 /* check for overflow */ |
|
5301 size_t newSize = table->size * 2; |
|
5302 size_t tsize = newSize * sizeof(NAMED *); |
|
5303 NAMED **newV = (NAMED **)table->mem->malloc_fcn(table->mem->allocData, tsize); |
|
5304 if (!newV) |
|
5305 return NULL; |
|
5306 memset(newV, 0, tsize); |
|
5307 for (i = 0; i < table->size; i++) |
|
5308 if (table->v[i]) { |
|
5309 size_t j; |
|
5310 for (j = hash(table->v[i]->name) & (newSize - 1); |
|
5311 newV[j]; |
|
5312 j == 0 ? j = newSize - 1 : --j) |
|
5313 ; |
|
5314 newV[j] = table->v[i]; |
|
5315 } |
|
5316 table->mem->free_fcn(table->mem->allocData, table->v); |
|
5317 table->v = newV; |
|
5318 table->size = newSize; |
|
5319 table->usedLim = newSize/2; |
|
5320 for (i = h & (table->size - 1); |
|
5321 table->v[i]; |
|
5322 i == 0 ? i = table->size - 1 : --i) |
|
5323 ; |
|
5324 } |
|
5325 } |
|
5326 table->v[i] = (NAMED *)table->mem->malloc_fcn(table->mem->allocData, createSize); |
|
5327 if (!table->v[i]) |
|
5328 return NULL; |
|
5329 memset(table->v[i], 0, createSize); |
|
5330 table->v[i]->name = name; |
|
5331 (table->used)++; |
|
5332 return table->v[i]; |
|
5333 } |
|
5334 |
|
5335 static void FASTCALL |
|
5336 hashTableClear(HASH_TABLE *table) |
|
5337 { |
|
5338 size_t i; |
|
5339 for (i = 0; i < table->size; i++) { |
|
5340 NAMED *p = table->v[i]; |
|
5341 if (p) { |
|
5342 table->mem->free_fcn(table->mem->allocData, p); |
|
5343 table->v[i] = NULL; |
|
5344 } |
|
5345 } |
|
5346 table->usedLim = table->size / 2; |
|
5347 table->used = 0; |
|
5348 } |
|
5349 |
|
5350 static void FASTCALL |
|
5351 hashTableDestroy(HASH_TABLE *table) |
|
5352 { |
|
5353 size_t i; |
|
5354 for (i = 0; i < table->size; i++) { |
|
5355 NAMED *p = table->v[i]; |
|
5356 if (p) |
|
5357 table->mem->free_fcn(table->mem->allocData, p); |
|
5358 } |
|
5359 if (table->v) |
|
5360 table->mem->free_fcn(table->mem->allocData, table->v); |
|
5361 } |
|
5362 |
|
5363 static void FASTCALL |
|
5364 hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms) |
|
5365 { |
|
5366 p->size = 0; |
|
5367 p->usedLim = 0; |
|
5368 p->used = 0; |
|
5369 p->v = NULL; |
|
5370 p->mem = ms; |
|
5371 } |
|
5372 |
|
5373 static void FASTCALL |
|
5374 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) |
|
5375 { |
|
5376 iter->p = table->v; |
|
5377 iter->end = iter->p + table->size; |
|
5378 } |
|
5379 |
|
5380 static NAMED * FASTCALL |
|
5381 hashTableIterNext(HASH_TABLE_ITER *iter) |
|
5382 { |
|
5383 while (iter->p != iter->end) { |
|
5384 NAMED *tem = *(iter->p)++; |
|
5385 if (tem) |
|
5386 return tem; |
|
5387 } |
|
5388 return NULL; |
|
5389 } |
|
5390 |
|
5391 static void FASTCALL |
|
5392 poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms) |
|
5393 { |
|
5394 pool->blocks = NULL; |
|
5395 pool->freeBlocks = NULL; |
|
5396 pool->start = NULL; |
|
5397 pool->ptr = NULL; |
|
5398 pool->end = NULL; |
|
5399 pool->mem = ms; |
|
5400 } |
|
5401 |
|
5402 static void FASTCALL |
|
5403 poolClear(STRING_POOL *pool) |
|
5404 { |
|
5405 if (!pool->freeBlocks) |
|
5406 pool->freeBlocks = pool->blocks; |
|
5407 else { |
|
5408 BLOCK *p = pool->blocks; |
|
5409 while (p) { |
|
5410 BLOCK *tem = p->next; |
|
5411 p->next = pool->freeBlocks; |
|
5412 pool->freeBlocks = p; |
|
5413 p = tem; |
|
5414 } |
|
5415 } |
|
5416 pool->blocks = NULL; |
|
5417 pool->start = NULL; |
|
5418 pool->ptr = NULL; |
|
5419 pool->end = NULL; |
|
5420 } |
|
5421 |
|
5422 static void FASTCALL |
|
5423 poolDestroy(STRING_POOL *pool) |
|
5424 { |
|
5425 BLOCK *p = pool->blocks; |
|
5426 while (p) { |
|
5427 BLOCK *tem = p->next; |
|
5428 pool->mem->free_fcn(pool->mem->allocData, p); |
|
5429 p = tem; |
|
5430 } |
|
5431 p = pool->freeBlocks; |
|
5432 while (p) { |
|
5433 BLOCK *tem = p->next; |
|
5434 pool->mem->free_fcn(pool->mem->allocData, p); |
|
5435 p = tem; |
|
5436 } |
|
5437 } |
|
5438 |
|
5439 static XML_Char * FASTCALL |
|
5440 poolAppend(STRING_POOL *pool, const ENCODING *enc, |
|
5441 const char *ptr, const char *end) |
|
5442 { |
|
5443 if (!pool->ptr && !poolGrow(pool)) |
|
5444 return NULL; |
|
5445 for (;;) { |
|
5446 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); |
|
5447 if (ptr == end) |
|
5448 break; |
|
5449 if (!poolGrow(pool)) |
|
5450 return NULL; |
|
5451 } |
|
5452 return pool->start; |
|
5453 } |
|
5454 |
|
5455 static const XML_Char * FASTCALL |
|
5456 poolCopyString(STRING_POOL *pool, const XML_Char *s) |
|
5457 { |
|
5458 do { |
|
5459 if (!poolAppendChar(pool, *s)) |
|
5460 return NULL; |
|
5461 } while (*s++); |
|
5462 s = pool->start; |
|
5463 poolFinish(pool); |
|
5464 return s; |
|
5465 } |
|
5466 |
|
5467 #ifndef SYMBIAN_MIN_SIZE |
|
5468 static const XML_Char * FASTCALL |
|
5469 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) |
|
5470 { |
|
5471 if (!pool->ptr && !poolGrow(pool)) |
|
5472 return NULL; |
|
5473 for (; n > 0; --n, s++) { |
|
5474 if (!poolAppendChar(pool, *s)) |
|
5475 return NULL; |
|
5476 } |
|
5477 s = pool->start; |
|
5478 poolFinish(pool); |
|
5479 return s; |
|
5480 } |
|
5481 #endif // SYMBIAN_MIN_SIZE |
|
5482 |
|
5483 #ifndef SYMBIAN_MIN_SIZE |
|
5484 static const XML_Char * FASTCALL |
|
5485 poolAppendString(STRING_POOL *pool, const XML_Char *s) |
|
5486 { |
|
5487 while (*s) { |
|
5488 if (!poolAppendChar(pool, *s)) |
|
5489 return NULL; |
|
5490 s++; |
|
5491 } |
|
5492 return pool->start; |
|
5493 } |
|
5494 #endif // SYMBIAN_MIN_SIZE |
|
5495 |
|
5496 static XML_Char * FASTCALL |
|
5497 poolStoreString(STRING_POOL *pool, const ENCODING *enc, |
|
5498 const char *ptr, const char *end) |
|
5499 { |
|
5500 if (!poolAppend(pool, enc, ptr, end)) |
|
5501 return NULL; |
|
5502 if (pool->ptr == pool->end && !poolGrow(pool)) |
|
5503 return NULL; |
|
5504 *(pool->ptr)++ = 0; |
|
5505 return pool->start; |
|
5506 } |
|
5507 |
|
5508 static XML_Bool FASTCALL |
|
5509 poolGrow(STRING_POOL *pool) |
|
5510 { |
|
5511 if (pool->freeBlocks) { |
|
5512 if (pool->start == 0) { |
|
5513 pool->blocks = pool->freeBlocks; |
|
5514 pool->freeBlocks = pool->freeBlocks->next; |
|
5515 pool->blocks->next = NULL; |
|
5516 pool->start = pool->blocks->s; |
|
5517 pool->end = pool->start + pool->blocks->size; |
|
5518 pool->ptr = pool->start; |
|
5519 return XML_TRUE; |
|
5520 } |
|
5521 if (pool->end - pool->start < pool->freeBlocks->size) { |
|
5522 BLOCK *tem = pool->freeBlocks->next; |
|
5523 pool->freeBlocks->next = pool->blocks; |
|
5524 pool->blocks = pool->freeBlocks; |
|
5525 pool->freeBlocks = tem; |
|
5526 memcpy(pool->blocks->s, pool->start, |
|
5527 (pool->end - pool->start) * sizeof(XML_Char)); |
|
5528 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); |
|
5529 pool->start = pool->blocks->s; |
|
5530 pool->end = pool->start + pool->blocks->size; |
|
5531 return XML_TRUE; |
|
5532 } |
|
5533 } |
|
5534 if (pool->blocks && pool->start == pool->blocks->s) { |
|
5535 int blockSize = (pool->end - pool->start)*2; |
|
5536 pool->blocks = (BLOCK *)pool->mem->realloc_fcn(pool->mem->allocData, pool->blocks, |
|
5537 offsetof(BLOCK, s) |
|
5538 + blockSize * sizeof(XML_Char)); |
|
5539 if (pool->blocks == NULL) |
|
5540 return XML_FALSE; |
|
5541 pool->blocks->size = blockSize; |
|
5542 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); |
|
5543 pool->start = pool->blocks->s; |
|
5544 pool->end = pool->start + blockSize; |
|
5545 } |
|
5546 else { |
|
5547 BLOCK *tem; |
|
5548 int blockSize = pool->end - pool->start; |
|
5549 if (blockSize < INIT_BLOCK_SIZE) |
|
5550 blockSize = INIT_BLOCK_SIZE; |
|
5551 else |
|
5552 blockSize *= 2; |
|
5553 tem = (BLOCK *)pool->mem->malloc_fcn(pool->mem->allocData, offsetof(BLOCK, s) |
|
5554 + blockSize * sizeof(XML_Char)); |
|
5555 if (!tem) |
|
5556 return XML_FALSE; |
|
5557 tem->size = blockSize; |
|
5558 tem->next = pool->blocks; |
|
5559 pool->blocks = tem; |
|
5560 if (pool->ptr != pool->start) |
|
5561 memcpy(tem->s, pool->start, |
|
5562 (pool->ptr - pool->start) * sizeof(XML_Char)); |
|
5563 pool->ptr = tem->s + (pool->ptr - pool->start); |
|
5564 pool->start = tem->s; |
|
5565 pool->end = tem->s + blockSize; |
|
5566 } |
|
5567 return XML_TRUE; |
|
5568 } |
|
5569 |
|
5570 static int FASTCALL |
|
5571 nextScaffoldPart(XML_Parser parser) |
|
5572 { |
|
5573 CONTENT_SCAFFOLD * me; |
|
5574 int next; |
|
5575 |
|
5576 if (!dtd.scaffIndex) { |
|
5577 dtd.scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); |
|
5578 if (!dtd.scaffIndex) |
|
5579 return -1; |
|
5580 dtd.scaffIndex[0] = 0; |
|
5581 } |
|
5582 |
|
5583 if (dtd.scaffCount >= dtd.scaffSize) { |
|
5584 CONTENT_SCAFFOLD *temp; |
|
5585 if (dtd.scaffold) { |
|
5586 temp = (CONTENT_SCAFFOLD *) |
|
5587 REALLOC(dtd.scaffold, dtd.scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); |
|
5588 if (temp == NULL) |
|
5589 return -1; |
|
5590 dtd.scaffSize *= 2; |
|
5591 } |
|
5592 else { |
|
5593 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD)); |
|
5594 if (temp == NULL) |
|
5595 return -1; |
|
5596 dtd.scaffSize = INIT_SCAFFOLD_ELEMENTS; |
|
5597 } |
|
5598 dtd.scaffold = temp; |
|
5599 } |
|
5600 next = dtd.scaffCount++; |
|
5601 me = &dtd.scaffold[next]; |
|
5602 if (dtd.scaffLevel) { |
|
5603 CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel-1]]; |
|
5604 if (parent->lastchild) { |
|
5605 dtd.scaffold[parent->lastchild].nextsib = next; |
|
5606 } |
|
5607 if (!parent->childcnt) |
|
5608 parent->firstchild = next; |
|
5609 parent->lastchild = next; |
|
5610 parent->childcnt++; |
|
5611 } |
|
5612 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; |
|
5613 return next; |
|
5614 } |
|
5615 |
|
5616 static void FASTCALL |
|
5617 build_node(XML_Parser parser, |
|
5618 int src_node, |
|
5619 XML_Content *dest, |
|
5620 XML_Content **contpos, |
|
5621 XML_Char **strpos) |
|
5622 { |
|
5623 dest->type = dtd.scaffold[src_node].type; |
|
5624 dest->quant = dtd.scaffold[src_node].quant; |
|
5625 if (dest->type == XML_CTYPE_NAME) { |
|
5626 const XML_Char *src; |
|
5627 dest->name = *strpos; |
|
5628 src = dtd.scaffold[src_node].name; |
|
5629 for (;;) { |
|
5630 *(*strpos)++ = *src; |
|
5631 if (!*src) |
|
5632 break; |
|
5633 src++; |
|
5634 } |
|
5635 dest->numchildren = 0; |
|
5636 dest->children = NULL; |
|
5637 } |
|
5638 else { |
|
5639 unsigned int i; |
|
5640 int cn; |
|
5641 dest->numchildren = dtd.scaffold[src_node].childcnt; |
|
5642 dest->children = *contpos; |
|
5643 *contpos += dest->numchildren; |
|
5644 for (i = 0, cn = dtd.scaffold[src_node].firstchild; |
|
5645 i < dest->numchildren; |
|
5646 i++, cn = dtd.scaffold[cn].nextsib) { |
|
5647 build_node(parser, cn, &(dest->children[i]), contpos, strpos); |
|
5648 } |
|
5649 dest->name = NULL; |
|
5650 } |
|
5651 } |
|
5652 |
|
5653 static XML_Content * FASTCALL |
|
5654 build_model (XML_Parser parser) |
|
5655 { |
|
5656 XML_Content *ret; |
|
5657 XML_Content *cpos; |
|
5658 XML_Char * str; |
|
5659 int allocsize = (dtd.scaffCount * sizeof(XML_Content) |
|
5660 + (dtd.contentStringLen * sizeof(XML_Char))); |
|
5661 |
|
5662 ret = (XML_Content *)MALLOC(allocsize); |
|
5663 if (!ret) |
|
5664 return NULL; |
|
5665 |
|
5666 str = (XML_Char *) (&ret[dtd.scaffCount]); |
|
5667 cpos = &ret[1]; |
|
5668 |
|
5669 build_node(parser, 0, ret, &cpos, &str); |
|
5670 return ret; |
|
5671 } |
|
5672 |
|
5673 static ELEMENT_TYPE * FASTCALL |
|
5674 getElementType(XML_Parser parser, |
|
5675 const ENCODING *enc, |
|
5676 const char *ptr, |
|
5677 const char *end) |
|
5678 { |
|
5679 const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end); |
|
5680 ELEMENT_TYPE *ret; |
|
5681 |
|
5682 if (!name) |
|
5683 return NULL; |
|
5684 ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); |
|
5685 if (!ret) |
|
5686 return NULL; |
|
5687 if (ret->name != name) |
|
5688 poolDiscard(&dtd.pool); |
|
5689 else { |
|
5690 poolFinish(&dtd.pool); |
|
5691 if (!setElementTypePrefix(parser, ret)) |
|
5692 return NULL; |
|
5693 } |
|
5694 return ret; |
|
5695 } |