2 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3 See the file copying.txt for copying permission.
11 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
12 #define XmlConvert XmlUtf16Convert
13 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
14 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
15 #define XmlEncode XmlUtf16Encode
16 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
17 typedef unsigned short ICHAR
;
19 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
20 #define XmlConvert XmlUtf8Convert
21 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
22 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
23 #define XmlEncode XmlUtf8Encode
24 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
31 #define XmlInitEncodingNS XmlInitEncoding
32 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
33 #undef XmlGetInternalEncodingNS
34 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
35 #define XmlParseXmlDeclNS XmlParseXmlDecl
39 #ifdef XML_UNICODE_WCHAR_T
40 #define XML_T(x) L ## x
45 /* Round up n to be a multiple of sz, where sz is a power of 2. */
46 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
51 typedef const XML_Char
*KEY
;
69 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
70 #define INIT_DATA_BUF_SIZE 1024
71 #define INIT_ATTS_SIZE 16
72 #define INIT_BLOCK_SIZE 1024
73 #define INIT_BUFFER_SIZE 1024
75 #define EXPAND_SPARE 24
77 typedef struct binding
{
78 struct prefix
*prefix
;
79 struct binding
*nextTagBinding
;
80 struct binding
*prevPrefixBinding
;
81 const struct attribute_id
*attId
;
87 typedef struct prefix
{
94 const XML_Char
*localPart
;
109 const XML_Char
*name
;
110 const XML_Char
*textPtr
;
112 const XML_Char
*systemId
;
113 const XML_Char
*base
;
114 const XML_Char
*publicId
;
115 const XML_Char
*notation
;
119 typedef struct block
{
133 /* The XML_Char before the name is used to determine whether
134 an attribute has been specified. */
135 typedef struct attribute_id
{
143 const ATTRIBUTE_ID
*id
;
145 const XML_Char
*value
;
149 const XML_Char
*name
;
151 const ATTRIBUTE_ID
*idAtt
;
153 int allocDefaultAtts
;
154 DEFAULT_ATTRIBUTE
*defaultAtts
;
158 HASH_TABLE generalEntities
;
159 HASH_TABLE elementTypes
;
160 HASH_TABLE attributeIds
;
166 HASH_TABLE paramEntities
;
168 PREFIX defaultPrefix
;
171 typedef struct open_internal_entity
{
172 const char *internalEventPtr
;
173 const char *internalEventEndPtr
;
174 struct open_internal_entity
*next
;
176 } OPEN_INTERNAL_ENTITY
;
178 typedef enum XML_Error
Processor(XML_Parser parser
,
181 const char **endPtr
);
183 static Processor prologProcessor
;
184 static Processor prologInitProcessor
;
185 static Processor contentProcessor
;
186 static Processor cdataSectionProcessor
;
188 static Processor ignoreSectionProcessor
;
190 static Processor epilogProcessor
;
191 static Processor errorProcessor
;
192 static Processor externalEntityInitProcessor
;
193 static Processor externalEntityInitProcessor2
;
194 static Processor externalEntityInitProcessor3
;
195 static Processor externalEntityContentProcessor
;
197 static enum XML_Error
198 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
199 static enum XML_Error
200 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
, const char *, const char *);
201 static enum XML_Error
202 initializeEncoding(XML_Parser parser
);
203 static enum XML_Error
204 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
205 const char *end
, int tok
, const char *next
, const char **nextPtr
);
206 static enum XML_Error
207 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
208 static enum XML_Error
209 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
210 const char *start
, const char *end
, const char **endPtr
);
211 static enum XML_Error
212 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
, const char *end
, const char **nextPtr
);
214 static enum XML_Error
215 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
, const char *end
, const char **nextPtr
);
217 static enum XML_Error
storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
218 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
220 int addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
, const XML_Char
*uri
, BINDING
**bindingsPtr
);
222 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, int isCdata
, int isId
, const XML_Char
*dfltValue
);
223 static enum XML_Error
224 storeAttributeValue(XML_Parser parser
, const ENCODING
*, int isCdata
, const char *, const char *,
226 static enum XML_Error
227 appendAttributeValue(XML_Parser parser
, const ENCODING
*, int isCdata
, const char *, const char *,
229 static ATTRIBUTE_ID
*
230 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
231 static int setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
232 static enum XML_Error
233 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
235 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
237 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
239 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
241 static const XML_Char
*getContext(XML_Parser parser
);
242 static int setContext(XML_Parser parser
, const XML_Char
*context
);
243 static void normalizePublicId(XML_Char
*s
);
244 static int dtdInit(DTD
*);
245 static void dtdDestroy(DTD
*);
246 static int dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
);
247 static int copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
249 static void dtdSwap(DTD
*, DTD
*);
251 static NAMED
*lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
252 static void hashTableInit(HASH_TABLE
*);
253 static void hashTableDestroy(HASH_TABLE
*);
254 static void hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
255 static NAMED
*hashTableIterNext(HASH_TABLE_ITER
*);
256 static void poolInit(STRING_POOL
*);
257 static void poolClear(STRING_POOL
*);
258 static void poolDestroy(STRING_POOL
*);
259 static XML_Char
*poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
260 const char *ptr
, const char *end
);
261 static XML_Char
*poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
262 const char *ptr
, const char *end
);
263 static int poolGrow(STRING_POOL
*pool
);
264 static const XML_Char
*poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
265 static const XML_Char
*poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
267 #define poolStart(pool) ((pool)->start)
268 #define poolEnd(pool) ((pool)->ptr)
269 #define poolLength(pool) ((pool)->ptr - (pool)->start)
270 #define poolChop(pool) ((void)--(pool->ptr))
271 #define poolLastChar(pool) (((pool)->ptr)[-1])
272 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
273 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
274 #define poolAppendChar(pool, c) \
275 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
277 : ((*((pool)->ptr)++ = c), 1))
280 /* The first member must be userData so that the XML_GetUserData macro works. */
284 /* first character to be parsed */
285 const char *m_bufferPtr
;
286 /* past last character to be parsed */
288 /* allocated end of buffer */
289 const char *m_bufferLim
;
290 long m_parseEndByteIndex
;
291 const char *m_parseEndPtr
;
293 XML_Char
*m_dataBufEnd
;
294 XML_StartElementHandler m_startElementHandler
;
295 XML_EndElementHandler m_endElementHandler
;
296 XML_CharacterDataHandler m_characterDataHandler
;
297 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
298 XML_CommentHandler m_commentHandler
;
299 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
300 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
301 XML_DefaultHandler m_defaultHandler
;
302 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
303 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
304 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
305 XML_NotationDeclHandler m_notationDeclHandler
;
306 XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler
;
307 XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler
;
308 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
309 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
310 XML_NotStandaloneHandler m_notStandaloneHandler
;
311 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
312 void *m_externalEntityRefHandlerArg
;
313 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
314 const ENCODING
*m_encoding
;
315 INIT_ENCODING m_initEncoding
;
316 const ENCODING
*m_internalEncoding
;
317 const XML_Char
*m_protocolEncodingName
;
319 void *m_unknownEncodingMem
;
320 void *m_unknownEncodingData
;
321 void *m_unknownEncodingHandlerData
;
322 void (*m_unknownEncodingRelease
)(void *);
323 PROLOG_STATE m_prologState
;
324 Processor
*m_processor
;
325 enum XML_Error m_errorCode
;
326 const char *m_eventPtr
;
327 const char *m_eventEndPtr
;
328 const char *m_positionPtr
;
329 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
330 int m_defaultExpandInternalEntities
;
332 ENTITY
*m_declEntity
;
333 const XML_Char
*m_declNotationName
;
334 const XML_Char
*m_declNotationPublicId
;
335 ELEMENT_TYPE
*m_declElementType
;
336 ATTRIBUTE_ID
*m_declAttributeId
;
337 char m_declAttributeIsCdata
;
338 char m_declAttributeIsId
;
340 const XML_Char
*m_curBase
;
343 BINDING
*m_inheritedBindings
;
344 BINDING
*m_freeBindingList
;
346 int m_nSpecifiedAtts
;
350 STRING_POOL m_tempPool
;
351 STRING_POOL m_temp2Pool
;
352 char *m_groupConnector
;
353 unsigned m_groupSize
;
354 int m_hadExternalDoctype
;
355 XML_Char m_namespaceSeparator
;
357 enum XML_ParamEntityParsing m_paramEntityParsing
;
358 XML_Parser m_parentParser
;
362 #define userData (((Parser *)parser)->m_userData)
363 #define handlerArg (((Parser *)parser)->m_handlerArg)
364 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
365 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
366 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
367 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
368 #define commentHandler (((Parser *)parser)->m_commentHandler)
369 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
370 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
371 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
372 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
373 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
374 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
375 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
376 #define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler)
377 #define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler)
378 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
379 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
380 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
381 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
382 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
383 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
384 #define encoding (((Parser *)parser)->m_encoding)
385 #define initEncoding (((Parser *)parser)->m_initEncoding)
386 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
387 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
388 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
389 #define unknownEncodingHandlerData \
390 (((Parser *)parser)->m_unknownEncodingHandlerData)
391 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
392 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
393 #define ns (((Parser *)parser)->m_ns)
394 #define prologState (((Parser *)parser)->m_prologState)
395 #define processor (((Parser *)parser)->m_processor)
396 #define errorCode (((Parser *)parser)->m_errorCode)
397 #define eventPtr (((Parser *)parser)->m_eventPtr)
398 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
399 #define positionPtr (((Parser *)parser)->m_positionPtr)
400 #define position (((Parser *)parser)->m_position)
401 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
402 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
403 #define tagLevel (((Parser *)parser)->m_tagLevel)
404 #define buffer (((Parser *)parser)->m_buffer)
405 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
406 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
407 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
408 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
409 #define bufferLim (((Parser *)parser)->m_bufferLim)
410 #define dataBuf (((Parser *)parser)->m_dataBuf)
411 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
412 #define dtd (((Parser *)parser)->m_dtd)
413 #define curBase (((Parser *)parser)->m_curBase)
414 #define declEntity (((Parser *)parser)->m_declEntity)
415 #define declNotationName (((Parser *)parser)->m_declNotationName)
416 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
417 #define declElementType (((Parser *)parser)->m_declElementType)
418 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
419 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
420 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
421 #define freeTagList (((Parser *)parser)->m_freeTagList)
422 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
423 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
424 #define tagStack (((Parser *)parser)->m_tagStack)
425 #define atts (((Parser *)parser)->m_atts)
426 #define attsSize (((Parser *)parser)->m_attsSize)
427 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
428 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
429 #define tempPool (((Parser *)parser)->m_tempPool)
430 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
431 #define groupConnector (((Parser *)parser)->m_groupConnector)
432 #define groupSize (((Parser *)parser)->m_groupSize)
433 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
434 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
436 #define parentParser (((Parser *)parser)->m_parentParser)
437 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
442 Parser
*asParser(XML_Parser parser
)
449 XML_Parser
XML_ParserCreate(const XML_Char
*encodingName
)
451 XML_Parser parser
= malloc(sizeof(Parser
));
454 processor
= prologInitProcessor
;
455 XmlPrologStateInit(&prologState
);
458 startElementHandler
= 0;
459 endElementHandler
= 0;
460 characterDataHandler
= 0;
461 processingInstructionHandler
= 0;
463 startCdataSectionHandler
= 0;
464 endCdataSectionHandler
= 0;
466 startDoctypeDeclHandler
= 0;
467 endDoctypeDeclHandler
= 0;
468 unparsedEntityDeclHandler
= 0;
469 notationDeclHandler
= 0;
470 externalParsedEntityDeclHandler
= 0;
471 internalParsedEntityDeclHandler
= 0;
472 startNamespaceDeclHandler
= 0;
473 endNamespaceDeclHandler
= 0;
474 notStandaloneHandler
= 0;
475 externalEntityRefHandler
= 0;
476 externalEntityRefHandlerArg
= parser
;
477 unknownEncodingHandler
= 0;
481 parseEndByteIndex
= 0;
487 declNotationName
= 0;
488 declNotationPublicId
= 0;
489 memset(&position
, 0, sizeof(POSITION
));
490 errorCode
= XML_ERROR_NONE
;
494 openInternalEntities
= 0;
499 inheritedBindings
= 0;
500 attsSize
= INIT_ATTS_SIZE
;
501 atts
= malloc(attsSize
* sizeof(ATTRIBUTE
));
503 dataBuf
= malloc(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
506 hadExternalDoctype
= 0;
507 unknownEncodingMem
= 0;
508 unknownEncodingRelease
= 0;
509 unknownEncodingData
= 0;
510 unknownEncodingHandlerData
= 0;
511 namespaceSeparator
= '!';
514 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
518 poolInit(&temp2Pool
);
519 protocolEncodingName
= encodingName
? poolCopyString(&tempPool
, encodingName
) : 0;
521 if (!dtdInit(&dtd
) || !atts
|| !dataBuf
522 || (encodingName
&& !protocolEncodingName
)) {
523 XML_ParserFree(parser
);
526 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
527 XmlInitEncoding(&initEncoding
, &encoding
, 0);
528 internalEncoding
= XmlGetInternalEncoding();
532 XML_Parser
XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
535 const XML_Char implicitContext
[] = {
536 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
537 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
538 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
539 XML_T('.'), XML_T('w'), XML_T('3'),
540 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
541 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
542 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
543 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
544 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
548 XML_Parser parser
= XML_ParserCreate(encodingName
);
550 XmlInitEncodingNS(&initEncoding
, &encoding
, 0);
552 internalEncoding
= XmlGetInternalEncodingNS();
553 namespaceSeparator
= nsSep
;
555 if (!setContext(parser
, implicitContext
)) {
556 XML_ParserFree(parser
);
562 int XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
565 protocolEncodingName
= 0;
567 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
568 if (!protocolEncodingName
)
574 XML_Parser
XML_ExternalEntityParserCreate(XML_Parser oldParser
,
575 const XML_Char
*context
,
576 const XML_Char
*encodingName
)
578 XML_Parser parser
= oldParser
;
580 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
581 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
582 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
583 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
= processingInstructionHandler
;
584 XML_CommentHandler oldCommentHandler
= commentHandler
;
585 XML_StartCdataSectionHandler oldStartCdataSectionHandler
= startCdataSectionHandler
;
586 XML_EndCdataSectionHandler oldEndCdataSectionHandler
= endCdataSectionHandler
;
587 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
588 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
= unparsedEntityDeclHandler
;
589 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
590 XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler
= externalParsedEntityDeclHandler
;
591 XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler
= internalParsedEntityDeclHandler
;
592 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
= startNamespaceDeclHandler
;
593 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
= endNamespaceDeclHandler
;
594 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
595 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
= externalEntityRefHandler
;
596 XML_UnknownEncodingHandler oldUnknownEncodingHandler
= unknownEncodingHandler
;
597 void *oldUserData
= userData
;
598 void *oldHandlerArg
= handlerArg
;
599 int oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
600 void *oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
602 int oldParamEntityParsing
= paramEntityParsing
;
605 ? XML_ParserCreateNS(encodingName
, namespaceSeparator
)
606 : XML_ParserCreate(encodingName
));
609 startElementHandler
= oldStartElementHandler
;
610 endElementHandler
= oldEndElementHandler
;
611 characterDataHandler
= oldCharacterDataHandler
;
612 processingInstructionHandler
= oldProcessingInstructionHandler
;
613 commentHandler
= oldCommentHandler
;
614 startCdataSectionHandler
= oldStartCdataSectionHandler
;
615 endCdataSectionHandler
= oldEndCdataSectionHandler
;
616 defaultHandler
= oldDefaultHandler
;
617 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
618 notationDeclHandler
= oldNotationDeclHandler
;
619 externalParsedEntityDeclHandler
= oldExternalParsedEntityDeclHandler
;
620 internalParsedEntityDeclHandler
= oldInternalParsedEntityDeclHandler
;
621 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
622 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
623 notStandaloneHandler
= oldNotStandaloneHandler
;
624 externalEntityRefHandler
= oldExternalEntityRefHandler
;
625 unknownEncodingHandler
= oldUnknownEncodingHandler
;
626 userData
= oldUserData
;
627 if (oldUserData
== oldHandlerArg
)
628 handlerArg
= userData
;
631 if (oldExternalEntityRefHandlerArg
!= oldParser
)
632 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
633 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
635 paramEntityParsing
= oldParamEntityParsing
;
638 if (!dtdCopy(&dtd
, oldDtd
) || !setContext(parser
, context
)) {
639 XML_ParserFree(parser
);
642 processor
= externalEntityInitProcessor
;
646 dtdSwap(&dtd
, oldDtd
);
647 parentParser
= oldParser
;
648 XmlPrologStateInitExternalEntity(&prologState
);
650 hadExternalDoctype
= 1;
657 void destroyBindings(BINDING
*bindings
)
660 BINDING
*b
= bindings
;
663 bindings
= b
->nextTagBinding
;
669 void XML_ParserFree(XML_Parser parser
)
674 if (freeTagList
== 0)
676 tagStack
= freeTagList
;
680 tagStack
= tagStack
->parent
;
682 destroyBindings(p
->bindings
);
685 destroyBindings(freeBindingList
);
686 destroyBindings(inheritedBindings
);
687 poolDestroy(&tempPool
);
688 poolDestroy(&temp2Pool
);
691 if (hadExternalDoctype
)
693 dtdSwap(&dtd
, &((Parser
*)parentParser
)->m_dtd
);
698 free(groupConnector
);
701 free(unknownEncodingMem
);
702 if (unknownEncodingRelease
)
703 unknownEncodingRelease(unknownEncodingData
);
707 void XML_UseParserAsHandlerArg(XML_Parser parser
)
712 void XML_SetUserData(XML_Parser parser
, void *p
)
714 if (handlerArg
== userData
)
715 handlerArg
= userData
= p
;
720 int XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
723 p
= poolCopyString(&dtd
.pool
, p
);
733 const XML_Char
*XML_GetBase(XML_Parser parser
)
738 int XML_GetSpecifiedAttributeCount(XML_Parser parser
)
740 return nSpecifiedAtts
;
743 int XML_GetIdAttributeIndex(XML_Parser parser
)
748 void XML_SetElementHandler(XML_Parser parser
,
749 XML_StartElementHandler start
,
750 XML_EndElementHandler end
)
752 startElementHandler
= start
;
753 endElementHandler
= end
;
756 void XML_SetCharacterDataHandler(XML_Parser parser
,
757 XML_CharacterDataHandler handler
)
759 characterDataHandler
= handler
;
762 void XML_SetProcessingInstructionHandler(XML_Parser parser
,
763 XML_ProcessingInstructionHandler handler
)
765 processingInstructionHandler
= handler
;
768 void XML_SetCommentHandler(XML_Parser parser
,
769 XML_CommentHandler handler
)
771 commentHandler
= handler
;
774 void XML_SetCdataSectionHandler(XML_Parser parser
,
775 XML_StartCdataSectionHandler start
,
776 XML_EndCdataSectionHandler end
)
778 startCdataSectionHandler
= start
;
779 endCdataSectionHandler
= end
;
782 void XML_SetDefaultHandler(XML_Parser parser
,
783 XML_DefaultHandler handler
)
785 defaultHandler
= handler
;
786 defaultExpandInternalEntities
= 0;
789 void XML_SetDefaultHandlerExpand(XML_Parser parser
,
790 XML_DefaultHandler handler
)
792 defaultHandler
= handler
;
793 defaultExpandInternalEntities
= 1;
796 void XML_SetDoctypeDeclHandler(XML_Parser parser
,
797 XML_StartDoctypeDeclHandler start
,
798 XML_EndDoctypeDeclHandler end
)
800 startDoctypeDeclHandler
= start
;
801 endDoctypeDeclHandler
= end
;
804 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
805 XML_UnparsedEntityDeclHandler handler
)
807 unparsedEntityDeclHandler
= handler
;
810 void XML_SetExternalParsedEntityDeclHandler(XML_Parser parser
,
811 XML_ExternalParsedEntityDeclHandler handler
)
813 externalParsedEntityDeclHandler
= handler
;
816 void XML_SetInternalParsedEntityDeclHandler(XML_Parser parser
,
817 XML_InternalParsedEntityDeclHandler handler
)
819 internalParsedEntityDeclHandler
= handler
;
822 void XML_SetNotationDeclHandler(XML_Parser parser
,
823 XML_NotationDeclHandler handler
)
825 notationDeclHandler
= handler
;
828 void XML_SetNamespaceDeclHandler(XML_Parser parser
,
829 XML_StartNamespaceDeclHandler start
,
830 XML_EndNamespaceDeclHandler end
)
832 startNamespaceDeclHandler
= start
;
833 endNamespaceDeclHandler
= end
;
836 void XML_SetNotStandaloneHandler(XML_Parser parser
,
837 XML_NotStandaloneHandler handler
)
839 notStandaloneHandler
= handler
;
842 void XML_SetExternalEntityRefHandler(XML_Parser parser
,
843 XML_ExternalEntityRefHandler handler
)
845 externalEntityRefHandler
= handler
;
848 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
851 externalEntityRefHandlerArg
= arg
;
853 externalEntityRefHandlerArg
= parser
;
856 void XML_SetUnknownEncodingHandler(XML_Parser parser
,
857 XML_UnknownEncodingHandler handler
,
860 unknownEncodingHandler
= handler
;
861 unknownEncodingHandlerData
= data
;
864 int XML_SetParamEntityParsing(XML_Parser parser
,
865 enum XML_ParamEntityParsing parsing
)
868 paramEntityParsing
= parsing
;
871 return parsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
875 int XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
880 positionPtr
= bufferPtr
;
881 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
882 if (errorCode
== XML_ERROR_NONE
)
884 eventEndPtr
= eventPtr
;
885 processor
= errorProcessor
;
888 else if (bufferPtr
== bufferEnd
) {
891 parseEndByteIndex
+= len
;
894 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
895 if (errorCode
== XML_ERROR_NONE
)
897 eventEndPtr
= eventPtr
;
898 processor
= errorProcessor
;
901 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
902 if (errorCode
!= XML_ERROR_NONE
) {
903 eventEndPtr
= eventPtr
;
904 processor
= errorProcessor
;
907 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
908 nLeftOver
= s
+ len
- end
;
910 if (buffer
== 0 || nLeftOver
> bufferLim
- buffer
) {
911 /* FIXME avoid integer overflow */
912 buffer
= buffer
== 0 ? malloc(len
* 2) : realloc(buffer
, len
* 2);
913 /* FIXME storage leak if realloc fails */
915 errorCode
= XML_ERROR_NO_MEMORY
;
916 eventPtr
= eventEndPtr
= 0;
917 processor
= errorProcessor
;
920 bufferLim
= buffer
+ len
* 2;
922 memcpy(buffer
, end
, nLeftOver
);
924 bufferEnd
= buffer
+ nLeftOver
;
929 memcpy(XML_GetBuffer(parser
, len
), s
, len
);
930 return XML_ParseBuffer(parser
, len
, isFinal
);
934 int XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
936 const char *start
= bufferPtr
;
939 parseEndByteIndex
+= len
;
940 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
941 isFinal
? (const char **)0 : &bufferPtr
);
942 if (errorCode
== XML_ERROR_NONE
) {
944 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
948 eventEndPtr
= eventPtr
;
949 processor
= errorProcessor
;
954 void *XML_GetBuffer(XML_Parser parser
, int len
)
956 if (len
> bufferLim
- bufferEnd
) {
957 /* FIXME avoid integer overflow */
958 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
959 if (neededSize
<= bufferLim
- buffer
) {
960 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
961 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
966 int bufferSize
= bufferLim
- bufferPtr
;
968 bufferSize
= INIT_BUFFER_SIZE
;
971 } while (bufferSize
< neededSize
);
972 newBuf
= malloc(bufferSize
);
974 errorCode
= XML_ERROR_NO_MEMORY
;
977 bufferLim
= newBuf
+ bufferSize
;
979 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
982 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
983 bufferPtr
= buffer
= newBuf
;
989 enum XML_Error
XML_GetErrorCode(XML_Parser parser
)
994 long XML_GetCurrentByteIndex(XML_Parser parser
)
997 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1001 int XML_GetCurrentByteCount(XML_Parser parser
)
1003 if (eventEndPtr
&& eventPtr
)
1004 return eventEndPtr
- eventPtr
;
1008 int XML_GetCurrentLineNumber(XML_Parser parser
)
1011 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1012 positionPtr
= eventPtr
;
1014 return position
.lineNumber
+ 1;
1017 int XML_GetCurrentColumnNumber(XML_Parser parser
)
1020 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1021 positionPtr
= eventPtr
;
1023 return position
.columnNumber
;
1026 void XML_DefaultCurrent(XML_Parser parser
)
1028 if (defaultHandler
) {
1029 if (openInternalEntities
)
1030 reportDefault(parser
,
1032 openInternalEntities
->internalEventPtr
,
1033 openInternalEntities
->internalEventEndPtr
);
1035 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1039 const XML_LChar
*XML_ErrorString(int code
)
1041 static const XML_LChar
*message
[] = {
1043 XML_T("out of memory"),
1044 XML_T("syntax error"),
1045 XML_T("no element found"),
1046 XML_T("not well-formed"),
1047 XML_T("unclosed token"),
1048 XML_T("unclosed token"),
1049 XML_T("mismatched tag"),
1050 XML_T("duplicate attribute"),
1051 XML_T("junk after document element"),
1052 XML_T("illegal parameter entity reference"),
1053 XML_T("undefined entity"),
1054 XML_T("recursive entity reference"),
1055 XML_T("asynchronous entity"),
1056 XML_T("reference to invalid character number"),
1057 XML_T("reference to binary entity"),
1058 XML_T("reference to external entity in attribute"),
1059 XML_T("xml processing instruction not at start of external entity"),
1060 XML_T("unknown encoding"),
1061 XML_T("encoding specified in XML declaration is incorrect"),
1062 XML_T("unclosed CDATA section"),
1063 XML_T("error in processing external entity reference"),
1064 XML_T("document is not standalone")
1066 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1067 return message
[code
];
1072 enum XML_Error
contentProcessor(XML_Parser parser
,
1075 const char **endPtr
)
1077 return doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1081 enum XML_Error
externalEntityInitProcessor(XML_Parser parser
,
1084 const char **endPtr
)
1086 enum XML_Error result
= initializeEncoding(parser
);
1087 if (result
!= XML_ERROR_NONE
)
1089 processor
= externalEntityInitProcessor2
;
1090 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1094 enum XML_Error
externalEntityInitProcessor2(XML_Parser parser
,
1097 const char **endPtr
)
1100 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1105 case XML_TOK_PARTIAL
:
1108 return XML_ERROR_NONE
;
1111 return XML_ERROR_UNCLOSED_TOKEN
;
1112 case XML_TOK_PARTIAL_CHAR
:
1115 return XML_ERROR_NONE
;
1118 return XML_ERROR_PARTIAL_CHAR
;
1120 processor
= externalEntityInitProcessor3
;
1121 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1125 enum XML_Error
externalEntityInitProcessor3(XML_Parser parser
,
1128 const char **endPtr
)
1131 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1133 case XML_TOK_XML_DECL
:
1135 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1136 if (result
!= XML_ERROR_NONE
)
1141 case XML_TOK_PARTIAL
:
1144 return XML_ERROR_NONE
;
1147 return XML_ERROR_UNCLOSED_TOKEN
;
1148 case XML_TOK_PARTIAL_CHAR
:
1151 return XML_ERROR_NONE
;
1154 return XML_ERROR_PARTIAL_CHAR
;
1156 processor
= externalEntityContentProcessor
;
1158 return doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1162 enum XML_Error
externalEntityContentProcessor(XML_Parser parser
,
1165 const char **endPtr
)
1167 return doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1170 static enum XML_Error
1171 doContent(XML_Parser parser
,
1173 const ENCODING
*enc
,
1176 const char **nextPtr
)
1178 const char **eventPP
;
1179 const char **eventEndPP
;
1180 if (enc
== encoding
) {
1181 eventPP
= &eventPtr
;
1182 eventEndPP
= &eventEndPtr
;
1185 eventPP
= &(openInternalEntities
->internalEventPtr
);
1186 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1190 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1191 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1194 case XML_TOK_TRAILING_CR
:
1197 return XML_ERROR_NONE
;
1200 if (characterDataHandler
) {
1202 characterDataHandler(handlerArg
, &c
, 1);
1204 else if (defaultHandler
)
1205 reportDefault(parser
, enc
, s
, end
);
1206 if (startTagLevel
== 0)
1207 return XML_ERROR_NO_ELEMENTS
;
1208 if (tagLevel
!= startTagLevel
)
1209 return XML_ERROR_ASYNC_ENTITY
;
1210 return XML_ERROR_NONE
;
1214 return XML_ERROR_NONE
;
1216 if (startTagLevel
> 0) {
1217 if (tagLevel
!= startTagLevel
)
1218 return XML_ERROR_ASYNC_ENTITY
;
1219 return XML_ERROR_NONE
;
1221 return XML_ERROR_NO_ELEMENTS
;
1222 case XML_TOK_INVALID
:
1224 return XML_ERROR_INVALID_TOKEN
;
1225 case XML_TOK_PARTIAL
:
1228 return XML_ERROR_NONE
;
1230 return XML_ERROR_UNCLOSED_TOKEN
;
1231 case XML_TOK_PARTIAL_CHAR
:
1234 return XML_ERROR_NONE
;
1236 return XML_ERROR_PARTIAL_CHAR
;
1237 case XML_TOK_ENTITY_REF
:
1239 const XML_Char
*name
;
1241 XML_Char ch
= XmlPredefinedEntityName(enc
,
1242 s
+ enc
->minBytesPerChar
,
1243 next
- enc
->minBytesPerChar
);
1245 if (characterDataHandler
)
1246 characterDataHandler(handlerArg
, &ch
, 1);
1247 else if (defaultHandler
)
1248 reportDefault(parser
, enc
, s
, next
);
1251 name
= poolStoreString(&dtd
.pool
, enc
,
1252 s
+ enc
->minBytesPerChar
,
1253 next
- enc
->minBytesPerChar
);
1255 return XML_ERROR_NO_MEMORY
;
1256 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
1257 poolDiscard(&dtd
.pool
);
1259 if (dtd
.complete
|| dtd
.standalone
)
1260 return XML_ERROR_UNDEFINED_ENTITY
;
1262 reportDefault(parser
, enc
, s
, next
);
1266 return XML_ERROR_RECURSIVE_ENTITY_REF
;
1267 if (entity
->notation
)
1268 return XML_ERROR_BINARY_ENTITY_REF
;
1270 if (entity
->textPtr
) {
1271 enum XML_Error result
;
1272 OPEN_INTERNAL_ENTITY openEntity
;
1273 if (defaultHandler
&& !defaultExpandInternalEntities
) {
1274 reportDefault(parser
, enc
, s
, next
);
1278 openEntity
.next
= openInternalEntities
;
1279 openInternalEntities
= &openEntity
;
1280 openEntity
.entity
= entity
;
1281 openEntity
.internalEventPtr
= 0;
1282 openEntity
.internalEventEndPtr
= 0;
1283 result
= doContent(parser
,
1286 (char *)entity
->textPtr
,
1287 (char *)(entity
->textPtr
+ entity
->textLen
),
1290 openInternalEntities
= openEntity
.next
;
1294 else if (externalEntityRefHandler
) {
1295 const XML_Char
*context
;
1297 context
= getContext(parser
);
1300 return XML_ERROR_NO_MEMORY
;
1301 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
1306 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
1307 poolDiscard(&tempPool
);
1309 else if (defaultHandler
)
1310 reportDefault(parser
, enc
, s
, next
);
1314 case XML_TOK_START_TAG_WITH_ATTS
:
1315 if (!startElementHandler
) {
1316 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
1321 case XML_TOK_START_TAG_NO_ATTS
:
1326 freeTagList
= freeTagList
->parent
;
1329 tag
= malloc(sizeof(TAG
));
1331 return XML_ERROR_NO_MEMORY
;
1332 tag
->buf
= malloc(INIT_TAG_BUF_SIZE
);
1334 return XML_ERROR_NO_MEMORY
;
1335 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
1338 tag
->parent
= tagStack
;
1340 tag
->name
.localPart
= 0;
1341 tag
->rawName
= s
+ enc
->minBytesPerChar
;
1342 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
1344 /* Need to guarantee that:
1345 tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1346 if (tag
->rawNameLength
+ (int)(sizeof(XML_Char
) - 1) + (int)sizeof(XML_Char
) > tag
->bufEnd
- tag
->buf
) {
1347 int bufSize
= tag
->rawNameLength
* 4;
1348 bufSize
= ROUND_UP(bufSize
, sizeof(XML_Char
));
1349 tag
->buf
= realloc(tag
->buf
, bufSize
);
1351 return XML_ERROR_NO_MEMORY
;
1352 tag
->bufEnd
= tag
->buf
+ bufSize
;
1354 memcpy(tag
->buf
, tag
->rawName
, tag
->rawNameLength
);
1355 tag
->rawName
= tag
->buf
;
1358 if (startElementHandler
) {
1359 enum XML_Error result
;
1362 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
1363 const char *fromPtr
= tag
->rawName
;
1366 toPtr
= (XML_Char
*)(tag
->buf
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
)));
1368 toPtr
= (XML_Char
*)tag
->buf
;
1369 tag
->name
.str
= toPtr
;
1371 &fromPtr
, rawNameEnd
,
1372 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
1373 if (fromPtr
== rawNameEnd
)
1375 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
1376 tag
->buf
= realloc(tag
->buf
, bufSize
);
1378 return XML_ERROR_NO_MEMORY
;
1379 tag
->bufEnd
= tag
->buf
+ bufSize
;
1381 tag
->rawName
= tag
->buf
;
1383 *toPtr
= XML_T('\0');
1384 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
1387 startElementHandler(handlerArg
, tag
->name
.str
, (const XML_Char
**)atts
);
1388 poolClear(&tempPool
);
1393 reportDefault(parser
, enc
, s
, next
);
1397 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
1398 if (!startElementHandler
) {
1399 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
1404 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
1405 if (startElementHandler
|| endElementHandler
) {
1406 const char *rawName
= s
+ enc
->minBytesPerChar
;
1407 enum XML_Error result
;
1408 BINDING
*bindings
= 0;
1410 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
1411 rawName
+ XmlNameLength(enc
, rawName
));
1413 return XML_ERROR_NO_MEMORY
;
1414 poolFinish(&tempPool
);
1415 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
1418 poolFinish(&tempPool
);
1419 if (startElementHandler
)
1420 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
1421 if (endElementHandler
) {
1422 if (startElementHandler
)
1423 *eventPP
= *eventEndPP
;
1424 endElementHandler(handlerArg
, name
.str
);
1426 poolClear(&tempPool
);
1428 BINDING
*b
= bindings
;
1429 if (endNamespaceDeclHandler
)
1430 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
1431 bindings
= bindings
->nextTagBinding
;
1432 b
->nextTagBinding
= freeBindingList
;
1433 freeBindingList
= b
;
1434 b
->prefix
->binding
= b
->prevPrefixBinding
;
1437 else if (defaultHandler
)
1438 reportDefault(parser
, enc
, s
, next
);
1440 return epilogProcessor(parser
, next
, end
, nextPtr
);
1442 case XML_TOK_END_TAG
:
1443 if (tagLevel
== startTagLevel
)
1444 return XML_ERROR_ASYNC_ENTITY
;
1447 const char *rawName
;
1448 TAG
*tag
= tagStack
;
1449 tagStack
= tag
->parent
;
1450 tag
->parent
= freeTagList
;
1452 rawName
= s
+ enc
->minBytesPerChar
*2;
1453 len
= XmlNameLength(enc
, rawName
);
1454 if (len
!= tag
->rawNameLength
1455 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
1457 return XML_ERROR_TAG_MISMATCH
;
1460 if (endElementHandler
&& tag
->name
.str
) {
1461 if (tag
->name
.localPart
) {
1462 XML_Char
*to
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
1463 const XML_Char
*from
= tag
->name
.localPart
;
1464 while ((*to
++ = *from
++) != 0)
1467 endElementHandler(handlerArg
, tag
->name
.str
);
1469 else if (defaultHandler
)
1470 reportDefault(parser
, enc
, s
, next
);
1471 while (tag
->bindings
) {
1472 BINDING
*b
= tag
->bindings
;
1473 if (endNamespaceDeclHandler
)
1474 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
1475 tag
->bindings
= tag
->bindings
->nextTagBinding
;
1476 b
->nextTagBinding
= freeBindingList
;
1477 freeBindingList
= b
;
1478 b
->prefix
->binding
= b
->prevPrefixBinding
;
1481 return epilogProcessor(parser
, next
, end
, nextPtr
);
1484 case XML_TOK_CHAR_REF
:
1486 int n
= XmlCharRefNumber(enc
, s
);
1488 return XML_ERROR_BAD_CHAR_REF
;
1489 if (characterDataHandler
) {
1490 XML_Char buf
[XML_ENCODE_MAX
];
1491 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
1493 else if (defaultHandler
)
1494 reportDefault(parser
, enc
, s
, next
);
1497 case XML_TOK_XML_DECL
:
1498 return XML_ERROR_MISPLACED_XML_PI
;
1499 case XML_TOK_DATA_NEWLINE
:
1500 if (characterDataHandler
) {
1502 characterDataHandler(handlerArg
, &c
, 1);
1504 else if (defaultHandler
)
1505 reportDefault(parser
, enc
, s
, next
);
1507 case XML_TOK_CDATA_SECT_OPEN
:
1509 enum XML_Error result
;
1510 if (startCdataSectionHandler
)
1511 startCdataSectionHandler(handlerArg
);
1513 /* Suppose you doing a transformation on a document that involves
1514 changing only the character data. You set up a defaultHandler
1515 and a characterDataHandler. The defaultHandler simply copies
1516 characters through. The characterDataHandler does the transformation
1517 and writes the characters out escaping them as necessary. This case
1518 will fail to work if we leave out the following two lines (because &
1519 and < inside CDATA sections will be incorrectly escaped).
1521 However, now we have a start/endCdataSectionHandler, so it seems
1522 easier to let the user deal with this. */
1524 else if (characterDataHandler
)
1525 characterDataHandler(handlerArg
, dataBuf
, 0);
1527 else if (defaultHandler
)
1528 reportDefault(parser
, enc
, s
, next
);
1529 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
1531 processor
= cdataSectionProcessor
;
1536 case XML_TOK_TRAILING_RSQB
:
1539 return XML_ERROR_NONE
;
1541 if (characterDataHandler
) {
1542 if (MUST_CONVERT(enc
, s
)) {
1543 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
1544 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
1545 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
1548 characterDataHandler(handlerArg
,
1550 (XML_Char
*)end
- (XML_Char
*)s
);
1552 else if (defaultHandler
)
1553 reportDefault(parser
, enc
, s
, end
);
1554 if (startTagLevel
== 0) {
1556 return XML_ERROR_NO_ELEMENTS
;
1558 if (tagLevel
!= startTagLevel
) {
1560 return XML_ERROR_ASYNC_ENTITY
;
1562 return XML_ERROR_NONE
;
1563 case XML_TOK_DATA_CHARS
:
1564 if (characterDataHandler
) {
1565 if (MUST_CONVERT(enc
, s
)) {
1567 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
1568 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
1570 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
1577 characterDataHandler(handlerArg
,
1579 (XML_Char
*)next
- (XML_Char
*)s
);
1581 else if (defaultHandler
)
1582 reportDefault(parser
, enc
, s
, next
);
1585 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
1586 return XML_ERROR_NO_MEMORY
;
1588 case XML_TOK_COMMENT
:
1589 if (!reportComment(parser
, enc
, s
, next
))
1590 return XML_ERROR_NO_MEMORY
;
1594 reportDefault(parser
, enc
, s
, next
);
1597 *eventPP
= s
= next
;
1602 /* If tagNamePtr is non-null, build a real list of attributes,
1603 otherwise just check the attributes for well-formedness. */
1605 static enum XML_Error
storeAtts(XML_Parser parser
, const ENCODING
*enc
,
1606 const char *attStr
, TAG_NAME
*tagNamePtr
,
1607 BINDING
**bindingsPtr
)
1609 ELEMENT_TYPE
*elementType
= 0;
1610 int nDefaultAtts
= 0;
1611 const XML_Char
**appAtts
; /* the attribute list to pass to the application */
1617 const XML_Char
*localPart
;
1619 /* lookup the element type name */
1621 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
, 0);
1623 tagNamePtr
->str
= poolCopyString(&dtd
.pool
, tagNamePtr
->str
);
1624 if (!tagNamePtr
->str
)
1625 return XML_ERROR_NO_MEMORY
;
1626 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
, sizeof(ELEMENT_TYPE
));
1628 return XML_ERROR_NO_MEMORY
;
1629 if (ns
&& !setElementTypePrefix(parser
, elementType
))
1630 return XML_ERROR_NO_MEMORY
;
1632 nDefaultAtts
= elementType
->nDefaultAtts
;
1634 /* get the attributes from the tokenizer */
1635 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
1636 if (n
+ nDefaultAtts
> attsSize
) {
1637 int oldAttsSize
= attsSize
;
1638 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
1639 atts
= realloc((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
1641 return XML_ERROR_NO_MEMORY
;
1642 if (n
> oldAttsSize
)
1643 XmlGetAttributes(enc
, attStr
, n
, atts
);
1645 appAtts
= (const XML_Char
**)atts
;
1646 for (i
= 0; i
< n
; i
++) {
1647 /* add the name and value to the attribute list */
1648 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
1650 + XmlNameLength(enc
, atts
[i
].name
));
1652 return XML_ERROR_NO_MEMORY
;
1653 /* detect duplicate attributes */
1654 if ((attId
->name
)[-1]) {
1655 if (enc
== encoding
)
1656 eventPtr
= atts
[i
].name
;
1657 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
1659 (attId
->name
)[-1] = 1;
1660 appAtts
[attIndex
++] = attId
->name
;
1661 if (!atts
[i
].normalized
) {
1662 enum XML_Error result
;
1665 /* figure out whether declared as other than CDATA */
1666 if (attId
->maybeTokenized
) {
1668 for (j
= 0; j
< nDefaultAtts
; j
++) {
1669 if (attId
== elementType
->defaultAtts
[j
].id
) {
1670 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
1676 /* normalize the attribute value */
1677 result
= storeAttributeValue(parser
, enc
, isCdata
,
1678 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
1683 appAtts
[attIndex
] = poolStart(&tempPool
);
1684 poolFinish(&tempPool
);
1687 poolDiscard(&tempPool
);
1689 else if (tagNamePtr
) {
1690 /* the value did not need normalizing */
1691 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
, atts
[i
].valueEnd
);
1692 if (appAtts
[attIndex
] == 0)
1693 return XML_ERROR_NO_MEMORY
;
1694 poolFinish(&tempPool
);
1696 /* handle prefixed attribute names */
1697 if (attId
->prefix
&& tagNamePtr
) {
1699 /* deal with namespace declarations here */
1700 if (!addBinding(parser
, attId
->prefix
, attId
, appAtts
[attIndex
], bindingsPtr
))
1701 return XML_ERROR_NO_MEMORY
;
1705 /* deal with other prefixed names later */
1708 (attId
->name
)[-1] = 2;
1716 nSpecifiedAtts
= attIndex
;
1717 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
1718 for (i
= 0; i
< attIndex
; i
+= 2)
1719 if (appAtts
[i
] == elementType
->idAtt
->name
) {
1726 /* do attribute defaulting */
1727 for (j
= 0; j
< nDefaultAtts
; j
++) {
1728 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ j
;
1729 if (!(da
->id
->name
)[-1] && da
->value
) {
1730 if (da
->id
->prefix
) {
1731 if (da
->id
->xmlns
) {
1732 if (!addBinding(parser
, da
->id
->prefix
, da
->id
, da
->value
, bindingsPtr
))
1733 return XML_ERROR_NO_MEMORY
;
1736 (da
->id
->name
)[-1] = 2;
1738 appAtts
[attIndex
++] = da
->id
->name
;
1739 appAtts
[attIndex
++] = da
->value
;
1743 (da
->id
->name
)[-1] = 1;
1744 appAtts
[attIndex
++] = da
->id
->name
;
1745 appAtts
[attIndex
++] = da
->value
;
1749 appAtts
[attIndex
] = 0;
1753 /* expand prefixed attribute names */
1754 for (; i
< attIndex
; i
+= 2) {
1755 if (appAtts
[i
][-1] == 2) {
1757 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
1758 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, appAtts
[i
], 0);
1759 if (id
->prefix
->binding
) {
1761 const BINDING
*b
= id
->prefix
->binding
;
1762 const XML_Char
*s
= appAtts
[i
];
1763 for (j
= 0; j
< b
->uriLen
; j
++) {
1764 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
1765 return XML_ERROR_NO_MEMORY
;
1770 if (!poolAppendChar(&tempPool
, *s
))
1771 return XML_ERROR_NO_MEMORY
;
1773 appAtts
[i
] = poolStart(&tempPool
);
1774 poolFinish(&tempPool
);
1780 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
1783 /* clear the flags that say whether attributes were specified */
1784 for (; i
< attIndex
; i
+= 2)
1785 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
1787 return XML_ERROR_NONE
;
1788 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
1789 binding
->attId
->name
[-1] = 0;
1790 /* expand the element type name */
1791 if (elementType
->prefix
) {
1792 binding
= elementType
->prefix
->binding
;
1794 return XML_ERROR_NONE
;
1795 localPart
= tagNamePtr
->str
;
1796 while (*localPart
++ != XML_T(':'))
1799 else if (dtd
.defaultPrefix
.binding
) {
1800 binding
= dtd
.defaultPrefix
.binding
;
1801 localPart
= tagNamePtr
->str
;
1804 return XML_ERROR_NONE
;
1805 tagNamePtr
->localPart
= localPart
;
1806 tagNamePtr
->uriLen
= binding
->uriLen
;
1807 for (i
= 0; localPart
[i
++];)
1809 n
= i
+ binding
->uriLen
;
1810 if (n
> binding
->uriAlloc
) {
1812 XML_Char
*uri
= malloc((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
1814 return XML_ERROR_NO_MEMORY
;
1815 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
1816 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
1817 for (p
= tagStack
; p
; p
= p
->parent
)
1818 if (p
->name
.str
== binding
->uri
)
1823 memcpy(binding
->uri
+ binding
->uriLen
, localPart
, i
* sizeof(XML_Char
));
1824 tagNamePtr
->str
= binding
->uri
;
1825 return XML_ERROR_NONE
;
1829 int addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
, const XML_Char
*uri
, BINDING
**bindingsPtr
)
1833 for (len
= 0; uri
[len
]; len
++)
1835 if (namespaceSeparator
)
1837 if (freeBindingList
) {
1838 b
= freeBindingList
;
1839 if (len
> b
->uriAlloc
) {
1840 b
->uri
= realloc(b
->uri
, sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
1843 b
->uriAlloc
= len
+ EXPAND_SPARE
;
1845 freeBindingList
= b
->nextTagBinding
;
1848 b
= malloc(sizeof(BINDING
));
1851 b
->uri
= malloc(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
1856 b
->uriAlloc
= len
+ EXPAND_SPARE
;
1859 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
1860 if (namespaceSeparator
)
1861 b
->uri
[len
- 1] = namespaceSeparator
;
1864 b
->prevPrefixBinding
= prefix
->binding
;
1865 if (*uri
== XML_T('\0') && prefix
== &dtd
.defaultPrefix
)
1866 prefix
->binding
= 0;
1868 prefix
->binding
= b
;
1869 b
->nextTagBinding
= *bindingsPtr
;
1871 if (startNamespaceDeclHandler
)
1872 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
1873 prefix
->binding
? uri
: 0);
1877 /* The idea here is to avoid using stack for each CDATA section when
1878 the whole file is parsed with one call. */
1881 enum XML_Error
cdataSectionProcessor(XML_Parser parser
,
1884 const char **endPtr
)
1886 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
, endPtr
);
1888 processor
= contentProcessor
;
1889 return contentProcessor(parser
, start
, end
, endPtr
);
1894 /* startPtr gets set to non-null is the section is closed, and to null if
1895 the section is not yet closed. */
1898 enum XML_Error
doCdataSection(XML_Parser parser
,
1899 const ENCODING
*enc
,
1900 const char **startPtr
,
1902 const char **nextPtr
)
1904 const char *s
= *startPtr
;
1905 const char **eventPP
;
1906 const char **eventEndPP
;
1907 if (enc
== encoding
) {
1908 eventPP
= &eventPtr
;
1910 eventEndPP
= &eventEndPtr
;
1913 eventPP
= &(openInternalEntities
->internalEventPtr
);
1914 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1920 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
1923 case XML_TOK_CDATA_SECT_CLOSE
:
1924 if (endCdataSectionHandler
)
1925 endCdataSectionHandler(handlerArg
);
1927 /* see comment under XML_TOK_CDATA_SECT_OPEN */
1928 else if (characterDataHandler
)
1929 characterDataHandler(handlerArg
, dataBuf
, 0);
1931 else if (defaultHandler
)
1932 reportDefault(parser
, enc
, s
, next
);
1934 return XML_ERROR_NONE
;
1935 case XML_TOK_DATA_NEWLINE
:
1936 if (characterDataHandler
) {
1938 characterDataHandler(handlerArg
, &c
, 1);
1940 else if (defaultHandler
)
1941 reportDefault(parser
, enc
, s
, next
);
1943 case XML_TOK_DATA_CHARS
:
1944 if (characterDataHandler
) {
1945 if (MUST_CONVERT(enc
, s
)) {
1947 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
1948 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
1950 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
1957 characterDataHandler(handlerArg
,
1959 (XML_Char
*)next
- (XML_Char
*)s
);
1961 else if (defaultHandler
)
1962 reportDefault(parser
, enc
, s
, next
);
1964 case XML_TOK_INVALID
:
1966 return XML_ERROR_INVALID_TOKEN
;
1967 case XML_TOK_PARTIAL_CHAR
:
1970 return XML_ERROR_NONE
;
1972 return XML_ERROR_PARTIAL_CHAR
;
1973 case XML_TOK_PARTIAL
:
1977 return XML_ERROR_NONE
;
1979 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
1983 *eventPP
= s
= next
;
1990 /* The idea here is to avoid using stack for each IGNORE section when
1991 the whole file is parsed with one call. */
1994 enum XML_Error
ignoreSectionProcessor(XML_Parser parser
,
1997 const char **endPtr
)
1999 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
, endPtr
);
2001 processor
= prologProcessor
;
2002 return prologProcessor(parser
, start
, end
, endPtr
);
2007 /* startPtr gets set to non-null is the section is closed, and to null if
2008 the section is not yet closed. */
2011 enum XML_Error
doIgnoreSection(XML_Parser parser
,
2012 const ENCODING
*enc
,
2013 const char **startPtr
,
2015 const char **nextPtr
)
2019 const char *s
= *startPtr
;
2020 const char **eventPP
;
2021 const char **eventEndPP
;
2022 if (enc
== encoding
) {
2023 eventPP
= &eventPtr
;
2025 eventEndPP
= &eventEndPtr
;
2028 eventPP
= &(openInternalEntities
->internalEventPtr
);
2029 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2033 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2036 case XML_TOK_IGNORE_SECT
:
2038 reportDefault(parser
, enc
, s
, next
);
2040 return XML_ERROR_NONE
;
2041 case XML_TOK_INVALID
:
2043 return XML_ERROR_INVALID_TOKEN
;
2044 case XML_TOK_PARTIAL_CHAR
:
2047 return XML_ERROR_NONE
;
2049 return XML_ERROR_PARTIAL_CHAR
;
2050 case XML_TOK_PARTIAL
:
2054 return XML_ERROR_NONE
;
2056 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2063 #endif /* XML_DTD */
2065 static enum XML_Error
2066 initializeEncoding(XML_Parser parser
)
2070 char encodingBuf
[128];
2071 if (!protocolEncodingName
)
2075 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2076 if (i
== sizeof(encodingBuf
) - 1
2077 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2078 encodingBuf
[0] = '\0';
2081 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2083 encodingBuf
[i
] = '\0';
2087 s
= protocolEncodingName
;
2089 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2090 return XML_ERROR_NONE
;
2091 return handleUnknownEncoding(parser
, protocolEncodingName
);
2094 static enum XML_Error
2095 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2096 const char *s
, const char *next
)
2098 const char *encodingName
= 0;
2099 const ENCODING
*newEncoding
= 0;
2100 const char *version
;
2101 int standalone
= -1;
2104 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2113 return XML_ERROR_SYNTAX
;
2114 if (!isGeneralTextEntity
&& standalone
== 1) {
2117 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2118 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2119 #endif /* XML_DTD */
2122 reportDefault(parser
, encoding
, s
, next
);
2123 if (!protocolEncodingName
) {
2125 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2126 eventPtr
= encodingName
;
2127 return XML_ERROR_INCORRECT_ENCODING
;
2129 encoding
= newEncoding
;
2131 else if (encodingName
) {
2132 enum XML_Error result
;
2133 const XML_Char
*s
= poolStoreString(&tempPool
,
2137 + XmlNameLength(encoding
, encodingName
));
2139 return XML_ERROR_NO_MEMORY
;
2140 result
= handleUnknownEncoding(parser
, s
);
2141 poolDiscard(&tempPool
);
2142 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2143 eventPtr
= encodingName
;
2147 return XML_ERROR_NONE
;
2150 static enum XML_Error
2151 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2153 if (unknownEncodingHandler
) {
2156 for (i
= 0; i
< 256; i
++)
2161 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
, &info
)) {
2163 unknownEncodingMem
= malloc(XmlSizeOfUnknownEncoding());
2164 if (!unknownEncodingMem
) {
2166 info
.release(info
.data
);
2167 return XML_ERROR_NO_MEMORY
;
2170 ? XmlInitUnknownEncodingNS
2171 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
2176 unknownEncodingData
= info
.data
;
2177 unknownEncodingRelease
= info
.release
;
2179 return XML_ERROR_NONE
;
2183 info
.release(info
.data
);
2185 return XML_ERROR_UNKNOWN_ENCODING
;
2188 static enum XML_Error
2189 prologInitProcessor(XML_Parser parser
,
2192 const char **nextPtr
)
2194 enum XML_Error result
= initializeEncoding(parser
);
2195 if (result
!= XML_ERROR_NONE
)
2197 processor
= prologProcessor
;
2198 return prologProcessor(parser
, s
, end
, nextPtr
);
2201 static enum XML_Error
2202 prologProcessor(XML_Parser parser
,
2205 const char **nextPtr
)
2208 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
2209 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
2212 static enum XML_Error
2213 doProlog(XML_Parser parser
,
2214 const ENCODING
*enc
,
2219 const char **nextPtr
)
2222 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
2223 #endif /* XML_DTD */
2225 const char **eventPP
;
2226 const char **eventEndPP
;
2227 if (enc
== encoding
) {
2228 eventPP
= &eventPtr
;
2229 eventEndPP
= &eventEndPtr
;
2232 eventPP
= &(openInternalEntities
->internalEventPtr
);
2233 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2240 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
2242 return XML_ERROR_NONE
;
2245 case XML_TOK_INVALID
:
2247 return XML_ERROR_INVALID_TOKEN
;
2248 case XML_TOK_PARTIAL
:
2249 return XML_ERROR_UNCLOSED_TOKEN
;
2250 case XML_TOK_PARTIAL_CHAR
:
2251 return XML_ERROR_PARTIAL_CHAR
;
2254 if (enc
!= encoding
)
2255 return XML_ERROR_NONE
;
2257 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
2259 return XML_ERROR_SYNTAX
;
2260 hadExternalDoctype
= 0;
2261 return XML_ERROR_NONE
;
2263 #endif /* XML_DTD */
2264 return XML_ERROR_NO_ELEMENTS
;
2271 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
2273 case XML_ROLE_XML_DECL
:
2275 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
2276 if (result
!= XML_ERROR_NONE
)
2281 case XML_ROLE_DOCTYPE_NAME
:
2282 if (startDoctypeDeclHandler
) {
2283 const XML_Char
*name
= poolStoreString(&tempPool
, enc
, s
, next
);
2285 return XML_ERROR_NO_MEMORY
;
2286 startDoctypeDeclHandler(handlerArg
, name
);
2287 poolClear(&tempPool
);
2291 case XML_ROLE_TEXT_DECL
:
2293 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
2294 if (result
!= XML_ERROR_NONE
)
2299 #endif /* XML_DTD */
2300 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
2302 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2306 return XML_ERROR_NO_MEMORY
;
2307 #endif /* XML_DTD */
2309 case XML_ROLE_ENTITY_PUBLIC_ID
:
2310 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
2311 return XML_ERROR_SYNTAX
;
2313 XML_Char
*tem
= poolStoreString(&dtd
.pool
,
2315 s
+ enc
->minBytesPerChar
,
2316 next
- enc
->minBytesPerChar
);
2318 return XML_ERROR_NO_MEMORY
;
2319 normalizePublicId(tem
);
2320 declEntity
->publicId
= tem
;
2321 poolFinish(&dtd
.pool
);
2324 case XML_ROLE_DOCTYPE_CLOSE
:
2325 if (dtd
.complete
&& hadExternalDoctype
) {
2328 if (paramEntityParsing
&& externalEntityRefHandler
) {
2329 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2332 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2337 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2339 #endif /* XML_DTD */
2342 && notStandaloneHandler
2343 && !notStandaloneHandler(handlerArg
))
2344 return XML_ERROR_NOT_STANDALONE
;
2346 if (endDoctypeDeclHandler
)
2347 endDoctypeDeclHandler(handlerArg
);
2349 case XML_ROLE_INSTANCE_START
:
2350 processor
= contentProcessor
;
2351 return contentProcessor(parser
, s
, end
, nextPtr
);
2352 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
2354 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2356 return XML_ERROR_NO_MEMORY
;
2357 declElementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, name
, sizeof(ELEMENT_TYPE
));
2358 if (!declElementType
)
2359 return XML_ERROR_NO_MEMORY
;
2360 if (declElementType
->name
!= name
)
2361 poolDiscard(&dtd
.pool
);
2363 poolFinish(&dtd
.pool
);
2364 if (!setElementTypePrefix(parser
, declElementType
))
2365 return XML_ERROR_NO_MEMORY
;
2369 case XML_ROLE_ATTRIBUTE_NAME
:
2370 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
2371 if (!declAttributeId
)
2372 return XML_ERROR_NO_MEMORY
;
2373 declAttributeIsCdata
= 0;
2374 declAttributeIsId
= 0;
2376 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
2377 declAttributeIsCdata
= 1;
2379 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
2380 declAttributeIsId
= 1;
2382 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
2383 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
2385 && !defineAttribute(declElementType
, declAttributeId
, declAttributeIsCdata
,
2386 declAttributeIsId
, 0))
2387 return XML_ERROR_NO_MEMORY
;
2389 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
2390 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
2392 const XML_Char
*attVal
;
2393 enum XML_Error result
2394 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
2395 s
+ enc
->minBytesPerChar
,
2396 next
- enc
->minBytesPerChar
,
2400 attVal
= poolStart(&dtd
.pool
);
2401 poolFinish(&dtd
.pool
);
2403 // ID attributes aren't allowed to have a default
2404 && !defineAttribute(declElementType
, declAttributeId
, declAttributeIsCdata
, 0, attVal
))
2405 return XML_ERROR_NO_MEMORY
;
2408 case XML_ROLE_ENTITY_VALUE
:
2410 enum XML_Error result
= storeEntityValue(parser
, enc
,
2411 s
+ enc
->minBytesPerChar
,
2412 next
- enc
->minBytesPerChar
);
2414 declEntity
->textPtr
= poolStart(&dtd
.pool
);
2415 declEntity
->textLen
= poolLength(&dtd
.pool
);
2416 poolFinish(&dtd
.pool
);
2417 if (internalParsedEntityDeclHandler
2418 // Check it's not a parameter entity
2419 && ((ENTITY
*)lookup(&dtd
.generalEntities
, declEntity
->name
, 0)
2422 internalParsedEntityDeclHandler(handlerArg
,
2424 declEntity
->textPtr
,
2425 declEntity
->textLen
);
2429 poolDiscard(&dtd
.pool
);
2430 if (result
!= XML_ERROR_NONE
)
2434 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
2437 && !paramEntityParsing
2438 #endif /* XML_DTD */
2439 && notStandaloneHandler
2440 && !notStandaloneHandler(handlerArg
))
2441 return XML_ERROR_NOT_STANDALONE
;
2442 hadExternalDoctype
= 1;
2447 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2451 return XML_ERROR_NO_MEMORY
;
2454 #endif /* XML_DTD */
2455 case XML_ROLE_ENTITY_SYSTEM_ID
:
2457 declEntity
->systemId
= poolStoreString(&dtd
.pool
, enc
,
2458 s
+ enc
->minBytesPerChar
,
2459 next
- enc
->minBytesPerChar
);
2460 if (!declEntity
->systemId
)
2461 return XML_ERROR_NO_MEMORY
;
2462 declEntity
->base
= curBase
;
2463 poolFinish(&dtd
.pool
);
2466 case XML_ROLE_ENTITY_NOTATION_NAME
:
2468 declEntity
->notation
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2469 if (!declEntity
->notation
)
2470 return XML_ERROR_NO_MEMORY
;
2471 poolFinish(&dtd
.pool
);
2472 if (unparsedEntityDeclHandler
) {
2474 unparsedEntityDeclHandler(handlerArg
,
2477 declEntity
->systemId
,
2478 declEntity
->publicId
,
2479 declEntity
->notation
);
2484 case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION
:
2485 if (declEntity
&& externalParsedEntityDeclHandler
) {
2487 externalParsedEntityDeclHandler(handlerArg
,
2490 declEntity
->systemId
,
2491 declEntity
->publicId
);
2494 case XML_ROLE_GENERAL_ENTITY_NAME
:
2496 const XML_Char
*name
;
2497 if (XmlPredefinedEntityName(enc
, s
, next
)) {
2501 name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2503 return XML_ERROR_NO_MEMORY
;
2505 declEntity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, sizeof(ENTITY
));
2507 return XML_ERROR_NO_MEMORY
;
2508 if (declEntity
->name
!= name
) {
2509 poolDiscard(&dtd
.pool
);
2513 poolFinish(&dtd
.pool
);
2516 poolDiscard(&dtd
.pool
);
2521 case XML_ROLE_PARAM_ENTITY_NAME
:
2524 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2526 return XML_ERROR_NO_MEMORY
;
2527 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, sizeof(ENTITY
));
2529 return XML_ERROR_NO_MEMORY
;
2530 if (declEntity
->name
!= name
) {
2531 poolDiscard(&dtd
.pool
);
2535 poolFinish(&dtd
.pool
);
2537 #else /* not XML_DTD */
2539 #endif /* not XML_DTD */
2541 case XML_ROLE_NOTATION_NAME
:
2542 declNotationPublicId
= 0;
2543 declNotationName
= 0;
2544 if (notationDeclHandler
) {
2545 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
2546 if (!declNotationName
)
2547 return XML_ERROR_NO_MEMORY
;
2548 poolFinish(&tempPool
);
2551 case XML_ROLE_NOTATION_PUBLIC_ID
:
2552 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
2553 return XML_ERROR_SYNTAX
;
2554 if (declNotationName
) {
2555 XML_Char
*tem
= poolStoreString(&tempPool
,
2557 s
+ enc
->minBytesPerChar
,
2558 next
- enc
->minBytesPerChar
);
2560 return XML_ERROR_NO_MEMORY
;
2561 normalizePublicId(tem
);
2562 declNotationPublicId
= tem
;
2563 poolFinish(&tempPool
);
2566 case XML_ROLE_NOTATION_SYSTEM_ID
:
2567 if (declNotationName
&& notationDeclHandler
) {
2568 const XML_Char
*systemId
2569 = poolStoreString(&tempPool
, enc
,
2570 s
+ enc
->minBytesPerChar
,
2571 next
- enc
->minBytesPerChar
);
2573 return XML_ERROR_NO_MEMORY
;
2575 notationDeclHandler(handlerArg
,
2579 declNotationPublicId
);
2581 poolClear(&tempPool
);
2583 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
2584 if (declNotationPublicId
&& notationDeclHandler
) {
2586 notationDeclHandler(handlerArg
,
2590 declNotationPublicId
);
2592 poolClear(&tempPool
);
2594 case XML_ROLE_ERROR
:
2596 case XML_TOK_PARAM_ENTITY_REF
:
2597 return XML_ERROR_PARAM_ENTITY_REF
;
2598 case XML_TOK_XML_DECL
:
2599 return XML_ERROR_MISPLACED_XML_PI
;
2601 return XML_ERROR_SYNTAX
;
2604 case XML_ROLE_IGNORE_SECT
:
2606 enum XML_Error result
;
2608 reportDefault(parser
, enc
, s
, next
);
2609 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
2611 processor
= ignoreSectionProcessor
;
2616 #endif /* XML_DTD */
2617 case XML_ROLE_GROUP_OPEN
:
2618 if (prologState
.level
>= groupSize
) {
2620 groupConnector
= realloc(groupConnector
, groupSize
*= 2);
2622 groupConnector
= malloc(groupSize
= 32);
2623 if (!groupConnector
)
2624 return XML_ERROR_NO_MEMORY
;
2626 groupConnector
[prologState
.level
] = 0;
2628 case XML_ROLE_GROUP_SEQUENCE
:
2629 if (groupConnector
[prologState
.level
] == '|')
2630 return XML_ERROR_SYNTAX
;
2631 groupConnector
[prologState
.level
] = ',';
2633 case XML_ROLE_GROUP_CHOICE
:
2634 if (groupConnector
[prologState
.level
] == ',')
2635 return XML_ERROR_SYNTAX
;
2636 groupConnector
[prologState
.level
] = '|';
2638 case XML_ROLE_PARAM_ENTITY_REF
:
2640 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
2641 if (paramEntityParsing
2642 && (dtd
.complete
|| role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)) {
2643 const XML_Char
*name
;
2645 name
= poolStoreString(&dtd
.pool
, enc
,
2646 s
+ enc
->minBytesPerChar
,
2647 next
- enc
->minBytesPerChar
);
2649 return XML_ERROR_NO_MEMORY
;
2650 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
2651 poolDiscard(&dtd
.pool
);
2653 /* FIXME what to do if !dtd.complete? */
2654 return XML_ERROR_UNDEFINED_ENTITY
;
2657 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2658 if (entity
->textPtr
) {
2659 enum XML_Error result
;
2660 result
= processInternalParamEntity(parser
, entity
);
2661 if (result
!= XML_ERROR_NONE
)
2665 if (role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
2666 return XML_ERROR_PARAM_ENTITY_REF
;
2667 if (externalEntityRefHandler
) {
2670 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2674 entity
->publicId
)) {
2676 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2683 #endif /* XML_DTD */
2685 && notStandaloneHandler
2686 && !notStandaloneHandler(handlerArg
))
2687 return XML_ERROR_NOT_STANDALONE
;
2690 reportDefault(parser
, enc
, s
, next
);
2695 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2696 return XML_ERROR_NO_MEMORY
;
2698 case XML_TOK_COMMENT
:
2699 if (!reportComment(parser
, enc
, s
, next
))
2700 return XML_ERROR_NO_MEMORY
;
2705 if (defaultHandler
) {
2708 case XML_TOK_COMMENT
:
2710 case XML_TOK_XML_DECL
:
2712 case XML_TOK_IGNORE_SECT
:
2713 #endif /* XML_DTD */
2714 case XML_TOK_PARAM_ENTITY_REF
:
2718 if (role
!= XML_ROLE_IGNORE_SECT
)
2719 #endif /* XML_DTD */
2720 reportDefault(parser
, enc
, s
, next
);
2724 tok
= XmlPrologTok(enc
, s
, end
, &next
);
2730 enum XML_Error
epilogProcessor(XML_Parser parser
,
2733 const char **nextPtr
)
2735 processor
= epilogProcessor
;
2739 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
2742 case -XML_TOK_PROLOG_S
:
2743 if (defaultHandler
) {
2745 reportDefault(parser
, encoding
, s
, end
);
2751 return XML_ERROR_NONE
;
2752 case XML_TOK_PROLOG_S
:
2754 reportDefault(parser
, encoding
, s
, next
);
2757 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
2758 return XML_ERROR_NO_MEMORY
;
2760 case XML_TOK_COMMENT
:
2761 if (!reportComment(parser
, encoding
, s
, next
))
2762 return XML_ERROR_NO_MEMORY
;
2764 case XML_TOK_INVALID
:
2766 return XML_ERROR_INVALID_TOKEN
;
2767 case XML_TOK_PARTIAL
:
2770 return XML_ERROR_NONE
;
2772 return XML_ERROR_UNCLOSED_TOKEN
;
2773 case XML_TOK_PARTIAL_CHAR
:
2776 return XML_ERROR_NONE
;
2778 return XML_ERROR_PARTIAL_CHAR
;
2780 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
2782 eventPtr
= s
= next
;
2788 static enum XML_Error
2789 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
2791 const char *s
, *end
, *next
;
2793 enum XML_Error result
;
2794 OPEN_INTERNAL_ENTITY openEntity
;
2796 openEntity
.next
= openInternalEntities
;
2797 openInternalEntities
= &openEntity
;
2798 openEntity
.entity
= entity
;
2799 openEntity
.internalEventPtr
= 0;
2800 openEntity
.internalEventEndPtr
= 0;
2801 s
= (char *)entity
->textPtr
;
2802 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
2803 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
2804 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
2806 openInternalEntities
= openEntity
.next
;
2810 #endif /* XML_DTD */
2813 enum XML_Error
errorProcessor(XML_Parser parser
,
2816 const char **nextPtr
)
2821 static enum XML_Error
2822 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, int isCdata
,
2823 const char *ptr
, const char *end
,
2826 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
, end
, pool
);
2829 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
2831 if (!poolAppendChar(pool
, XML_T('\0')))
2832 return XML_ERROR_NO_MEMORY
;
2833 return XML_ERROR_NONE
;
2836 static enum XML_Error
2837 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, int isCdata
,
2838 const char *ptr
, const char *end
,
2843 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
2846 return XML_ERROR_NONE
;
2847 case XML_TOK_INVALID
:
2848 if (enc
== encoding
)
2850 return XML_ERROR_INVALID_TOKEN
;
2851 case XML_TOK_PARTIAL
:
2852 if (enc
== encoding
)
2854 return XML_ERROR_INVALID_TOKEN
;
2855 case XML_TOK_CHAR_REF
:
2857 XML_Char buf
[XML_ENCODE_MAX
];
2859 int n
= XmlCharRefNumber(enc
, ptr
);
2861 if (enc
== encoding
)
2863 return XML_ERROR_BAD_CHAR_REF
;
2866 && n
== 0x20 /* space */
2867 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
2869 n
= XmlEncode(n
, (ICHAR
*)buf
);
2871 if (enc
== encoding
)
2873 return XML_ERROR_BAD_CHAR_REF
;
2875 for (i
= 0; i
< n
; i
++) {
2876 if (!poolAppendChar(pool
, buf
[i
]))
2877 return XML_ERROR_NO_MEMORY
;
2881 case XML_TOK_DATA_CHARS
:
2882 if (!poolAppend(pool
, enc
, ptr
, next
))
2883 return XML_ERROR_NO_MEMORY
;
2886 case XML_TOK_TRAILING_CR
:
2887 next
= ptr
+ enc
->minBytesPerChar
;
2889 case XML_TOK_ATTRIBUTE_VALUE_S
:
2890 case XML_TOK_DATA_NEWLINE
:
2891 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
2893 if (!poolAppendChar(pool
, 0x20))
2894 return XML_ERROR_NO_MEMORY
;
2896 case XML_TOK_ENTITY_REF
:
2898 const XML_Char
*name
;
2900 XML_Char ch
= XmlPredefinedEntityName(enc
,
2901 ptr
+ enc
->minBytesPerChar
,
2902 next
- enc
->minBytesPerChar
);
2904 if (!poolAppendChar(pool
, ch
))
2905 return XML_ERROR_NO_MEMORY
;
2908 name
= poolStoreString(&temp2Pool
, enc
,
2909 ptr
+ enc
->minBytesPerChar
,
2910 next
- enc
->minBytesPerChar
);
2912 return XML_ERROR_NO_MEMORY
;
2913 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
2914 poolDiscard(&temp2Pool
);
2917 if (enc
== encoding
)
2919 return XML_ERROR_UNDEFINED_ENTITY
;
2922 else if (entity
->open
) {
2923 if (enc
== encoding
)
2925 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2927 else if (entity
->notation
) {
2928 if (enc
== encoding
)
2930 return XML_ERROR_BINARY_ENTITY_REF
;
2932 else if (!entity
->textPtr
) {
2933 if (enc
== encoding
)
2935 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
2938 enum XML_Error result
;
2939 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
2941 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
, (char *)entity
->textPtr
, (char *)textEnd
, pool
);
2957 enum XML_Error
storeEntityValue(XML_Parser parser
,
2958 const ENCODING
*enc
,
2959 const char *entityTextPtr
,
2960 const char *entityTextEnd
)
2962 STRING_POOL
*pool
= &(dtd
.pool
);
2965 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
2967 case XML_TOK_PARAM_ENTITY_REF
:
2969 if (parentParser
|| enc
!= encoding
) {
2970 enum XML_Error result
;
2971 const XML_Char
*name
;
2973 name
= poolStoreString(&tempPool
, enc
,
2974 entityTextPtr
+ enc
->minBytesPerChar
,
2975 next
- enc
->minBytesPerChar
);
2977 return XML_ERROR_NO_MEMORY
;
2978 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
2979 poolDiscard(&tempPool
);
2981 if (enc
== encoding
)
2982 eventPtr
= entityTextPtr
;
2983 return XML_ERROR_UNDEFINED_ENTITY
;
2986 if (enc
== encoding
)
2987 eventPtr
= entityTextPtr
;
2988 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2990 if (entity
->systemId
) {
2991 if (enc
== encoding
)
2992 eventPtr
= entityTextPtr
;
2993 return XML_ERROR_PARAM_ENTITY_REF
;
2996 result
= storeEntityValue(parser
,
2998 (char *)entity
->textPtr
,
2999 (char *)(entity
->textPtr
+ entity
->textLen
));
3005 #endif /* XML_DTD */
3006 eventPtr
= entityTextPtr
;
3007 return XML_ERROR_SYNTAX
;
3009 return XML_ERROR_NONE
;
3010 case XML_TOK_ENTITY_REF
:
3011 case XML_TOK_DATA_CHARS
:
3012 if (!poolAppend(pool
, enc
, entityTextPtr
, next
))
3013 return XML_ERROR_NO_MEMORY
;
3015 case XML_TOK_TRAILING_CR
:
3016 next
= entityTextPtr
+ enc
->minBytesPerChar
;
3018 case XML_TOK_DATA_NEWLINE
:
3019 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
))
3020 return XML_ERROR_NO_MEMORY
;
3021 *(pool
->ptr
)++ = 0xA;
3023 case XML_TOK_CHAR_REF
:
3025 XML_Char buf
[XML_ENCODE_MAX
];
3027 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
3029 if (enc
== encoding
)
3030 eventPtr
= entityTextPtr
;
3031 return XML_ERROR_BAD_CHAR_REF
;
3033 n
= XmlEncode(n
, (ICHAR
*)buf
);
3035 if (enc
== encoding
)
3036 eventPtr
= entityTextPtr
;
3037 return XML_ERROR_BAD_CHAR_REF
;
3039 for (i
= 0; i
< n
; i
++) {
3040 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
))
3041 return XML_ERROR_NO_MEMORY
;
3042 *(pool
->ptr
)++ = buf
[i
];
3046 case XML_TOK_PARTIAL
:
3047 if (enc
== encoding
)
3048 eventPtr
= entityTextPtr
;
3049 return XML_ERROR_INVALID_TOKEN
;
3050 case XML_TOK_INVALID
:
3051 if (enc
== encoding
)
3053 return XML_ERROR_INVALID_TOKEN
;
3057 entityTextPtr
= next
;
3063 normalizeLines(XML_Char
*s
)
3067 if (*s
== XML_T('\0'))
3086 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3088 const XML_Char
*target
;
3091 if (!processingInstructionHandler
) {
3093 reportDefault(parser
, enc
, start
, end
);
3096 start
+= enc
->minBytesPerChar
* 2;
3097 tem
= start
+ XmlNameLength(enc
, start
);
3098 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
3101 poolFinish(&tempPool
);
3102 data
= poolStoreString(&tempPool
, enc
,
3104 end
- enc
->minBytesPerChar
*2);
3107 normalizeLines(data
);
3108 processingInstructionHandler(handlerArg
, target
, data
);
3109 poolClear(&tempPool
);
3114 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3117 if (!commentHandler
) {
3119 reportDefault(parser
, enc
, start
, end
);
3122 data
= poolStoreString(&tempPool
,
3124 start
+ enc
->minBytesPerChar
* 4,
3125 end
- enc
->minBytesPerChar
* 3);
3128 normalizeLines(data
);
3129 commentHandler(handlerArg
, data
);
3130 poolClear(&tempPool
);
3135 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *s
, const char *end
)
3137 if (MUST_CONVERT(enc
, s
)) {
3138 const char **eventPP
;
3139 const char **eventEndPP
;
3140 if (enc
== encoding
) {
3141 eventPP
= &eventPtr
;
3142 eventEndPP
= &eventEndPtr
;
3145 eventPP
= &(openInternalEntities
->internalEventPtr
);
3146 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3149 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3150 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3152 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
3157 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
3162 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, int isCdata
, int isId
, const XML_Char
*value
)
3164 DEFAULT_ATTRIBUTE
*att
;
3165 if (value
|| isId
) {
3166 /* The handling of default attributes gets messed up if we have
3167 a default which duplicates a non-default. */
3169 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
3170 if (attId
== type
->defaultAtts
[i
].id
)
3172 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
3173 type
->idAtt
= attId
;
3175 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
3176 if (type
->allocDefaultAtts
== 0) {
3177 type
->allocDefaultAtts
= 8;
3178 type
->defaultAtts
= malloc(type
->allocDefaultAtts
*sizeof(DEFAULT_ATTRIBUTE
));
3181 type
->allocDefaultAtts
*= 2;
3182 type
->defaultAtts
= realloc(type
->defaultAtts
,
3183 type
->allocDefaultAtts
*sizeof(DEFAULT_ATTRIBUTE
));
3185 if (!type
->defaultAtts
)
3188 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
3191 att
->isCdata
= isCdata
;
3193 attId
->maybeTokenized
= 1;
3194 type
->nDefaultAtts
+= 1;
3198 static int setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
3200 const XML_Char
*name
;
3201 for (name
= elementType
->name
; *name
; name
++) {
3202 if (*name
== XML_T(':')) {
3205 for (s
= elementType
->name
; s
!= name
; s
++) {
3206 if (!poolAppendChar(&dtd
.pool
, *s
))
3209 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3211 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
), sizeof(PREFIX
));
3214 if (prefix
->name
== poolStart(&dtd
.pool
))
3215 poolFinish(&dtd
.pool
);
3217 poolDiscard(&dtd
.pool
);
3218 elementType
->prefix
= prefix
;
3225 static ATTRIBUTE_ID
*
3226 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3229 const XML_Char
*name
;
3230 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3232 name
= poolStoreString(&dtd
.pool
, enc
, start
, end
);
3236 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
3239 if (id
->name
!= name
)
3240 poolDiscard(&dtd
.pool
);
3242 poolFinish(&dtd
.pool
);
3245 else if (name
[0] == 'x'
3250 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
3251 if (name
[5] == '\0')
3252 id
->prefix
= &dtd
.defaultPrefix
;
3254 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, name
+ 6, sizeof(PREFIX
));
3259 for (i
= 0; name
[i
]; i
++) {
3260 if (name
[i
] == XML_T(':')) {
3262 for (j
= 0; j
< i
; j
++) {
3263 if (!poolAppendChar(&dtd
.pool
, name
[j
]))
3266 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3268 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
), sizeof(PREFIX
));
3269 if (id
->prefix
->name
== poolStart(&dtd
.pool
))
3270 poolFinish(&dtd
.pool
);
3272 poolDiscard(&dtd
.pool
);
3281 #define CONTEXT_SEP XML_T('\f')
3284 const XML_Char
*getContext(XML_Parser parser
)
3286 HASH_TABLE_ITER iter
;
3289 if (dtd
.defaultPrefix
.binding
) {
3292 if (!poolAppendChar(&tempPool
, XML_T('=')))
3294 len
= dtd
.defaultPrefix
.binding
->uriLen
;
3295 if (namespaceSeparator
!= XML_T('\0'))
3297 for (i
= 0; i
< len
; i
++)
3298 if (!poolAppendChar(&tempPool
, dtd
.defaultPrefix
.binding
->uri
[i
]))
3303 hashTableIterInit(&iter
, &(dtd
.prefixes
));
3308 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
3311 if (!prefix
->binding
)
3313 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
3315 for (s
= prefix
->name
; *s
; s
++)
3316 if (!poolAppendChar(&tempPool
, *s
))
3318 if (!poolAppendChar(&tempPool
, XML_T('=')))
3320 len
= prefix
->binding
->uriLen
;
3321 if (namespaceSeparator
!= XML_T('\0'))
3323 for (i
= 0; i
< len
; i
++)
3324 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
3330 hashTableIterInit(&iter
, &(dtd
.generalEntities
));
3333 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
3338 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
3340 for (s
= e
->name
; *s
; s
++)
3341 if (!poolAppendChar(&tempPool
, *s
))
3346 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3348 return tempPool
.start
;
3352 int setContext(XML_Parser parser
, const XML_Char
*context
)
3354 const XML_Char
*s
= context
;
3356 while (*context
!= XML_T('\0')) {
3357 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
3359 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3361 e
= (ENTITY
*)lookup(&dtd
.generalEntities
, poolStart(&tempPool
), 0);
3364 if (*s
!= XML_T('\0'))
3367 poolDiscard(&tempPool
);
3369 else if (*s
== '=') {
3371 if (poolLength(&tempPool
) == 0)
3372 prefix
= &dtd
.defaultPrefix
;
3374 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3376 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&tempPool
), sizeof(PREFIX
));
3379 if (prefix
->name
== poolStart(&tempPool
)) {
3380 prefix
->name
= poolCopyString(&dtd
.pool
, prefix
->name
);
3384 poolDiscard(&tempPool
);
3386 for (context
= s
+ 1; *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0'); context
++)
3387 if (!poolAppendChar(&tempPool
, *context
))
3389 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3391 if (!addBinding(parser
, prefix
, 0, poolStart(&tempPool
), &inheritedBindings
))
3393 poolDiscard(&tempPool
);
3394 if (*context
!= XML_T('\0'))
3399 if (!poolAppendChar(&tempPool
, *s
))
3409 void normalizePublicId(XML_Char
*publicId
)
3411 XML_Char
*p
= publicId
;
3413 for (s
= publicId
; *s
; s
++) {
3418 if (p
!= publicId
&& p
[-1] != 0x20)
3425 if (p
!= publicId
&& p
[-1] == 0x20)
3430 static int dtdInit(DTD
*p
)
3432 poolInit(&(p
->pool
));
3433 hashTableInit(&(p
->generalEntities
));
3434 hashTableInit(&(p
->elementTypes
));
3435 hashTableInit(&(p
->attributeIds
));
3436 hashTableInit(&(p
->prefixes
));
3440 hashTableInit(&(p
->paramEntities
));
3441 #endif /* XML_DTD */
3442 p
->defaultPrefix
.name
= 0;
3443 p
->defaultPrefix
.binding
= 0;
3449 static void dtdSwap(DTD
*p1
, DTD
*p2
)
3452 memcpy(&tem
, p1
, sizeof(DTD
));
3453 memcpy(p1
, p2
, sizeof(DTD
));
3454 memcpy(p2
, &tem
, sizeof(DTD
));
3457 #endif /* XML_DTD */
3459 static void dtdDestroy(DTD
*p
)
3461 HASH_TABLE_ITER iter
;
3462 hashTableIterInit(&iter
, &(p
->elementTypes
));
3464 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
3467 if (e
->allocDefaultAtts
!= 0)
3468 free(e
->defaultAtts
);
3470 hashTableDestroy(&(p
->generalEntities
));
3472 hashTableDestroy(&(p
->paramEntities
));
3473 #endif /* XML_DTD */
3474 hashTableDestroy(&(p
->elementTypes
));
3475 hashTableDestroy(&(p
->attributeIds
));
3476 hashTableDestroy(&(p
->prefixes
));
3477 poolDestroy(&(p
->pool
));
3480 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
3481 The new DTD has already been initialized. */
3483 static int dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
)
3485 HASH_TABLE_ITER iter
;
3487 /* Copy the prefix table. */
3489 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
3491 const XML_Char
*name
;
3492 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
3495 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
3498 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
3502 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
3504 /* Copy the attribute id table. */
3508 const XML_Char
*name
;
3509 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
3513 /* Remember to allocate the scratch byte before the name. */
3514 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
3516 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
3520 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
, sizeof(ATTRIBUTE_ID
));
3523 newA
->maybeTokenized
= oldA
->maybeTokenized
;
3525 newA
->xmlns
= oldA
->xmlns
;
3526 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
3527 newA
->prefix
= &newDtd
->defaultPrefix
;
3529 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
), oldA
->prefix
->name
, 0);
3533 /* Copy the element type table. */
3535 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
3540 const XML_Char
*name
;
3541 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
3544 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
3547 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
, sizeof(ELEMENT_TYPE
));
3550 if (oldE
->nDefaultAtts
) {
3551 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)malloc(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
3552 if (!newE
->defaultAtts
)
3556 newE
->idAtt
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
3557 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
3559 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
), oldE
->prefix
->name
, 0);
3560 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
3561 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
3562 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
3563 if (oldE
->defaultAtts
[i
].value
) {
3564 newE
->defaultAtts
[i
].value
= poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
3565 if (!newE
->defaultAtts
[i
].value
)
3569 newE
->defaultAtts
[i
].value
= 0;
3573 /* Copy the entity tables. */
3574 if (!copyEntityTable(&(newDtd
->generalEntities
),
3576 &(oldDtd
->generalEntities
)))
3580 if (!copyEntityTable(&(newDtd
->paramEntities
),
3582 &(oldDtd
->paramEntities
)))
3584 #endif /* XML_DTD */
3586 newDtd
->complete
= oldDtd
->complete
;
3587 newDtd
->standalone
= oldDtd
->standalone
;
3591 static int copyEntityTable(HASH_TABLE
*newTable
,
3592 STRING_POOL
*newPool
,
3593 const HASH_TABLE
*oldTable
)
3595 HASH_TABLE_ITER iter
;
3596 const XML_Char
*cachedOldBase
= 0;
3597 const XML_Char
*cachedNewBase
= 0;
3599 hashTableIterInit(&iter
, oldTable
);
3603 const XML_Char
*name
;
3604 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
3607 name
= poolCopyString(newPool
, oldE
->name
);
3610 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
3613 if (oldE
->systemId
) {
3614 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
3617 newE
->systemId
= tem
;
3619 if (oldE
->base
== cachedOldBase
)
3620 newE
->base
= cachedNewBase
;
3622 cachedOldBase
= oldE
->base
;
3623 tem
= poolCopyString(newPool
, cachedOldBase
);
3626 cachedNewBase
= newE
->base
= tem
;
3631 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
, oldE
->textLen
);
3634 newE
->textPtr
= tem
;
3635 newE
->textLen
= oldE
->textLen
;
3637 if (oldE
->notation
) {
3638 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
3641 newE
->notation
= tem
;
3647 #define INIT_SIZE 64
3650 int keyeq(KEY s1
, KEY s2
)
3652 for (; *s1
== *s2
; s1
++, s2
++)
3659 unsigned long hash(KEY s
)
3661 unsigned long h
= 0;
3663 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
3668 NAMED
*lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
3671 if (table
->size
== 0) {
3674 table
->v
= calloc(INIT_SIZE
, sizeof(NAMED
*));
3677 table
->size
= INIT_SIZE
;
3678 table
->usedLim
= INIT_SIZE
/ 2;
3679 i
= hash(name
) & (table
->size
- 1);
3682 unsigned long h
= hash(name
);
3683 for (i
= h
& (table
->size
- 1);
3685 i
== 0 ? i
= table
->size
- 1 : --i
) {
3686 if (keyeq(name
, table
->v
[i
]->name
))
3691 if (table
->used
== table
->usedLim
) {
3692 /* check for overflow */
3693 size_t newSize
= table
->size
* 2;
3694 NAMED
**newV
= calloc(newSize
, sizeof(NAMED
*));
3697 for (i
= 0; i
< table
->size
; i
++)
3700 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
3702 j
== 0 ? j
= newSize
- 1 : --j
)
3704 newV
[j
] = table
->v
[i
];
3708 table
->size
= newSize
;
3709 table
->usedLim
= newSize
/2;
3710 for (i
= h
& (table
->size
- 1);
3712 i
== 0 ? i
= table
->size
- 1 : --i
)
3716 table
->v
[i
] = calloc(1, createSize
);
3719 table
->v
[i
]->name
= name
;
3725 void hashTableDestroy(HASH_TABLE
*table
)
3728 for (i
= 0; i
< table
->size
; i
++) {
3729 NAMED
*p
= table
->v
[i
];
3738 void hashTableInit(HASH_TABLE
*p
)
3747 void hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
3750 iter
->end
= iter
->p
+ table
->size
;
3754 NAMED
*hashTableIterNext(HASH_TABLE_ITER
*iter
)
3756 while (iter
->p
!= iter
->end
) {
3757 NAMED
*tem
= *(iter
->p
)++;
3766 void poolInit(STRING_POOL
*pool
)
3769 pool
->freeBlocks
= 0;
3776 void poolClear(STRING_POOL
*pool
)
3778 if (!pool
->freeBlocks
)
3779 pool
->freeBlocks
= pool
->blocks
;
3781 BLOCK
*p
= pool
->blocks
;
3783 BLOCK
*tem
= p
->next
;
3784 p
->next
= pool
->freeBlocks
;
3785 pool
->freeBlocks
= p
;
3796 void poolDestroy(STRING_POOL
*pool
)
3798 BLOCK
*p
= pool
->blocks
;
3800 BLOCK
*tem
= p
->next
;
3805 p
= pool
->freeBlocks
;
3807 BLOCK
*tem
= p
->next
;
3811 pool
->freeBlocks
= 0;
3818 XML_Char
*poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
3819 const char *ptr
, const char *end
)
3821 if (!pool
->ptr
&& !poolGrow(pool
))
3824 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
3827 if (!poolGrow(pool
))
3833 static const XML_Char
*poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
3836 if (!poolAppendChar(pool
, *s
))
3844 static const XML_Char
*poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
3846 if (!pool
->ptr
&& !poolGrow(pool
))
3848 for (; n
> 0; --n
, s
++) {
3849 if (!poolAppendChar(pool
, *s
))
3859 XML_Char
*poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
3860 const char *ptr
, const char *end
)
3862 if (!poolAppend(pool
, enc
, ptr
, end
))
3864 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
3871 int poolGrow(STRING_POOL
*pool
)
3873 if (pool
->freeBlocks
) {
3874 if (pool
->start
== 0) {
3875 pool
->blocks
= pool
->freeBlocks
;
3876 pool
->freeBlocks
= pool
->freeBlocks
->next
;
3877 pool
->blocks
->next
= 0;
3878 pool
->start
= pool
->blocks
->s
;
3879 pool
->end
= pool
->start
+ pool
->blocks
->size
;
3880 pool
->ptr
= pool
->start
;
3883 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
3884 BLOCK
*tem
= pool
->freeBlocks
->next
;
3885 pool
->freeBlocks
->next
= pool
->blocks
;
3886 pool
->blocks
= pool
->freeBlocks
;
3887 pool
->freeBlocks
= tem
;
3888 memcpy(pool
->blocks
->s
, pool
->start
, (pool
->end
- pool
->start
) * sizeof(XML_Char
));
3889 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
3890 pool
->start
= pool
->blocks
->s
;
3891 pool
->end
= pool
->start
+ pool
->blocks
->size
;
3895 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
3896 int blockSize
= (pool
->end
- pool
->start
)*2;
3897 pool
->blocks
= realloc(pool
->blocks
, offsetof(BLOCK
, s
) + blockSize
* sizeof(XML_Char
));
3900 pool
->blocks
->size
= blockSize
;
3901 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
3902 pool
->start
= pool
->blocks
->s
;
3903 pool
->end
= pool
->start
+ blockSize
;
3907 int blockSize
= pool
->end
- pool
->start
;
3908 if (blockSize
< INIT_BLOCK_SIZE
)
3909 blockSize
= INIT_BLOCK_SIZE
;
3912 tem
= malloc(offsetof(BLOCK
, s
) + blockSize
* sizeof(XML_Char
));
3915 tem
->size
= blockSize
;
3916 tem
->next
= pool
->blocks
;
3918 if (pool
->ptr
!= pool
->start
)
3919 memcpy(tem
->s
, pool
->start
, (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
3920 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
3921 pool
->start
= tem
->s
;
3922 pool
->end
= tem
->s
+ blockSize
;