1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
8 #ifdef COMPILED_FROM_DSP
10 #include "winconfig.h"
13 #elif defined(MACOS_CLASSIC)
15 #include "macconfig.h"
20 #include <expat_config.h>
23 #define XMLPARSEAPI(type) type __cdecl
31 #endif /* ndef COMPILED_FROM_DSP */
34 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
35 #define XmlConvert XmlUtf16Convert
36 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
37 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
38 #define XmlEncode XmlUtf16Encode
39 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
40 typedef unsigned short ICHAR
;
42 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
43 #define XmlConvert XmlUtf8Convert
44 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
45 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
46 #define XmlEncode XmlUtf8Encode
47 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
54 #define XmlInitEncodingNS XmlInitEncoding
55 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
56 #undef XmlGetInternalEncodingNS
57 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
58 #define XmlParseXmlDeclNS XmlParseXmlDecl
64 #ifdef XML_UNICODE_WCHAR_T
65 #define XML_T(x) (const wchar_t)x
66 #define XML_L(x) L ## x
68 #define XML_T(x) (const unsigned short)x
79 /* Round up n to be a multiple of sz, where sz is a power of 2. */
80 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
82 /* Handle the case where memmove() doesn't exist. */
85 #define memmove(d,s,l) bcopy((s),(d),(l))
87 #error memmove does not exist on this platform, nor is a substitute available
88 #endif /* HAVE_BCOPY */
89 #endif /* HAVE_MEMMOVE */
95 typedef const XML_Char
*KEY
;
106 const XML_Memory_Handling_Suite
*mem
;
114 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
115 #define INIT_DATA_BUF_SIZE 1024
116 #define INIT_ATTS_SIZE 16
117 #define INIT_BLOCK_SIZE 1024
118 #define INIT_BUFFER_SIZE 1024
120 #define EXPAND_SPARE 24
122 typedef struct binding
{
123 struct prefix
*prefix
;
124 struct binding
*nextTagBinding
;
125 struct binding
*prevPrefixBinding
;
126 const struct attribute_id
*attId
;
132 typedef struct prefix
{
133 const XML_Char
*name
;
139 const XML_Char
*localPart
;
140 const XML_Char
*prefix
;
146 /* TAG represents an open element.
147 The name of the element is stored in both the document and API
148 encodings. The memory buffer 'buf' is a separately-allocated
149 memory area which stores the name. During the XML_Parse()/
150 XMLParseBuffer() when the element is open, the memory for the 'raw'
151 version of the name (in the document encoding) is shared with the
152 document buffer. If the element is open across calls to
153 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
154 contain the 'raw' name as well.
156 A parser re-uses these structures, maintaining a list of allocated
157 TAG objects in a free list.
160 struct tag
*parent
; /* parent of this element */
161 const char *rawName
; /* tagName in the original encoding */
163 TAG_NAME name
; /* tagName in the API encoding */
164 char *buf
; /* buffer for name components */
165 char *bufEnd
; /* end of the buffer */
170 const XML_Char
*name
;
171 const XML_Char
*textPtr
;
173 const XML_Char
*systemId
;
174 const XML_Char
*base
;
175 const XML_Char
*publicId
;
176 const XML_Char
*notation
;
179 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
183 enum XML_Content_Type type
;
184 enum XML_Content_Quant quant
;
185 const XML_Char
* name
;
192 #define INIT_SCAFFOLD_ELEMENTS 32
194 typedef struct block
{
206 const XML_Memory_Handling_Suite
*mem
;
209 /* The XML_Char before the name is used to determine whether
210 an attribute has been specified. */
211 typedef struct attribute_id
{
214 XML_Bool maybeTokenized
;
219 const ATTRIBUTE_ID
*id
;
221 const XML_Char
*value
;
225 const XML_Char
*name
;
227 const ATTRIBUTE_ID
*idAtt
;
229 int allocDefaultAtts
;
230 DEFAULT_ATTRIBUTE
*defaultAtts
;
234 HASH_TABLE generalEntities
;
235 HASH_TABLE elementTypes
;
236 HASH_TABLE attributeIds
;
239 STRING_POOL entityValuePool
;
240 /* false once a parameter entity reference has been skipped */
241 XML_Bool keepProcessing
;
242 /* true once an internal or external PE reference has been encountered;
243 this includes the reference to an external subset */
244 XML_Bool hasParamEntityRefs
;
247 /* indicates if external PE has been read */
248 XML_Bool paramEntityRead
;
249 HASH_TABLE paramEntities
;
251 PREFIX defaultPrefix
;
252 /* === scaffolding for building content model === */
254 CONTENT_SCAFFOLD
*scaffold
;
255 unsigned contentStringLen
;
262 typedef struct open_internal_entity
{
263 const char *internalEventPtr
;
264 const char *internalEventEndPtr
;
265 struct open_internal_entity
*next
;
267 } OPEN_INTERNAL_ENTITY
;
269 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
272 const char **endPtr
);
274 static Processor prologProcessor
;
275 static Processor prologInitProcessor
;
276 static Processor contentProcessor
;
277 static Processor cdataSectionProcessor
;
279 static Processor ignoreSectionProcessor
;
280 static Processor externalParEntProcessor
;
281 static Processor externalParEntInitProcessor
;
282 static Processor entityValueProcessor
;
283 static Processor entityValueInitProcessor
;
285 static Processor epilogProcessor
;
286 static Processor errorProcessor
;
287 static Processor externalEntityInitProcessor
;
288 static Processor externalEntityInitProcessor2
;
289 static Processor externalEntityInitProcessor3
;
290 static Processor externalEntityContentProcessor
;
292 static enum XML_Error
293 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
294 static enum XML_Error
295 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
296 const char *, const char *);
297 static enum XML_Error
298 initializeEncoding(XML_Parser parser
);
299 static enum XML_Error
300 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
301 const char *end
, int tok
, const char *next
, const char **nextPtr
);
302 static enum XML_Error
303 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
304 static enum XML_Error
305 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
306 const char *start
, const char *end
, const char **endPtr
);
307 static enum XML_Error
308 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
309 const char *end
, const char **nextPtr
);
311 static enum XML_Error
312 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
313 const char *end
, const char **nextPtr
);
316 static enum XML_Error
317 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
318 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
319 static enum XML_Error
320 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
321 const XML_Char
*uri
, BINDING
**bindingsPtr
);
323 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
324 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
326 static enum XML_Error
327 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
328 const char *, const char *, STRING_POOL
*);
329 static enum XML_Error
330 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
331 const char *, const char *, STRING_POOL
*);
332 static ATTRIBUTE_ID
*
333 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
336 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
337 static enum XML_Error
338 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
341 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
342 const char *start
, const char *end
);
344 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
347 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
350 static const XML_Char
* getContext(XML_Parser parser
);
352 setContext(XML_Parser parser
, const XML_Char
*context
);
354 static void FASTCALL
normalizePublicId(XML_Char
*s
);
356 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
357 /* do not call if parentParser != NULL */
358 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
360 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
362 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
364 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
367 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
369 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
370 static void FASTCALL
hashTableClear(HASH_TABLE
*);
371 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
373 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
374 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
377 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
378 static void FASTCALL
poolClear(STRING_POOL
*);
379 static void FASTCALL
poolDestroy(STRING_POOL
*);
381 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
382 const char *ptr
, const char *end
);
384 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
385 const char *ptr
, const char *end
);
386 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
387 static const XML_Char
* FASTCALL
388 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
389 static const XML_Char
*
390 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
391 static const XML_Char
* FASTCALL
392 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
394 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
395 static XML_Content
* build_model(XML_Parser parser
);
396 static ELEMENT_TYPE
*
397 getElementType(XML_Parser parser
, const ENCODING
*enc
,
398 const char *ptr
, const char *end
);
401 parserCreate(const XML_Char
*encodingName
,
402 const XML_Memory_Handling_Suite
*memsuite
,
403 const XML_Char
*nameSep
,
406 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
408 #define poolStart(pool) ((pool)->start)
409 #define poolEnd(pool) ((pool)->ptr)
410 #define poolLength(pool) ((pool)->ptr - (pool)->start)
411 #define poolChop(pool) ((void)--(pool->ptr))
412 #define poolLastChar(pool) (((pool)->ptr)[-1])
413 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
414 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
415 #define poolAppendChar(pool, c) \
416 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
418 : ((*((pool)->ptr)++ = c), 1))
420 struct XML_ParserStruct
{
421 /* The first member must be userData so that the XML_GetUserData
426 const XML_Memory_Handling_Suite m_mem
;
427 /* first character to be parsed */
428 const char *m_bufferPtr
;
429 /* past last character to be parsed */
431 /* allocated end of buffer */
432 const char *m_bufferLim
;
433 long m_parseEndByteIndex
;
434 const char *m_parseEndPtr
;
436 XML_Char
*m_dataBufEnd
;
437 XML_StartElementHandler m_startElementHandler
;
438 XML_EndElementHandler m_endElementHandler
;
439 XML_CharacterDataHandler m_characterDataHandler
;
440 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
441 XML_CommentHandler m_commentHandler
;
442 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
443 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
444 XML_DefaultHandler m_defaultHandler
;
445 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
446 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
447 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
448 XML_NotationDeclHandler m_notationDeclHandler
;
449 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
450 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
451 XML_NotStandaloneHandler m_notStandaloneHandler
;
452 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
453 XML_Parser m_externalEntityRefHandlerArg
;
454 XML_SkippedEntityHandler m_skippedEntityHandler
;
455 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
456 XML_ElementDeclHandler m_elementDeclHandler
;
457 XML_AttlistDeclHandler m_attlistDeclHandler
;
458 XML_EntityDeclHandler m_entityDeclHandler
;
459 XML_XmlDeclHandler m_xmlDeclHandler
;
460 const ENCODING
*m_encoding
;
461 INIT_ENCODING m_initEncoding
;
462 const ENCODING
*m_internalEncoding
;
463 const XML_Char
*m_protocolEncodingName
;
465 XML_Bool m_ns_triplets
;
466 void *m_unknownEncodingMem
;
467 void *m_unknownEncodingData
;
468 void *m_unknownEncodingHandlerData
;
469 void (*m_unknownEncodingRelease
)(void *);
470 PROLOG_STATE m_prologState
;
471 Processor
*m_processor
;
472 enum XML_Error m_errorCode
;
473 const char *m_eventPtr
;
474 const char *m_eventEndPtr
;
475 const char *m_positionPtr
;
476 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
477 XML_Bool m_defaultExpandInternalEntities
;
479 ENTITY
*m_declEntity
;
480 const XML_Char
*m_doctypeName
;
481 const XML_Char
*m_doctypeSysid
;
482 const XML_Char
*m_doctypePubid
;
483 const XML_Char
*m_declAttributeType
;
484 const XML_Char
*m_declNotationName
;
485 const XML_Char
*m_declNotationPublicId
;
486 ELEMENT_TYPE
*m_declElementType
;
487 ATTRIBUTE_ID
*m_declAttributeId
;
488 XML_Bool m_declAttributeIsCdata
;
489 XML_Bool m_declAttributeIsId
;
491 const XML_Char
*m_curBase
;
494 BINDING
*m_inheritedBindings
;
495 BINDING
*m_freeBindingList
;
497 int m_nSpecifiedAtts
;
501 STRING_POOL m_tempPool
;
502 STRING_POOL m_temp2Pool
;
503 char *m_groupConnector
;
504 unsigned m_groupSize
;
505 XML_Char m_namespaceSeparator
;
506 XML_Parser m_parentParser
;
508 XML_Bool m_isParamEntity
;
509 XML_Bool m_useForeignDTD
;
510 enum XML_ParamEntityParsing m_paramEntityParsing
;
514 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
515 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
516 #define FREE(p) (parser->m_mem.free_fcn((p)))
518 #define userData (parser->m_userData)
519 #define handlerArg (parser->m_handlerArg)
520 #define startElementHandler (parser->m_startElementHandler)
521 #define endElementHandler (parser->m_endElementHandler)
522 #define characterDataHandler (parser->m_characterDataHandler)
523 #define processingInstructionHandler \
524 (parser->m_processingInstructionHandler)
525 #define commentHandler (parser->m_commentHandler)
526 #define startCdataSectionHandler \
527 (parser->m_startCdataSectionHandler)
528 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
529 #define defaultHandler (parser->m_defaultHandler)
530 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
531 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
532 #define unparsedEntityDeclHandler \
533 (parser->m_unparsedEntityDeclHandler)
534 #define notationDeclHandler (parser->m_notationDeclHandler)
535 #define startNamespaceDeclHandler \
536 (parser->m_startNamespaceDeclHandler)
537 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
538 #define notStandaloneHandler (parser->m_notStandaloneHandler)
539 #define externalEntityRefHandler \
540 (parser->m_externalEntityRefHandler)
541 #define externalEntityRefHandlerArg \
542 (parser->m_externalEntityRefHandlerArg)
543 #define internalEntityRefHandler \
544 (parser->m_internalEntityRefHandler)
545 #define skippedEntityHandler (parser->m_skippedEntityHandler)
546 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
547 #define elementDeclHandler (parser->m_elementDeclHandler)
548 #define attlistDeclHandler (parser->m_attlistDeclHandler)
549 #define entityDeclHandler (parser->m_entityDeclHandler)
550 #define xmlDeclHandler (parser->m_xmlDeclHandler)
551 #define encoding (parser->m_encoding)
552 #define initEncoding (parser->m_initEncoding)
553 #define internalEncoding (parser->m_internalEncoding)
554 #define unknownEncodingMem (parser->m_unknownEncodingMem)
555 #define unknownEncodingData (parser->m_unknownEncodingData)
556 #define unknownEncodingHandlerData \
557 (parser->m_unknownEncodingHandlerData)
558 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
559 #define protocolEncodingName (parser->m_protocolEncodingName)
560 #define ns (parser->m_ns)
561 #define ns_triplets (parser->m_ns_triplets)
562 #define prologState (parser->m_prologState)
563 #define processor (parser->m_processor)
564 #define errorCode (parser->m_errorCode)
565 #define eventPtr (parser->m_eventPtr)
566 #define eventEndPtr (parser->m_eventEndPtr)
567 #define positionPtr (parser->m_positionPtr)
568 #define position (parser->m_position)
569 #define openInternalEntities (parser->m_openInternalEntities)
570 #define defaultExpandInternalEntities \
571 (parser->m_defaultExpandInternalEntities)
572 #define tagLevel (parser->m_tagLevel)
573 #define buffer (parser->m_buffer)
574 #define bufferPtr (parser->m_bufferPtr)
575 #define bufferEnd (parser->m_bufferEnd)
576 #define parseEndByteIndex (parser->m_parseEndByteIndex)
577 #define parseEndPtr (parser->m_parseEndPtr)
578 #define bufferLim (parser->m_bufferLim)
579 #define dataBuf (parser->m_dataBuf)
580 #define dataBufEnd (parser->m_dataBufEnd)
581 #define _dtd (parser->m_dtd)
582 #define curBase (parser->m_curBase)
583 #define declEntity (parser->m_declEntity)
584 #define doctypeName (parser->m_doctypeName)
585 #define doctypeSysid (parser->m_doctypeSysid)
586 #define doctypePubid (parser->m_doctypePubid)
587 #define declAttributeType (parser->m_declAttributeType)
588 #define declNotationName (parser->m_declNotationName)
589 #define declNotationPublicId (parser->m_declNotationPublicId)
590 #define declElementType (parser->m_declElementType)
591 #define declAttributeId (parser->m_declAttributeId)
592 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
593 #define declAttributeIsId (parser->m_declAttributeIsId)
594 #define freeTagList (parser->m_freeTagList)
595 #define freeBindingList (parser->m_freeBindingList)
596 #define inheritedBindings (parser->m_inheritedBindings)
597 #define tagStack (parser->m_tagStack)
598 #define atts (parser->m_atts)
599 #define attsSize (parser->m_attsSize)
600 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
601 #define idAttIndex (parser->m_idAttIndex)
602 #define tempPool (parser->m_tempPool)
603 #define temp2Pool (parser->m_temp2Pool)
604 #define groupConnector (parser->m_groupConnector)
605 #define groupSize (parser->m_groupSize)
606 #define namespaceSeparator (parser->m_namespaceSeparator)
607 #define parentParser (parser->m_parentParser)
609 #define isParamEntity (parser->m_isParamEntity)
610 #define useForeignDTD (parser->m_useForeignDTD)
611 #define paramEntityParsing (parser->m_paramEntityParsing)
619 (processor != externalParEntInitProcessor) \
621 (processor != externalEntityInitProcessor)) \
623 (processor != prologInitProcessor))
626 XML_ParserCreate(const XML_Char
*encodingName
)
628 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
632 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
636 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
639 static const XML_Char implicitContext
[] = {
640 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
641 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
642 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
643 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
647 XML_ParserCreate_MM(const XML_Char
*encodingName
,
648 const XML_Memory_Handling_Suite
*memsuite
,
649 const XML_Char
*nameSep
)
651 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
652 if (parser
!= NULL
&& ns
) {
653 /* implicit context only set for root parser, since child
654 parsers (i.e. external entity parsers) will inherit it
656 if (!setContext(parser
, implicitContext
)) {
657 XML_ParserFree(parser
);
665 parserCreate(const XML_Char
*encodingName
,
666 const XML_Memory_Handling_Suite
*memsuite
,
667 const XML_Char
*nameSep
,
673 XML_Memory_Handling_Suite
*mtemp
;
674 parser
= (XML_Parser
)
675 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
676 if (parser
!= NULL
) {
677 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
678 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
679 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
680 mtemp
->free_fcn
= memsuite
->free_fcn
;
684 XML_Memory_Handling_Suite
*mtemp
;
685 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
686 if (parser
!= NULL
) {
687 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
688 mtemp
->malloc_fcn
= malloc
;
689 mtemp
->realloc_fcn
= realloc
;
690 mtemp
->free_fcn
= free
;
700 attsSize
= INIT_ATTS_SIZE
;
701 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
706 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
707 if (dataBuf
== NULL
) {
712 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
717 _dtd
= dtdCreate(&parser
->m_mem
);
726 freeBindingList
= NULL
;
730 groupConnector
= NULL
;
732 unknownEncodingHandler
= NULL
;
733 unknownEncodingHandlerData
= NULL
;
735 namespaceSeparator
= '!';
737 ns_triplets
= XML_FALSE
;
739 poolInit(&tempPool
, &(parser
->m_mem
));
740 poolInit(&temp2Pool
, &(parser
->m_mem
));
741 parserInit(parser
, encodingName
);
743 if (encodingName
&& !protocolEncodingName
) {
744 XML_ParserFree(parser
);
750 internalEncoding
= XmlGetInternalEncodingNS();
751 namespaceSeparator
= *nameSep
;
754 internalEncoding
= XmlGetInternalEncoding();
761 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
763 processor
= prologInitProcessor
;
764 XmlPrologStateInit(&prologState
);
765 protocolEncodingName
= (encodingName
!= NULL
766 ? poolCopyString(&tempPool
, encodingName
)
769 XmlInitEncoding(&initEncoding
, &encoding
, 0);
772 startElementHandler
= NULL
;
773 endElementHandler
= NULL
;
774 characterDataHandler
= NULL
;
775 processingInstructionHandler
= NULL
;
776 commentHandler
= NULL
;
777 startCdataSectionHandler
= NULL
;
778 endCdataSectionHandler
= NULL
;
779 defaultHandler
= NULL
;
780 startDoctypeDeclHandler
= NULL
;
781 endDoctypeDeclHandler
= NULL
;
782 unparsedEntityDeclHandler
= NULL
;
783 notationDeclHandler
= NULL
;
784 startNamespaceDeclHandler
= NULL
;
785 endNamespaceDeclHandler
= NULL
;
786 notStandaloneHandler
= NULL
;
787 externalEntityRefHandler
= NULL
;
788 externalEntityRefHandlerArg
= parser
;
789 skippedEntityHandler
= NULL
;
790 elementDeclHandler
= NULL
;
791 attlistDeclHandler
= NULL
;
792 entityDeclHandler
= NULL
;
793 xmlDeclHandler
= NULL
;
796 parseEndByteIndex
= 0;
798 declElementType
= NULL
;
799 declAttributeId
= NULL
;
804 declAttributeType
= NULL
;
805 declNotationName
= NULL
;
806 declNotationPublicId
= NULL
;
807 declAttributeIsCdata
= XML_FALSE
;
808 declAttributeIsId
= XML_FALSE
;
809 memset(&position
, 0, sizeof(POSITION
));
810 errorCode
= XML_ERROR_NONE
;
814 openInternalEntities
= 0;
815 defaultExpandInternalEntities
= XML_TRUE
;
818 inheritedBindings
= NULL
;
820 unknownEncodingMem
= NULL
;
821 unknownEncodingRelease
= NULL
;
822 unknownEncodingData
= NULL
;
825 isParamEntity
= XML_FALSE
;
826 useForeignDTD
= XML_FALSE
;
827 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
831 /* moves list of bindings to freeBindingList */
833 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
836 BINDING
*b
= bindings
;
837 bindings
= bindings
->nextTagBinding
;
838 b
->nextTagBinding
= freeBindingList
;
844 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
849 /* move tagStack to freeTagList */
854 tag
->parent
= freeTagList
;
855 moveToFreeBindingList(parser
, tag
->bindings
);
856 tag
->bindings
= NULL
;
859 moveToFreeBindingList(parser
, inheritedBindings
);
860 if (unknownEncodingMem
)
861 FREE(unknownEncodingMem
);
862 if (unknownEncodingRelease
)
863 unknownEncodingRelease(unknownEncodingData
);
864 poolClear(&tempPool
);
865 poolClear(&temp2Pool
);
866 parserInit(parser
, encodingName
);
867 dtdReset(_dtd
, &parser
->m_mem
);
868 return setContext(parser
, implicitContext
);
872 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
874 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
875 XXX There's no way for the caller to determine which of the
876 XXX possible error cases caused the XML_STATUS_ERROR return.
879 return XML_STATUS_ERROR
;
880 if (encodingName
== NULL
)
881 protocolEncodingName
= NULL
;
883 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
884 if (!protocolEncodingName
)
885 return XML_STATUS_ERROR
;
887 return XML_STATUS_OK
;
891 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
892 const XML_Char
*context
,
893 const XML_Char
*encodingName
)
895 XML_Parser parser
= oldParser
;
898 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
899 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
900 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
901 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
902 = processingInstructionHandler
;
903 XML_CommentHandler oldCommentHandler
= commentHandler
;
904 XML_StartCdataSectionHandler oldStartCdataSectionHandler
905 = startCdataSectionHandler
;
906 XML_EndCdataSectionHandler oldEndCdataSectionHandler
907 = endCdataSectionHandler
;
908 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
909 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
910 = unparsedEntityDeclHandler
;
911 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
912 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
913 = startNamespaceDeclHandler
;
914 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
915 = endNamespaceDeclHandler
;
916 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
917 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
918 = externalEntityRefHandler
;
919 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
920 XML_UnknownEncodingHandler oldUnknownEncodingHandler
921 = unknownEncodingHandler
;
922 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
923 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
924 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
925 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
926 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
928 void *oldUserData
= userData
;
929 void *oldHandlerArg
= handlerArg
;
930 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
931 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
933 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
934 int oldInEntityValue
= prologState
.inEntityValue
;
936 XML_Bool oldns_triplets
= ns_triplets
;
943 /* Note that the magical uses of the pre-processor to make field
944 access look more like C++ require that `parser' be overwritten
945 here. This makes this function more painful to follow than it
950 *tmp
= namespaceSeparator
;
951 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
954 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
960 startElementHandler
= oldStartElementHandler
;
961 endElementHandler
= oldEndElementHandler
;
962 characterDataHandler
= oldCharacterDataHandler
;
963 processingInstructionHandler
= oldProcessingInstructionHandler
;
964 commentHandler
= oldCommentHandler
;
965 startCdataSectionHandler
= oldStartCdataSectionHandler
;
966 endCdataSectionHandler
= oldEndCdataSectionHandler
;
967 defaultHandler
= oldDefaultHandler
;
968 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
969 notationDeclHandler
= oldNotationDeclHandler
;
970 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
971 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
972 notStandaloneHandler
= oldNotStandaloneHandler
;
973 externalEntityRefHandler
= oldExternalEntityRefHandler
;
974 skippedEntityHandler
= oldSkippedEntityHandler
;
975 unknownEncodingHandler
= oldUnknownEncodingHandler
;
976 elementDeclHandler
= oldElementDeclHandler
;
977 attlistDeclHandler
= oldAttlistDeclHandler
;
978 entityDeclHandler
= oldEntityDeclHandler
;
979 xmlDeclHandler
= oldXmlDeclHandler
;
980 declElementType
= oldDeclElementType
;
981 userData
= oldUserData
;
982 if (oldUserData
== oldHandlerArg
)
983 handlerArg
= userData
;
986 if (oldExternalEntityRefHandlerArg
!= oldParser
)
987 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
988 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
989 ns_triplets
= oldns_triplets
;
990 parentParser
= oldParser
;
992 paramEntityParsing
= oldParamEntityParsing
;
993 prologState
.inEntityValue
= oldInEntityValue
;
996 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
997 || !setContext(parser
, context
)) {
998 XML_ParserFree(parser
);
1001 processor
= externalEntityInitProcessor
;
1005 /* The DTD instance referenced by _dtd is shared between the document's
1006 root parser and external PE parsers, therefore one does not need to
1007 call setContext. In addition, one also *must* not call setContext,
1008 because this would overwrite existing prefix->binding pointers in
1009 _dtd with ones that get destroyed with the external PE parser.
1010 This would leave those prefixes with dangling pointers.
1012 isParamEntity
= XML_TRUE
;
1013 XmlPrologStateInitExternalEntity(&prologState
);
1014 processor
= externalParEntInitProcessor
;
1016 #endif /* XML_DTD */
1020 static void FASTCALL
1021 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1024 BINDING
*b
= bindings
;
1027 bindings
= b
->nextTagBinding
;
1034 XML_ParserFree(XML_Parser parser
)
1038 if (tagStack
== NULL
) {
1039 if (freeTagList
== NULL
)
1041 tagStack
= freeTagList
;
1045 tagStack
= tagStack
->parent
;
1047 destroyBindings(p
->bindings
, parser
);
1050 destroyBindings(freeBindingList
, parser
);
1051 destroyBindings(inheritedBindings
, parser
);
1052 poolDestroy(&tempPool
);
1053 poolDestroy(&temp2Pool
);
1055 /* external parameter entity parsers share the DTD structure
1056 parser->m_dtd with the root parser, so we must not destroy it
1058 if (!isParamEntity
&& _dtd
)
1061 #endif /* XML_DTD */
1062 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1065 FREE(groupConnector
);
1069 if (unknownEncodingMem
)
1070 FREE(unknownEncodingMem
);
1071 if (unknownEncodingRelease
)
1072 unknownEncodingRelease(unknownEncodingData
);
1077 XML_UseParserAsHandlerArg(XML_Parser parser
)
1079 handlerArg
= parser
;
1083 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1086 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1088 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1089 useForeignDTD
= useDTD
;
1090 return XML_ERROR_NONE
;
1092 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1097 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1099 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1102 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1106 XML_SetUserData(XML_Parser parser
, void *p
)
1108 if (handlerArg
== userData
)
1109 handlerArg
= userData
= p
;
1115 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1118 p
= poolCopyString(&_dtd
->pool
, p
);
1120 return XML_STATUS_ERROR
;
1125 return XML_STATUS_OK
;
1129 XML_GetBase(XML_Parser parser
)
1135 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1137 return nSpecifiedAtts
;
1141 XML_GetIdAttributeIndex(XML_Parser parser
)
1147 XML_SetElementHandler(XML_Parser parser
,
1148 XML_StartElementHandler start
,
1149 XML_EndElementHandler end
)
1151 startElementHandler
= start
;
1152 endElementHandler
= end
;
1156 XML_SetStartElementHandler(XML_Parser parser
,
1157 XML_StartElementHandler start
) {
1158 startElementHandler
= start
;
1162 XML_SetEndElementHandler(XML_Parser parser
,
1163 XML_EndElementHandler end
) {
1164 endElementHandler
= end
;
1168 XML_SetCharacterDataHandler(XML_Parser parser
,
1169 XML_CharacterDataHandler handler
)
1171 characterDataHandler
= handler
;
1175 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1176 XML_ProcessingInstructionHandler handler
)
1178 processingInstructionHandler
= handler
;
1182 XML_SetCommentHandler(XML_Parser parser
,
1183 XML_CommentHandler handler
)
1185 commentHandler
= handler
;
1189 XML_SetCdataSectionHandler(XML_Parser parser
,
1190 XML_StartCdataSectionHandler start
,
1191 XML_EndCdataSectionHandler end
)
1193 startCdataSectionHandler
= start
;
1194 endCdataSectionHandler
= end
;
1198 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1199 XML_StartCdataSectionHandler start
) {
1200 startCdataSectionHandler
= start
;
1204 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1205 XML_EndCdataSectionHandler end
) {
1206 endCdataSectionHandler
= end
;
1210 XML_SetDefaultHandler(XML_Parser parser
,
1211 XML_DefaultHandler handler
)
1213 defaultHandler
= handler
;
1214 defaultExpandInternalEntities
= XML_FALSE
;
1218 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1219 XML_DefaultHandler handler
)
1221 defaultHandler
= handler
;
1222 defaultExpandInternalEntities
= XML_TRUE
;
1226 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1227 XML_StartDoctypeDeclHandler start
,
1228 XML_EndDoctypeDeclHandler end
)
1230 startDoctypeDeclHandler
= start
;
1231 endDoctypeDeclHandler
= end
;
1235 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1236 XML_StartDoctypeDeclHandler start
) {
1237 startDoctypeDeclHandler
= start
;
1241 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1242 XML_EndDoctypeDeclHandler end
) {
1243 endDoctypeDeclHandler
= end
;
1247 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1248 XML_UnparsedEntityDeclHandler handler
)
1250 unparsedEntityDeclHandler
= handler
;
1254 XML_SetNotationDeclHandler(XML_Parser parser
,
1255 XML_NotationDeclHandler handler
)
1257 notationDeclHandler
= handler
;
1261 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1262 XML_StartNamespaceDeclHandler start
,
1263 XML_EndNamespaceDeclHandler end
)
1265 startNamespaceDeclHandler
= start
;
1266 endNamespaceDeclHandler
= end
;
1270 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1271 XML_StartNamespaceDeclHandler start
) {
1272 startNamespaceDeclHandler
= start
;
1276 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1277 XML_EndNamespaceDeclHandler end
) {
1278 endNamespaceDeclHandler
= end
;
1282 XML_SetNotStandaloneHandler(XML_Parser parser
,
1283 XML_NotStandaloneHandler handler
)
1285 notStandaloneHandler
= handler
;
1289 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1290 XML_ExternalEntityRefHandler handler
)
1292 externalEntityRefHandler
= handler
;
1296 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1299 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1301 externalEntityRefHandlerArg
= parser
;
1305 XML_SetSkippedEntityHandler(XML_Parser parser
,
1306 XML_SkippedEntityHandler handler
)
1308 skippedEntityHandler
= handler
;
1312 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1313 XML_UnknownEncodingHandler handler
,
1316 unknownEncodingHandler
= handler
;
1317 unknownEncodingHandlerData
= data
;
1321 XML_SetElementDeclHandler(XML_Parser parser
,
1322 XML_ElementDeclHandler eldecl
)
1324 elementDeclHandler
= eldecl
;
1328 XML_SetAttlistDeclHandler(XML_Parser parser
,
1329 XML_AttlistDeclHandler attdecl
)
1331 attlistDeclHandler
= attdecl
;
1335 XML_SetEntityDeclHandler(XML_Parser parser
,
1336 XML_EntityDeclHandler handler
)
1338 entityDeclHandler
= handler
;
1342 XML_SetXmlDeclHandler(XML_Parser parser
,
1343 XML_XmlDeclHandler handler
) {
1344 xmlDeclHandler
= handler
;
1348 XML_SetParamEntityParsing(XML_Parser parser
,
1349 enum XML_ParamEntityParsing peParsing
)
1351 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1355 paramEntityParsing
= peParsing
;
1358 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1363 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1367 return XML_STATUS_OK
;
1368 positionPtr
= bufferPtr
;
1369 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1370 if (errorCode
== XML_ERROR_NONE
)
1371 return XML_STATUS_OK
;
1372 eventEndPtr
= eventPtr
;
1373 processor
= errorProcessor
;
1374 return XML_STATUS_ERROR
;
1376 #ifndef XML_CONTEXT_BYTES
1377 else if (bufferPtr
== bufferEnd
) {
1380 parseEndByteIndex
+= len
;
1383 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1384 if (errorCode
== XML_ERROR_NONE
)
1385 return XML_STATUS_OK
;
1386 eventEndPtr
= eventPtr
;
1387 processor
= errorProcessor
;
1388 return XML_STATUS_ERROR
;
1390 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1391 if (errorCode
!= XML_ERROR_NONE
) {
1392 eventEndPtr
= eventPtr
;
1393 processor
= errorProcessor
;
1394 return XML_STATUS_ERROR
;
1396 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1398 nLeftOver
= s
+ len
- end
;
1400 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1401 /* FIXME avoid integer overflow */
1403 temp
= (buffer
== NULL
1404 ? (char *)MALLOC(len
* 2)
1405 : (char *)REALLOC(buffer
, len
* 2));
1407 errorCode
= XML_ERROR_NO_MEMORY
;
1408 return XML_STATUS_ERROR
;
1412 errorCode
= XML_ERROR_NO_MEMORY
;
1413 eventPtr
= eventEndPtr
= NULL
;
1414 processor
= errorProcessor
;
1415 return XML_STATUS_ERROR
;
1417 bufferLim
= buffer
+ len
* 2;
1419 memcpy(buffer
, end
, nLeftOver
);
1421 bufferEnd
= buffer
+ nLeftOver
;
1423 return XML_STATUS_OK
;
1425 #endif /* not defined XML_CONTEXT_BYTES */
1427 void *buff
= XML_GetBuffer(parser
, len
);
1429 return XML_STATUS_ERROR
;
1431 memcpy(buff
, s
, len
);
1432 return XML_ParseBuffer(parser
, len
, isFinal
);
1438 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1440 const char *start
= bufferPtr
;
1441 positionPtr
= start
;
1443 parseEndByteIndex
+= len
;
1444 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1445 isFinal
? (const char **)NULL
: &bufferPtr
);
1446 if (errorCode
== XML_ERROR_NONE
) {
1448 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1449 positionPtr
= bufferPtr
;
1451 return XML_STATUS_OK
;
1454 eventEndPtr
= eventPtr
;
1455 processor
= errorProcessor
;
1456 return XML_STATUS_ERROR
;
1461 XML_GetBuffer(XML_Parser parser
, int len
)
1463 if (len
> bufferLim
- bufferEnd
) {
1464 /* FIXME avoid integer overflow */
1465 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1466 #ifdef XML_CONTEXT_BYTES
1467 int keep
= bufferPtr
- buffer
;
1469 if (keep
> XML_CONTEXT_BYTES
)
1470 keep
= XML_CONTEXT_BYTES
;
1472 #endif /* defined XML_CONTEXT_BYTES */
1473 if (neededSize
<= bufferLim
- buffer
) {
1474 #ifdef XML_CONTEXT_BYTES
1475 if (keep
< bufferPtr
- buffer
) {
1476 int offset
= (bufferPtr
- buffer
) - keep
;
1477 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1478 bufferEnd
-= offset
;
1479 bufferPtr
-= offset
;
1482 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1483 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1485 #endif /* not defined XML_CONTEXT_BYTES */
1489 int bufferSize
= bufferLim
- bufferPtr
;
1490 if (bufferSize
== 0)
1491 bufferSize
= INIT_BUFFER_SIZE
;
1494 } while (bufferSize
< neededSize
);
1495 newBuf
= (char *)MALLOC(bufferSize
);
1497 errorCode
= XML_ERROR_NO_MEMORY
;
1500 bufferLim
= newBuf
+ bufferSize
;
1501 #ifdef XML_CONTEXT_BYTES
1503 int keep
= bufferPtr
- buffer
;
1504 if (keep
> XML_CONTEXT_BYTES
)
1505 keep
= XML_CONTEXT_BYTES
;
1506 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1509 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1510 bufferPtr
= buffer
+ keep
;
1513 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1514 bufferPtr
= buffer
= newBuf
;
1518 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1521 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1522 bufferPtr
= buffer
= newBuf
;
1523 #endif /* not defined XML_CONTEXT_BYTES */
1530 XML_GetErrorCode(XML_Parser parser
)
1536 XML_GetCurrentByteIndex(XML_Parser parser
)
1539 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1544 XML_GetCurrentByteCount(XML_Parser parser
)
1546 if (eventEndPtr
&& eventPtr
)
1547 return eventEndPtr
- eventPtr
;
1552 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1554 #ifdef XML_CONTEXT_BYTES
1555 if (eventPtr
&& buffer
) {
1556 *offset
= eventPtr
- buffer
;
1557 *size
= bufferEnd
- buffer
;
1560 #endif /* defined XML_CONTEXT_BYTES */
1565 XML_GetCurrentLineNumber(XML_Parser parser
)
1568 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1569 positionPtr
= eventPtr
;
1571 return position
.lineNumber
+ 1;
1575 XML_GetCurrentColumnNumber(XML_Parser parser
)
1578 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1579 positionPtr
= eventPtr
;
1581 return position
.columnNumber
;
1585 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1591 XML_MemMalloc(XML_Parser parser
, size_t size
)
1593 return MALLOC(size
);
1597 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1599 return REALLOC(ptr
, size
);
1603 XML_MemFree(XML_Parser parser
, void *ptr
)
1609 XML_DefaultCurrent(XML_Parser parser
)
1611 if (defaultHandler
) {
1612 if (openInternalEntities
)
1613 reportDefault(parser
,
1615 openInternalEntities
->internalEventPtr
,
1616 openInternalEntities
->internalEventEndPtr
);
1618 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1623 XML_ErrorString(enum XML_Error code
)
1625 static const XML_LChar
*message
[] = {
1627 XML_L("out of memory"),
1628 XML_L("syntax error"),
1629 XML_L("no element found"),
1630 XML_L("not well-formed (invalid token)"),
1631 XML_L("unclosed token"),
1632 XML_L("partial character"),
1633 XML_L("mismatched tag"),
1634 XML_L("duplicate attribute"),
1635 XML_L("junk after document element"),
1636 XML_L("illegal parameter entity reference"),
1637 XML_L("undefined entity"),
1638 XML_L("recursive entity reference"),
1639 XML_L("asynchronous entity"),
1640 XML_L("reference to invalid character number"),
1641 XML_L("reference to binary entity"),
1642 XML_L("reference to external entity in attribute"),
1643 XML_L("xml declaration not at start of external entity"),
1644 XML_L("unknown encoding"),
1645 XML_L("encoding specified in XML declaration is incorrect"),
1646 XML_L("unclosed CDATA section"),
1647 XML_L("error in processing external entity reference"),
1648 XML_L("document is not standalone"),
1649 XML_L("unexpected parser state - please send a bug report"),
1650 XML_L("entity declared in parameter entity"),
1651 XML_L("requested feature requires XML_DTD support in Expat"),
1652 XML_L("cannot change setting once parsing has begun")
1654 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1655 return message
[code
];
1660 XML_ExpatVersion(void) {
1662 /* V1 is used to string-ize the version number. However, it would
1663 string-ize the actual version macro *names* unless we get them
1664 substituted before being passed to V1. CPP is defined to expand
1665 a macro, then rescan for more expansions. Thus, we use V2 to expand
1666 the version macros, then CPP will expand the resulting V1() macro
1667 with the correct numerals. */
1668 /* ### I'm assuming cpp is portable in this respect... */
1670 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1671 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1673 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1680 XML_ExpatVersionInfo(void)
1682 XML_Expat_Version version
;
1684 version
.major
= XML_MAJOR_VERSION
;
1685 version
.minor
= XML_MINOR_VERSION
;
1686 version
.micro
= XML_MICRO_VERSION
;
1692 XML_GetFeatureList(void)
1694 static XML_Feature features
[] = {
1695 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1696 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1698 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1700 #ifdef XML_UNICODE_WCHAR_T
1701 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1704 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1706 #ifdef XML_CONTEXT_BYTES
1707 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1711 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1713 {XML_FEATURE_END
, NULL
}
1716 features
[0].value
= sizeof(XML_Char
);
1717 features
[1].value
= sizeof(XML_LChar
);
1721 /* Initially tag->rawName always points into the parse buffer;
1722 for those TAG instances opened while the current parse buffer was
1723 processed, and not yet closed, we need to store tag->rawName in a more
1724 permanent location, since the parse buffer is about to be discarded.
1727 storeRawNames(XML_Parser parser
)
1729 TAG
*tag
= tagStack
;
1732 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1733 char *rawNameBuf
= tag
->buf
+ nameLen
;
1734 /* Stop if already stored. Since tagStack is a stack, we can stop
1735 at the first entry that has already been copied; everything
1736 below it in the stack is already been accounted for in a
1737 previous call to this function.
1739 if (tag
->rawName
== rawNameBuf
)
1741 /* For re-use purposes we need to ensure that the
1742 size of tag->buf is a multiple of sizeof(XML_Char).
1744 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1745 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1746 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1749 /* if tag->name.str points to tag->buf (only when namespace
1750 processing is off) then we have to update it
1752 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1753 tag
->name
.str
= (XML_Char
*)temp
;
1754 /* if tag->name.localPart is set (when namespace processing is on)
1755 then update it as well, since it will always point into tag->buf
1757 if (tag
->name
.localPart
)
1758 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1759 (XML_Char
*)tag
->buf
);
1761 tag
->bufEnd
= temp
+ bufSize
;
1762 rawNameBuf
= temp
+ nameLen
;
1764 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1765 tag
->rawName
= rawNameBuf
;
1771 static enum XML_Error PTRCALL
1772 contentProcessor(XML_Parser parser
,
1775 const char **endPtr
)
1777 enum XML_Error result
=
1778 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1779 if (result
!= XML_ERROR_NONE
)
1781 if (!storeRawNames(parser
))
1782 return XML_ERROR_NO_MEMORY
;
1786 static enum XML_Error PTRCALL
1787 externalEntityInitProcessor(XML_Parser parser
,
1790 const char **endPtr
)
1792 enum XML_Error result
= initializeEncoding(parser
);
1793 if (result
!= XML_ERROR_NONE
)
1795 processor
= externalEntityInitProcessor2
;
1796 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1799 static enum XML_Error PTRCALL
1800 externalEntityInitProcessor2(XML_Parser parser
,
1803 const char **endPtr
)
1805 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1806 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1809 /* If we are at the end of the buffer, this would cause the next stage,
1810 i.e. externalEntityInitProcessor3, to pass control directly to
1811 doContent (by detecting XML_TOK_NONE) without processing any xml text
1812 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1814 if (next
== end
&& endPtr
) {
1816 return XML_ERROR_NONE
;
1820 case XML_TOK_PARTIAL
:
1823 return XML_ERROR_NONE
;
1826 return XML_ERROR_UNCLOSED_TOKEN
;
1827 case XML_TOK_PARTIAL_CHAR
:
1830 return XML_ERROR_NONE
;
1833 return XML_ERROR_PARTIAL_CHAR
;
1835 processor
= externalEntityInitProcessor3
;
1836 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1839 static enum XML_Error PTRCALL
1840 externalEntityInitProcessor3(XML_Parser parser
,
1843 const char **endPtr
)
1845 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1846 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1848 case XML_TOK_XML_DECL
:
1850 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1851 if (result
!= XML_ERROR_NONE
)
1856 case XML_TOK_PARTIAL
:
1859 return XML_ERROR_NONE
;
1862 return XML_ERROR_UNCLOSED_TOKEN
;
1863 case XML_TOK_PARTIAL_CHAR
:
1866 return XML_ERROR_NONE
;
1869 return XML_ERROR_PARTIAL_CHAR
;
1871 processor
= externalEntityContentProcessor
;
1873 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1876 static enum XML_Error PTRCALL
1877 externalEntityContentProcessor(XML_Parser parser
,
1880 const char **endPtr
)
1882 enum XML_Error result
=
1883 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1884 if (result
!= XML_ERROR_NONE
)
1886 if (!storeRawNames(parser
))
1887 return XML_ERROR_NO_MEMORY
;
1891 static enum XML_Error
1892 doContent(XML_Parser parser
,
1894 const ENCODING
*enc
,
1897 const char **nextPtr
)
1899 DTD
* const dtd
= _dtd
; /* save one level of indirection */
1900 const char **eventPP
;
1901 const char **eventEndPP
;
1902 if (enc
== encoding
) {
1903 eventPP
= &eventPtr
;
1904 eventEndPP
= &eventEndPtr
;
1907 eventPP
= &(openInternalEntities
->internalEventPtr
);
1908 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1912 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1913 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1916 case XML_TOK_TRAILING_CR
:
1919 return XML_ERROR_NONE
;
1922 if (characterDataHandler
) {
1924 characterDataHandler(handlerArg
, &c
, 1);
1926 else if (defaultHandler
)
1927 reportDefault(parser
, enc
, s
, end
);
1928 if (startTagLevel
== 0)
1929 return XML_ERROR_NO_ELEMENTS
;
1930 if (tagLevel
!= startTagLevel
)
1931 return XML_ERROR_ASYNC_ENTITY
;
1932 return XML_ERROR_NONE
;
1936 return XML_ERROR_NONE
;
1938 if (startTagLevel
> 0) {
1939 if (tagLevel
!= startTagLevel
)
1940 return XML_ERROR_ASYNC_ENTITY
;
1941 return XML_ERROR_NONE
;
1943 return XML_ERROR_NO_ELEMENTS
;
1944 case XML_TOK_INVALID
:
1946 return XML_ERROR_INVALID_TOKEN
;
1947 case XML_TOK_PARTIAL
:
1950 return XML_ERROR_NONE
;
1952 return XML_ERROR_UNCLOSED_TOKEN
;
1953 case XML_TOK_PARTIAL_CHAR
:
1956 return XML_ERROR_NONE
;
1958 return XML_ERROR_PARTIAL_CHAR
;
1959 case XML_TOK_ENTITY_REF
:
1961 const XML_Char
*name
;
1963 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1964 s
+ enc
->minBytesPerChar
,
1965 next
- enc
->minBytesPerChar
);
1967 if (characterDataHandler
)
1968 characterDataHandler(handlerArg
, &ch
, 1);
1969 else if (defaultHandler
)
1970 reportDefault(parser
, enc
, s
, next
);
1973 name
= poolStoreString(&dtd
->pool
, enc
,
1974 s
+ enc
->minBytesPerChar
,
1975 next
- enc
->minBytesPerChar
);
1977 return XML_ERROR_NO_MEMORY
;
1978 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
1979 poolDiscard(&dtd
->pool
);
1980 /* First, determine if a check for an existing declaration is needed;
1981 if yes, check that the entity exists, and that it is internal,
1982 otherwise call the skipped entity or default handler.
1984 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
1986 return XML_ERROR_UNDEFINED_ENTITY
;
1987 else if (!entity
->is_internal
)
1988 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
1991 if (skippedEntityHandler
)
1992 skippedEntityHandler(handlerArg
, name
, 0);
1993 else if (defaultHandler
)
1994 reportDefault(parser
, enc
, s
, next
);
1998 return XML_ERROR_RECURSIVE_ENTITY_REF
;
1999 if (entity
->notation
)
2000 return XML_ERROR_BINARY_ENTITY_REF
;
2001 if (entity
->textPtr
) {
2002 enum XML_Error result
;
2003 OPEN_INTERNAL_ENTITY openEntity
;
2004 if (!defaultExpandInternalEntities
) {
2005 if (skippedEntityHandler
)
2006 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2007 else if (defaultHandler
)
2008 reportDefault(parser
, enc
, s
, next
);
2011 entity
->open
= XML_TRUE
;
2012 openEntity
.next
= openInternalEntities
;
2013 openInternalEntities
= &openEntity
;
2014 openEntity
.entity
= entity
;
2015 openEntity
.internalEventPtr
= NULL
;
2016 openEntity
.internalEventEndPtr
= NULL
;
2017 result
= doContent(parser
,
2020 (char *)entity
->textPtr
,
2021 (char *)(entity
->textPtr
+ entity
->textLen
),
2023 entity
->open
= XML_FALSE
;
2024 openInternalEntities
= openEntity
.next
;
2028 else if (externalEntityRefHandler
) {
2029 const XML_Char
*context
;
2030 entity
->open
= XML_TRUE
;
2031 context
= getContext(parser
);
2032 entity
->open
= XML_FALSE
;
2034 return XML_ERROR_NO_MEMORY
;
2035 if (!externalEntityRefHandler((XML_Parser
)externalEntityRefHandlerArg
,
2040 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2041 poolDiscard(&tempPool
);
2043 else if (defaultHandler
)
2044 reportDefault(parser
, enc
, s
, next
);
2047 case XML_TOK_START_TAG_NO_ATTS
:
2049 case XML_TOK_START_TAG_WITH_ATTS
:
2052 enum XML_Error result
;
2056 freeTagList
= freeTagList
->parent
;
2059 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2061 return XML_ERROR_NO_MEMORY
;
2062 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2065 return XML_ERROR_NO_MEMORY
;
2067 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2069 tag
->bindings
= NULL
;
2070 tag
->parent
= tagStack
;
2072 tag
->name
.localPart
= NULL
;
2073 tag
->name
.prefix
= NULL
;
2074 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2075 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2078 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2079 const char *fromPtr
= tag
->rawName
;
2080 toPtr
= (XML_Char
*)tag
->buf
;
2085 &fromPtr
, rawNameEnd
,
2086 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2087 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2088 if (fromPtr
== rawNameEnd
) {
2089 tag
->name
.strLen
= convLen
;
2092 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2094 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2096 return XML_ERROR_NO_MEMORY
;
2098 tag
->bufEnd
= temp
+ bufSize
;
2099 toPtr
= (XML_Char
*)temp
+ convLen
;
2103 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2104 *toPtr
= XML_T('\0');
2105 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2108 if (startElementHandler
)
2109 startElementHandler(handlerArg
, tag
->name
.str
,
2110 (const XML_Char
**)atts
);
2111 else if (defaultHandler
)
2112 reportDefault(parser
, enc
, s
, next
);
2113 poolClear(&tempPool
);
2116 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2118 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2120 const char *rawName
= s
+ enc
->minBytesPerChar
;
2121 enum XML_Error result
;
2122 BINDING
*bindings
= NULL
;
2123 XML_Bool noElmHandlers
= XML_TRUE
;
2125 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2126 rawName
+ XmlNameLength(enc
, rawName
));
2128 return XML_ERROR_NO_MEMORY
;
2129 poolFinish(&tempPool
);
2130 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2133 poolFinish(&tempPool
);
2134 if (startElementHandler
) {
2135 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2136 noElmHandlers
= XML_FALSE
;
2138 if (endElementHandler
) {
2139 if (startElementHandler
)
2140 *eventPP
= *eventEndPP
;
2141 endElementHandler(handlerArg
, name
.str
);
2142 noElmHandlers
= XML_FALSE
;
2144 if (noElmHandlers
&& defaultHandler
)
2145 reportDefault(parser
, enc
, s
, next
);
2146 poolClear(&tempPool
);
2148 BINDING
*b
= bindings
;
2149 if (endNamespaceDeclHandler
)
2150 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2151 bindings
= bindings
->nextTagBinding
;
2152 b
->nextTagBinding
= freeBindingList
;
2153 freeBindingList
= b
;
2154 b
->prefix
->binding
= b
->prevPrefixBinding
;
2158 return epilogProcessor(parser
, next
, end
, nextPtr
);
2160 case XML_TOK_END_TAG
:
2161 if (tagLevel
== startTagLevel
)
2162 return XML_ERROR_ASYNC_ENTITY
;
2165 const char *rawName
;
2166 TAG
*tag
= tagStack
;
2167 tagStack
= tag
->parent
;
2168 tag
->parent
= freeTagList
;
2170 rawName
= s
+ enc
->minBytesPerChar
*2;
2171 len
= XmlNameLength(enc
, rawName
);
2172 if (len
!= tag
->rawNameLength
2173 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2175 return XML_ERROR_TAG_MISMATCH
;
2178 if (endElementHandler
) {
2179 const XML_Char
*localPart
;
2180 const XML_Char
*prefix
;
2182 localPart
= tag
->name
.localPart
;
2183 if (ns
&& localPart
) {
2184 /* localPart and prefix may have been overwritten in
2185 tag->name.str, since this points to the binding->uri
2186 buffer which gets re-used; so we have to add them again
2188 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2189 /* don't need to check for space - already done in storeAtts() */
2190 while (*localPart
) *uri
++ = *localPart
++;
2191 prefix
= (XML_Char
*)tag
->name
.prefix
;
2192 if (ns_triplets
&& prefix
) {
2193 *uri
++ = namespaceSeparator
;
2194 while (*prefix
) *uri
++ = *prefix
++;
2198 endElementHandler(handlerArg
, tag
->name
.str
);
2200 else if (defaultHandler
)
2201 reportDefault(parser
, enc
, s
, next
);
2202 while (tag
->bindings
) {
2203 BINDING
*b
= tag
->bindings
;
2204 if (endNamespaceDeclHandler
)
2205 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2206 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2207 b
->nextTagBinding
= freeBindingList
;
2208 freeBindingList
= b
;
2209 b
->prefix
->binding
= b
->prevPrefixBinding
;
2212 return epilogProcessor(parser
, next
, end
, nextPtr
);
2215 case XML_TOK_CHAR_REF
:
2217 int n
= XmlCharRefNumber(enc
, s
);
2219 return XML_ERROR_BAD_CHAR_REF
;
2220 if (characterDataHandler
) {
2221 XML_Char buf
[XML_ENCODE_MAX
];
2222 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2224 else if (defaultHandler
)
2225 reportDefault(parser
, enc
, s
, next
);
2228 case XML_TOK_XML_DECL
:
2229 return XML_ERROR_MISPLACED_XML_PI
;
2230 case XML_TOK_DATA_NEWLINE
:
2231 if (characterDataHandler
) {
2233 characterDataHandler(handlerArg
, &c
, 1);
2235 else if (defaultHandler
)
2236 reportDefault(parser
, enc
, s
, next
);
2238 case XML_TOK_CDATA_SECT_OPEN
:
2240 enum XML_Error result
;
2241 if (startCdataSectionHandler
)
2242 startCdataSectionHandler(handlerArg
);
2244 /* Suppose you doing a transformation on a document that involves
2245 changing only the character data. You set up a defaultHandler
2246 and a characterDataHandler. The defaultHandler simply copies
2247 characters through. The characterDataHandler does the
2248 transformation and writes the characters out escaping them as
2249 necessary. This case will fail to work if we leave out the
2250 following two lines (because & and < inside CDATA sections will
2251 be incorrectly escaped).
2253 However, now we have a start/endCdataSectionHandler, so it seems
2254 easier to let the user deal with this.
2256 else if (characterDataHandler
)
2257 characterDataHandler(handlerArg
, dataBuf
, 0);
2259 else if (defaultHandler
)
2260 reportDefault(parser
, enc
, s
, next
);
2261 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2263 processor
= cdataSectionProcessor
;
2268 case XML_TOK_TRAILING_RSQB
:
2271 return XML_ERROR_NONE
;
2273 if (characterDataHandler
) {
2274 if (MUST_CONVERT(enc
, s
)) {
2275 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2276 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2277 characterDataHandler(handlerArg
, dataBuf
,
2278 dataPtr
- (ICHAR
*)dataBuf
);
2281 characterDataHandler(handlerArg
,
2283 (XML_Char
*)end
- (XML_Char
*)s
);
2285 else if (defaultHandler
)
2286 reportDefault(parser
, enc
, s
, end
);
2287 if (startTagLevel
== 0) {
2289 return XML_ERROR_NO_ELEMENTS
;
2291 if (tagLevel
!= startTagLevel
) {
2293 return XML_ERROR_ASYNC_ENTITY
;
2295 return XML_ERROR_NONE
;
2296 case XML_TOK_DATA_CHARS
:
2297 if (characterDataHandler
) {
2298 if (MUST_CONVERT(enc
, s
)) {
2300 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2301 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2303 characterDataHandler(handlerArg
, dataBuf
,
2304 dataPtr
- (ICHAR
*)dataBuf
);
2311 characterDataHandler(handlerArg
,
2313 (XML_Char
*)next
- (XML_Char
*)s
);
2315 else if (defaultHandler
)
2316 reportDefault(parser
, enc
, s
, next
);
2319 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2320 return XML_ERROR_NO_MEMORY
;
2322 case XML_TOK_COMMENT
:
2323 if (!reportComment(parser
, enc
, s
, next
))
2324 return XML_ERROR_NO_MEMORY
;
2328 reportDefault(parser
, enc
, s
, next
);
2331 *eventPP
= s
= next
;
2336 /* Precondition: all arguments must be non-NULL;
2338 - normalize attributes
2339 - check attributes for well-formedness
2340 - generate namespace aware attribute names (URI, prefix)
2341 - build list of attributes for startElementHandler
2342 - default attributes
2343 - process namespace declarations (check and report them)
2344 - generate namespace aware element name (URI, prefix)
2346 static enum XML_Error
2347 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2348 const char *attStr
, TAG_NAME
*tagNamePtr
,
2349 BINDING
**bindingsPtr
)
2351 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2352 ELEMENT_TYPE
*elementType
= NULL
;
2353 int nDefaultAtts
= 0;
2354 const XML_Char
**appAtts
; /* the attribute list for the application */
2362 const XML_Char
*localPart
;
2364 /* lookup the element type name */
2365 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2367 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2369 return XML_ERROR_NO_MEMORY
;
2370 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2371 sizeof(ELEMENT_TYPE
));
2373 return XML_ERROR_NO_MEMORY
;
2374 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2375 return XML_ERROR_NO_MEMORY
;
2377 nDefaultAtts
= elementType
->nDefaultAtts
;
2379 /* get the attributes from the tokenizer */
2380 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2381 if (n
+ nDefaultAtts
> attsSize
) {
2382 int oldAttsSize
= attsSize
;
2384 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2385 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2387 return XML_ERROR_NO_MEMORY
;
2389 if (n
> oldAttsSize
)
2390 XmlGetAttributes(enc
, attStr
, n
, atts
);
2393 appAtts
= (const XML_Char
**)atts
;
2394 for (i
= 0; i
< n
; i
++) {
2395 /* add the name and value to the attribute list */
2396 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2398 + XmlNameLength(enc
, atts
[i
].name
));
2400 return XML_ERROR_NO_MEMORY
;
2401 /* detect duplicate attributes */
2402 if ((attId
->name
)[-1]) {
2403 if (enc
== encoding
)
2404 eventPtr
= atts
[i
].name
;
2405 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2407 (attId
->name
)[-1] = 1;
2408 appAtts
[attIndex
++] = attId
->name
;
2409 if (!atts
[i
].normalized
) {
2410 enum XML_Error result
;
2411 XML_Bool isCdata
= XML_TRUE
;
2413 /* figure out whether declared as other than CDATA */
2414 if (attId
->maybeTokenized
) {
2416 for (j
= 0; j
< nDefaultAtts
; j
++) {
2417 if (attId
== elementType
->defaultAtts
[j
].id
) {
2418 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2424 /* normalize the attribute value */
2425 result
= storeAttributeValue(parser
, enc
, isCdata
,
2426 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2430 appAtts
[attIndex
] = poolStart(&tempPool
);
2431 poolFinish(&tempPool
);
2434 /* the value did not need normalizing */
2435 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2437 if (appAtts
[attIndex
] == 0)
2438 return XML_ERROR_NO_MEMORY
;
2439 poolFinish(&tempPool
);
2441 /* handle prefixed attribute names */
2442 if (attId
->prefix
) {
2444 /* deal with namespace declarations here */
2445 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2446 appAtts
[attIndex
], bindingsPtr
);
2452 /* deal with other prefixed names later */
2455 (attId
->name
)[-1] = 2;
2462 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2463 nSpecifiedAtts
= attIndex
;
2464 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2465 for (i
= 0; i
< attIndex
; i
+= 2)
2466 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2474 /* do attribute defaulting */
2475 for (i
= 0; i
< nDefaultAtts
; i
++) {
2476 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2477 if (!(da
->id
->name
)[-1] && da
->value
) {
2478 if (da
->id
->prefix
) {
2479 if (da
->id
->xmlns
) {
2480 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2481 da
->value
, bindingsPtr
);
2486 (da
->id
->name
)[-1] = 2;
2488 appAtts
[attIndex
++] = da
->id
->name
;
2489 appAtts
[attIndex
++] = da
->value
;
2493 (da
->id
->name
)[-1] = 1;
2494 appAtts
[attIndex
++] = da
->id
->name
;
2495 appAtts
[attIndex
++] = da
->value
;
2499 appAtts
[attIndex
] = 0;
2503 /* expand prefixed attribute names */
2504 for (; i
< attIndex
; i
+= 2) {
2505 if (appAtts
[i
][-1] == 2) {
2507 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2508 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, appAtts
[i
], 0);
2509 if (id
->prefix
->binding
) {
2511 const BINDING
*b
= id
->prefix
->binding
;
2512 const XML_Char
*s
= appAtts
[i
];
2513 for (j
= 0; j
< b
->uriLen
; j
++) {
2514 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2515 return XML_ERROR_NO_MEMORY
;
2517 while (*s
++ != XML_T(':'))
2520 if (!poolAppendChar(&tempPool
, *s
))
2521 return XML_ERROR_NO_MEMORY
;
2524 tempPool
.ptr
[-1] = namespaceSeparator
;
2525 s
= b
->prefix
->name
;
2527 if (!poolAppendChar(&tempPool
, *s
))
2528 return XML_ERROR_NO_MEMORY
;
2532 appAtts
[i
] = poolStart(&tempPool
);
2533 poolFinish(&tempPool
);
2539 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2542 /* clear the flags that say whether attributes were specified */
2543 for (; i
< attIndex
; i
+= 2)
2544 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2545 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2546 binding
->attId
->name
[-1] = 0;
2548 /* expand the element type name */
2549 if (elementType
->prefix
) {
2550 binding
= elementType
->prefix
->binding
;
2552 return XML_ERROR_NONE
;
2553 localPart
= tagNamePtr
->str
;
2554 while (*localPart
++ != XML_T(':'))
2557 else if (dtd
->defaultPrefix
.binding
) {
2558 binding
= dtd
->defaultPrefix
.binding
;
2559 localPart
= tagNamePtr
->str
;
2562 return XML_ERROR_NONE
;
2564 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2565 for (; binding
->prefix
->name
[prefixLen
++];)
2568 tagNamePtr
->localPart
= localPart
;
2569 tagNamePtr
->uriLen
= binding
->uriLen
;
2570 tagNamePtr
->prefix
= binding
->prefix
->name
;
2571 tagNamePtr
->prefixLen
= prefixLen
;
2572 for (i
= 0; localPart
[i
++];)
2574 n
= i
+ binding
->uriLen
+ prefixLen
;
2575 if (n
> binding
->uriAlloc
) {
2577 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2579 return XML_ERROR_NO_MEMORY
;
2580 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2581 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2582 for (p
= tagStack
; p
; p
= p
->parent
)
2583 if (p
->name
.str
== binding
->uri
)
2588 uri
= binding
->uri
+ binding
->uriLen
;
2589 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2591 uri
= uri
+ (i
- 1);
2592 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2593 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2595 tagNamePtr
->str
= binding
->uri
;
2596 return XML_ERROR_NONE
;
2599 /* addBinding() overwrites the value of prefix->binding without checking.
2600 Therefore one must keep track of the old value outside of addBinding().
2602 static enum XML_Error
2603 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2604 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2609 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2610 if (*uri
== XML_T('\0') && prefix
->name
)
2611 return XML_ERROR_SYNTAX
;
2613 for (len
= 0; uri
[len
]; len
++)
2615 if (namespaceSeparator
)
2617 if (freeBindingList
) {
2618 b
= freeBindingList
;
2619 if (len
> b
->uriAlloc
) {
2620 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2621 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2623 return XML_ERROR_NO_MEMORY
;
2625 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2627 freeBindingList
= b
->nextTagBinding
;
2630 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2632 return XML_ERROR_NO_MEMORY
;
2633 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2636 return XML_ERROR_NO_MEMORY
;
2638 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2641 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2642 if (namespaceSeparator
)
2643 b
->uri
[len
- 1] = namespaceSeparator
;
2646 b
->prevPrefixBinding
= prefix
->binding
;
2647 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2648 prefix
->binding
= NULL
;
2650 prefix
->binding
= b
;
2651 b
->nextTagBinding
= *bindingsPtr
;
2653 if (startNamespaceDeclHandler
)
2654 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2655 prefix
->binding
? uri
: 0);
2656 return XML_ERROR_NONE
;
2659 /* The idea here is to avoid using stack for each CDATA section when
2660 the whole file is parsed with one call.
2662 static enum XML_Error PTRCALL
2663 cdataSectionProcessor(XML_Parser parser
,
2666 const char **endPtr
)
2668 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2671 if (parentParser
) { /* we are parsing an external entity */
2672 processor
= externalEntityContentProcessor
;
2673 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2676 processor
= contentProcessor
;
2677 return contentProcessor(parser
, start
, end
, endPtr
);
2683 /* startPtr gets set to non-null is the section is closed, and to null if
2684 the section is not yet closed.
2686 static enum XML_Error
2687 doCdataSection(XML_Parser parser
,
2688 const ENCODING
*enc
,
2689 const char **startPtr
,
2691 const char **nextPtr
)
2693 const char *s
= *startPtr
;
2694 const char **eventPP
;
2695 const char **eventEndPP
;
2696 if (enc
== encoding
) {
2697 eventPP
= &eventPtr
;
2699 eventEndPP
= &eventEndPtr
;
2702 eventPP
= &(openInternalEntities
->internalEventPtr
);
2703 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2709 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2712 case XML_TOK_CDATA_SECT_CLOSE
:
2713 if (endCdataSectionHandler
)
2714 endCdataSectionHandler(handlerArg
);
2716 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2717 else if (characterDataHandler
)
2718 characterDataHandler(handlerArg
, dataBuf
, 0);
2720 else if (defaultHandler
)
2721 reportDefault(parser
, enc
, s
, next
);
2723 return XML_ERROR_NONE
;
2724 case XML_TOK_DATA_NEWLINE
:
2725 if (characterDataHandler
) {
2727 characterDataHandler(handlerArg
, &c
, 1);
2729 else if (defaultHandler
)
2730 reportDefault(parser
, enc
, s
, next
);
2732 case XML_TOK_DATA_CHARS
:
2733 if (characterDataHandler
) {
2734 if (MUST_CONVERT(enc
, s
)) {
2736 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2737 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2739 characterDataHandler(handlerArg
, dataBuf
,
2740 dataPtr
- (ICHAR
*)dataBuf
);
2747 characterDataHandler(handlerArg
,
2749 (XML_Char
*)next
- (XML_Char
*)s
);
2751 else if (defaultHandler
)
2752 reportDefault(parser
, enc
, s
, next
);
2754 case XML_TOK_INVALID
:
2756 return XML_ERROR_INVALID_TOKEN
;
2757 case XML_TOK_PARTIAL_CHAR
:
2760 return XML_ERROR_NONE
;
2762 return XML_ERROR_PARTIAL_CHAR
;
2763 case XML_TOK_PARTIAL
:
2767 return XML_ERROR_NONE
;
2769 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2772 return XML_ERROR_UNEXPECTED_STATE
;
2774 *eventPP
= s
= next
;
2781 /* The idea here is to avoid using stack for each IGNORE section when
2782 the whole file is parsed with one call.
2784 static enum XML_Error PTRCALL
2785 ignoreSectionProcessor(XML_Parser parser
,
2788 const char **endPtr
)
2790 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2793 processor
= prologProcessor
;
2794 return prologProcessor(parser
, start
, end
, endPtr
);
2799 /* startPtr gets set to non-null is the section is closed, and to null
2800 if the section is not yet closed.
2802 static enum XML_Error
2803 doIgnoreSection(XML_Parser parser
,
2804 const ENCODING
*enc
,
2805 const char **startPtr
,
2807 const char **nextPtr
)
2811 const char *s
= *startPtr
;
2812 const char **eventPP
;
2813 const char **eventEndPP
;
2814 if (enc
== encoding
) {
2815 eventPP
= &eventPtr
;
2817 eventEndPP
= &eventEndPtr
;
2820 eventPP
= &(openInternalEntities
->internalEventPtr
);
2821 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2825 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2828 case XML_TOK_IGNORE_SECT
:
2830 reportDefault(parser
, enc
, s
, next
);
2832 return XML_ERROR_NONE
;
2833 case XML_TOK_INVALID
:
2835 return XML_ERROR_INVALID_TOKEN
;
2836 case XML_TOK_PARTIAL_CHAR
:
2839 return XML_ERROR_NONE
;
2841 return XML_ERROR_PARTIAL_CHAR
;
2842 case XML_TOK_PARTIAL
:
2846 return XML_ERROR_NONE
;
2848 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2851 return XML_ERROR_UNEXPECTED_STATE
;
2856 #endif /* XML_DTD */
2858 static enum XML_Error
2859 initializeEncoding(XML_Parser parser
)
2863 char encodingBuf
[128];
2864 if (!protocolEncodingName
)
2868 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2869 if (i
== sizeof(encodingBuf
) - 1
2870 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2871 encodingBuf
[0] = '\0';
2874 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2876 encodingBuf
[i
] = '\0';
2880 s
= protocolEncodingName
;
2882 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2883 return XML_ERROR_NONE
;
2884 return handleUnknownEncoding(parser
, protocolEncodingName
);
2887 static enum XML_Error
2888 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2889 const char *s
, const char *next
)
2891 const char *encodingName
= NULL
;
2892 const XML_Char
*storedEncName
= NULL
;
2893 const ENCODING
*newEncoding
= NULL
;
2894 const char *version
= NULL
;
2895 const char *versionend
;
2896 const XML_Char
*storedversion
= NULL
;
2897 int standalone
= -1;
2900 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2910 return XML_ERROR_SYNTAX
;
2911 if (!isGeneralTextEntity
&& standalone
== 1) {
2912 _dtd
->standalone
= XML_TRUE
;
2914 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2915 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2916 #endif /* XML_DTD */
2918 if (xmlDeclHandler
) {
2919 if (encodingName
!= NULL
) {
2920 storedEncName
= poolStoreString(&temp2Pool
,
2924 + XmlNameLength(encoding
, encodingName
));
2926 return XML_ERROR_NO_MEMORY
;
2927 poolFinish(&temp2Pool
);
2930 storedversion
= poolStoreString(&temp2Pool
,
2933 versionend
- encoding
->minBytesPerChar
);
2935 return XML_ERROR_NO_MEMORY
;
2937 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2939 else if (defaultHandler
)
2940 reportDefault(parser
, encoding
, s
, next
);
2941 if (protocolEncodingName
== NULL
) {
2943 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2944 eventPtr
= encodingName
;
2945 return XML_ERROR_INCORRECT_ENCODING
;
2947 encoding
= newEncoding
;
2949 else if (encodingName
) {
2950 enum XML_Error result
;
2951 if (!storedEncName
) {
2952 storedEncName
= poolStoreString(
2953 &temp2Pool
, encoding
, encodingName
,
2954 encodingName
+ XmlNameLength(encoding
, encodingName
));
2956 return XML_ERROR_NO_MEMORY
;
2958 result
= handleUnknownEncoding(parser
, storedEncName
);
2959 poolClear(&temp2Pool
);
2960 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2961 eventPtr
= encodingName
;
2966 if (storedEncName
|| storedversion
)
2967 poolClear(&temp2Pool
);
2969 return XML_ERROR_NONE
;
2972 static enum XML_Error
2973 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2975 if (unknownEncodingHandler
) {
2978 for (i
= 0; i
< 256; i
++)
2980 info
.convert
= NULL
;
2982 info
.release
= NULL
;
2983 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2986 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2987 if (!unknownEncodingMem
) {
2989 info
.release(info
.data
);
2990 return XML_ERROR_NO_MEMORY
;
2993 ? XmlInitUnknownEncodingNS
2994 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
2999 unknownEncodingData
= info
.data
;
3000 unknownEncodingRelease
= info
.release
;
3002 return XML_ERROR_NONE
;
3005 if (info
.release
!= NULL
)
3006 info
.release(info
.data
);
3008 return XML_ERROR_UNKNOWN_ENCODING
;
3011 static enum XML_Error PTRCALL
3012 prologInitProcessor(XML_Parser parser
,
3015 const char **nextPtr
)
3017 enum XML_Error result
= initializeEncoding(parser
);
3018 if (result
!= XML_ERROR_NONE
)
3020 processor
= prologProcessor
;
3021 return prologProcessor(parser
, s
, end
, nextPtr
);
3026 static enum XML_Error PTRCALL
3027 externalParEntInitProcessor(XML_Parser parser
,
3030 const char **nextPtr
)
3032 enum XML_Error result
= initializeEncoding(parser
);
3033 if (result
!= XML_ERROR_NONE
)
3036 /* we know now that XML_Parse(Buffer) has been called,
3037 so we consider the external parameter entity read */
3038 _dtd
->paramEntityRead
= XML_TRUE
;
3040 if (prologState
.inEntityValue
) {
3041 processor
= entityValueInitProcessor
;
3042 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3045 processor
= externalParEntProcessor
;
3046 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3050 static enum XML_Error PTRCALL
3051 entityValueInitProcessor(XML_Parser parser
,
3054 const char **nextPtr
)
3056 const char *start
= s
;
3057 const char *next
= s
;
3061 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3063 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3065 return XML_ERROR_NONE
;
3068 case XML_TOK_INVALID
:
3069 return XML_ERROR_INVALID_TOKEN
;
3070 case XML_TOK_PARTIAL
:
3071 return XML_ERROR_UNCLOSED_TOKEN
;
3072 case XML_TOK_PARTIAL_CHAR
:
3073 return XML_ERROR_PARTIAL_CHAR
;
3074 case XML_TOK_NONE
: /* start == end */
3078 return storeEntityValue(parser
, encoding
, s
, end
);
3080 else if (tok
== XML_TOK_XML_DECL
) {
3081 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
3082 if (result
!= XML_ERROR_NONE
)
3084 if (nextPtr
) *nextPtr
= next
;
3085 /* stop scanning for text declaration - we found one */
3086 processor
= entityValueProcessor
;
3087 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3089 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3090 return XML_TOK_NONE on the next call, which would then cause the
3091 function to exit with *nextPtr set to s - that is what we want for other
3092 tokens, but not for the BOM - we would rather like to skip it;
3093 then, when this routine is entered the next time, XmlPrologTok will
3094 return XML_TOK_INVALID, since the BOM is still in the buffer
3096 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3098 return XML_ERROR_NONE
;
3104 static enum XML_Error PTRCALL
3105 externalParEntProcessor(XML_Parser parser
,
3108 const char **nextPtr
)
3110 const char *start
= s
;
3111 const char *next
= s
;
3114 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3116 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3118 return XML_ERROR_NONE
;
3121 case XML_TOK_INVALID
:
3122 return XML_ERROR_INVALID_TOKEN
;
3123 case XML_TOK_PARTIAL
:
3124 return XML_ERROR_UNCLOSED_TOKEN
;
3125 case XML_TOK_PARTIAL_CHAR
:
3126 return XML_ERROR_PARTIAL_CHAR
;
3127 case XML_TOK_NONE
: /* start == end */
3132 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3133 However, when parsing an external subset, doProlog will not accept a BOM
3134 as valid, and report a syntax error, so we have to skip the BOM
3136 else if (tok
== XML_TOK_BOM
) {
3138 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3141 processor
= prologProcessor
;
3142 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3145 static enum XML_Error PTRCALL
3146 entityValueProcessor(XML_Parser parser
,
3149 const char **nextPtr
)
3151 const char *start
= s
;
3152 const char *next
= s
;
3153 const ENCODING
*enc
= encoding
;
3157 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3159 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3161 return XML_ERROR_NONE
;
3164 case XML_TOK_INVALID
:
3165 return XML_ERROR_INVALID_TOKEN
;
3166 case XML_TOK_PARTIAL
:
3167 return XML_ERROR_UNCLOSED_TOKEN
;
3168 case XML_TOK_PARTIAL_CHAR
:
3169 return XML_ERROR_PARTIAL_CHAR
;
3170 case XML_TOK_NONE
: /* start == end */
3174 return storeEntityValue(parser
, enc
, s
, end
);
3180 #endif /* XML_DTD */
3182 static enum XML_Error PTRCALL
3183 prologProcessor(XML_Parser parser
,
3186 const char **nextPtr
)
3188 const char *next
= s
;
3189 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3190 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3193 static enum XML_Error
3194 doProlog(XML_Parser parser
,
3195 const ENCODING
*enc
,
3200 const char **nextPtr
)
3203 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3204 #endif /* XML_DTD */
3205 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3206 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3207 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3208 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3209 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3210 static const XML_Char atypeENTITIES
[] =
3211 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3212 static const XML_Char atypeNMTOKEN
[] = {
3213 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3214 static const XML_Char atypeNMTOKENS
[] = {
3215 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3216 static const XML_Char notationPrefix
[] = {
3217 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3218 static const XML_Char enumValueSep
[] = { '|', '\0' };
3219 static const XML_Char enumValueStart
[] = { '(', '\0' };
3221 DTD
* const dtd
= _dtd
; /* save one level of indirection */
3223 const char **eventPP
;
3224 const char **eventEndPP
;
3225 enum XML_Content_Quant quant
;
3227 if (enc
== encoding
) {
3228 eventPP
= &eventPtr
;
3229 eventEndPP
= &eventEndPtr
;
3232 eventPP
= &(openInternalEntities
->internalEventPtr
);
3233 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3237 XML_Bool handleDefault
= XML_TRUE
;
3241 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3243 return XML_ERROR_NONE
;
3246 case XML_TOK_INVALID
:
3248 return XML_ERROR_INVALID_TOKEN
;
3249 case XML_TOK_PARTIAL
:
3250 return XML_ERROR_UNCLOSED_TOKEN
;
3251 case XML_TOK_PARTIAL_CHAR
:
3252 return XML_ERROR_PARTIAL_CHAR
;
3255 if (enc
!= encoding
)
3256 return XML_ERROR_NONE
;
3257 if (isParamEntity
) {
3258 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3260 return XML_ERROR_SYNTAX
;
3261 return XML_ERROR_NONE
;
3263 #endif /* XML_DTD */
3264 return XML_ERROR_NO_ELEMENTS
;
3271 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3273 case XML_ROLE_XML_DECL
:
3275 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3276 if (result
!= XML_ERROR_NONE
)
3279 handleDefault
= XML_FALSE
;
3282 case XML_ROLE_DOCTYPE_NAME
:
3283 if (startDoctypeDeclHandler
) {
3284 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3286 return XML_ERROR_NO_MEMORY
;
3287 poolFinish(&tempPool
);
3288 doctypePubid
= NULL
;
3289 handleDefault
= XML_FALSE
;
3291 doctypeSysid
= NULL
; /* always initialize to NULL */
3293 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3294 if (startDoctypeDeclHandler
) {
3295 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3298 poolClear(&tempPool
);
3299 handleDefault
= XML_FALSE
;
3303 case XML_ROLE_TEXT_DECL
:
3305 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3306 if (result
!= XML_ERROR_NONE
)
3309 handleDefault
= XML_FALSE
;
3312 #endif /* XML_DTD */
3313 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3315 useForeignDTD
= XML_FALSE
;
3316 #endif /* XML_DTD */
3317 dtd
->hasParamEntityRefs
= XML_TRUE
;
3318 if (startDoctypeDeclHandler
) {
3319 doctypePubid
= poolStoreString(&tempPool
, enc
,
3320 s
+ enc
->minBytesPerChar
,
3321 next
- enc
->minBytesPerChar
);
3323 return XML_ERROR_NO_MEMORY
;
3324 poolFinish(&tempPool
);
3325 handleDefault
= XML_FALSE
;
3328 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3332 return XML_ERROR_NO_MEMORY
;
3333 #endif /* XML_DTD */
3335 case XML_ROLE_ENTITY_PUBLIC_ID
:
3336 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3337 return XML_ERROR_SYNTAX
;
3338 if (dtd
->keepProcessing
&& declEntity
) {
3339 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3341 s
+ enc
->minBytesPerChar
,
3342 next
- enc
->minBytesPerChar
);
3344 return XML_ERROR_NO_MEMORY
;
3345 normalizePublicId(tem
);
3346 declEntity
->publicId
= tem
;
3347 poolFinish(&dtd
->pool
);
3348 if (entityDeclHandler
)
3349 handleDefault
= XML_FALSE
;
3352 case XML_ROLE_DOCTYPE_CLOSE
:
3354 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3355 doctypeSysid
, doctypePubid
, 0);
3356 poolClear(&tempPool
);
3357 handleDefault
= XML_FALSE
;
3359 /* doctypeSysid will be non-NULL in the case of a previous
3360 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3361 was not set, indicating an external subset
3364 if (doctypeSysid
|| useForeignDTD
) {
3365 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3366 if (paramEntityParsing
&& externalEntityRefHandler
) {
3367 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3371 return XML_ERROR_NO_MEMORY
;
3373 entity
->base
= curBase
;
3374 dtd
->paramEntityRead
= XML_FALSE
;
3375 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3380 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3381 if (dtd
->paramEntityRead
&&
3383 notStandaloneHandler
&&
3384 !notStandaloneHandler(handlerArg
))
3385 return XML_ERROR_NOT_STANDALONE
;
3386 /* end of DTD - no need to update dtd->keepProcessing */
3388 useForeignDTD
= XML_FALSE
;
3390 #endif /* XML_DTD */
3391 if (endDoctypeDeclHandler
) {
3392 endDoctypeDeclHandler(handlerArg
);
3393 handleDefault
= XML_FALSE
;
3396 case XML_ROLE_INSTANCE_START
:
3398 /* if there is no DOCTYPE declaration then now is the
3399 last chance to read the foreign DTD
3401 if (useForeignDTD
) {
3402 dtd
->hasParamEntityRefs
= XML_TRUE
;
3403 if (paramEntityParsing
&& externalEntityRefHandler
) {
3404 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3408 return XML_ERROR_NO_MEMORY
;
3409 entity
->base
= curBase
;
3410 dtd
->paramEntityRead
= XML_FALSE
;
3411 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3416 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3417 if (dtd
->paramEntityRead
&&
3419 notStandaloneHandler
&&
3420 !notStandaloneHandler(handlerArg
))
3421 return XML_ERROR_NOT_STANDALONE
;
3422 /* end of DTD - no need to update dtd->keepProcessing */
3425 #endif /* XML_DTD */
3426 processor
= contentProcessor
;
3427 return contentProcessor(parser
, s
, end
, nextPtr
);
3428 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3429 declElementType
= getElementType(parser
, enc
, s
, next
);
3430 if (!declElementType
)
3431 return XML_ERROR_NO_MEMORY
;
3432 goto checkAttListDeclHandler
;
3433 case XML_ROLE_ATTRIBUTE_NAME
:
3434 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3435 if (!declAttributeId
)
3436 return XML_ERROR_NO_MEMORY
;
3437 declAttributeIsCdata
= XML_FALSE
;
3438 declAttributeType
= NULL
;
3439 declAttributeIsId
= XML_FALSE
;
3440 goto checkAttListDeclHandler
;
3441 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3442 declAttributeIsCdata
= XML_TRUE
;
3443 declAttributeType
= atypeCDATA
;
3444 goto checkAttListDeclHandler
;
3445 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3446 declAttributeIsId
= XML_TRUE
;
3447 declAttributeType
= atypeID
;
3448 goto checkAttListDeclHandler
;
3449 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3450 declAttributeType
= atypeIDREF
;
3451 goto checkAttListDeclHandler
;
3452 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3453 declAttributeType
= atypeIDREFS
;
3454 goto checkAttListDeclHandler
;
3455 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3456 declAttributeType
= atypeENTITY
;
3457 goto checkAttListDeclHandler
;
3458 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3459 declAttributeType
= atypeENTITIES
;
3460 goto checkAttListDeclHandler
;
3461 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3462 declAttributeType
= atypeNMTOKEN
;
3463 goto checkAttListDeclHandler
;
3464 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3465 declAttributeType
= atypeNMTOKENS
;
3466 checkAttListDeclHandler
:
3467 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3468 handleDefault
= XML_FALSE
;
3470 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3471 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3472 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3473 const XML_Char
*prefix
;
3474 if (declAttributeType
) {
3475 prefix
= enumValueSep
;
3478 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3482 if (!poolAppendString(&tempPool
, prefix
))
3483 return XML_ERROR_NO_MEMORY
;
3484 if (!poolAppend(&tempPool
, enc
, s
, next
))
3485 return XML_ERROR_NO_MEMORY
;
3486 declAttributeType
= tempPool
.start
;
3487 handleDefault
= XML_FALSE
;
3490 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3491 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3492 if (dtd
->keepProcessing
) {
3493 if (!defineAttribute(declElementType
, declAttributeId
,
3494 declAttributeIsCdata
, declAttributeIsId
, 0,
3496 return XML_ERROR_NO_MEMORY
;
3497 if (attlistDeclHandler
&& declAttributeType
) {
3498 if (*declAttributeType
== XML_T('(')
3499 || (*declAttributeType
== XML_T('N')
3500 && declAttributeType
[1] == XML_T('O'))) {
3501 /* Enumerated or Notation type */
3502 if (!poolAppendChar(&tempPool
, XML_T(')'))
3503 || !poolAppendChar(&tempPool
, XML_T('\0')))
3504 return XML_ERROR_NO_MEMORY
;
3505 declAttributeType
= tempPool
.start
;
3506 poolFinish(&tempPool
);
3509 attlistDeclHandler(handlerArg
, declElementType
->name
,
3510 declAttributeId
->name
, declAttributeType
,
3511 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3512 poolClear(&tempPool
);
3513 handleDefault
= XML_FALSE
;
3517 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3518 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3519 if (dtd
->keepProcessing
) {
3520 const XML_Char
*attVal
;
3521 enum XML_Error result
3522 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3523 s
+ enc
->minBytesPerChar
,
3524 next
- enc
->minBytesPerChar
,
3528 attVal
= poolStart(&dtd
->pool
);
3529 poolFinish(&dtd
->pool
);
3530 /* ID attributes aren't allowed to have a default */
3531 if (!defineAttribute(declElementType
, declAttributeId
,
3532 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3533 return XML_ERROR_NO_MEMORY
;
3534 if (attlistDeclHandler
&& declAttributeType
) {
3535 if (*declAttributeType
== XML_T('(')
3536 || (*declAttributeType
== XML_T('N')
3537 && declAttributeType
[1] == XML_T('O'))) {
3538 /* Enumerated or Notation type */
3539 if (!poolAppendChar(&tempPool
, XML_T(')'))
3540 || !poolAppendChar(&tempPool
, XML_T('\0')))
3541 return XML_ERROR_NO_MEMORY
;
3542 declAttributeType
= tempPool
.start
;
3543 poolFinish(&tempPool
);
3546 attlistDeclHandler(handlerArg
, declElementType
->name
,
3547 declAttributeId
->name
, declAttributeType
,
3549 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3550 poolClear(&tempPool
);
3551 handleDefault
= XML_FALSE
;
3555 case XML_ROLE_ENTITY_VALUE
:
3556 if (dtd
->keepProcessing
) {
3557 enum XML_Error result
= storeEntityValue(parser
, enc
,
3558 s
+ enc
->minBytesPerChar
,
3559 next
- enc
->minBytesPerChar
);
3561 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3562 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3563 poolFinish(&dtd
->entityValuePool
);
3564 if (entityDeclHandler
) {
3566 entityDeclHandler(handlerArg
,
3568 declEntity
->is_param
,
3569 declEntity
->textPtr
,
3570 declEntity
->textLen
,
3572 handleDefault
= XML_FALSE
;
3576 poolDiscard(&dtd
->entityValuePool
);
3577 if (result
!= XML_ERROR_NONE
)
3581 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3583 useForeignDTD
= XML_FALSE
;
3584 #endif /* XML_DTD */
3585 dtd
->hasParamEntityRefs
= XML_TRUE
;
3586 if (startDoctypeDeclHandler
) {
3587 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3588 s
+ enc
->minBytesPerChar
,
3589 next
- enc
->minBytesPerChar
);
3590 if (doctypeSysid
== NULL
)
3591 return XML_ERROR_NO_MEMORY
;
3592 poolFinish(&tempPool
);
3593 handleDefault
= XML_FALSE
;
3597 /* use externalSubsetName to make doctypeSysid non-NULL
3598 for the case where no startDoctypeDeclHandler is set */
3599 doctypeSysid
= externalSubsetName
;
3600 #endif /* XML_DTD */
3601 if (!dtd
->standalone
3603 && !paramEntityParsing
3604 #endif /* XML_DTD */
3605 && notStandaloneHandler
3606 && !notStandaloneHandler(handlerArg
))
3607 return XML_ERROR_NOT_STANDALONE
;
3612 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3616 return XML_ERROR_NO_MEMORY
;
3617 declEntity
->publicId
= NULL
;
3620 #endif /* XML_DTD */
3621 case XML_ROLE_ENTITY_SYSTEM_ID
:
3622 if (dtd
->keepProcessing
&& declEntity
) {
3623 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
3624 s
+ enc
->minBytesPerChar
,
3625 next
- enc
->minBytesPerChar
);
3626 if (!declEntity
->systemId
)
3627 return XML_ERROR_NO_MEMORY
;
3628 declEntity
->base
= curBase
;
3629 poolFinish(&dtd
->pool
);
3630 if (entityDeclHandler
)
3631 handleDefault
= XML_FALSE
;
3634 case XML_ROLE_ENTITY_COMPLETE
:
3635 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
3637 entityDeclHandler(handlerArg
,
3639 declEntity
->is_param
,
3642 declEntity
->systemId
,
3643 declEntity
->publicId
,
3645 handleDefault
= XML_FALSE
;
3648 case XML_ROLE_ENTITY_NOTATION_NAME
:
3649 if (dtd
->keepProcessing
&& declEntity
) {
3650 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3651 if (!declEntity
->notation
)
3652 return XML_ERROR_NO_MEMORY
;
3653 poolFinish(&dtd
->pool
);
3654 if (unparsedEntityDeclHandler
) {
3656 unparsedEntityDeclHandler(handlerArg
,
3659 declEntity
->systemId
,
3660 declEntity
->publicId
,
3661 declEntity
->notation
);
3662 handleDefault
= XML_FALSE
;
3664 else if (entityDeclHandler
) {
3666 entityDeclHandler(handlerArg
,
3670 declEntity
->systemId
,
3671 declEntity
->publicId
,
3672 declEntity
->notation
);
3673 handleDefault
= XML_FALSE
;
3677 case XML_ROLE_GENERAL_ENTITY_NAME
:
3679 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3683 if (dtd
->keepProcessing
) {
3684 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3686 return XML_ERROR_NO_MEMORY
;
3687 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
3690 return XML_ERROR_NO_MEMORY
;
3691 if (declEntity
->name
!= name
) {
3692 poolDiscard(&dtd
->pool
);
3696 poolFinish(&dtd
->pool
);
3697 declEntity
->publicId
= NULL
;
3698 declEntity
->is_param
= XML_FALSE
;
3699 /* if we have a parent parser or are reading an internal parameter
3700 entity, then the entity declaration is not considered "internal"
3702 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3703 if (entityDeclHandler
)
3704 handleDefault
= XML_FALSE
;
3708 poolDiscard(&dtd
->pool
);
3713 case XML_ROLE_PARAM_ENTITY_NAME
:
3715 if (dtd
->keepProcessing
) {
3716 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3718 return XML_ERROR_NO_MEMORY
;
3719 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3720 name
, sizeof(ENTITY
));
3722 return XML_ERROR_NO_MEMORY
;
3723 if (declEntity
->name
!= name
) {
3724 poolDiscard(&dtd
->pool
);
3728 poolFinish(&dtd
->pool
);
3729 declEntity
->publicId
= NULL
;
3730 declEntity
->is_param
= XML_TRUE
;
3731 /* if we have a parent parser or are reading an internal parameter
3732 entity, then the entity declaration is not considered "internal"
3734 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3735 if (entityDeclHandler
)
3736 handleDefault
= XML_FALSE
;
3740 poolDiscard(&dtd
->pool
);
3743 #else /* not XML_DTD */
3745 #endif /* XML_DTD */
3747 case XML_ROLE_NOTATION_NAME
:
3748 declNotationPublicId
= NULL
;
3749 declNotationName
= NULL
;
3750 if (notationDeclHandler
) {
3751 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3752 if (!declNotationName
)
3753 return XML_ERROR_NO_MEMORY
;
3754 poolFinish(&tempPool
);
3755 handleDefault
= XML_FALSE
;
3758 case XML_ROLE_NOTATION_PUBLIC_ID
:
3759 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3760 return XML_ERROR_SYNTAX
;
3761 if (declNotationName
) { /* means notationDeclHandler != NULL */
3762 XML_Char
*tem
= poolStoreString(&tempPool
,
3764 s
+ enc
->minBytesPerChar
,
3765 next
- enc
->minBytesPerChar
);
3767 return XML_ERROR_NO_MEMORY
;
3768 normalizePublicId(tem
);
3769 declNotationPublicId
= tem
;
3770 poolFinish(&tempPool
);
3771 handleDefault
= XML_FALSE
;
3774 case XML_ROLE_NOTATION_SYSTEM_ID
:
3775 if (declNotationName
&& notationDeclHandler
) {
3776 const XML_Char
*systemId
3777 = poolStoreString(&tempPool
, enc
,
3778 s
+ enc
->minBytesPerChar
,
3779 next
- enc
->minBytesPerChar
);
3781 return XML_ERROR_NO_MEMORY
;
3783 notationDeclHandler(handlerArg
,
3787 declNotationPublicId
);
3788 handleDefault
= XML_FALSE
;
3790 poolClear(&tempPool
);
3792 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3793 if (declNotationPublicId
&& notationDeclHandler
) {
3795 notationDeclHandler(handlerArg
,
3799 declNotationPublicId
);
3800 handleDefault
= XML_FALSE
;
3802 poolClear(&tempPool
);
3804 case XML_ROLE_ERROR
:
3806 case XML_TOK_PARAM_ENTITY_REF
:
3807 return XML_ERROR_PARAM_ENTITY_REF
;
3808 case XML_TOK_XML_DECL
:
3809 return XML_ERROR_MISPLACED_XML_PI
;
3811 return XML_ERROR_SYNTAX
;
3814 case XML_ROLE_IGNORE_SECT
:
3816 enum XML_Error result
;
3818 reportDefault(parser
, enc
, s
, next
);
3819 handleDefault
= XML_FALSE
;
3820 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3822 processor
= ignoreSectionProcessor
;
3827 #endif /* XML_DTD */
3828 case XML_ROLE_GROUP_OPEN
:
3829 if (prologState
.level
>= groupSize
) {
3831 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
3833 return XML_ERROR_NO_MEMORY
;
3834 groupConnector
= temp
;
3835 if (dtd
->scaffIndex
) {
3836 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
3837 groupSize
* sizeof(int));
3839 return XML_ERROR_NO_MEMORY
;
3840 dtd
->scaffIndex
= temp
;
3844 groupConnector
= (char *)MALLOC(groupSize
= 32);
3845 if (!groupConnector
)
3846 return XML_ERROR_NO_MEMORY
;
3849 groupConnector
[prologState
.level
] = 0;
3850 if (dtd
->in_eldecl
) {
3851 int myindex
= nextScaffoldPart(parser
);
3853 return XML_ERROR_NO_MEMORY
;
3854 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
3856 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3857 if (elementDeclHandler
)
3858 handleDefault
= XML_FALSE
;
3861 case XML_ROLE_GROUP_SEQUENCE
:
3862 if (groupConnector
[prologState
.level
] == '|')
3863 return XML_ERROR_SYNTAX
;
3864 groupConnector
[prologState
.level
] = ',';
3865 if (dtd
->in_eldecl
&& elementDeclHandler
)
3866 handleDefault
= XML_FALSE
;
3868 case XML_ROLE_GROUP_CHOICE
:
3869 if (groupConnector
[prologState
.level
] == ',')
3870 return XML_ERROR_SYNTAX
;
3872 && !groupConnector
[prologState
.level
]
3873 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3876 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3878 if (elementDeclHandler
)
3879 handleDefault
= XML_FALSE
;
3881 groupConnector
[prologState
.level
] = '|';
3883 case XML_ROLE_PARAM_ENTITY_REF
:
3885 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3886 /* PE references in internal subset are
3887 not allowed within declarations */
3888 if (prologState
.documentEntity
&&
3889 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3890 return XML_ERROR_PARAM_ENTITY_REF
;
3891 dtd
->hasParamEntityRefs
= XML_TRUE
;
3892 if (!paramEntityParsing
)
3893 dtd
->keepProcessing
= dtd
->standalone
;
3895 const XML_Char
*name
;
3897 name
= poolStoreString(&dtd
->pool
, enc
,
3898 s
+ enc
->minBytesPerChar
,
3899 next
- enc
->minBytesPerChar
);
3901 return XML_ERROR_NO_MEMORY
;
3902 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
3903 poolDiscard(&dtd
->pool
);
3904 /* first, determine if a check for an existing declaration is needed;
3905 if yes, check that the entity exists, and that it is internal,
3906 otherwise call the skipped entity handler
3908 if (prologState
.documentEntity
&&
3910 ? !openInternalEntities
3911 : !dtd
->hasParamEntityRefs
)) {
3913 return XML_ERROR_UNDEFINED_ENTITY
;
3914 else if (!entity
->is_internal
)
3915 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3918 dtd
->keepProcessing
= dtd
->standalone
;
3919 /* cannot report skipped entities in declarations */
3920 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3921 skippedEntityHandler(handlerArg
, name
, 1);
3922 handleDefault
= XML_FALSE
;
3927 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3928 if (entity
->textPtr
) {
3929 enum XML_Error result
;
3930 result
= processInternalParamEntity(parser
, entity
);
3931 if (result
!= XML_ERROR_NONE
)
3933 handleDefault
= XML_FALSE
;
3936 if (externalEntityRefHandler
) {
3937 dtd
->paramEntityRead
= XML_FALSE
;
3938 entity
->open
= XML_TRUE
;
3939 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3943 entity
->publicId
)) {
3944 entity
->open
= XML_FALSE
;
3945 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3947 entity
->open
= XML_FALSE
;
3948 handleDefault
= XML_FALSE
;
3949 if (!dtd
->paramEntityRead
) {
3950 dtd
->keepProcessing
= dtd
->standalone
;
3955 dtd
->keepProcessing
= dtd
->standalone
;
3959 #endif /* XML_DTD */
3960 if (!dtd
->standalone
&&
3961 notStandaloneHandler
&&
3962 !notStandaloneHandler(handlerArg
))
3963 return XML_ERROR_NOT_STANDALONE
;
3966 /* Element declaration stuff */
3968 case XML_ROLE_ELEMENT_NAME
:
3969 if (elementDeclHandler
) {
3970 declElementType
= getElementType(parser
, enc
, s
, next
);
3971 if (!declElementType
)
3972 return XML_ERROR_NO_MEMORY
;
3973 dtd
->scaffLevel
= 0;
3974 dtd
->scaffCount
= 0;
3975 dtd
->in_eldecl
= XML_TRUE
;
3976 handleDefault
= XML_FALSE
;
3980 case XML_ROLE_CONTENT_ANY
:
3981 case XML_ROLE_CONTENT_EMPTY
:
3982 if (dtd
->in_eldecl
) {
3983 if (elementDeclHandler
) {
3984 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3986 return XML_ERROR_NO_MEMORY
;
3987 content
->quant
= XML_CQUANT_NONE
;
3988 content
->name
= NULL
;
3989 content
->numchildren
= 0;
3990 content
->children
= NULL
;
3991 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
3995 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
3996 handleDefault
= XML_FALSE
;
3998 dtd
->in_eldecl
= XML_FALSE
;
4002 case XML_ROLE_CONTENT_PCDATA
:
4003 if (dtd
->in_eldecl
) {
4004 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4006 if (elementDeclHandler
)
4007 handleDefault
= XML_FALSE
;
4011 case XML_ROLE_CONTENT_ELEMENT
:
4012 quant
= XML_CQUANT_NONE
;
4013 goto elementContent
;
4014 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4015 quant
= XML_CQUANT_OPT
;
4016 goto elementContent
;
4017 case XML_ROLE_CONTENT_ELEMENT_REP
:
4018 quant
= XML_CQUANT_REP
;
4019 goto elementContent
;
4020 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4021 quant
= XML_CQUANT_PLUS
;
4023 if (dtd
->in_eldecl
) {
4025 const XML_Char
*name
;
4027 const char *nxt
= (quant
== XML_CQUANT_NONE
4029 : next
- enc
->minBytesPerChar
);
4030 int myindex
= nextScaffoldPart(parser
);
4032 return XML_ERROR_NO_MEMORY
;
4033 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4034 dtd
->scaffold
[myindex
].quant
= quant
;
4035 el
= getElementType(parser
, enc
, s
, nxt
);
4037 return XML_ERROR_NO_MEMORY
;
4039 dtd
->scaffold
[myindex
].name
= name
;
4041 for (; name
[nameLen
++]; )
4043 dtd
->contentStringLen
+= nameLen
;
4044 if (elementDeclHandler
)
4045 handleDefault
= XML_FALSE
;
4049 case XML_ROLE_GROUP_CLOSE
:
4050 quant
= XML_CQUANT_NONE
;
4052 case XML_ROLE_GROUP_CLOSE_OPT
:
4053 quant
= XML_CQUANT_OPT
;
4055 case XML_ROLE_GROUP_CLOSE_REP
:
4056 quant
= XML_CQUANT_REP
;
4058 case XML_ROLE_GROUP_CLOSE_PLUS
:
4059 quant
= XML_CQUANT_PLUS
;
4061 if (dtd
->in_eldecl
) {
4062 if (elementDeclHandler
)
4063 handleDefault
= XML_FALSE
;
4065 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4066 if (dtd
->scaffLevel
== 0) {
4067 if (!handleDefault
) {
4068 XML_Content
*model
= build_model(parser
);
4070 return XML_ERROR_NO_MEMORY
;
4072 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4074 dtd
->in_eldecl
= XML_FALSE
;
4075 dtd
->contentStringLen
= 0;
4079 /* End element declaration stuff */
4082 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4083 return XML_ERROR_NO_MEMORY
;
4084 handleDefault
= XML_FALSE
;
4086 case XML_ROLE_COMMENT
:
4087 if (!reportComment(parser
, enc
, s
, next
))
4088 return XML_ERROR_NO_MEMORY
;
4089 handleDefault
= XML_FALSE
;
4094 handleDefault
= XML_FALSE
;
4098 case XML_ROLE_DOCTYPE_NONE
:
4099 if (startDoctypeDeclHandler
)
4100 handleDefault
= XML_FALSE
;
4102 case XML_ROLE_ENTITY_NONE
:
4103 if (dtd
->keepProcessing
&& entityDeclHandler
)
4104 handleDefault
= XML_FALSE
;
4106 case XML_ROLE_NOTATION_NONE
:
4107 if (notationDeclHandler
)
4108 handleDefault
= XML_FALSE
;
4110 case XML_ROLE_ATTLIST_NONE
:
4111 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4112 handleDefault
= XML_FALSE
;
4114 case XML_ROLE_ELEMENT_NONE
:
4115 if (elementDeclHandler
)
4116 handleDefault
= XML_FALSE
;
4118 } /* end of big switch */
4120 if (handleDefault
&& defaultHandler
)
4121 reportDefault(parser
, enc
, s
, next
);
4124 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4129 static enum XML_Error PTRCALL
4130 epilogProcessor(XML_Parser parser
,
4133 const char **nextPtr
)
4135 processor
= epilogProcessor
;
4138 const char *next
= NULL
;
4139 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4142 /* report partial linebreak - it might be the last token */
4143 case -XML_TOK_PROLOG_S
:
4144 if (defaultHandler
) {
4146 reportDefault(parser
, encoding
, s
, next
);
4150 return XML_ERROR_NONE
;
4154 return XML_ERROR_NONE
;
4155 case XML_TOK_PROLOG_S
:
4157 reportDefault(parser
, encoding
, s
, next
);
4160 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4161 return XML_ERROR_NO_MEMORY
;
4163 case XML_TOK_COMMENT
:
4164 if (!reportComment(parser
, encoding
, s
, next
))
4165 return XML_ERROR_NO_MEMORY
;
4167 case XML_TOK_INVALID
:
4169 return XML_ERROR_INVALID_TOKEN
;
4170 case XML_TOK_PARTIAL
:
4173 return XML_ERROR_NONE
;
4175 return XML_ERROR_UNCLOSED_TOKEN
;
4176 case XML_TOK_PARTIAL_CHAR
:
4179 return XML_ERROR_NONE
;
4181 return XML_ERROR_PARTIAL_CHAR
;
4183 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4185 eventPtr
= s
= next
;
4191 static enum XML_Error
4192 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4194 const char *s
, *end
, *next
;
4196 enum XML_Error result
;
4197 OPEN_INTERNAL_ENTITY openEntity
;
4198 entity
->open
= XML_TRUE
;
4199 openEntity
.next
= openInternalEntities
;
4200 openInternalEntities
= &openEntity
;
4201 openEntity
.entity
= entity
;
4202 openEntity
.internalEventPtr
= NULL
;
4203 openEntity
.internalEventEndPtr
= NULL
;
4204 s
= (char *)entity
->textPtr
;
4205 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4206 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4207 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4208 entity
->open
= XML_FALSE
;
4209 openInternalEntities
= openEntity
.next
;
4213 #endif /* XML_DTD */
4215 static enum XML_Error PTRCALL
4216 errorProcessor(XML_Parser parser
,
4219 const char **nextPtr
)
4224 static enum XML_Error
4225 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4226 const char *ptr
, const char *end
,
4229 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4233 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4235 if (!poolAppendChar(pool
, XML_T('\0')))
4236 return XML_ERROR_NO_MEMORY
;
4237 return XML_ERROR_NONE
;
4240 static enum XML_Error
4241 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4242 const char *ptr
, const char *end
,
4245 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4248 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4251 return XML_ERROR_NONE
;
4252 case XML_TOK_INVALID
:
4253 if (enc
== encoding
)
4255 return XML_ERROR_INVALID_TOKEN
;
4256 case XML_TOK_PARTIAL
:
4257 if (enc
== encoding
)
4259 return XML_ERROR_INVALID_TOKEN
;
4260 case XML_TOK_CHAR_REF
:
4262 XML_Char buf
[XML_ENCODE_MAX
];
4264 int n
= XmlCharRefNumber(enc
, ptr
);
4266 if (enc
== encoding
)
4268 return XML_ERROR_BAD_CHAR_REF
;
4271 && n
== 0x20 /* space */
4272 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4274 n
= XmlEncode(n
, (ICHAR
*)buf
);
4276 if (enc
== encoding
)
4278 return XML_ERROR_BAD_CHAR_REF
;
4280 for (i
= 0; i
< n
; i
++) {
4281 if (!poolAppendChar(pool
, buf
[i
]))
4282 return XML_ERROR_NO_MEMORY
;
4286 case XML_TOK_DATA_CHARS
:
4287 if (!poolAppend(pool
, enc
, ptr
, next
))
4288 return XML_ERROR_NO_MEMORY
;
4290 case XML_TOK_TRAILING_CR
:
4291 next
= ptr
+ enc
->minBytesPerChar
;
4293 case XML_TOK_ATTRIBUTE_VALUE_S
:
4294 case XML_TOK_DATA_NEWLINE
:
4295 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4297 if (!poolAppendChar(pool
, 0x20))
4298 return XML_ERROR_NO_MEMORY
;
4300 case XML_TOK_ENTITY_REF
:
4302 const XML_Char
*name
;
4304 char checkEntityDecl
;
4305 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4306 ptr
+ enc
->minBytesPerChar
,
4307 next
- enc
->minBytesPerChar
);
4309 if (!poolAppendChar(pool
, ch
))
4310 return XML_ERROR_NO_MEMORY
;
4313 name
= poolStoreString(&temp2Pool
, enc
,
4314 ptr
+ enc
->minBytesPerChar
,
4315 next
- enc
->minBytesPerChar
);
4317 return XML_ERROR_NO_MEMORY
;
4318 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4319 poolDiscard(&temp2Pool
);
4320 /* first, determine if a check for an existing declaration is needed;
4321 if yes, check that the entity exists, and that it is internal,
4322 otherwise call the default handler (if called from content)
4324 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4327 prologState
.documentEntity
&&
4328 #endif /* XML_DTD */
4330 ? !openInternalEntities
4331 : !dtd
->hasParamEntityRefs
);
4332 else /* if (pool == &tempPool): we are called from content */
4333 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4334 if (checkEntityDecl
) {
4336 return XML_ERROR_UNDEFINED_ENTITY
;
4337 else if (!entity
->is_internal
)
4338 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4341 /* cannot report skipped entity here - see comments on
4342 skippedEntityHandler
4343 if (skippedEntityHandler)
4344 skippedEntityHandler(handlerArg, name, 0);
4346 if ((pool
== &tempPool
) && defaultHandler
)
4347 reportDefault(parser
, enc
, ptr
, next
);
4351 if (enc
== encoding
)
4353 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4355 if (entity
->notation
) {
4356 if (enc
== encoding
)
4358 return XML_ERROR_BINARY_ENTITY_REF
;
4360 if (!entity
->textPtr
) {
4361 if (enc
== encoding
)
4363 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4366 enum XML_Error result
;
4367 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4368 entity
->open
= XML_TRUE
;
4369 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4370 (char *)entity
->textPtr
,
4371 (char *)textEnd
, pool
);
4372 entity
->open
= XML_FALSE
;
4379 if (enc
== encoding
)
4381 return XML_ERROR_UNEXPECTED_STATE
;
4388 static enum XML_Error
4389 storeEntityValue(XML_Parser parser
,
4390 const ENCODING
*enc
,
4391 const char *entityTextPtr
,
4392 const char *entityTextEnd
)
4394 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4395 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4396 enum XML_Error result
= XML_ERROR_NONE
;
4398 int oldInEntityValue
= prologState
.inEntityValue
;
4399 prologState
.inEntityValue
= 1;
4400 #endif /* XML_DTD */
4401 /* never return Null for the value argument in EntityDeclHandler,
4402 since this would indicate an external entity; therefore we
4403 have to make sure that entityValuePool.start is not null */
4404 if (!pool
->blocks
) {
4405 if (!poolGrow(pool
))
4406 return XML_ERROR_NO_MEMORY
;
4411 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4413 case XML_TOK_PARAM_ENTITY_REF
:
4415 if (isParamEntity
|| enc
!= encoding
) {
4416 const XML_Char
*name
;
4418 name
= poolStoreString(&tempPool
, enc
,
4419 entityTextPtr
+ enc
->minBytesPerChar
,
4420 next
- enc
->minBytesPerChar
);
4422 result
= XML_ERROR_NO_MEMORY
;
4423 goto endEntityValue
;
4425 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4426 poolDiscard(&tempPool
);
4428 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4429 /* cannot report skipped entity here - see comments on
4430 skippedEntityHandler
4431 if (skippedEntityHandler)
4432 skippedEntityHandler(handlerArg, name, 0);
4434 dtd
->keepProcessing
= dtd
->standalone
;
4435 goto endEntityValue
;
4438 if (enc
== encoding
)
4439 eventPtr
= entityTextPtr
;
4440 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4441 goto endEntityValue
;
4443 if (entity
->systemId
) {
4444 if (externalEntityRefHandler
) {
4445 dtd
->paramEntityRead
= XML_FALSE
;
4446 entity
->open
= XML_TRUE
;
4447 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4451 entity
->publicId
)) {
4452 entity
->open
= XML_FALSE
;
4453 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4454 goto endEntityValue
;
4456 entity
->open
= XML_FALSE
;
4457 if (!dtd
->paramEntityRead
)
4458 dtd
->keepProcessing
= dtd
->standalone
;
4461 dtd
->keepProcessing
= dtd
->standalone
;
4464 entity
->open
= XML_TRUE
;
4465 result
= storeEntityValue(parser
,
4467 (char *)entity
->textPtr
,
4468 (char *)(entity
->textPtr
4469 + entity
->textLen
));
4470 entity
->open
= XML_FALSE
;
4472 goto endEntityValue
;
4476 #endif /* XML_DTD */
4477 /* in the internal subset, PE references are not legal
4478 within markup declarations, e.g entity values in this case */
4479 eventPtr
= entityTextPtr
;
4480 result
= XML_ERROR_PARAM_ENTITY_REF
;
4481 goto endEntityValue
;
4483 result
= XML_ERROR_NONE
;
4484 goto endEntityValue
;
4485 case XML_TOK_ENTITY_REF
:
4486 case XML_TOK_DATA_CHARS
:
4487 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4488 result
= XML_ERROR_NO_MEMORY
;
4489 goto endEntityValue
;
4492 case XML_TOK_TRAILING_CR
:
4493 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4495 case XML_TOK_DATA_NEWLINE
:
4496 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4497 result
= XML_ERROR_NO_MEMORY
;
4498 goto endEntityValue
;
4500 *(pool
->ptr
)++ = 0xA;
4502 case XML_TOK_CHAR_REF
:
4504 XML_Char buf
[XML_ENCODE_MAX
];
4506 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4508 if (enc
== encoding
)
4509 eventPtr
= entityTextPtr
;
4510 result
= XML_ERROR_BAD_CHAR_REF
;
4511 goto endEntityValue
;
4513 n
= XmlEncode(n
, (ICHAR
*)buf
);
4515 if (enc
== encoding
)
4516 eventPtr
= entityTextPtr
;
4517 result
= XML_ERROR_BAD_CHAR_REF
;
4518 goto endEntityValue
;
4520 for (i
= 0; i
< n
; i
++) {
4521 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4522 result
= XML_ERROR_NO_MEMORY
;
4523 goto endEntityValue
;
4525 *(pool
->ptr
)++ = buf
[i
];
4529 case XML_TOK_PARTIAL
:
4530 if (enc
== encoding
)
4531 eventPtr
= entityTextPtr
;
4532 result
= XML_ERROR_INVALID_TOKEN
;
4533 goto endEntityValue
;
4534 case XML_TOK_INVALID
:
4535 if (enc
== encoding
)
4537 result
= XML_ERROR_INVALID_TOKEN
;
4538 goto endEntityValue
;
4540 if (enc
== encoding
)
4541 eventPtr
= entityTextPtr
;
4542 result
= XML_ERROR_UNEXPECTED_STATE
;
4543 goto endEntityValue
;
4545 entityTextPtr
= next
;
4549 prologState
.inEntityValue
= oldInEntityValue
;
4550 #endif /* XML_DTD */
4554 static void FASTCALL
4555 normalizeLines(XML_Char
*s
)
4559 if (*s
== XML_T('\0'))
4578 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4579 const char *start
, const char *end
)
4581 const XML_Char
*target
;
4584 if (!processingInstructionHandler
) {
4586 reportDefault(parser
, enc
, start
, end
);
4589 start
+= enc
->minBytesPerChar
* 2;
4590 tem
= start
+ XmlNameLength(enc
, start
);
4591 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4594 poolFinish(&tempPool
);
4595 data
= poolStoreString(&tempPool
, enc
,
4597 end
- enc
->minBytesPerChar
*2);
4600 normalizeLines(data
);
4601 processingInstructionHandler(handlerArg
, target
, data
);
4602 poolClear(&tempPool
);
4607 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4608 const char *start
, const char *end
)
4611 if (!commentHandler
) {
4613 reportDefault(parser
, enc
, start
, end
);
4616 data
= poolStoreString(&tempPool
,
4618 start
+ enc
->minBytesPerChar
* 4,
4619 end
- enc
->minBytesPerChar
* 3);
4622 normalizeLines(data
);
4623 commentHandler(handlerArg
, data
);
4624 poolClear(&tempPool
);
4629 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4630 const char *s
, const char *end
)
4632 if (MUST_CONVERT(enc
, s
)) {
4633 const char **eventPP
;
4634 const char **eventEndPP
;
4635 if (enc
== encoding
) {
4636 eventPP
= &eventPtr
;
4637 eventEndPP
= &eventEndPtr
;
4640 eventPP
= &(openInternalEntities
->internalEventPtr
);
4641 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4644 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4645 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4647 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4652 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4657 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4658 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4660 DEFAULT_ATTRIBUTE
*att
;
4661 if (value
|| isId
) {
4662 /* The handling of default attributes gets messed up if we have
4663 a default which duplicates a non-default. */
4665 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4666 if (attId
== type
->defaultAtts
[i
].id
)
4668 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4669 type
->idAtt
= attId
;
4671 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4672 if (type
->allocDefaultAtts
== 0) {
4673 type
->allocDefaultAtts
= 8;
4674 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
4675 * sizeof(DEFAULT_ATTRIBUTE
));
4676 if (!type
->defaultAtts
)
4680 DEFAULT_ATTRIBUTE
*temp
;
4681 int count
= type
->allocDefaultAtts
* 2;
4682 temp
= (DEFAULT_ATTRIBUTE
*)
4683 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4686 type
->allocDefaultAtts
= count
;
4687 type
->defaultAtts
= temp
;
4690 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4693 att
->isCdata
= isCdata
;
4695 attId
->maybeTokenized
= XML_TRUE
;
4696 type
->nDefaultAtts
+= 1;
4701 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4703 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4704 const XML_Char
*name
;
4705 for (name
= elementType
->name
; *name
; name
++) {
4706 if (*name
== XML_T(':')) {
4709 for (s
= elementType
->name
; s
!= name
; s
++) {
4710 if (!poolAppendChar(&dtd
->pool
, *s
))
4713 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4715 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4719 if (prefix
->name
== poolStart(&dtd
->pool
))
4720 poolFinish(&dtd
->pool
);
4722 poolDiscard(&dtd
->pool
);
4723 elementType
->prefix
= prefix
;
4730 static ATTRIBUTE_ID
*
4731 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4732 const char *start
, const char *end
)
4734 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4736 const XML_Char
*name
;
4737 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4739 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
4743 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4746 if (id
->name
!= name
)
4747 poolDiscard(&dtd
->pool
);
4749 poolFinish(&dtd
->pool
);
4752 else if (name
[0] == XML_T('x')
4753 && name
[1] == XML_T('m')
4754 && name
[2] == XML_T('l')
4755 && name
[3] == XML_T('n')
4756 && name
[4] == XML_T('s')
4757 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4758 if (name
[5] == XML_T('\0'))
4759 id
->prefix
= &dtd
->defaultPrefix
;
4761 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
4762 id
->xmlns
= XML_TRUE
;
4766 for (i
= 0; name
[i
]; i
++) {
4767 if (name
[i
] == XML_T(':')) {
4769 for (j
= 0; j
< i
; j
++) {
4770 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
4773 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4775 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4777 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
4778 poolFinish(&dtd
->pool
);
4780 poolDiscard(&dtd
->pool
);
4789 #define CONTEXT_SEP XML_T('\f')
4791 static const XML_Char
*
4792 getContext(XML_Parser parser
)
4794 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4795 HASH_TABLE_ITER iter
;
4796 XML_Bool needSep
= XML_FALSE
;
4798 if (dtd
->defaultPrefix
.binding
) {
4801 if (!poolAppendChar(&tempPool
, XML_T('=')))
4803 len
= dtd
->defaultPrefix
.binding
->uriLen
;
4804 if (namespaceSeparator
!= XML_T('\0'))
4806 for (i
= 0; i
< len
; i
++)
4807 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
4812 hashTableIterInit(&iter
, &(dtd
->prefixes
));
4817 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4820 if (!prefix
->binding
)
4822 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4824 for (s
= prefix
->name
; *s
; s
++)
4825 if (!poolAppendChar(&tempPool
, *s
))
4827 if (!poolAppendChar(&tempPool
, XML_T('=')))
4829 len
= prefix
->binding
->uriLen
;
4830 if (namespaceSeparator
!= XML_T('\0'))
4832 for (i
= 0; i
< len
; i
++)
4833 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4839 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
4842 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4847 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4849 for (s
= e
->name
; *s
; s
++)
4850 if (!poolAppendChar(&tempPool
, *s
))
4855 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4857 return tempPool
.start
;
4861 setContext(XML_Parser parser
, const XML_Char
*context
)
4863 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4864 const XML_Char
*s
= context
;
4866 while (*context
!= XML_T('\0')) {
4867 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4869 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4871 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
4874 if (*s
!= XML_T('\0'))
4877 poolDiscard(&tempPool
);
4879 else if (*s
== XML_T('=')) {
4881 if (poolLength(&tempPool
) == 0)
4882 prefix
= &dtd
->defaultPrefix
;
4884 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4886 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
4890 if (prefix
->name
== poolStart(&tempPool
)) {
4891 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
4895 poolDiscard(&tempPool
);
4897 for (context
= s
+ 1;
4898 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4900 if (!poolAppendChar(&tempPool
, *context
))
4902 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4904 if (addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4905 &inheritedBindings
) != XML_ERROR_NONE
)
4907 poolDiscard(&tempPool
);
4908 if (*context
!= XML_T('\0'))
4913 if (!poolAppendChar(&tempPool
, *s
))
4921 static void FASTCALL
4922 normalizePublicId(XML_Char
*publicId
)
4924 XML_Char
*p
= publicId
;
4926 for (s
= publicId
; *s
; s
++) {
4931 if (p
!= publicId
&& p
[-1] != 0x20)
4938 if (p
!= publicId
&& p
[-1] == 0x20)
4944 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
4946 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
4949 poolInit(&(p
->pool
), ms
);
4951 poolInit(&(p
->entityValuePool
), ms
);
4952 #endif /* XML_DTD */
4953 hashTableInit(&(p
->generalEntities
), ms
);
4954 hashTableInit(&(p
->elementTypes
), ms
);
4955 hashTableInit(&(p
->attributeIds
), ms
);
4956 hashTableInit(&(p
->prefixes
), ms
);
4958 p
->paramEntityRead
= XML_FALSE
;
4959 hashTableInit(&(p
->paramEntities
), ms
);
4960 #endif /* XML_DTD */
4961 p
->defaultPrefix
.name
= NULL
;
4962 p
->defaultPrefix
.binding
= NULL
;
4964 p
->in_eldecl
= XML_FALSE
;
4965 p
->scaffIndex
= NULL
;
4970 p
->contentStringLen
= 0;
4972 p
->keepProcessing
= XML_TRUE
;
4973 p
->hasParamEntityRefs
= XML_FALSE
;
4974 p
->standalone
= XML_FALSE
;
4979 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
4981 HASH_TABLE_ITER iter
;
4982 hashTableIterInit(&iter
, &(p
->elementTypes
));
4984 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4987 if (e
->allocDefaultAtts
!= 0)
4988 ms
->free_fcn(e
->defaultAtts
);
4990 hashTableClear(&(p
->generalEntities
));
4992 p
->paramEntityRead
= XML_FALSE
;
4993 hashTableClear(&(p
->paramEntities
));
4994 #endif /* XML_DTD */
4995 hashTableClear(&(p
->elementTypes
));
4996 hashTableClear(&(p
->attributeIds
));
4997 hashTableClear(&(p
->prefixes
));
4998 poolClear(&(p
->pool
));
5000 poolClear(&(p
->entityValuePool
));
5001 #endif /* XML_DTD */
5002 p
->defaultPrefix
.name
= NULL
;
5003 p
->defaultPrefix
.binding
= NULL
;
5005 p
->in_eldecl
= XML_FALSE
;
5006 if (p
->scaffIndex
) {
5007 ms
->free_fcn(p
->scaffIndex
);
5008 p
->scaffIndex
= NULL
;
5011 ms
->free_fcn(p
->scaffold
);
5017 p
->contentStringLen
= 0;
5019 p
->keepProcessing
= XML_TRUE
;
5020 p
->hasParamEntityRefs
= XML_FALSE
;
5021 p
->standalone
= XML_FALSE
;
5025 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5027 HASH_TABLE_ITER iter
;
5028 hashTableIterInit(&iter
, &(p
->elementTypes
));
5030 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5033 if (e
->allocDefaultAtts
!= 0)
5034 ms
->free_fcn(e
->defaultAtts
);
5036 hashTableDestroy(&(p
->generalEntities
));
5038 hashTableDestroy(&(p
->paramEntities
));
5039 #endif /* XML_DTD */
5040 hashTableDestroy(&(p
->elementTypes
));
5041 hashTableDestroy(&(p
->attributeIds
));
5042 hashTableDestroy(&(p
->prefixes
));
5043 poolDestroy(&(p
->pool
));
5045 poolDestroy(&(p
->entityValuePool
));
5046 #endif /* XML_DTD */
5049 ms
->free_fcn(p
->scaffIndex
);
5051 ms
->free_fcn(p
->scaffold
);
5056 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5057 The new DTD has already been initialized.
5060 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5062 HASH_TABLE_ITER iter
;
5064 /* Copy the prefix table. */
5066 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5068 const XML_Char
*name
;
5069 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5072 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5075 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5079 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5081 /* Copy the attribute id table. */
5085 const XML_Char
*name
;
5086 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5090 /* Remember to allocate the scratch byte before the name. */
5091 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5093 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5097 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5098 sizeof(ATTRIBUTE_ID
));
5101 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5103 newA
->xmlns
= oldA
->xmlns
;
5104 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5105 newA
->prefix
= &newDtd
->defaultPrefix
;
5107 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5108 oldA
->prefix
->name
, 0);
5112 /* Copy the element type table. */
5114 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5119 const XML_Char
*name
;
5120 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5123 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5126 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5127 sizeof(ELEMENT_TYPE
));
5130 if (oldE
->nDefaultAtts
) {
5131 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5132 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5133 if (!newE
->defaultAtts
) {
5139 newE
->idAtt
= (ATTRIBUTE_ID
*)
5140 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5141 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5143 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5144 oldE
->prefix
->name
, 0);
5145 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5146 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5147 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5148 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5149 if (oldE
->defaultAtts
[i
].value
) {
5150 newE
->defaultAtts
[i
].value
5151 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5152 if (!newE
->defaultAtts
[i
].value
)
5156 newE
->defaultAtts
[i
].value
= NULL
;
5160 /* Copy the entity tables. */
5161 if (!copyEntityTable(&(newDtd
->generalEntities
),
5163 &(oldDtd
->generalEntities
)))
5167 if (!copyEntityTable(&(newDtd
->paramEntities
),
5169 &(oldDtd
->paramEntities
)))
5171 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5172 #endif /* XML_DTD */
5174 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5175 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5176 newDtd
->standalone
= oldDtd
->standalone
;
5178 /* Don't want deep copying for scaffolding */
5179 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5180 newDtd
->scaffold
= oldDtd
->scaffold
;
5181 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5182 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5183 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5184 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5190 copyEntityTable(HASH_TABLE
*newTable
,
5191 STRING_POOL
*newPool
,
5192 const HASH_TABLE
*oldTable
)
5194 HASH_TABLE_ITER iter
;
5195 const XML_Char
*cachedOldBase
= NULL
;
5196 const XML_Char
*cachedNewBase
= NULL
;
5198 hashTableIterInit(&iter
, oldTable
);
5202 const XML_Char
*name
;
5203 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5206 name
= poolCopyString(newPool
, oldE
->name
);
5209 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5212 if (oldE
->systemId
) {
5213 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5216 newE
->systemId
= tem
;
5218 if (oldE
->base
== cachedOldBase
)
5219 newE
->base
= cachedNewBase
;
5221 cachedOldBase
= oldE
->base
;
5222 tem
= poolCopyString(newPool
, cachedOldBase
);
5225 cachedNewBase
= newE
->base
= tem
;
5228 if (oldE
->publicId
) {
5229 tem
= poolCopyString(newPool
, oldE
->publicId
);
5232 newE
->publicId
= tem
;
5236 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5240 newE
->textPtr
= tem
;
5241 newE
->textLen
= oldE
->textLen
;
5243 if (oldE
->notation
) {
5244 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5247 newE
->notation
= tem
;
5249 newE
->is_param
= oldE
->is_param
;
5250 newE
->is_internal
= oldE
->is_internal
;
5255 #define INIT_SIZE 64
5258 keyeq(KEY s1
, KEY s2
)
5260 for (; *s1
== *s2
; s1
++, s2
++)
5266 static unsigned long FASTCALL
5269 unsigned long h
= 0;
5271 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5276 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5279 if (table
->size
== 0) {
5284 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5285 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5288 memset(table
->v
, 0, tsize
);
5289 table
->size
= INIT_SIZE
;
5290 table
->usedLim
= INIT_SIZE
/ 2;
5291 i
= hash(name
) & (table
->size
- 1);
5294 unsigned long h
= hash(name
);
5295 for (i
= h
& (table
->size
- 1);
5297 i
== 0 ? i
= table
->size
- 1 : --i
) {
5298 if (keyeq(name
, table
->v
[i
]->name
))
5303 if (table
->used
== table
->usedLim
) {
5304 /* check for overflow */
5305 size_t newSize
= table
->size
* 2;
5306 size_t tsize
= newSize
* sizeof(NAMED
*);
5307 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5310 memset(newV
, 0, tsize
);
5311 for (i
= 0; i
< table
->size
; i
++)
5314 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5316 j
== 0 ? j
= newSize
- 1 : --j
)
5318 newV
[j
] = table
->v
[i
];
5320 table
->mem
->free_fcn(table
->v
);
5322 table
->size
= newSize
;
5323 table
->usedLim
= newSize
/2;
5324 for (i
= h
& (table
->size
- 1);
5326 i
== 0 ? i
= table
->size
- 1 : --i
)
5330 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5333 memset(table
->v
[i
], 0, createSize
);
5334 table
->v
[i
]->name
= name
;
5339 static void FASTCALL
5340 hashTableClear(HASH_TABLE
*table
)
5343 for (i
= 0; i
< table
->size
; i
++) {
5344 NAMED
*p
= table
->v
[i
];
5346 table
->mem
->free_fcn(p
);
5350 table
->usedLim
= table
->size
/ 2;
5354 static void FASTCALL
5355 hashTableDestroy(HASH_TABLE
*table
)
5358 for (i
= 0; i
< table
->size
; i
++) {
5359 NAMED
*p
= table
->v
[i
];
5361 table
->mem
->free_fcn(p
);
5364 table
->mem
->free_fcn(table
->v
);
5367 static void FASTCALL
5368 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5377 static void FASTCALL
5378 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5381 iter
->end
= iter
->p
+ table
->size
;
5384 static NAMED
* FASTCALL
5385 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5387 while (iter
->p
!= iter
->end
) {
5388 NAMED
*tem
= *(iter
->p
)++;
5395 static void FASTCALL
5396 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5398 pool
->blocks
= NULL
;
5399 pool
->freeBlocks
= NULL
;
5406 static void FASTCALL
5407 poolClear(STRING_POOL
*pool
)
5409 if (!pool
->freeBlocks
)
5410 pool
->freeBlocks
= pool
->blocks
;
5412 BLOCK
*p
= pool
->blocks
;
5414 BLOCK
*tem
= p
->next
;
5415 p
->next
= pool
->freeBlocks
;
5416 pool
->freeBlocks
= p
;
5420 pool
->blocks
= NULL
;
5426 static void FASTCALL
5427 poolDestroy(STRING_POOL
*pool
)
5429 BLOCK
*p
= pool
->blocks
;
5431 BLOCK
*tem
= p
->next
;
5432 pool
->mem
->free_fcn(p
);
5435 p
= pool
->freeBlocks
;
5437 BLOCK
*tem
= p
->next
;
5438 pool
->mem
->free_fcn(p
);
5444 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5445 const char *ptr
, const char *end
)
5447 if (!pool
->ptr
&& !poolGrow(pool
))
5450 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5453 if (!poolGrow(pool
))
5459 static const XML_Char
* FASTCALL
5460 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5463 if (!poolAppendChar(pool
, *s
))
5471 static const XML_Char
*
5472 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5474 if (!pool
->ptr
&& !poolGrow(pool
))
5476 for (; n
> 0; --n
, s
++) {
5477 if (!poolAppendChar(pool
, *s
))
5485 static const XML_Char
* FASTCALL
5486 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5489 if (!poolAppendChar(pool
, *s
))
5497 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5498 const char *ptr
, const char *end
)
5500 if (!poolAppend(pool
, enc
, ptr
, end
))
5502 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5508 static XML_Bool FASTCALL
5509 poolGrow(STRING_POOL
*pool
)
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
;
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
;
5534 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5535 int blockSize
= (pool
->end
- pool
->start
)*2;
5536 pool
->blocks
= (BLOCK
*)
5537 pool
->mem
->realloc_fcn(pool
->blocks
,
5539 + blockSize
* sizeof(XML_Char
)));
5540 if (pool
->blocks
== NULL
)
5542 pool
->blocks
->size
= blockSize
;
5543 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5544 pool
->start
= pool
->blocks
->s
;
5545 pool
->end
= pool
->start
+ blockSize
;
5549 int blockSize
= pool
->end
- pool
->start
;
5550 if (blockSize
< INIT_BLOCK_SIZE
)
5551 blockSize
= INIT_BLOCK_SIZE
;
5554 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5555 + blockSize
* sizeof(XML_Char
));
5558 tem
->size
= blockSize
;
5559 tem
->next
= pool
->blocks
;
5561 if (pool
->ptr
!= pool
->start
)
5562 memcpy(tem
->s
, pool
->start
,
5563 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5564 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5565 pool
->start
= tem
->s
;
5566 pool
->end
= tem
->s
+ blockSize
;
5572 nextScaffoldPart(XML_Parser parser
)
5574 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5575 CONTENT_SCAFFOLD
* me
;
5578 if (!dtd
->scaffIndex
) {
5579 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
5580 if (!dtd
->scaffIndex
)
5582 dtd
->scaffIndex
[0] = 0;
5585 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
5586 CONTENT_SCAFFOLD
*temp
;
5587 if (dtd
->scaffold
) {
5588 temp
= (CONTENT_SCAFFOLD
*)
5589 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5592 dtd
->scaffSize
*= 2;
5595 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
5596 * sizeof(CONTENT_SCAFFOLD
));
5599 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5601 dtd
->scaffold
= temp
;
5603 next
= dtd
->scaffCount
++;
5604 me
= &dtd
->scaffold
[next
];
5605 if (dtd
->scaffLevel
) {
5606 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
5607 if (parent
->lastchild
) {
5608 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
5610 if (!parent
->childcnt
)
5611 parent
->firstchild
= next
;
5612 parent
->lastchild
= next
;
5615 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5620 build_node(XML_Parser parser
,
5623 XML_Content
**contpos
,
5626 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5627 dest
->type
= dtd
->scaffold
[src_node
].type
;
5628 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
5629 if (dest
->type
== XML_CTYPE_NAME
) {
5630 const XML_Char
*src
;
5631 dest
->name
= *strpos
;
5632 src
= dtd
->scaffold
[src_node
].name
;
5634 *(*strpos
)++ = *src
;
5639 dest
->numchildren
= 0;
5640 dest
->children
= NULL
;
5645 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
5646 dest
->children
= *contpos
;
5647 *contpos
+= dest
->numchildren
;
5648 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
5649 i
< dest
->numchildren
;
5650 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
5651 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5657 static XML_Content
*
5658 build_model (XML_Parser parser
)
5660 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5664 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
5665 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
5667 ret
= (XML_Content
*)MALLOC(allocsize
);
5671 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
5674 build_node(parser
, 0, ret
, &cpos
, &str
);
5678 static ELEMENT_TYPE
*
5679 getElementType(XML_Parser parser
,
5680 const ENCODING
*enc
,
5684 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5685 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
5690 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5693 if (ret
->name
!= name
)
5694 poolDiscard(&dtd
->pool
);
5696 poolFinish(&dtd
->pool
);
5697 if (!setElementTypePrefix(parser
, ret
))