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"
15 #include "os2config.h"
18 #elif defined(__MSDOS__)
20 #include "dosconfig.h"
23 #elif defined(MACOS_CLASSIC)
25 #include "macconfig.h"
30 #include "expat_config.h"
33 #define XMLPARSEAPI(type) type __cdecl
41 #endif /* ndef COMPILED_FROM_DSP */
44 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
45 #define XmlConvert XmlUtf16Convert
46 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
47 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
48 #define XmlEncode XmlUtf16Encode
49 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
50 typedef unsigned short ICHAR
;
52 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
53 #define XmlConvert XmlUtf8Convert
54 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
55 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
56 #define XmlEncode XmlUtf8Encode
57 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
64 #define XmlInitEncodingNS XmlInitEncoding
65 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
66 #undef XmlGetInternalEncodingNS
67 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
68 #define XmlParseXmlDeclNS XmlParseXmlDecl
74 #ifdef XML_UNICODE_WCHAR_T
75 #define XML_T(x) (const wchar_t)x
76 #define XML_L(x) L ## x
78 #define XML_T(x) (const unsigned short)x
89 /* Round up n to be a multiple of sz, where sz is a power of 2. */
90 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
92 /* Handle the case where memmove() doesn't exist. */
95 #define memmove(d,s,l) bcopy((s),(d),(l))
97 #error memmove does not exist on this platform, nor is a substitute available
98 #endif /* HAVE_BCOPY */
99 #endif /* HAVE_MEMMOVE */
101 #include "internal.h"
105 typedef const XML_Char
*KEY
;
116 const XML_Memory_Handling_Suite
*mem
;
124 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
125 #define INIT_DATA_BUF_SIZE 1024
126 #define INIT_ATTS_SIZE 16
127 #define INIT_BLOCK_SIZE 1024
128 #define INIT_BUFFER_SIZE 1024
130 #define EXPAND_SPARE 24
132 typedef struct binding
{
133 struct prefix
*prefix
;
134 struct binding
*nextTagBinding
;
135 struct binding
*prevPrefixBinding
;
136 const struct attribute_id
*attId
;
142 typedef struct prefix
{
143 const XML_Char
*name
;
149 const XML_Char
*localPart
;
150 const XML_Char
*prefix
;
156 /* TAG represents an open element.
157 The name of the element is stored in both the document and API
158 encodings. The memory buffer 'buf' is a separately-allocated
159 memory area which stores the name. During the XML_Parse()/
160 XMLParseBuffer() when the element is open, the memory for the 'raw'
161 version of the name (in the document encoding) is shared with the
162 document buffer. If the element is open across calls to
163 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
164 contain the 'raw' name as well.
166 A parser re-uses these structures, maintaining a list of allocated
167 TAG objects in a free list.
170 struct tag
*parent
; /* parent of this element */
171 const char *rawName
; /* tagName in the original encoding */
173 TAG_NAME name
; /* tagName in the API encoding */
174 char *buf
; /* buffer for name components */
175 char *bufEnd
; /* end of the buffer */
180 const XML_Char
*name
;
181 const XML_Char
*textPtr
;
183 const XML_Char
*systemId
;
184 const XML_Char
*base
;
185 const XML_Char
*publicId
;
186 const XML_Char
*notation
;
189 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
193 enum XML_Content_Type type
;
194 enum XML_Content_Quant quant
;
195 const XML_Char
* name
;
202 #define INIT_SCAFFOLD_ELEMENTS 32
204 typedef struct block
{
216 const XML_Memory_Handling_Suite
*mem
;
219 /* The XML_Char before the name is used to determine whether
220 an attribute has been specified. */
221 typedef struct attribute_id
{
224 XML_Bool maybeTokenized
;
229 const ATTRIBUTE_ID
*id
;
231 const XML_Char
*value
;
235 const XML_Char
*name
;
237 const ATTRIBUTE_ID
*idAtt
;
239 int allocDefaultAtts
;
240 DEFAULT_ATTRIBUTE
*defaultAtts
;
244 HASH_TABLE generalEntities
;
245 HASH_TABLE elementTypes
;
246 HASH_TABLE attributeIds
;
249 STRING_POOL entityValuePool
;
250 /* false once a parameter entity reference has been skipped */
251 XML_Bool keepProcessing
;
252 /* true once an internal or external PE reference has been encountered;
253 this includes the reference to an external subset */
254 XML_Bool hasParamEntityRefs
;
257 /* indicates if external PE has been read */
258 XML_Bool paramEntityRead
;
259 HASH_TABLE paramEntities
;
261 PREFIX defaultPrefix
;
262 /* === scaffolding for building content model === */
264 CONTENT_SCAFFOLD
*scaffold
;
265 unsigned contentStringLen
;
272 typedef struct open_internal_entity
{
273 const char *internalEventPtr
;
274 const char *internalEventEndPtr
;
275 struct open_internal_entity
*next
;
277 } OPEN_INTERNAL_ENTITY
;
279 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
282 const char **endPtr
);
284 static Processor prologProcessor
;
285 static Processor prologInitProcessor
;
286 static Processor contentProcessor
;
287 static Processor cdataSectionProcessor
;
289 static Processor ignoreSectionProcessor
;
290 static Processor externalParEntProcessor
;
291 static Processor externalParEntInitProcessor
;
292 static Processor entityValueProcessor
;
293 static Processor entityValueInitProcessor
;
295 static Processor epilogProcessor
;
296 static Processor errorProcessor
;
297 static Processor externalEntityInitProcessor
;
298 static Processor externalEntityInitProcessor2
;
299 static Processor externalEntityInitProcessor3
;
300 static Processor externalEntityContentProcessor
;
302 static enum XML_Error
303 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
304 static enum XML_Error
305 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
306 const char *, const char *);
307 static enum XML_Error
308 initializeEncoding(XML_Parser parser
);
309 static enum XML_Error
310 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
311 const char *end
, int tok
, const char *next
, const char **nextPtr
);
312 static enum XML_Error
313 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
314 static enum XML_Error
315 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
316 const char *start
, const char *end
, const char **endPtr
);
317 static enum XML_Error
318 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
319 const char *end
, const char **nextPtr
);
321 static enum XML_Error
322 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
323 const char *end
, const char **nextPtr
);
326 static enum XML_Error
327 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
328 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
329 static enum XML_Error
330 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
331 const XML_Char
*uri
, BINDING
**bindingsPtr
);
333 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
334 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
336 static enum XML_Error
337 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
338 const char *, const char *, STRING_POOL
*);
339 static enum XML_Error
340 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
341 const char *, const char *, STRING_POOL
*);
342 static ATTRIBUTE_ID
*
343 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
346 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
347 static enum XML_Error
348 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
351 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
352 const char *start
, const char *end
);
354 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
357 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
360 static const XML_Char
* getContext(XML_Parser parser
);
362 setContext(XML_Parser parser
, const XML_Char
*context
);
364 static void FASTCALL
normalizePublicId(XML_Char
*s
);
366 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
367 /* do not call if parentParser != NULL */
368 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
370 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
372 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
374 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
377 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
379 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
380 static void FASTCALL
hashTableClear(HASH_TABLE
*);
381 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
383 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
384 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
387 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
388 static void FASTCALL
poolClear(STRING_POOL
*);
389 static void FASTCALL
poolDestroy(STRING_POOL
*);
391 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
392 const char *ptr
, const char *end
);
394 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
395 const char *ptr
, const char *end
);
396 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
397 static const XML_Char
* FASTCALL
398 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
399 static const XML_Char
*
400 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
401 static const XML_Char
* FASTCALL
402 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
404 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
405 static XML_Content
* build_model(XML_Parser parser
);
406 static ELEMENT_TYPE
*
407 getElementType(XML_Parser parser
, const ENCODING
*enc
,
408 const char *ptr
, const char *end
);
411 parserCreate(const XML_Char
*encodingName
,
412 const XML_Memory_Handling_Suite
*memsuite
,
413 const XML_Char
*nameSep
,
416 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
418 #define poolStart(pool) ((pool)->start)
419 #define poolEnd(pool) ((pool)->ptr)
420 #define poolLength(pool) ((pool)->ptr - (pool)->start)
421 #define poolChop(pool) ((void)--(pool->ptr))
422 #define poolLastChar(pool) (((pool)->ptr)[-1])
423 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
424 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
425 #define poolAppendChar(pool, c) \
426 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
428 : ((*((pool)->ptr)++ = c), 1))
430 struct XML_ParserStruct
{
431 /* The first member must be userData so that the XML_GetUserData
436 const XML_Memory_Handling_Suite m_mem
;
437 /* first character to be parsed */
438 const char *m_bufferPtr
;
439 /* past last character to be parsed */
441 /* allocated end of buffer */
442 const char *m_bufferLim
;
443 long m_parseEndByteIndex
;
444 const char *m_parseEndPtr
;
446 XML_Char
*m_dataBufEnd
;
447 XML_StartElementHandler m_startElementHandler
;
448 XML_EndElementHandler m_endElementHandler
;
449 XML_CharacterDataHandler m_characterDataHandler
;
450 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
451 XML_CommentHandler m_commentHandler
;
452 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
453 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
454 XML_DefaultHandler m_defaultHandler
;
455 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
456 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
457 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
458 XML_NotationDeclHandler m_notationDeclHandler
;
459 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
460 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
461 XML_NotStandaloneHandler m_notStandaloneHandler
;
462 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
463 XML_Parser m_externalEntityRefHandlerArg
;
464 XML_SkippedEntityHandler m_skippedEntityHandler
;
465 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
466 XML_ElementDeclHandler m_elementDeclHandler
;
467 XML_AttlistDeclHandler m_attlistDeclHandler
;
468 XML_EntityDeclHandler m_entityDeclHandler
;
469 XML_XmlDeclHandler m_xmlDeclHandler
;
470 const ENCODING
*m_encoding
;
471 INIT_ENCODING m_initEncoding
;
472 const ENCODING
*m_internalEncoding
;
473 const XML_Char
*m_protocolEncodingName
;
475 XML_Bool m_ns_triplets
;
476 void *m_unknownEncodingMem
;
477 void *m_unknownEncodingData
;
478 void *m_unknownEncodingHandlerData
;
479 void (*m_unknownEncodingRelease
)(void *);
480 PROLOG_STATE m_prologState
;
481 Processor
*m_processor
;
482 enum XML_Error m_errorCode
;
483 const char *m_eventPtr
;
484 const char *m_eventEndPtr
;
485 const char *m_positionPtr
;
486 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
487 XML_Bool m_defaultExpandInternalEntities
;
489 ENTITY
*m_declEntity
;
490 const XML_Char
*m_doctypeName
;
491 const XML_Char
*m_doctypeSysid
;
492 const XML_Char
*m_doctypePubid
;
493 const XML_Char
*m_declAttributeType
;
494 const XML_Char
*m_declNotationName
;
495 const XML_Char
*m_declNotationPublicId
;
496 ELEMENT_TYPE
*m_declElementType
;
497 ATTRIBUTE_ID
*m_declAttributeId
;
498 XML_Bool m_declAttributeIsCdata
;
499 XML_Bool m_declAttributeIsId
;
501 const XML_Char
*m_curBase
;
504 BINDING
*m_inheritedBindings
;
505 BINDING
*m_freeBindingList
;
507 int m_nSpecifiedAtts
;
511 STRING_POOL m_tempPool
;
512 STRING_POOL m_temp2Pool
;
513 char *m_groupConnector
;
514 unsigned m_groupSize
;
515 XML_Char m_namespaceSeparator
;
516 XML_Parser m_parentParser
;
518 XML_Bool m_isParamEntity
;
519 XML_Bool m_useForeignDTD
;
520 enum XML_ParamEntityParsing m_paramEntityParsing
;
524 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
525 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
526 #define FREE(p) (parser->m_mem.free_fcn((p)))
528 #define userData (parser->m_userData)
529 #define handlerArg (parser->m_handlerArg)
530 #define startElementHandler (parser->m_startElementHandler)
531 #define endElementHandler (parser->m_endElementHandler)
532 #define characterDataHandler (parser->m_characterDataHandler)
533 #define processingInstructionHandler \
534 (parser->m_processingInstructionHandler)
535 #define commentHandler (parser->m_commentHandler)
536 #define startCdataSectionHandler \
537 (parser->m_startCdataSectionHandler)
538 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
539 #define defaultHandler (parser->m_defaultHandler)
540 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
541 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
542 #define unparsedEntityDeclHandler \
543 (parser->m_unparsedEntityDeclHandler)
544 #define notationDeclHandler (parser->m_notationDeclHandler)
545 #define startNamespaceDeclHandler \
546 (parser->m_startNamespaceDeclHandler)
547 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
548 #define notStandaloneHandler (parser->m_notStandaloneHandler)
549 #define externalEntityRefHandler \
550 (parser->m_externalEntityRefHandler)
551 #define externalEntityRefHandlerArg \
552 (parser->m_externalEntityRefHandlerArg)
553 #define internalEntityRefHandler \
554 (parser->m_internalEntityRefHandler)
555 #define skippedEntityHandler (parser->m_skippedEntityHandler)
556 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
557 #define elementDeclHandler (parser->m_elementDeclHandler)
558 #define attlistDeclHandler (parser->m_attlistDeclHandler)
559 #define entityDeclHandler (parser->m_entityDeclHandler)
560 #define xmlDeclHandler (parser->m_xmlDeclHandler)
561 #define encoding (parser->m_encoding)
562 #define initEncoding (parser->m_initEncoding)
563 #define internalEncoding (parser->m_internalEncoding)
564 #define unknownEncodingMem (parser->m_unknownEncodingMem)
565 #define unknownEncodingData (parser->m_unknownEncodingData)
566 #define unknownEncodingHandlerData \
567 (parser->m_unknownEncodingHandlerData)
568 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
569 #define protocolEncodingName (parser->m_protocolEncodingName)
570 #define ns (parser->m_ns)
571 #define ns_triplets (parser->m_ns_triplets)
572 #define prologState (parser->m_prologState)
573 #define processor (parser->m_processor)
574 #define errorCode (parser->m_errorCode)
575 #define eventPtr (parser->m_eventPtr)
576 #define eventEndPtr (parser->m_eventEndPtr)
577 #define positionPtr (parser->m_positionPtr)
578 #define position (parser->m_position)
579 #define openInternalEntities (parser->m_openInternalEntities)
580 #define defaultExpandInternalEntities \
581 (parser->m_defaultExpandInternalEntities)
582 #define tagLevel (parser->m_tagLevel)
583 #define buffer (parser->m_buffer)
584 #define bufferPtr (parser->m_bufferPtr)
585 #define bufferEnd (parser->m_bufferEnd)
586 #define parseEndByteIndex (parser->m_parseEndByteIndex)
587 #define parseEndPtr (parser->m_parseEndPtr)
588 #define bufferLim (parser->m_bufferLim)
589 #define dataBuf (parser->m_dataBuf)
590 #define dataBufEnd (parser->m_dataBufEnd)
591 #define _dtd (parser->m_dtd)
592 #define curBase (parser->m_curBase)
593 #define declEntity (parser->m_declEntity)
594 #define doctypeName (parser->m_doctypeName)
595 #define doctypeSysid (parser->m_doctypeSysid)
596 #define doctypePubid (parser->m_doctypePubid)
597 #define declAttributeType (parser->m_declAttributeType)
598 #define declNotationName (parser->m_declNotationName)
599 #define declNotationPublicId (parser->m_declNotationPublicId)
600 #define declElementType (parser->m_declElementType)
601 #define declAttributeId (parser->m_declAttributeId)
602 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
603 #define declAttributeIsId (parser->m_declAttributeIsId)
604 #define freeTagList (parser->m_freeTagList)
605 #define freeBindingList (parser->m_freeBindingList)
606 #define inheritedBindings (parser->m_inheritedBindings)
607 #define tagStack (parser->m_tagStack)
608 #define atts (parser->m_atts)
609 #define attsSize (parser->m_attsSize)
610 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
611 #define idAttIndex (parser->m_idAttIndex)
612 #define tempPool (parser->m_tempPool)
613 #define temp2Pool (parser->m_temp2Pool)
614 #define groupConnector (parser->m_groupConnector)
615 #define groupSize (parser->m_groupSize)
616 #define namespaceSeparator (parser->m_namespaceSeparator)
617 #define parentParser (parser->m_parentParser)
619 #define isParamEntity (parser->m_isParamEntity)
620 #define useForeignDTD (parser->m_useForeignDTD)
621 #define paramEntityParsing (parser->m_paramEntityParsing)
629 (processor != externalParEntInitProcessor) \
631 (processor != externalEntityInitProcessor)) \
633 (processor != prologInitProcessor))
636 XML_ParserCreate(const XML_Char
*encodingName
)
638 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
642 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
646 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
649 static const XML_Char implicitContext
[] = {
650 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
651 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
652 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
653 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
657 XML_ParserCreate_MM(const XML_Char
*encodingName
,
658 const XML_Memory_Handling_Suite
*memsuite
,
659 const XML_Char
*nameSep
)
661 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
662 if (parser
!= NULL
&& ns
) {
663 /* implicit context only set for root parser, since child
664 parsers (i.e. external entity parsers) will inherit it
666 if (!setContext(parser
, implicitContext
)) {
667 XML_ParserFree(parser
);
675 parserCreate(const XML_Char
*encodingName
,
676 const XML_Memory_Handling_Suite
*memsuite
,
677 const XML_Char
*nameSep
,
683 XML_Memory_Handling_Suite
*mtemp
;
684 parser
= (XML_Parser
)
685 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
686 if (parser
!= NULL
) {
687 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
688 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
689 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
690 mtemp
->free_fcn
= memsuite
->free_fcn
;
694 XML_Memory_Handling_Suite
*mtemp
;
695 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
696 if (parser
!= NULL
) {
697 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
698 mtemp
->malloc_fcn
= malloc
;
699 mtemp
->realloc_fcn
= realloc
;
700 mtemp
->free_fcn
= free
;
710 attsSize
= INIT_ATTS_SIZE
;
711 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
716 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
717 if (dataBuf
== NULL
) {
722 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
727 _dtd
= dtdCreate(&parser
->m_mem
);
736 freeBindingList
= NULL
;
740 groupConnector
= NULL
;
742 unknownEncodingHandler
= NULL
;
743 unknownEncodingHandlerData
= NULL
;
745 namespaceSeparator
= '!';
747 ns_triplets
= XML_FALSE
;
749 poolInit(&tempPool
, &(parser
->m_mem
));
750 poolInit(&temp2Pool
, &(parser
->m_mem
));
751 parserInit(parser
, encodingName
);
753 if (encodingName
&& !protocolEncodingName
) {
754 XML_ParserFree(parser
);
760 internalEncoding
= XmlGetInternalEncodingNS();
761 namespaceSeparator
= *nameSep
;
764 internalEncoding
= XmlGetInternalEncoding();
771 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
773 processor
= prologInitProcessor
;
774 XmlPrologStateInit(&prologState
);
775 protocolEncodingName
= (encodingName
!= NULL
776 ? poolCopyString(&tempPool
, encodingName
)
779 XmlInitEncoding(&initEncoding
, &encoding
, 0);
782 startElementHandler
= NULL
;
783 endElementHandler
= NULL
;
784 characterDataHandler
= NULL
;
785 processingInstructionHandler
= NULL
;
786 commentHandler
= NULL
;
787 startCdataSectionHandler
= NULL
;
788 endCdataSectionHandler
= NULL
;
789 defaultHandler
= NULL
;
790 startDoctypeDeclHandler
= NULL
;
791 endDoctypeDeclHandler
= NULL
;
792 unparsedEntityDeclHandler
= NULL
;
793 notationDeclHandler
= NULL
;
794 startNamespaceDeclHandler
= NULL
;
795 endNamespaceDeclHandler
= NULL
;
796 notStandaloneHandler
= NULL
;
797 externalEntityRefHandler
= NULL
;
798 externalEntityRefHandlerArg
= parser
;
799 skippedEntityHandler
= NULL
;
800 elementDeclHandler
= NULL
;
801 attlistDeclHandler
= NULL
;
802 entityDeclHandler
= NULL
;
803 xmlDeclHandler
= NULL
;
806 parseEndByteIndex
= 0;
808 declElementType
= NULL
;
809 declAttributeId
= NULL
;
814 declAttributeType
= NULL
;
815 declNotationName
= NULL
;
816 declNotationPublicId
= NULL
;
817 declAttributeIsCdata
= XML_FALSE
;
818 declAttributeIsId
= XML_FALSE
;
819 memset(&position
, 0, sizeof(POSITION
));
820 errorCode
= XML_ERROR_NONE
;
824 openInternalEntities
= 0;
825 defaultExpandInternalEntities
= XML_TRUE
;
828 inheritedBindings
= NULL
;
830 unknownEncodingMem
= NULL
;
831 unknownEncodingRelease
= NULL
;
832 unknownEncodingData
= NULL
;
835 isParamEntity
= XML_FALSE
;
836 useForeignDTD
= XML_FALSE
;
837 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
841 /* moves list of bindings to freeBindingList */
843 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
846 BINDING
*b
= bindings
;
847 bindings
= bindings
->nextTagBinding
;
848 b
->nextTagBinding
= freeBindingList
;
854 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
859 /* move tagStack to freeTagList */
864 tag
->parent
= freeTagList
;
865 moveToFreeBindingList(parser
, tag
->bindings
);
866 tag
->bindings
= NULL
;
869 moveToFreeBindingList(parser
, inheritedBindings
);
870 if (unknownEncodingMem
)
871 FREE(unknownEncodingMem
);
872 if (unknownEncodingRelease
)
873 unknownEncodingRelease(unknownEncodingData
);
874 poolClear(&tempPool
);
875 poolClear(&temp2Pool
);
876 parserInit(parser
, encodingName
);
877 dtdReset(_dtd
, &parser
->m_mem
);
878 return setContext(parser
, implicitContext
);
882 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
884 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
885 XXX There's no way for the caller to determine which of the
886 XXX possible error cases caused the XML_STATUS_ERROR return.
889 return XML_STATUS_ERROR
;
890 if (encodingName
== NULL
)
891 protocolEncodingName
= NULL
;
893 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
894 if (!protocolEncodingName
)
895 return XML_STATUS_ERROR
;
897 return XML_STATUS_OK
;
901 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
902 const XML_Char
*context
,
903 const XML_Char
*encodingName
)
905 XML_Parser parser
= oldParser
;
908 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
909 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
910 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
911 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
912 = processingInstructionHandler
;
913 XML_CommentHandler oldCommentHandler
= commentHandler
;
914 XML_StartCdataSectionHandler oldStartCdataSectionHandler
915 = startCdataSectionHandler
;
916 XML_EndCdataSectionHandler oldEndCdataSectionHandler
917 = endCdataSectionHandler
;
918 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
919 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
920 = unparsedEntityDeclHandler
;
921 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
922 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
923 = startNamespaceDeclHandler
;
924 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
925 = endNamespaceDeclHandler
;
926 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
927 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
928 = externalEntityRefHandler
;
929 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
930 XML_UnknownEncodingHandler oldUnknownEncodingHandler
931 = unknownEncodingHandler
;
932 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
933 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
934 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
935 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
936 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
938 void *oldUserData
= userData
;
939 void *oldHandlerArg
= handlerArg
;
940 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
941 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
943 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
944 int oldInEntityValue
= prologState
.inEntityValue
;
946 XML_Bool oldns_triplets
= ns_triplets
;
953 /* Note that the magical uses of the pre-processor to make field
954 access look more like C++ require that `parser' be overwritten
955 here. This makes this function more painful to follow than it
960 *tmp
= namespaceSeparator
;
961 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
964 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
970 startElementHandler
= oldStartElementHandler
;
971 endElementHandler
= oldEndElementHandler
;
972 characterDataHandler
= oldCharacterDataHandler
;
973 processingInstructionHandler
= oldProcessingInstructionHandler
;
974 commentHandler
= oldCommentHandler
;
975 startCdataSectionHandler
= oldStartCdataSectionHandler
;
976 endCdataSectionHandler
= oldEndCdataSectionHandler
;
977 defaultHandler
= oldDefaultHandler
;
978 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
979 notationDeclHandler
= oldNotationDeclHandler
;
980 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
981 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
982 notStandaloneHandler
= oldNotStandaloneHandler
;
983 externalEntityRefHandler
= oldExternalEntityRefHandler
;
984 skippedEntityHandler
= oldSkippedEntityHandler
;
985 unknownEncodingHandler
= oldUnknownEncodingHandler
;
986 elementDeclHandler
= oldElementDeclHandler
;
987 attlistDeclHandler
= oldAttlistDeclHandler
;
988 entityDeclHandler
= oldEntityDeclHandler
;
989 xmlDeclHandler
= oldXmlDeclHandler
;
990 declElementType
= oldDeclElementType
;
991 userData
= oldUserData
;
992 if (oldUserData
== oldHandlerArg
)
993 handlerArg
= userData
;
996 if (oldExternalEntityRefHandlerArg
!= oldParser
)
997 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
998 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
999 ns_triplets
= oldns_triplets
;
1000 parentParser
= oldParser
;
1002 paramEntityParsing
= oldParamEntityParsing
;
1003 prologState
.inEntityValue
= oldInEntityValue
;
1005 #endif /* XML_DTD */
1006 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1007 || !setContext(parser
, context
)) {
1008 XML_ParserFree(parser
);
1011 processor
= externalEntityInitProcessor
;
1015 /* The DTD instance referenced by _dtd is shared between the document's
1016 root parser and external PE parsers, therefore one does not need to
1017 call setContext. In addition, one also *must* not call setContext,
1018 because this would overwrite existing prefix->binding pointers in
1019 _dtd with ones that get destroyed with the external PE parser.
1020 This would leave those prefixes with dangling pointers.
1022 isParamEntity
= XML_TRUE
;
1023 XmlPrologStateInitExternalEntity(&prologState
);
1024 processor
= externalParEntInitProcessor
;
1026 #endif /* XML_DTD */
1030 static void FASTCALL
1031 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1034 BINDING
*b
= bindings
;
1037 bindings
= b
->nextTagBinding
;
1044 XML_ParserFree(XML_Parser parser
)
1048 if (tagStack
== NULL
) {
1049 if (freeTagList
== NULL
)
1051 tagStack
= freeTagList
;
1055 tagStack
= tagStack
->parent
;
1057 destroyBindings(p
->bindings
, parser
);
1060 destroyBindings(freeBindingList
, parser
);
1061 destroyBindings(inheritedBindings
, parser
);
1062 poolDestroy(&tempPool
);
1063 poolDestroy(&temp2Pool
);
1065 /* external parameter entity parsers share the DTD structure
1066 parser->m_dtd with the root parser, so we must not destroy it
1068 if (!isParamEntity
&& _dtd
)
1071 #endif /* XML_DTD */
1072 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1075 FREE(groupConnector
);
1079 if (unknownEncodingMem
)
1080 FREE(unknownEncodingMem
);
1081 if (unknownEncodingRelease
)
1082 unknownEncodingRelease(unknownEncodingData
);
1087 XML_UseParserAsHandlerArg(XML_Parser parser
)
1089 handlerArg
= parser
;
1093 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1096 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1098 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1099 useForeignDTD
= useDTD
;
1100 return XML_ERROR_NONE
;
1102 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1107 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1109 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1112 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1116 XML_SetUserData(XML_Parser parser
, void *p
)
1118 if (handlerArg
== userData
)
1119 handlerArg
= userData
= p
;
1125 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1128 p
= poolCopyString(&_dtd
->pool
, p
);
1130 return XML_STATUS_ERROR
;
1135 return XML_STATUS_OK
;
1139 XML_GetBase(XML_Parser parser
)
1145 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1147 return nSpecifiedAtts
;
1151 XML_GetIdAttributeIndex(XML_Parser parser
)
1157 XML_SetElementHandler(XML_Parser parser
,
1158 XML_StartElementHandler start
,
1159 XML_EndElementHandler end
)
1161 startElementHandler
= start
;
1162 endElementHandler
= end
;
1166 XML_SetStartElementHandler(XML_Parser parser
,
1167 XML_StartElementHandler start
) {
1168 startElementHandler
= start
;
1172 XML_SetEndElementHandler(XML_Parser parser
,
1173 XML_EndElementHandler end
) {
1174 endElementHandler
= end
;
1178 XML_SetCharacterDataHandler(XML_Parser parser
,
1179 XML_CharacterDataHandler handler
)
1181 characterDataHandler
= handler
;
1185 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1186 XML_ProcessingInstructionHandler handler
)
1188 processingInstructionHandler
= handler
;
1192 XML_SetCommentHandler(XML_Parser parser
,
1193 XML_CommentHandler handler
)
1195 commentHandler
= handler
;
1199 XML_SetCdataSectionHandler(XML_Parser parser
,
1200 XML_StartCdataSectionHandler start
,
1201 XML_EndCdataSectionHandler end
)
1203 startCdataSectionHandler
= start
;
1204 endCdataSectionHandler
= end
;
1208 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1209 XML_StartCdataSectionHandler start
) {
1210 startCdataSectionHandler
= start
;
1214 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1215 XML_EndCdataSectionHandler end
) {
1216 endCdataSectionHandler
= end
;
1220 XML_SetDefaultHandler(XML_Parser parser
,
1221 XML_DefaultHandler handler
)
1223 defaultHandler
= handler
;
1224 defaultExpandInternalEntities
= XML_FALSE
;
1228 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1229 XML_DefaultHandler handler
)
1231 defaultHandler
= handler
;
1232 defaultExpandInternalEntities
= XML_TRUE
;
1236 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1237 XML_StartDoctypeDeclHandler start
,
1238 XML_EndDoctypeDeclHandler end
)
1240 startDoctypeDeclHandler
= start
;
1241 endDoctypeDeclHandler
= end
;
1245 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1246 XML_StartDoctypeDeclHandler start
) {
1247 startDoctypeDeclHandler
= start
;
1251 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1252 XML_EndDoctypeDeclHandler end
) {
1253 endDoctypeDeclHandler
= end
;
1257 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1258 XML_UnparsedEntityDeclHandler handler
)
1260 unparsedEntityDeclHandler
= handler
;
1264 XML_SetNotationDeclHandler(XML_Parser parser
,
1265 XML_NotationDeclHandler handler
)
1267 notationDeclHandler
= handler
;
1271 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1272 XML_StartNamespaceDeclHandler start
,
1273 XML_EndNamespaceDeclHandler end
)
1275 startNamespaceDeclHandler
= start
;
1276 endNamespaceDeclHandler
= end
;
1280 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1281 XML_StartNamespaceDeclHandler start
) {
1282 startNamespaceDeclHandler
= start
;
1286 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1287 XML_EndNamespaceDeclHandler end
) {
1288 endNamespaceDeclHandler
= end
;
1292 XML_SetNotStandaloneHandler(XML_Parser parser
,
1293 XML_NotStandaloneHandler handler
)
1295 notStandaloneHandler
= handler
;
1299 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1300 XML_ExternalEntityRefHandler handler
)
1302 externalEntityRefHandler
= handler
;
1306 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1309 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1311 externalEntityRefHandlerArg
= parser
;
1315 XML_SetSkippedEntityHandler(XML_Parser parser
,
1316 XML_SkippedEntityHandler handler
)
1318 skippedEntityHandler
= handler
;
1322 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1323 XML_UnknownEncodingHandler handler
,
1326 unknownEncodingHandler
= handler
;
1327 unknownEncodingHandlerData
= data
;
1331 XML_SetElementDeclHandler(XML_Parser parser
,
1332 XML_ElementDeclHandler eldecl
)
1334 elementDeclHandler
= eldecl
;
1338 XML_SetAttlistDeclHandler(XML_Parser parser
,
1339 XML_AttlistDeclHandler attdecl
)
1341 attlistDeclHandler
= attdecl
;
1345 XML_SetEntityDeclHandler(XML_Parser parser
,
1346 XML_EntityDeclHandler handler
)
1348 entityDeclHandler
= handler
;
1352 XML_SetXmlDeclHandler(XML_Parser parser
,
1353 XML_XmlDeclHandler handler
) {
1354 xmlDeclHandler
= handler
;
1358 XML_SetParamEntityParsing(XML_Parser parser
,
1359 enum XML_ParamEntityParsing peParsing
)
1361 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1365 paramEntityParsing
= peParsing
;
1368 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1373 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1377 return XML_STATUS_OK
;
1378 positionPtr
= bufferPtr
;
1379 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1380 if (errorCode
== XML_ERROR_NONE
)
1381 return XML_STATUS_OK
;
1382 eventEndPtr
= eventPtr
;
1383 processor
= errorProcessor
;
1384 return XML_STATUS_ERROR
;
1386 #ifndef XML_CONTEXT_BYTES
1387 else if (bufferPtr
== bufferEnd
) {
1390 parseEndByteIndex
+= len
;
1393 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1394 if (errorCode
== XML_ERROR_NONE
)
1395 return XML_STATUS_OK
;
1396 eventEndPtr
= eventPtr
;
1397 processor
= errorProcessor
;
1398 return XML_STATUS_ERROR
;
1400 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1401 if (errorCode
!= XML_ERROR_NONE
) {
1402 eventEndPtr
= eventPtr
;
1403 processor
= errorProcessor
;
1404 return XML_STATUS_ERROR
;
1406 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1408 nLeftOver
= s
+ len
- end
;
1410 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1411 /* FIXME avoid integer overflow */
1413 temp
= (buffer
== NULL
1414 ? (char *)MALLOC(len
* 2)
1415 : (char *)REALLOC(buffer
, len
* 2));
1417 errorCode
= XML_ERROR_NO_MEMORY
;
1418 return XML_STATUS_ERROR
;
1422 errorCode
= XML_ERROR_NO_MEMORY
;
1423 eventPtr
= eventEndPtr
= NULL
;
1424 processor
= errorProcessor
;
1425 return XML_STATUS_ERROR
;
1427 bufferLim
= buffer
+ len
* 2;
1429 memcpy(buffer
, end
, nLeftOver
);
1431 bufferEnd
= buffer
+ nLeftOver
;
1433 return XML_STATUS_OK
;
1435 #endif /* not defined XML_CONTEXT_BYTES */
1437 void *buff
= XML_GetBuffer(parser
, len
);
1439 return XML_STATUS_ERROR
;
1441 memcpy(buff
, s
, len
);
1442 return XML_ParseBuffer(parser
, len
, isFinal
);
1448 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1450 const char *start
= bufferPtr
;
1451 positionPtr
= start
;
1453 parseEndByteIndex
+= len
;
1454 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1455 isFinal
? (const char **)NULL
: &bufferPtr
);
1456 if (errorCode
== XML_ERROR_NONE
) {
1458 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1459 positionPtr
= bufferPtr
;
1461 return XML_STATUS_OK
;
1464 eventEndPtr
= eventPtr
;
1465 processor
= errorProcessor
;
1466 return XML_STATUS_ERROR
;
1471 XML_GetBuffer(XML_Parser parser
, int len
)
1473 if (len
> bufferLim
- bufferEnd
) {
1474 /* FIXME avoid integer overflow */
1475 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1476 #ifdef XML_CONTEXT_BYTES
1477 int keep
= bufferPtr
- buffer
;
1479 if (keep
> XML_CONTEXT_BYTES
)
1480 keep
= XML_CONTEXT_BYTES
;
1482 #endif /* defined XML_CONTEXT_BYTES */
1483 if (neededSize
<= bufferLim
- buffer
) {
1484 #ifdef XML_CONTEXT_BYTES
1485 if (keep
< bufferPtr
- buffer
) {
1486 int offset
= (bufferPtr
- buffer
) - keep
;
1487 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1488 bufferEnd
-= offset
;
1489 bufferPtr
-= offset
;
1492 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1493 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1495 #endif /* not defined XML_CONTEXT_BYTES */
1499 int bufferSize
= bufferLim
- bufferPtr
;
1500 if (bufferSize
== 0)
1501 bufferSize
= INIT_BUFFER_SIZE
;
1504 } while (bufferSize
< neededSize
);
1505 newBuf
= (char *)MALLOC(bufferSize
);
1507 errorCode
= XML_ERROR_NO_MEMORY
;
1510 bufferLim
= newBuf
+ bufferSize
;
1511 #ifdef XML_CONTEXT_BYTES
1513 int keep
= bufferPtr
- buffer
;
1514 if (keep
> XML_CONTEXT_BYTES
)
1515 keep
= XML_CONTEXT_BYTES
;
1516 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1519 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1520 bufferPtr
= buffer
+ keep
;
1523 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1524 bufferPtr
= buffer
= newBuf
;
1528 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1531 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1532 bufferPtr
= buffer
= newBuf
;
1533 #endif /* not defined XML_CONTEXT_BYTES */
1540 XML_GetErrorCode(XML_Parser parser
)
1546 XML_GetCurrentByteIndex(XML_Parser parser
)
1549 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1554 XML_GetCurrentByteCount(XML_Parser parser
)
1556 if (eventEndPtr
&& eventPtr
)
1557 return eventEndPtr
- eventPtr
;
1562 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1564 #ifdef XML_CONTEXT_BYTES
1565 if (eventPtr
&& buffer
) {
1566 *offset
= eventPtr
- buffer
;
1567 *size
= bufferEnd
- buffer
;
1570 #endif /* defined XML_CONTEXT_BYTES */
1575 XML_GetCurrentLineNumber(XML_Parser parser
)
1578 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1579 positionPtr
= eventPtr
;
1581 return position
.lineNumber
+ 1;
1585 XML_GetCurrentColumnNumber(XML_Parser parser
)
1588 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1589 positionPtr
= eventPtr
;
1591 return position
.columnNumber
;
1595 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1601 XML_MemMalloc(XML_Parser parser
, size_t size
)
1603 return MALLOC(size
);
1607 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1609 return REALLOC(ptr
, size
);
1613 XML_MemFree(XML_Parser parser
, void *ptr
)
1619 XML_DefaultCurrent(XML_Parser parser
)
1621 if (defaultHandler
) {
1622 if (openInternalEntities
)
1623 reportDefault(parser
,
1625 openInternalEntities
->internalEventPtr
,
1626 openInternalEntities
->internalEventEndPtr
);
1628 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1633 XML_ErrorString(enum XML_Error code
)
1635 static const XML_LChar
*message
[] = {
1637 XML_L("out of memory"),
1638 XML_L("syntax error"),
1639 XML_L("no element found"),
1640 XML_L("not well-formed (invalid token)"),
1641 XML_L("unclosed token"),
1642 XML_L("partial character"),
1643 XML_L("mismatched tag"),
1644 XML_L("duplicate attribute"),
1645 XML_L("junk after document element"),
1646 XML_L("illegal parameter entity reference"),
1647 XML_L("undefined entity"),
1648 XML_L("recursive entity reference"),
1649 XML_L("asynchronous entity"),
1650 XML_L("reference to invalid character number"),
1651 XML_L("reference to binary entity"),
1652 XML_L("reference to external entity in attribute"),
1653 XML_L("xml declaration not at start of external entity"),
1654 XML_L("unknown encoding"),
1655 XML_L("encoding specified in XML declaration is incorrect"),
1656 XML_L("unclosed CDATA section"),
1657 XML_L("error in processing external entity reference"),
1658 XML_L("document is not standalone"),
1659 XML_L("unexpected parser state - please send a bug report"),
1660 XML_L("entity declared in parameter entity"),
1661 XML_L("requested feature requires XML_DTD support in Expat"),
1662 XML_L("cannot change setting once parsing has begun")
1664 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1665 return message
[code
];
1670 XML_ExpatVersion(void) {
1672 /* V1 is used to string-ize the version number. However, it would
1673 string-ize the actual version macro *names* unless we get them
1674 substituted before being passed to V1. CPP is defined to expand
1675 a macro, then rescan for more expansions. Thus, we use V2 to expand
1676 the version macros, then CPP will expand the resulting V1() macro
1677 with the correct numerals. */
1678 /* ### I'm assuming cpp is portable in this respect... */
1680 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1681 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1683 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1690 XML_ExpatVersionInfo(void)
1692 XML_Expat_Version version
;
1694 version
.major
= XML_MAJOR_VERSION
;
1695 version
.minor
= XML_MINOR_VERSION
;
1696 version
.micro
= XML_MICRO_VERSION
;
1702 XML_GetFeatureList(void)
1704 static XML_Feature features
[] = {
1705 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1706 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1708 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1710 #ifdef XML_UNICODE_WCHAR_T
1711 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1714 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1716 #ifdef XML_CONTEXT_BYTES
1717 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1721 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1723 {XML_FEATURE_END
, NULL
}
1726 features
[0].value
= sizeof(XML_Char
);
1727 features
[1].value
= sizeof(XML_LChar
);
1731 /* Initially tag->rawName always points into the parse buffer;
1732 for those TAG instances opened while the current parse buffer was
1733 processed, and not yet closed, we need to store tag->rawName in a more
1734 permanent location, since the parse buffer is about to be discarded.
1737 storeRawNames(XML_Parser parser
)
1739 TAG
*tag
= tagStack
;
1742 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1743 char *rawNameBuf
= tag
->buf
+ nameLen
;
1744 /* Stop if already stored. Since tagStack is a stack, we can stop
1745 at the first entry that has already been copied; everything
1746 below it in the stack is already been accounted for in a
1747 previous call to this function.
1749 if (tag
->rawName
== rawNameBuf
)
1751 /* For re-use purposes we need to ensure that the
1752 size of tag->buf is a multiple of sizeof(XML_Char).
1754 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1755 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1756 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1759 /* if tag->name.str points to tag->buf (only when namespace
1760 processing is off) then we have to update it
1762 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1763 tag
->name
.str
= (XML_Char
*)temp
;
1764 /* if tag->name.localPart is set (when namespace processing is on)
1765 then update it as well, since it will always point into tag->buf
1767 if (tag
->name
.localPart
)
1768 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1769 (XML_Char
*)tag
->buf
);
1771 tag
->bufEnd
= temp
+ bufSize
;
1772 rawNameBuf
= temp
+ nameLen
;
1774 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1775 tag
->rawName
= rawNameBuf
;
1781 static enum XML_Error PTRCALL
1782 contentProcessor(XML_Parser parser
,
1785 const char **endPtr
)
1787 enum XML_Error result
=
1788 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1789 if (result
!= XML_ERROR_NONE
)
1791 if (!storeRawNames(parser
))
1792 return XML_ERROR_NO_MEMORY
;
1796 static enum XML_Error PTRCALL
1797 externalEntityInitProcessor(XML_Parser parser
,
1800 const char **endPtr
)
1802 enum XML_Error result
= initializeEncoding(parser
);
1803 if (result
!= XML_ERROR_NONE
)
1805 processor
= externalEntityInitProcessor2
;
1806 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1809 static enum XML_Error PTRCALL
1810 externalEntityInitProcessor2(XML_Parser parser
,
1813 const char **endPtr
)
1815 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1816 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1819 /* If we are at the end of the buffer, this would cause the next stage,
1820 i.e. externalEntityInitProcessor3, to pass control directly to
1821 doContent (by detecting XML_TOK_NONE) without processing any xml text
1822 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1824 if (next
== end
&& endPtr
) {
1826 return XML_ERROR_NONE
;
1830 case XML_TOK_PARTIAL
:
1833 return XML_ERROR_NONE
;
1836 return XML_ERROR_UNCLOSED_TOKEN
;
1837 case XML_TOK_PARTIAL_CHAR
:
1840 return XML_ERROR_NONE
;
1843 return XML_ERROR_PARTIAL_CHAR
;
1845 processor
= externalEntityInitProcessor3
;
1846 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1849 static enum XML_Error PTRCALL
1850 externalEntityInitProcessor3(XML_Parser parser
,
1853 const char **endPtr
)
1855 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1856 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1858 case XML_TOK_XML_DECL
:
1860 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1861 if (result
!= XML_ERROR_NONE
)
1866 case XML_TOK_PARTIAL
:
1869 return XML_ERROR_NONE
;
1872 return XML_ERROR_UNCLOSED_TOKEN
;
1873 case XML_TOK_PARTIAL_CHAR
:
1876 return XML_ERROR_NONE
;
1879 return XML_ERROR_PARTIAL_CHAR
;
1881 processor
= externalEntityContentProcessor
;
1883 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1886 static enum XML_Error PTRCALL
1887 externalEntityContentProcessor(XML_Parser parser
,
1890 const char **endPtr
)
1892 enum XML_Error result
=
1893 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1894 if (result
!= XML_ERROR_NONE
)
1896 if (!storeRawNames(parser
))
1897 return XML_ERROR_NO_MEMORY
;
1901 static enum XML_Error
1902 doContent(XML_Parser parser
,
1904 const ENCODING
*enc
,
1907 const char **nextPtr
)
1909 DTD
* const dtd
= _dtd
; /* save one level of indirection */
1910 const char **eventPP
;
1911 const char **eventEndPP
;
1912 if (enc
== encoding
) {
1913 eventPP
= &eventPtr
;
1914 eventEndPP
= &eventEndPtr
;
1917 eventPP
= &(openInternalEntities
->internalEventPtr
);
1918 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1922 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1923 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1926 case XML_TOK_TRAILING_CR
:
1929 return XML_ERROR_NONE
;
1932 if (characterDataHandler
) {
1934 characterDataHandler(handlerArg
, &c
, 1);
1936 else if (defaultHandler
)
1937 reportDefault(parser
, enc
, s
, end
);
1938 if (startTagLevel
== 0)
1939 return XML_ERROR_NO_ELEMENTS
;
1940 if (tagLevel
!= startTagLevel
)
1941 return XML_ERROR_ASYNC_ENTITY
;
1942 return XML_ERROR_NONE
;
1946 return XML_ERROR_NONE
;
1948 if (startTagLevel
> 0) {
1949 if (tagLevel
!= startTagLevel
)
1950 return XML_ERROR_ASYNC_ENTITY
;
1951 return XML_ERROR_NONE
;
1953 return XML_ERROR_NO_ELEMENTS
;
1954 case XML_TOK_INVALID
:
1956 return XML_ERROR_INVALID_TOKEN
;
1957 case XML_TOK_PARTIAL
:
1960 return XML_ERROR_NONE
;
1962 return XML_ERROR_UNCLOSED_TOKEN
;
1963 case XML_TOK_PARTIAL_CHAR
:
1966 return XML_ERROR_NONE
;
1968 return XML_ERROR_PARTIAL_CHAR
;
1969 case XML_TOK_ENTITY_REF
:
1971 const XML_Char
*name
;
1973 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1974 s
+ enc
->minBytesPerChar
,
1975 next
- enc
->minBytesPerChar
);
1977 if (characterDataHandler
)
1978 characterDataHandler(handlerArg
, &ch
, 1);
1979 else if (defaultHandler
)
1980 reportDefault(parser
, enc
, s
, next
);
1983 name
= poolStoreString(&dtd
->pool
, enc
,
1984 s
+ enc
->minBytesPerChar
,
1985 next
- enc
->minBytesPerChar
);
1987 return XML_ERROR_NO_MEMORY
;
1988 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
1989 poolDiscard(&dtd
->pool
);
1990 /* First, determine if a check for an existing declaration is needed;
1991 if yes, check that the entity exists, and that it is internal,
1992 otherwise call the skipped entity or default handler.
1994 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
1996 return XML_ERROR_UNDEFINED_ENTITY
;
1997 else if (!entity
->is_internal
)
1998 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2001 if (skippedEntityHandler
)
2002 skippedEntityHandler(handlerArg
, name
, 0);
2003 else if (defaultHandler
)
2004 reportDefault(parser
, enc
, s
, next
);
2008 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2009 if (entity
->notation
)
2010 return XML_ERROR_BINARY_ENTITY_REF
;
2011 if (entity
->textPtr
) {
2012 enum XML_Error result
;
2013 OPEN_INTERNAL_ENTITY openEntity
;
2014 if (!defaultExpandInternalEntities
) {
2015 if (skippedEntityHandler
)
2016 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2017 else if (defaultHandler
)
2018 reportDefault(parser
, enc
, s
, next
);
2021 entity
->open
= XML_TRUE
;
2022 openEntity
.next
= openInternalEntities
;
2023 openInternalEntities
= &openEntity
;
2024 openEntity
.entity
= entity
;
2025 openEntity
.internalEventPtr
= NULL
;
2026 openEntity
.internalEventEndPtr
= NULL
;
2027 result
= doContent(parser
,
2030 (char *)entity
->textPtr
,
2031 (char *)(entity
->textPtr
+ entity
->textLen
),
2033 entity
->open
= XML_FALSE
;
2034 openInternalEntities
= openEntity
.next
;
2038 else if (externalEntityRefHandler
) {
2039 const XML_Char
*context
;
2040 entity
->open
= XML_TRUE
;
2041 context
= getContext(parser
);
2042 entity
->open
= XML_FALSE
;
2044 return XML_ERROR_NO_MEMORY
;
2045 if (!externalEntityRefHandler((XML_Parser
)externalEntityRefHandlerArg
,
2050 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2051 poolDiscard(&tempPool
);
2053 else if (defaultHandler
)
2054 reportDefault(parser
, enc
, s
, next
);
2057 case XML_TOK_START_TAG_NO_ATTS
:
2059 case XML_TOK_START_TAG_WITH_ATTS
:
2062 enum XML_Error result
;
2066 freeTagList
= freeTagList
->parent
;
2069 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2071 return XML_ERROR_NO_MEMORY
;
2072 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2075 return XML_ERROR_NO_MEMORY
;
2077 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2079 tag
->bindings
= NULL
;
2080 tag
->parent
= tagStack
;
2082 tag
->name
.localPart
= NULL
;
2083 tag
->name
.prefix
= NULL
;
2084 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2085 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2088 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2089 const char *fromPtr
= tag
->rawName
;
2090 toPtr
= (XML_Char
*)tag
->buf
;
2095 &fromPtr
, rawNameEnd
,
2096 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2097 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2098 if (fromPtr
== rawNameEnd
) {
2099 tag
->name
.strLen
= convLen
;
2102 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2104 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2106 return XML_ERROR_NO_MEMORY
;
2108 tag
->bufEnd
= temp
+ bufSize
;
2109 toPtr
= (XML_Char
*)temp
+ convLen
;
2113 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2114 *toPtr
= XML_T('\0');
2115 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2118 if (startElementHandler
)
2119 startElementHandler(handlerArg
, tag
->name
.str
,
2120 (const XML_Char
**)atts
);
2121 else if (defaultHandler
)
2122 reportDefault(parser
, enc
, s
, next
);
2123 poolClear(&tempPool
);
2126 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2128 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2130 const char *rawName
= s
+ enc
->minBytesPerChar
;
2131 enum XML_Error result
;
2132 BINDING
*bindings
= NULL
;
2133 XML_Bool noElmHandlers
= XML_TRUE
;
2135 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2136 rawName
+ XmlNameLength(enc
, rawName
));
2138 return XML_ERROR_NO_MEMORY
;
2139 poolFinish(&tempPool
);
2140 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2143 poolFinish(&tempPool
);
2144 if (startElementHandler
) {
2145 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2146 noElmHandlers
= XML_FALSE
;
2148 if (endElementHandler
) {
2149 if (startElementHandler
)
2150 *eventPP
= *eventEndPP
;
2151 endElementHandler(handlerArg
, name
.str
);
2152 noElmHandlers
= XML_FALSE
;
2154 if (noElmHandlers
&& defaultHandler
)
2155 reportDefault(parser
, enc
, s
, next
);
2156 poolClear(&tempPool
);
2158 BINDING
*b
= bindings
;
2159 if (endNamespaceDeclHandler
)
2160 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2161 bindings
= bindings
->nextTagBinding
;
2162 b
->nextTagBinding
= freeBindingList
;
2163 freeBindingList
= b
;
2164 b
->prefix
->binding
= b
->prevPrefixBinding
;
2168 return epilogProcessor(parser
, next
, end
, nextPtr
);
2170 case XML_TOK_END_TAG
:
2171 if (tagLevel
== startTagLevel
)
2172 return XML_ERROR_ASYNC_ENTITY
;
2175 const char *rawName
;
2176 TAG
*tag
= tagStack
;
2177 tagStack
= tag
->parent
;
2178 tag
->parent
= freeTagList
;
2180 rawName
= s
+ enc
->minBytesPerChar
*2;
2181 len
= XmlNameLength(enc
, rawName
);
2182 if (len
!= tag
->rawNameLength
2183 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2185 return XML_ERROR_TAG_MISMATCH
;
2188 if (endElementHandler
) {
2189 const XML_Char
*localPart
;
2190 const XML_Char
*prefix
;
2192 localPart
= tag
->name
.localPart
;
2193 if (ns
&& localPart
) {
2194 /* localPart and prefix may have been overwritten in
2195 tag->name.str, since this points to the binding->uri
2196 buffer which gets re-used; so we have to add them again
2198 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2199 /* don't need to check for space - already done in storeAtts() */
2200 while (*localPart
) *uri
++ = *localPart
++;
2201 prefix
= (XML_Char
*)tag
->name
.prefix
;
2202 if (ns_triplets
&& prefix
) {
2203 *uri
++ = namespaceSeparator
;
2204 while (*prefix
) *uri
++ = *prefix
++;
2208 endElementHandler(handlerArg
, tag
->name
.str
);
2210 else if (defaultHandler
)
2211 reportDefault(parser
, enc
, s
, next
);
2212 while (tag
->bindings
) {
2213 BINDING
*b
= tag
->bindings
;
2214 if (endNamespaceDeclHandler
)
2215 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2216 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2217 b
->nextTagBinding
= freeBindingList
;
2218 freeBindingList
= b
;
2219 b
->prefix
->binding
= b
->prevPrefixBinding
;
2222 return epilogProcessor(parser
, next
, end
, nextPtr
);
2225 case XML_TOK_CHAR_REF
:
2227 int n
= XmlCharRefNumber(enc
, s
);
2229 return XML_ERROR_BAD_CHAR_REF
;
2230 if (characterDataHandler
) {
2231 XML_Char buf
[XML_ENCODE_MAX
];
2232 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2234 else if (defaultHandler
)
2235 reportDefault(parser
, enc
, s
, next
);
2238 case XML_TOK_XML_DECL
:
2239 return XML_ERROR_MISPLACED_XML_PI
;
2240 case XML_TOK_DATA_NEWLINE
:
2241 if (characterDataHandler
) {
2243 characterDataHandler(handlerArg
, &c
, 1);
2245 else if (defaultHandler
)
2246 reportDefault(parser
, enc
, s
, next
);
2248 case XML_TOK_CDATA_SECT_OPEN
:
2250 enum XML_Error result
;
2251 if (startCdataSectionHandler
)
2252 startCdataSectionHandler(handlerArg
);
2254 /* Suppose you doing a transformation on a document that involves
2255 changing only the character data. You set up a defaultHandler
2256 and a characterDataHandler. The defaultHandler simply copies
2257 characters through. The characterDataHandler does the
2258 transformation and writes the characters out escaping them as
2259 necessary. This case will fail to work if we leave out the
2260 following two lines (because & and < inside CDATA sections will
2261 be incorrectly escaped).
2263 However, now we have a start/endCdataSectionHandler, so it seems
2264 easier to let the user deal with this.
2266 else if (characterDataHandler
)
2267 characterDataHandler(handlerArg
, dataBuf
, 0);
2269 else if (defaultHandler
)
2270 reportDefault(parser
, enc
, s
, next
);
2271 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2273 processor
= cdataSectionProcessor
;
2278 case XML_TOK_TRAILING_RSQB
:
2281 return XML_ERROR_NONE
;
2283 if (characterDataHandler
) {
2284 if (MUST_CONVERT(enc
, s
)) {
2285 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2286 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2287 characterDataHandler(handlerArg
, dataBuf
,
2288 dataPtr
- (ICHAR
*)dataBuf
);
2291 characterDataHandler(handlerArg
,
2293 (XML_Char
*)end
- (XML_Char
*)s
);
2295 else if (defaultHandler
)
2296 reportDefault(parser
, enc
, s
, end
);
2297 if (startTagLevel
== 0) {
2299 return XML_ERROR_NO_ELEMENTS
;
2301 if (tagLevel
!= startTagLevel
) {
2303 return XML_ERROR_ASYNC_ENTITY
;
2305 return XML_ERROR_NONE
;
2306 case XML_TOK_DATA_CHARS
:
2307 if (characterDataHandler
) {
2308 if (MUST_CONVERT(enc
, s
)) {
2310 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2311 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2313 characterDataHandler(handlerArg
, dataBuf
,
2314 dataPtr
- (ICHAR
*)dataBuf
);
2321 characterDataHandler(handlerArg
,
2323 (XML_Char
*)next
- (XML_Char
*)s
);
2325 else if (defaultHandler
)
2326 reportDefault(parser
, enc
, s
, next
);
2329 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2330 return XML_ERROR_NO_MEMORY
;
2332 case XML_TOK_COMMENT
:
2333 if (!reportComment(parser
, enc
, s
, next
))
2334 return XML_ERROR_NO_MEMORY
;
2338 reportDefault(parser
, enc
, s
, next
);
2341 *eventPP
= s
= next
;
2346 /* Precondition: all arguments must be non-NULL;
2348 - normalize attributes
2349 - check attributes for well-formedness
2350 - generate namespace aware attribute names (URI, prefix)
2351 - build list of attributes for startElementHandler
2352 - default attributes
2353 - process namespace declarations (check and report them)
2354 - generate namespace aware element name (URI, prefix)
2356 static enum XML_Error
2357 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2358 const char *attStr
, TAG_NAME
*tagNamePtr
,
2359 BINDING
**bindingsPtr
)
2361 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2362 ELEMENT_TYPE
*elementType
= NULL
;
2363 int nDefaultAtts
= 0;
2364 const XML_Char
**appAtts
; /* the attribute list for the application */
2372 const XML_Char
*localPart
;
2374 /* lookup the element type name */
2375 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2377 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2379 return XML_ERROR_NO_MEMORY
;
2380 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2381 sizeof(ELEMENT_TYPE
));
2383 return XML_ERROR_NO_MEMORY
;
2384 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2385 return XML_ERROR_NO_MEMORY
;
2387 nDefaultAtts
= elementType
->nDefaultAtts
;
2389 /* get the attributes from the tokenizer */
2390 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2391 if (n
+ nDefaultAtts
> attsSize
) {
2392 int oldAttsSize
= attsSize
;
2394 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2395 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2397 return XML_ERROR_NO_MEMORY
;
2399 if (n
> oldAttsSize
)
2400 XmlGetAttributes(enc
, attStr
, n
, atts
);
2403 appAtts
= (const XML_Char
**)atts
;
2404 for (i
= 0; i
< n
; i
++) {
2405 /* add the name and value to the attribute list */
2406 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2408 + XmlNameLength(enc
, atts
[i
].name
));
2410 return XML_ERROR_NO_MEMORY
;
2411 /* detect duplicate attributes */
2412 if ((attId
->name
)[-1]) {
2413 if (enc
== encoding
)
2414 eventPtr
= atts
[i
].name
;
2415 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2417 (attId
->name
)[-1] = 1;
2418 appAtts
[attIndex
++] = attId
->name
;
2419 if (!atts
[i
].normalized
) {
2420 enum XML_Error result
;
2421 XML_Bool isCdata
= XML_TRUE
;
2423 /* figure out whether declared as other than CDATA */
2424 if (attId
->maybeTokenized
) {
2426 for (j
= 0; j
< nDefaultAtts
; j
++) {
2427 if (attId
== elementType
->defaultAtts
[j
].id
) {
2428 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2434 /* normalize the attribute value */
2435 result
= storeAttributeValue(parser
, enc
, isCdata
,
2436 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2440 appAtts
[attIndex
] = poolStart(&tempPool
);
2441 poolFinish(&tempPool
);
2444 /* the value did not need normalizing */
2445 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2447 if (appAtts
[attIndex
] == 0)
2448 return XML_ERROR_NO_MEMORY
;
2449 poolFinish(&tempPool
);
2451 /* handle prefixed attribute names */
2452 if (attId
->prefix
) {
2454 /* deal with namespace declarations here */
2455 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2456 appAtts
[attIndex
], bindingsPtr
);
2462 /* deal with other prefixed names later */
2465 (attId
->name
)[-1] = 2;
2472 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2473 nSpecifiedAtts
= attIndex
;
2474 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2475 for (i
= 0; i
< attIndex
; i
+= 2)
2476 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2484 /* do attribute defaulting */
2485 for (i
= 0; i
< nDefaultAtts
; i
++) {
2486 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2487 if (!(da
->id
->name
)[-1] && da
->value
) {
2488 if (da
->id
->prefix
) {
2489 if (da
->id
->xmlns
) {
2490 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2491 da
->value
, bindingsPtr
);
2496 (da
->id
->name
)[-1] = 2;
2498 appAtts
[attIndex
++] = da
->id
->name
;
2499 appAtts
[attIndex
++] = da
->value
;
2503 (da
->id
->name
)[-1] = 1;
2504 appAtts
[attIndex
++] = da
->id
->name
;
2505 appAtts
[attIndex
++] = da
->value
;
2509 appAtts
[attIndex
] = 0;
2513 /* expand prefixed attribute names */
2514 for (; i
< attIndex
; i
+= 2) {
2515 if (appAtts
[i
][-1] == 2) {
2517 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2518 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, appAtts
[i
], 0);
2519 if (id
->prefix
->binding
) {
2521 const BINDING
*b
= id
->prefix
->binding
;
2522 const XML_Char
*s
= appAtts
[i
];
2523 for (j
= 0; j
< b
->uriLen
; j
++) {
2524 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2525 return XML_ERROR_NO_MEMORY
;
2527 while (*s
++ != XML_T(':'))
2530 if (!poolAppendChar(&tempPool
, *s
))
2531 return XML_ERROR_NO_MEMORY
;
2534 tempPool
.ptr
[-1] = namespaceSeparator
;
2535 s
= b
->prefix
->name
;
2537 if (!poolAppendChar(&tempPool
, *s
))
2538 return XML_ERROR_NO_MEMORY
;
2542 appAtts
[i
] = poolStart(&tempPool
);
2543 poolFinish(&tempPool
);
2549 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2552 /* clear the flags that say whether attributes were specified */
2553 for (; i
< attIndex
; i
+= 2)
2554 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2555 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2556 binding
->attId
->name
[-1] = 0;
2558 /* expand the element type name */
2559 if (elementType
->prefix
) {
2560 binding
= elementType
->prefix
->binding
;
2562 return XML_ERROR_NONE
;
2563 localPart
= tagNamePtr
->str
;
2564 while (*localPart
++ != XML_T(':'))
2567 else if (dtd
->defaultPrefix
.binding
) {
2568 binding
= dtd
->defaultPrefix
.binding
;
2569 localPart
= tagNamePtr
->str
;
2572 return XML_ERROR_NONE
;
2574 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2575 for (; binding
->prefix
->name
[prefixLen
++];)
2578 tagNamePtr
->localPart
= localPart
;
2579 tagNamePtr
->uriLen
= binding
->uriLen
;
2580 tagNamePtr
->prefix
= binding
->prefix
->name
;
2581 tagNamePtr
->prefixLen
= prefixLen
;
2582 for (i
= 0; localPart
[i
++];)
2584 n
= i
+ binding
->uriLen
+ prefixLen
;
2585 if (n
> binding
->uriAlloc
) {
2587 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2589 return XML_ERROR_NO_MEMORY
;
2590 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2591 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2592 for (p
= tagStack
; p
; p
= p
->parent
)
2593 if (p
->name
.str
== binding
->uri
)
2598 uri
= binding
->uri
+ binding
->uriLen
;
2599 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2601 uri
= uri
+ (i
- 1);
2602 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2603 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2605 tagNamePtr
->str
= binding
->uri
;
2606 return XML_ERROR_NONE
;
2609 /* addBinding() overwrites the value of prefix->binding without checking.
2610 Therefore one must keep track of the old value outside of addBinding().
2612 static enum XML_Error
2613 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2614 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2619 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2620 if (*uri
== XML_T('\0') && prefix
->name
)
2621 return XML_ERROR_SYNTAX
;
2623 for (len
= 0; uri
[len
]; len
++)
2625 if (namespaceSeparator
)
2627 if (freeBindingList
) {
2628 b
= freeBindingList
;
2629 if (len
> b
->uriAlloc
) {
2630 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2631 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2633 return XML_ERROR_NO_MEMORY
;
2635 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2637 freeBindingList
= b
->nextTagBinding
;
2640 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2642 return XML_ERROR_NO_MEMORY
;
2643 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2646 return XML_ERROR_NO_MEMORY
;
2648 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2651 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2652 if (namespaceSeparator
)
2653 b
->uri
[len
- 1] = namespaceSeparator
;
2656 b
->prevPrefixBinding
= prefix
->binding
;
2657 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2658 prefix
->binding
= NULL
;
2660 prefix
->binding
= b
;
2661 b
->nextTagBinding
= *bindingsPtr
;
2663 if (startNamespaceDeclHandler
)
2664 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2665 prefix
->binding
? uri
: 0);
2666 return XML_ERROR_NONE
;
2669 /* The idea here is to avoid using stack for each CDATA section when
2670 the whole file is parsed with one call.
2672 static enum XML_Error PTRCALL
2673 cdataSectionProcessor(XML_Parser parser
,
2676 const char **endPtr
)
2678 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2681 if (parentParser
) { /* we are parsing an external entity */
2682 processor
= externalEntityContentProcessor
;
2683 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2686 processor
= contentProcessor
;
2687 return contentProcessor(parser
, start
, end
, endPtr
);
2693 /* startPtr gets set to non-null is the section is closed, and to null if
2694 the section is not yet closed.
2696 static enum XML_Error
2697 doCdataSection(XML_Parser parser
,
2698 const ENCODING
*enc
,
2699 const char **startPtr
,
2701 const char **nextPtr
)
2703 const char *s
= *startPtr
;
2704 const char **eventPP
;
2705 const char **eventEndPP
;
2706 if (enc
== encoding
) {
2707 eventPP
= &eventPtr
;
2709 eventEndPP
= &eventEndPtr
;
2712 eventPP
= &(openInternalEntities
->internalEventPtr
);
2713 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2719 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2722 case XML_TOK_CDATA_SECT_CLOSE
:
2723 if (endCdataSectionHandler
)
2724 endCdataSectionHandler(handlerArg
);
2726 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2727 else if (characterDataHandler
)
2728 characterDataHandler(handlerArg
, dataBuf
, 0);
2730 else if (defaultHandler
)
2731 reportDefault(parser
, enc
, s
, next
);
2733 return XML_ERROR_NONE
;
2734 case XML_TOK_DATA_NEWLINE
:
2735 if (characterDataHandler
) {
2737 characterDataHandler(handlerArg
, &c
, 1);
2739 else if (defaultHandler
)
2740 reportDefault(parser
, enc
, s
, next
);
2742 case XML_TOK_DATA_CHARS
:
2743 if (characterDataHandler
) {
2744 if (MUST_CONVERT(enc
, s
)) {
2746 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2747 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2749 characterDataHandler(handlerArg
, dataBuf
,
2750 dataPtr
- (ICHAR
*)dataBuf
);
2757 characterDataHandler(handlerArg
,
2759 (XML_Char
*)next
- (XML_Char
*)s
);
2761 else if (defaultHandler
)
2762 reportDefault(parser
, enc
, s
, next
);
2764 case XML_TOK_INVALID
:
2766 return XML_ERROR_INVALID_TOKEN
;
2767 case XML_TOK_PARTIAL_CHAR
:
2770 return XML_ERROR_NONE
;
2772 return XML_ERROR_PARTIAL_CHAR
;
2773 case XML_TOK_PARTIAL
:
2777 return XML_ERROR_NONE
;
2779 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2782 return XML_ERROR_UNEXPECTED_STATE
;
2784 *eventPP
= s
= next
;
2791 /* The idea here is to avoid using stack for each IGNORE section when
2792 the whole file is parsed with one call.
2794 static enum XML_Error PTRCALL
2795 ignoreSectionProcessor(XML_Parser parser
,
2798 const char **endPtr
)
2800 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2803 processor
= prologProcessor
;
2804 return prologProcessor(parser
, start
, end
, endPtr
);
2809 /* startPtr gets set to non-null is the section is closed, and to null
2810 if the section is not yet closed.
2812 static enum XML_Error
2813 doIgnoreSection(XML_Parser parser
,
2814 const ENCODING
*enc
,
2815 const char **startPtr
,
2817 const char **nextPtr
)
2821 const char *s
= *startPtr
;
2822 const char **eventPP
;
2823 const char **eventEndPP
;
2824 if (enc
== encoding
) {
2825 eventPP
= &eventPtr
;
2827 eventEndPP
= &eventEndPtr
;
2830 eventPP
= &(openInternalEntities
->internalEventPtr
);
2831 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2835 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2838 case XML_TOK_IGNORE_SECT
:
2840 reportDefault(parser
, enc
, s
, next
);
2842 return XML_ERROR_NONE
;
2843 case XML_TOK_INVALID
:
2845 return XML_ERROR_INVALID_TOKEN
;
2846 case XML_TOK_PARTIAL_CHAR
:
2849 return XML_ERROR_NONE
;
2851 return XML_ERROR_PARTIAL_CHAR
;
2852 case XML_TOK_PARTIAL
:
2856 return XML_ERROR_NONE
;
2858 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2861 return XML_ERROR_UNEXPECTED_STATE
;
2866 #endif /* XML_DTD */
2868 static enum XML_Error
2869 initializeEncoding(XML_Parser parser
)
2873 char encodingBuf
[128];
2874 if (!protocolEncodingName
)
2878 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2879 if (i
== sizeof(encodingBuf
) - 1
2880 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2881 encodingBuf
[0] = '\0';
2884 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2886 encodingBuf
[i
] = '\0';
2890 s
= protocolEncodingName
;
2892 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2893 return XML_ERROR_NONE
;
2894 return handleUnknownEncoding(parser
, protocolEncodingName
);
2897 static enum XML_Error
2898 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2899 const char *s
, const char *next
)
2901 const char *encodingName
= NULL
;
2902 const XML_Char
*storedEncName
= NULL
;
2903 const ENCODING
*newEncoding
= NULL
;
2904 const char *version
= NULL
;
2905 const char *versionend
;
2906 const XML_Char
*storedversion
= NULL
;
2907 int standalone
= -1;
2910 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2920 return XML_ERROR_SYNTAX
;
2921 if (!isGeneralTextEntity
&& standalone
== 1) {
2922 _dtd
->standalone
= XML_TRUE
;
2924 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2925 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2926 #endif /* XML_DTD */
2928 if (xmlDeclHandler
) {
2929 if (encodingName
!= NULL
) {
2930 storedEncName
= poolStoreString(&temp2Pool
,
2934 + XmlNameLength(encoding
, encodingName
));
2936 return XML_ERROR_NO_MEMORY
;
2937 poolFinish(&temp2Pool
);
2940 storedversion
= poolStoreString(&temp2Pool
,
2943 versionend
- encoding
->minBytesPerChar
);
2945 return XML_ERROR_NO_MEMORY
;
2947 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2949 else if (defaultHandler
)
2950 reportDefault(parser
, encoding
, s
, next
);
2951 if (protocolEncodingName
== NULL
) {
2953 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2954 eventPtr
= encodingName
;
2955 return XML_ERROR_INCORRECT_ENCODING
;
2957 encoding
= newEncoding
;
2959 else if (encodingName
) {
2960 enum XML_Error result
;
2961 if (!storedEncName
) {
2962 storedEncName
= poolStoreString(
2963 &temp2Pool
, encoding
, encodingName
,
2964 encodingName
+ XmlNameLength(encoding
, encodingName
));
2966 return XML_ERROR_NO_MEMORY
;
2968 result
= handleUnknownEncoding(parser
, storedEncName
);
2969 poolClear(&temp2Pool
);
2970 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2971 eventPtr
= encodingName
;
2976 if (storedEncName
|| storedversion
)
2977 poolClear(&temp2Pool
);
2979 return XML_ERROR_NONE
;
2982 static enum XML_Error
2983 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2985 if (unknownEncodingHandler
) {
2988 for (i
= 0; i
< 256; i
++)
2990 info
.convert
= NULL
;
2992 info
.release
= NULL
;
2993 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2996 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2997 if (!unknownEncodingMem
) {
2999 info
.release(info
.data
);
3000 return XML_ERROR_NO_MEMORY
;
3003 ? XmlInitUnknownEncodingNS
3004 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3009 unknownEncodingData
= info
.data
;
3010 unknownEncodingRelease
= info
.release
;
3012 return XML_ERROR_NONE
;
3015 if (info
.release
!= NULL
)
3016 info
.release(info
.data
);
3018 return XML_ERROR_UNKNOWN_ENCODING
;
3021 static enum XML_Error PTRCALL
3022 prologInitProcessor(XML_Parser parser
,
3025 const char **nextPtr
)
3027 enum XML_Error result
= initializeEncoding(parser
);
3028 if (result
!= XML_ERROR_NONE
)
3030 processor
= prologProcessor
;
3031 return prologProcessor(parser
, s
, end
, nextPtr
);
3036 static enum XML_Error PTRCALL
3037 externalParEntInitProcessor(XML_Parser parser
,
3040 const char **nextPtr
)
3042 enum XML_Error result
= initializeEncoding(parser
);
3043 if (result
!= XML_ERROR_NONE
)
3046 /* we know now that XML_Parse(Buffer) has been called,
3047 so we consider the external parameter entity read */
3048 _dtd
->paramEntityRead
= XML_TRUE
;
3050 if (prologState
.inEntityValue
) {
3051 processor
= entityValueInitProcessor
;
3052 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3055 processor
= externalParEntProcessor
;
3056 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3060 static enum XML_Error PTRCALL
3061 entityValueInitProcessor(XML_Parser parser
,
3064 const char **nextPtr
)
3066 const char *start
= s
;
3067 const char *next
= s
;
3071 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3073 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3075 return XML_ERROR_NONE
;
3078 case XML_TOK_INVALID
:
3079 return XML_ERROR_INVALID_TOKEN
;
3080 case XML_TOK_PARTIAL
:
3081 return XML_ERROR_UNCLOSED_TOKEN
;
3082 case XML_TOK_PARTIAL_CHAR
:
3083 return XML_ERROR_PARTIAL_CHAR
;
3084 case XML_TOK_NONE
: /* start == end */
3088 return storeEntityValue(parser
, encoding
, s
, end
);
3090 else if (tok
== XML_TOK_XML_DECL
) {
3091 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
3092 if (result
!= XML_ERROR_NONE
)
3094 if (nextPtr
) *nextPtr
= next
;
3095 /* stop scanning for text declaration - we found one */
3096 processor
= entityValueProcessor
;
3097 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3099 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3100 return XML_TOK_NONE on the next call, which would then cause the
3101 function to exit with *nextPtr set to s - that is what we want for other
3102 tokens, but not for the BOM - we would rather like to skip it;
3103 then, when this routine is entered the next time, XmlPrologTok will
3104 return XML_TOK_INVALID, since the BOM is still in the buffer
3106 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3108 return XML_ERROR_NONE
;
3114 static enum XML_Error PTRCALL
3115 externalParEntProcessor(XML_Parser parser
,
3118 const char **nextPtr
)
3120 const char *start
= s
;
3121 const char *next
= s
;
3124 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3126 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3128 return XML_ERROR_NONE
;
3131 case XML_TOK_INVALID
:
3132 return XML_ERROR_INVALID_TOKEN
;
3133 case XML_TOK_PARTIAL
:
3134 return XML_ERROR_UNCLOSED_TOKEN
;
3135 case XML_TOK_PARTIAL_CHAR
:
3136 return XML_ERROR_PARTIAL_CHAR
;
3137 case XML_TOK_NONE
: /* start == end */
3142 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3143 However, when parsing an external subset, doProlog will not accept a BOM
3144 as valid, and report a syntax error, so we have to skip the BOM
3146 else if (tok
== XML_TOK_BOM
) {
3148 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3151 processor
= prologProcessor
;
3152 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3155 static enum XML_Error PTRCALL
3156 entityValueProcessor(XML_Parser parser
,
3159 const char **nextPtr
)
3161 const char *start
= s
;
3162 const char *next
= s
;
3163 const ENCODING
*enc
= encoding
;
3167 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3169 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3171 return XML_ERROR_NONE
;
3174 case XML_TOK_INVALID
:
3175 return XML_ERROR_INVALID_TOKEN
;
3176 case XML_TOK_PARTIAL
:
3177 return XML_ERROR_UNCLOSED_TOKEN
;
3178 case XML_TOK_PARTIAL_CHAR
:
3179 return XML_ERROR_PARTIAL_CHAR
;
3180 case XML_TOK_NONE
: /* start == end */
3184 return storeEntityValue(parser
, enc
, s
, end
);
3190 #endif /* XML_DTD */
3192 static enum XML_Error PTRCALL
3193 prologProcessor(XML_Parser parser
,
3196 const char **nextPtr
)
3198 const char *next
= s
;
3199 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3200 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3203 static enum XML_Error
3204 doProlog(XML_Parser parser
,
3205 const ENCODING
*enc
,
3210 const char **nextPtr
)
3213 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3214 #endif /* XML_DTD */
3215 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3216 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3217 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3218 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3219 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3220 static const XML_Char atypeENTITIES
[] =
3221 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3222 static const XML_Char atypeNMTOKEN
[] = {
3223 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3224 static const XML_Char atypeNMTOKENS
[] = {
3225 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3226 static const XML_Char notationPrefix
[] = {
3227 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3228 static const XML_Char enumValueSep
[] = { '|', '\0' };
3229 static const XML_Char enumValueStart
[] = { '(', '\0' };
3231 DTD
* const dtd
= _dtd
; /* save one level of indirection */
3233 const char **eventPP
;
3234 const char **eventEndPP
;
3235 enum XML_Content_Quant quant
;
3237 if (enc
== encoding
) {
3238 eventPP
= &eventPtr
;
3239 eventEndPP
= &eventEndPtr
;
3242 eventPP
= &(openInternalEntities
->internalEventPtr
);
3243 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3247 XML_Bool handleDefault
= XML_TRUE
;
3251 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3253 return XML_ERROR_NONE
;
3256 case XML_TOK_INVALID
:
3258 return XML_ERROR_INVALID_TOKEN
;
3259 case XML_TOK_PARTIAL
:
3260 return XML_ERROR_UNCLOSED_TOKEN
;
3261 case XML_TOK_PARTIAL_CHAR
:
3262 return XML_ERROR_PARTIAL_CHAR
;
3265 if (enc
!= encoding
)
3266 return XML_ERROR_NONE
;
3267 if (isParamEntity
) {
3268 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3270 return XML_ERROR_SYNTAX
;
3271 return XML_ERROR_NONE
;
3273 #endif /* XML_DTD */
3274 return XML_ERROR_NO_ELEMENTS
;
3281 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3283 case XML_ROLE_XML_DECL
:
3285 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3286 if (result
!= XML_ERROR_NONE
)
3289 handleDefault
= XML_FALSE
;
3292 case XML_ROLE_DOCTYPE_NAME
:
3293 if (startDoctypeDeclHandler
) {
3294 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3296 return XML_ERROR_NO_MEMORY
;
3297 poolFinish(&tempPool
);
3298 doctypePubid
= NULL
;
3299 handleDefault
= XML_FALSE
;
3301 doctypeSysid
= NULL
; /* always initialize to NULL */
3303 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3304 if (startDoctypeDeclHandler
) {
3305 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3308 poolClear(&tempPool
);
3309 handleDefault
= XML_FALSE
;
3313 case XML_ROLE_TEXT_DECL
:
3315 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3316 if (result
!= XML_ERROR_NONE
)
3319 handleDefault
= XML_FALSE
;
3322 #endif /* XML_DTD */
3323 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3325 useForeignDTD
= XML_FALSE
;
3326 #endif /* XML_DTD */
3327 dtd
->hasParamEntityRefs
= XML_TRUE
;
3328 if (startDoctypeDeclHandler
) {
3329 doctypePubid
= poolStoreString(&tempPool
, enc
,
3330 s
+ enc
->minBytesPerChar
,
3331 next
- enc
->minBytesPerChar
);
3333 return XML_ERROR_NO_MEMORY
;
3334 poolFinish(&tempPool
);
3335 handleDefault
= XML_FALSE
;
3338 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3342 return XML_ERROR_NO_MEMORY
;
3343 #endif /* XML_DTD */
3345 case XML_ROLE_ENTITY_PUBLIC_ID
:
3346 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3347 return XML_ERROR_SYNTAX
;
3348 if (dtd
->keepProcessing
&& declEntity
) {
3349 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3351 s
+ enc
->minBytesPerChar
,
3352 next
- enc
->minBytesPerChar
);
3354 return XML_ERROR_NO_MEMORY
;
3355 normalizePublicId(tem
);
3356 declEntity
->publicId
= tem
;
3357 poolFinish(&dtd
->pool
);
3358 if (entityDeclHandler
)
3359 handleDefault
= XML_FALSE
;
3362 case XML_ROLE_DOCTYPE_CLOSE
:
3364 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3365 doctypeSysid
, doctypePubid
, 0);
3366 poolClear(&tempPool
);
3367 handleDefault
= XML_FALSE
;
3369 /* doctypeSysid will be non-NULL in the case of a previous
3370 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3371 was not set, indicating an external subset
3374 if (doctypeSysid
|| useForeignDTD
) {
3375 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3376 if (paramEntityParsing
&& externalEntityRefHandler
) {
3377 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3381 return XML_ERROR_NO_MEMORY
;
3383 entity
->base
= curBase
;
3384 dtd
->paramEntityRead
= XML_FALSE
;
3385 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3390 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3391 if (dtd
->paramEntityRead
&&
3393 notStandaloneHandler
&&
3394 !notStandaloneHandler(handlerArg
))
3395 return XML_ERROR_NOT_STANDALONE
;
3396 /* end of DTD - no need to update dtd->keepProcessing */
3398 useForeignDTD
= XML_FALSE
;
3400 #endif /* XML_DTD */
3401 if (endDoctypeDeclHandler
) {
3402 endDoctypeDeclHandler(handlerArg
);
3403 handleDefault
= XML_FALSE
;
3406 case XML_ROLE_INSTANCE_START
:
3408 /* if there is no DOCTYPE declaration then now is the
3409 last chance to read the foreign DTD
3411 if (useForeignDTD
) {
3412 dtd
->hasParamEntityRefs
= XML_TRUE
;
3413 if (paramEntityParsing
&& externalEntityRefHandler
) {
3414 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3418 return XML_ERROR_NO_MEMORY
;
3419 entity
->base
= curBase
;
3420 dtd
->paramEntityRead
= XML_FALSE
;
3421 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3426 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3427 if (dtd
->paramEntityRead
&&
3429 notStandaloneHandler
&&
3430 !notStandaloneHandler(handlerArg
))
3431 return XML_ERROR_NOT_STANDALONE
;
3432 /* end of DTD - no need to update dtd->keepProcessing */
3435 #endif /* XML_DTD */
3436 processor
= contentProcessor
;
3437 return contentProcessor(parser
, s
, end
, nextPtr
);
3438 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3439 declElementType
= getElementType(parser
, enc
, s
, next
);
3440 if (!declElementType
)
3441 return XML_ERROR_NO_MEMORY
;
3442 goto checkAttListDeclHandler
;
3443 case XML_ROLE_ATTRIBUTE_NAME
:
3444 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3445 if (!declAttributeId
)
3446 return XML_ERROR_NO_MEMORY
;
3447 declAttributeIsCdata
= XML_FALSE
;
3448 declAttributeType
= NULL
;
3449 declAttributeIsId
= XML_FALSE
;
3450 goto checkAttListDeclHandler
;
3451 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3452 declAttributeIsCdata
= XML_TRUE
;
3453 declAttributeType
= atypeCDATA
;
3454 goto checkAttListDeclHandler
;
3455 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3456 declAttributeIsId
= XML_TRUE
;
3457 declAttributeType
= atypeID
;
3458 goto checkAttListDeclHandler
;
3459 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3460 declAttributeType
= atypeIDREF
;
3461 goto checkAttListDeclHandler
;
3462 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3463 declAttributeType
= atypeIDREFS
;
3464 goto checkAttListDeclHandler
;
3465 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3466 declAttributeType
= atypeENTITY
;
3467 goto checkAttListDeclHandler
;
3468 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3469 declAttributeType
= atypeENTITIES
;
3470 goto checkAttListDeclHandler
;
3471 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3472 declAttributeType
= atypeNMTOKEN
;
3473 goto checkAttListDeclHandler
;
3474 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3475 declAttributeType
= atypeNMTOKENS
;
3476 checkAttListDeclHandler
:
3477 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3478 handleDefault
= XML_FALSE
;
3480 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3481 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3482 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3483 const XML_Char
*prefix
;
3484 if (declAttributeType
) {
3485 prefix
= enumValueSep
;
3488 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3492 if (!poolAppendString(&tempPool
, prefix
))
3493 return XML_ERROR_NO_MEMORY
;
3494 if (!poolAppend(&tempPool
, enc
, s
, next
))
3495 return XML_ERROR_NO_MEMORY
;
3496 declAttributeType
= tempPool
.start
;
3497 handleDefault
= XML_FALSE
;
3500 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3501 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3502 if (dtd
->keepProcessing
) {
3503 if (!defineAttribute(declElementType
, declAttributeId
,
3504 declAttributeIsCdata
, declAttributeIsId
, 0,
3506 return XML_ERROR_NO_MEMORY
;
3507 if (attlistDeclHandler
&& declAttributeType
) {
3508 if (*declAttributeType
== XML_T('(')
3509 || (*declAttributeType
== XML_T('N')
3510 && declAttributeType
[1] == XML_T('O'))) {
3511 /* Enumerated or Notation type */
3512 if (!poolAppendChar(&tempPool
, XML_T(')'))
3513 || !poolAppendChar(&tempPool
, XML_T('\0')))
3514 return XML_ERROR_NO_MEMORY
;
3515 declAttributeType
= tempPool
.start
;
3516 poolFinish(&tempPool
);
3519 attlistDeclHandler(handlerArg
, declElementType
->name
,
3520 declAttributeId
->name
, declAttributeType
,
3521 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3522 poolClear(&tempPool
);
3523 handleDefault
= XML_FALSE
;
3527 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3528 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3529 if (dtd
->keepProcessing
) {
3530 const XML_Char
*attVal
;
3531 enum XML_Error result
3532 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3533 s
+ enc
->minBytesPerChar
,
3534 next
- enc
->minBytesPerChar
,
3538 attVal
= poolStart(&dtd
->pool
);
3539 poolFinish(&dtd
->pool
);
3540 /* ID attributes aren't allowed to have a default */
3541 if (!defineAttribute(declElementType
, declAttributeId
,
3542 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3543 return XML_ERROR_NO_MEMORY
;
3544 if (attlistDeclHandler
&& declAttributeType
) {
3545 if (*declAttributeType
== XML_T('(')
3546 || (*declAttributeType
== XML_T('N')
3547 && declAttributeType
[1] == XML_T('O'))) {
3548 /* Enumerated or Notation type */
3549 if (!poolAppendChar(&tempPool
, XML_T(')'))
3550 || !poolAppendChar(&tempPool
, XML_T('\0')))
3551 return XML_ERROR_NO_MEMORY
;
3552 declAttributeType
= tempPool
.start
;
3553 poolFinish(&tempPool
);
3556 attlistDeclHandler(handlerArg
, declElementType
->name
,
3557 declAttributeId
->name
, declAttributeType
,
3559 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3560 poolClear(&tempPool
);
3561 handleDefault
= XML_FALSE
;
3565 case XML_ROLE_ENTITY_VALUE
:
3566 if (dtd
->keepProcessing
) {
3567 enum XML_Error result
= storeEntityValue(parser
, enc
,
3568 s
+ enc
->minBytesPerChar
,
3569 next
- enc
->minBytesPerChar
);
3571 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3572 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3573 poolFinish(&dtd
->entityValuePool
);
3574 if (entityDeclHandler
) {
3576 entityDeclHandler(handlerArg
,
3578 declEntity
->is_param
,
3579 declEntity
->textPtr
,
3580 declEntity
->textLen
,
3582 handleDefault
= XML_FALSE
;
3586 poolDiscard(&dtd
->entityValuePool
);
3587 if (result
!= XML_ERROR_NONE
)
3591 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3593 useForeignDTD
= XML_FALSE
;
3594 #endif /* XML_DTD */
3595 dtd
->hasParamEntityRefs
= XML_TRUE
;
3596 if (startDoctypeDeclHandler
) {
3597 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3598 s
+ enc
->minBytesPerChar
,
3599 next
- enc
->minBytesPerChar
);
3600 if (doctypeSysid
== NULL
)
3601 return XML_ERROR_NO_MEMORY
;
3602 poolFinish(&tempPool
);
3603 handleDefault
= XML_FALSE
;
3607 /* use externalSubsetName to make doctypeSysid non-NULL
3608 for the case where no startDoctypeDeclHandler is set */
3609 doctypeSysid
= externalSubsetName
;
3610 #endif /* XML_DTD */
3611 if (!dtd
->standalone
3613 && !paramEntityParsing
3614 #endif /* XML_DTD */
3615 && notStandaloneHandler
3616 && !notStandaloneHandler(handlerArg
))
3617 return XML_ERROR_NOT_STANDALONE
;
3622 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3626 return XML_ERROR_NO_MEMORY
;
3627 declEntity
->publicId
= NULL
;
3630 #endif /* XML_DTD */
3631 case XML_ROLE_ENTITY_SYSTEM_ID
:
3632 if (dtd
->keepProcessing
&& declEntity
) {
3633 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
3634 s
+ enc
->minBytesPerChar
,
3635 next
- enc
->minBytesPerChar
);
3636 if (!declEntity
->systemId
)
3637 return XML_ERROR_NO_MEMORY
;
3638 declEntity
->base
= curBase
;
3639 poolFinish(&dtd
->pool
);
3640 if (entityDeclHandler
)
3641 handleDefault
= XML_FALSE
;
3644 case XML_ROLE_ENTITY_COMPLETE
:
3645 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
3647 entityDeclHandler(handlerArg
,
3649 declEntity
->is_param
,
3652 declEntity
->systemId
,
3653 declEntity
->publicId
,
3655 handleDefault
= XML_FALSE
;
3658 case XML_ROLE_ENTITY_NOTATION_NAME
:
3659 if (dtd
->keepProcessing
&& declEntity
) {
3660 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3661 if (!declEntity
->notation
)
3662 return XML_ERROR_NO_MEMORY
;
3663 poolFinish(&dtd
->pool
);
3664 if (unparsedEntityDeclHandler
) {
3666 unparsedEntityDeclHandler(handlerArg
,
3669 declEntity
->systemId
,
3670 declEntity
->publicId
,
3671 declEntity
->notation
);
3672 handleDefault
= XML_FALSE
;
3674 else if (entityDeclHandler
) {
3676 entityDeclHandler(handlerArg
,
3680 declEntity
->systemId
,
3681 declEntity
->publicId
,
3682 declEntity
->notation
);
3683 handleDefault
= XML_FALSE
;
3687 case XML_ROLE_GENERAL_ENTITY_NAME
:
3689 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3693 if (dtd
->keepProcessing
) {
3694 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3696 return XML_ERROR_NO_MEMORY
;
3697 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
3700 return XML_ERROR_NO_MEMORY
;
3701 if (declEntity
->name
!= name
) {
3702 poolDiscard(&dtd
->pool
);
3706 poolFinish(&dtd
->pool
);
3707 declEntity
->publicId
= NULL
;
3708 declEntity
->is_param
= XML_FALSE
;
3709 /* if we have a parent parser or are reading an internal parameter
3710 entity, then the entity declaration is not considered "internal"
3712 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3713 if (entityDeclHandler
)
3714 handleDefault
= XML_FALSE
;
3718 poolDiscard(&dtd
->pool
);
3723 case XML_ROLE_PARAM_ENTITY_NAME
:
3725 if (dtd
->keepProcessing
) {
3726 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3728 return XML_ERROR_NO_MEMORY
;
3729 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3730 name
, sizeof(ENTITY
));
3732 return XML_ERROR_NO_MEMORY
;
3733 if (declEntity
->name
!= name
) {
3734 poolDiscard(&dtd
->pool
);
3738 poolFinish(&dtd
->pool
);
3739 declEntity
->publicId
= NULL
;
3740 declEntity
->is_param
= XML_TRUE
;
3741 /* if we have a parent parser or are reading an internal parameter
3742 entity, then the entity declaration is not considered "internal"
3744 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3745 if (entityDeclHandler
)
3746 handleDefault
= XML_FALSE
;
3750 poolDiscard(&dtd
->pool
);
3753 #else /* not XML_DTD */
3755 #endif /* XML_DTD */
3757 case XML_ROLE_NOTATION_NAME
:
3758 declNotationPublicId
= NULL
;
3759 declNotationName
= NULL
;
3760 if (notationDeclHandler
) {
3761 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3762 if (!declNotationName
)
3763 return XML_ERROR_NO_MEMORY
;
3764 poolFinish(&tempPool
);
3765 handleDefault
= XML_FALSE
;
3768 case XML_ROLE_NOTATION_PUBLIC_ID
:
3769 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3770 return XML_ERROR_SYNTAX
;
3771 if (declNotationName
) { /* means notationDeclHandler != NULL */
3772 XML_Char
*tem
= poolStoreString(&tempPool
,
3774 s
+ enc
->minBytesPerChar
,
3775 next
- enc
->minBytesPerChar
);
3777 return XML_ERROR_NO_MEMORY
;
3778 normalizePublicId(tem
);
3779 declNotationPublicId
= tem
;
3780 poolFinish(&tempPool
);
3781 handleDefault
= XML_FALSE
;
3784 case XML_ROLE_NOTATION_SYSTEM_ID
:
3785 if (declNotationName
&& notationDeclHandler
) {
3786 const XML_Char
*systemId
3787 = poolStoreString(&tempPool
, enc
,
3788 s
+ enc
->minBytesPerChar
,
3789 next
- enc
->minBytesPerChar
);
3791 return XML_ERROR_NO_MEMORY
;
3793 notationDeclHandler(handlerArg
,
3797 declNotationPublicId
);
3798 handleDefault
= XML_FALSE
;
3800 poolClear(&tempPool
);
3802 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3803 if (declNotationPublicId
&& notationDeclHandler
) {
3805 notationDeclHandler(handlerArg
,
3809 declNotationPublicId
);
3810 handleDefault
= XML_FALSE
;
3812 poolClear(&tempPool
);
3814 case XML_ROLE_ERROR
:
3816 case XML_TOK_PARAM_ENTITY_REF
:
3817 return XML_ERROR_PARAM_ENTITY_REF
;
3818 case XML_TOK_XML_DECL
:
3819 return XML_ERROR_MISPLACED_XML_PI
;
3821 return XML_ERROR_SYNTAX
;
3824 case XML_ROLE_IGNORE_SECT
:
3826 enum XML_Error result
;
3828 reportDefault(parser
, enc
, s
, next
);
3829 handleDefault
= XML_FALSE
;
3830 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3832 processor
= ignoreSectionProcessor
;
3837 #endif /* XML_DTD */
3838 case XML_ROLE_GROUP_OPEN
:
3839 if (prologState
.level
>= groupSize
) {
3841 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
3843 return XML_ERROR_NO_MEMORY
;
3844 groupConnector
= temp
;
3845 if (dtd
->scaffIndex
) {
3846 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
3847 groupSize
* sizeof(int));
3849 return XML_ERROR_NO_MEMORY
;
3850 dtd
->scaffIndex
= temp
;
3854 groupConnector
= (char *)MALLOC(groupSize
= 32);
3855 if (!groupConnector
)
3856 return XML_ERROR_NO_MEMORY
;
3859 groupConnector
[prologState
.level
] = 0;
3860 if (dtd
->in_eldecl
) {
3861 int myindex
= nextScaffoldPart(parser
);
3863 return XML_ERROR_NO_MEMORY
;
3864 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
3866 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3867 if (elementDeclHandler
)
3868 handleDefault
= XML_FALSE
;
3871 case XML_ROLE_GROUP_SEQUENCE
:
3872 if (groupConnector
[prologState
.level
] == '|')
3873 return XML_ERROR_SYNTAX
;
3874 groupConnector
[prologState
.level
] = ',';
3875 if (dtd
->in_eldecl
&& elementDeclHandler
)
3876 handleDefault
= XML_FALSE
;
3878 case XML_ROLE_GROUP_CHOICE
:
3879 if (groupConnector
[prologState
.level
] == ',')
3880 return XML_ERROR_SYNTAX
;
3882 && !groupConnector
[prologState
.level
]
3883 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3886 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3888 if (elementDeclHandler
)
3889 handleDefault
= XML_FALSE
;
3891 groupConnector
[prologState
.level
] = '|';
3893 case XML_ROLE_PARAM_ENTITY_REF
:
3895 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3896 /* PE references in internal subset are
3897 not allowed within declarations */
3898 if (prologState
.documentEntity
&&
3899 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3900 return XML_ERROR_PARAM_ENTITY_REF
;
3901 dtd
->hasParamEntityRefs
= XML_TRUE
;
3902 if (!paramEntityParsing
)
3903 dtd
->keepProcessing
= dtd
->standalone
;
3905 const XML_Char
*name
;
3907 name
= poolStoreString(&dtd
->pool
, enc
,
3908 s
+ enc
->minBytesPerChar
,
3909 next
- enc
->minBytesPerChar
);
3911 return XML_ERROR_NO_MEMORY
;
3912 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
3913 poolDiscard(&dtd
->pool
);
3914 /* first, determine if a check for an existing declaration is needed;
3915 if yes, check that the entity exists, and that it is internal,
3916 otherwise call the skipped entity handler
3918 if (prologState
.documentEntity
&&
3920 ? !openInternalEntities
3921 : !dtd
->hasParamEntityRefs
)) {
3923 return XML_ERROR_UNDEFINED_ENTITY
;
3924 else if (!entity
->is_internal
)
3925 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3928 dtd
->keepProcessing
= dtd
->standalone
;
3929 /* cannot report skipped entities in declarations */
3930 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3931 skippedEntityHandler(handlerArg
, name
, 1);
3932 handleDefault
= XML_FALSE
;
3937 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3938 if (entity
->textPtr
) {
3939 enum XML_Error result
;
3940 result
= processInternalParamEntity(parser
, entity
);
3941 if (result
!= XML_ERROR_NONE
)
3943 handleDefault
= XML_FALSE
;
3946 if (externalEntityRefHandler
) {
3947 dtd
->paramEntityRead
= XML_FALSE
;
3948 entity
->open
= XML_TRUE
;
3949 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3953 entity
->publicId
)) {
3954 entity
->open
= XML_FALSE
;
3955 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3957 entity
->open
= XML_FALSE
;
3958 handleDefault
= XML_FALSE
;
3959 if (!dtd
->paramEntityRead
) {
3960 dtd
->keepProcessing
= dtd
->standalone
;
3965 dtd
->keepProcessing
= dtd
->standalone
;
3969 #endif /* XML_DTD */
3970 if (!dtd
->standalone
&&
3971 notStandaloneHandler
&&
3972 !notStandaloneHandler(handlerArg
))
3973 return XML_ERROR_NOT_STANDALONE
;
3976 /* Element declaration stuff */
3978 case XML_ROLE_ELEMENT_NAME
:
3979 if (elementDeclHandler
) {
3980 declElementType
= getElementType(parser
, enc
, s
, next
);
3981 if (!declElementType
)
3982 return XML_ERROR_NO_MEMORY
;
3983 dtd
->scaffLevel
= 0;
3984 dtd
->scaffCount
= 0;
3985 dtd
->in_eldecl
= XML_TRUE
;
3986 handleDefault
= XML_FALSE
;
3990 case XML_ROLE_CONTENT_ANY
:
3991 case XML_ROLE_CONTENT_EMPTY
:
3992 if (dtd
->in_eldecl
) {
3993 if (elementDeclHandler
) {
3994 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3996 return XML_ERROR_NO_MEMORY
;
3997 content
->quant
= XML_CQUANT_NONE
;
3998 content
->name
= NULL
;
3999 content
->numchildren
= 0;
4000 content
->children
= NULL
;
4001 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4005 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4006 handleDefault
= XML_FALSE
;
4008 dtd
->in_eldecl
= XML_FALSE
;
4012 case XML_ROLE_CONTENT_PCDATA
:
4013 if (dtd
->in_eldecl
) {
4014 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4016 if (elementDeclHandler
)
4017 handleDefault
= XML_FALSE
;
4021 case XML_ROLE_CONTENT_ELEMENT
:
4022 quant
= XML_CQUANT_NONE
;
4023 goto elementContent
;
4024 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4025 quant
= XML_CQUANT_OPT
;
4026 goto elementContent
;
4027 case XML_ROLE_CONTENT_ELEMENT_REP
:
4028 quant
= XML_CQUANT_REP
;
4029 goto elementContent
;
4030 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4031 quant
= XML_CQUANT_PLUS
;
4033 if (dtd
->in_eldecl
) {
4035 const XML_Char
*name
;
4037 const char *nxt
= (quant
== XML_CQUANT_NONE
4039 : next
- enc
->minBytesPerChar
);
4040 int myindex
= nextScaffoldPart(parser
);
4042 return XML_ERROR_NO_MEMORY
;
4043 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4044 dtd
->scaffold
[myindex
].quant
= quant
;
4045 el
= getElementType(parser
, enc
, s
, nxt
);
4047 return XML_ERROR_NO_MEMORY
;
4049 dtd
->scaffold
[myindex
].name
= name
;
4051 for (; name
[nameLen
++]; )
4053 dtd
->contentStringLen
+= nameLen
;
4054 if (elementDeclHandler
)
4055 handleDefault
= XML_FALSE
;
4059 case XML_ROLE_GROUP_CLOSE
:
4060 quant
= XML_CQUANT_NONE
;
4062 case XML_ROLE_GROUP_CLOSE_OPT
:
4063 quant
= XML_CQUANT_OPT
;
4065 case XML_ROLE_GROUP_CLOSE_REP
:
4066 quant
= XML_CQUANT_REP
;
4068 case XML_ROLE_GROUP_CLOSE_PLUS
:
4069 quant
= XML_CQUANT_PLUS
;
4071 if (dtd
->in_eldecl
) {
4072 if (elementDeclHandler
)
4073 handleDefault
= XML_FALSE
;
4075 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4076 if (dtd
->scaffLevel
== 0) {
4077 if (!handleDefault
) {
4078 XML_Content
*model
= build_model(parser
);
4080 return XML_ERROR_NO_MEMORY
;
4082 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4084 dtd
->in_eldecl
= XML_FALSE
;
4085 dtd
->contentStringLen
= 0;
4089 /* End element declaration stuff */
4092 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4093 return XML_ERROR_NO_MEMORY
;
4094 handleDefault
= XML_FALSE
;
4096 case XML_ROLE_COMMENT
:
4097 if (!reportComment(parser
, enc
, s
, next
))
4098 return XML_ERROR_NO_MEMORY
;
4099 handleDefault
= XML_FALSE
;
4104 handleDefault
= XML_FALSE
;
4108 case XML_ROLE_DOCTYPE_NONE
:
4109 if (startDoctypeDeclHandler
)
4110 handleDefault
= XML_FALSE
;
4112 case XML_ROLE_ENTITY_NONE
:
4113 if (dtd
->keepProcessing
&& entityDeclHandler
)
4114 handleDefault
= XML_FALSE
;
4116 case XML_ROLE_NOTATION_NONE
:
4117 if (notationDeclHandler
)
4118 handleDefault
= XML_FALSE
;
4120 case XML_ROLE_ATTLIST_NONE
:
4121 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4122 handleDefault
= XML_FALSE
;
4124 case XML_ROLE_ELEMENT_NONE
:
4125 if (elementDeclHandler
)
4126 handleDefault
= XML_FALSE
;
4128 } /* end of big switch */
4130 if (handleDefault
&& defaultHandler
)
4131 reportDefault(parser
, enc
, s
, next
);
4134 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4139 static enum XML_Error PTRCALL
4140 epilogProcessor(XML_Parser parser
,
4143 const char **nextPtr
)
4145 processor
= epilogProcessor
;
4148 const char *next
= NULL
;
4149 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4152 /* report partial linebreak - it might be the last token */
4153 case -XML_TOK_PROLOG_S
:
4154 if (defaultHandler
) {
4156 reportDefault(parser
, encoding
, s
, next
);
4160 return XML_ERROR_NONE
;
4164 return XML_ERROR_NONE
;
4165 case XML_TOK_PROLOG_S
:
4167 reportDefault(parser
, encoding
, s
, next
);
4170 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4171 return XML_ERROR_NO_MEMORY
;
4173 case XML_TOK_COMMENT
:
4174 if (!reportComment(parser
, encoding
, s
, next
))
4175 return XML_ERROR_NO_MEMORY
;
4177 case XML_TOK_INVALID
:
4179 return XML_ERROR_INVALID_TOKEN
;
4180 case XML_TOK_PARTIAL
:
4183 return XML_ERROR_NONE
;
4185 return XML_ERROR_UNCLOSED_TOKEN
;
4186 case XML_TOK_PARTIAL_CHAR
:
4189 return XML_ERROR_NONE
;
4191 return XML_ERROR_PARTIAL_CHAR
;
4193 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4195 eventPtr
= s
= next
;
4201 static enum XML_Error
4202 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4204 const char *s
, *end
, *next
;
4206 enum XML_Error result
;
4207 OPEN_INTERNAL_ENTITY openEntity
;
4208 entity
->open
= XML_TRUE
;
4209 openEntity
.next
= openInternalEntities
;
4210 openInternalEntities
= &openEntity
;
4211 openEntity
.entity
= entity
;
4212 openEntity
.internalEventPtr
= NULL
;
4213 openEntity
.internalEventEndPtr
= NULL
;
4214 s
= (char *)entity
->textPtr
;
4215 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4216 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4217 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4218 entity
->open
= XML_FALSE
;
4219 openInternalEntities
= openEntity
.next
;
4223 #endif /* XML_DTD */
4225 static enum XML_Error PTRCALL
4226 errorProcessor(XML_Parser parser
,
4229 const char **nextPtr
)
4234 static enum XML_Error
4235 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4236 const char *ptr
, const char *end
,
4239 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4243 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4245 if (!poolAppendChar(pool
, XML_T('\0')))
4246 return XML_ERROR_NO_MEMORY
;
4247 return XML_ERROR_NONE
;
4250 static enum XML_Error
4251 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4252 const char *ptr
, const char *end
,
4255 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4258 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4261 return XML_ERROR_NONE
;
4262 case XML_TOK_INVALID
:
4263 if (enc
== encoding
)
4265 return XML_ERROR_INVALID_TOKEN
;
4266 case XML_TOK_PARTIAL
:
4267 if (enc
== encoding
)
4269 return XML_ERROR_INVALID_TOKEN
;
4270 case XML_TOK_CHAR_REF
:
4272 XML_Char buf
[XML_ENCODE_MAX
];
4274 int n
= XmlCharRefNumber(enc
, ptr
);
4276 if (enc
== encoding
)
4278 return XML_ERROR_BAD_CHAR_REF
;
4281 && n
== 0x20 /* space */
4282 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4284 n
= XmlEncode(n
, (ICHAR
*)buf
);
4286 if (enc
== encoding
)
4288 return XML_ERROR_BAD_CHAR_REF
;
4290 for (i
= 0; i
< n
; i
++) {
4291 if (!poolAppendChar(pool
, buf
[i
]))
4292 return XML_ERROR_NO_MEMORY
;
4296 case XML_TOK_DATA_CHARS
:
4297 if (!poolAppend(pool
, enc
, ptr
, next
))
4298 return XML_ERROR_NO_MEMORY
;
4300 case XML_TOK_TRAILING_CR
:
4301 next
= ptr
+ enc
->minBytesPerChar
;
4303 case XML_TOK_ATTRIBUTE_VALUE_S
:
4304 case XML_TOK_DATA_NEWLINE
:
4305 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4307 if (!poolAppendChar(pool
, 0x20))
4308 return XML_ERROR_NO_MEMORY
;
4310 case XML_TOK_ENTITY_REF
:
4312 const XML_Char
*name
;
4314 char checkEntityDecl
;
4315 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4316 ptr
+ enc
->minBytesPerChar
,
4317 next
- enc
->minBytesPerChar
);
4319 if (!poolAppendChar(pool
, ch
))
4320 return XML_ERROR_NO_MEMORY
;
4323 name
= poolStoreString(&temp2Pool
, enc
,
4324 ptr
+ enc
->minBytesPerChar
,
4325 next
- enc
->minBytesPerChar
);
4327 return XML_ERROR_NO_MEMORY
;
4328 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4329 poolDiscard(&temp2Pool
);
4330 /* first, determine if a check for an existing declaration is needed;
4331 if yes, check that the entity exists, and that it is internal,
4332 otherwise call the default handler (if called from content)
4334 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4337 prologState
.documentEntity
&&
4338 #endif /* XML_DTD */
4340 ? !openInternalEntities
4341 : !dtd
->hasParamEntityRefs
);
4342 else /* if (pool == &tempPool): we are called from content */
4343 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4344 if (checkEntityDecl
) {
4346 return XML_ERROR_UNDEFINED_ENTITY
;
4347 else if (!entity
->is_internal
)
4348 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4351 /* cannot report skipped entity here - see comments on
4352 skippedEntityHandler
4353 if (skippedEntityHandler)
4354 skippedEntityHandler(handlerArg, name, 0);
4356 if ((pool
== &tempPool
) && defaultHandler
)
4357 reportDefault(parser
, enc
, ptr
, next
);
4361 if (enc
== encoding
)
4363 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4365 if (entity
->notation
) {
4366 if (enc
== encoding
)
4368 return XML_ERROR_BINARY_ENTITY_REF
;
4370 if (!entity
->textPtr
) {
4371 if (enc
== encoding
)
4373 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4376 enum XML_Error result
;
4377 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4378 entity
->open
= XML_TRUE
;
4379 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4380 (char *)entity
->textPtr
,
4381 (char *)textEnd
, pool
);
4382 entity
->open
= XML_FALSE
;
4389 if (enc
== encoding
)
4391 return XML_ERROR_UNEXPECTED_STATE
;
4398 static enum XML_Error
4399 storeEntityValue(XML_Parser parser
,
4400 const ENCODING
*enc
,
4401 const char *entityTextPtr
,
4402 const char *entityTextEnd
)
4404 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4405 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4406 enum XML_Error result
= XML_ERROR_NONE
;
4408 int oldInEntityValue
= prologState
.inEntityValue
;
4409 prologState
.inEntityValue
= 1;
4410 #endif /* XML_DTD */
4411 /* never return Null for the value argument in EntityDeclHandler,
4412 since this would indicate an external entity; therefore we
4413 have to make sure that entityValuePool.start is not null */
4414 if (!pool
->blocks
) {
4415 if (!poolGrow(pool
))
4416 return XML_ERROR_NO_MEMORY
;
4421 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4423 case XML_TOK_PARAM_ENTITY_REF
:
4425 if (isParamEntity
|| enc
!= encoding
) {
4426 const XML_Char
*name
;
4428 name
= poolStoreString(&tempPool
, enc
,
4429 entityTextPtr
+ enc
->minBytesPerChar
,
4430 next
- enc
->minBytesPerChar
);
4432 result
= XML_ERROR_NO_MEMORY
;
4433 goto endEntityValue
;
4435 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4436 poolDiscard(&tempPool
);
4438 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4439 /* cannot report skipped entity here - see comments on
4440 skippedEntityHandler
4441 if (skippedEntityHandler)
4442 skippedEntityHandler(handlerArg, name, 0);
4444 dtd
->keepProcessing
= dtd
->standalone
;
4445 goto endEntityValue
;
4448 if (enc
== encoding
)
4449 eventPtr
= entityTextPtr
;
4450 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4451 goto endEntityValue
;
4453 if (entity
->systemId
) {
4454 if (externalEntityRefHandler
) {
4455 dtd
->paramEntityRead
= XML_FALSE
;
4456 entity
->open
= XML_TRUE
;
4457 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4461 entity
->publicId
)) {
4462 entity
->open
= XML_FALSE
;
4463 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4464 goto endEntityValue
;
4466 entity
->open
= XML_FALSE
;
4467 if (!dtd
->paramEntityRead
)
4468 dtd
->keepProcessing
= dtd
->standalone
;
4471 dtd
->keepProcessing
= dtd
->standalone
;
4474 entity
->open
= XML_TRUE
;
4475 result
= storeEntityValue(parser
,
4477 (char *)entity
->textPtr
,
4478 (char *)(entity
->textPtr
4479 + entity
->textLen
));
4480 entity
->open
= XML_FALSE
;
4482 goto endEntityValue
;
4486 #endif /* XML_DTD */
4487 /* in the internal subset, PE references are not legal
4488 within markup declarations, e.g entity values in this case */
4489 eventPtr
= entityTextPtr
;
4490 result
= XML_ERROR_PARAM_ENTITY_REF
;
4491 goto endEntityValue
;
4493 result
= XML_ERROR_NONE
;
4494 goto endEntityValue
;
4495 case XML_TOK_ENTITY_REF
:
4496 case XML_TOK_DATA_CHARS
:
4497 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4498 result
= XML_ERROR_NO_MEMORY
;
4499 goto endEntityValue
;
4502 case XML_TOK_TRAILING_CR
:
4503 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4505 case XML_TOK_DATA_NEWLINE
:
4506 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4507 result
= XML_ERROR_NO_MEMORY
;
4508 goto endEntityValue
;
4510 *(pool
->ptr
)++ = 0xA;
4512 case XML_TOK_CHAR_REF
:
4514 XML_Char buf
[XML_ENCODE_MAX
];
4516 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4518 if (enc
== encoding
)
4519 eventPtr
= entityTextPtr
;
4520 result
= XML_ERROR_BAD_CHAR_REF
;
4521 goto endEntityValue
;
4523 n
= XmlEncode(n
, (ICHAR
*)buf
);
4525 if (enc
== encoding
)
4526 eventPtr
= entityTextPtr
;
4527 result
= XML_ERROR_BAD_CHAR_REF
;
4528 goto endEntityValue
;
4530 for (i
= 0; i
< n
; i
++) {
4531 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4532 result
= XML_ERROR_NO_MEMORY
;
4533 goto endEntityValue
;
4535 *(pool
->ptr
)++ = buf
[i
];
4539 case XML_TOK_PARTIAL
:
4540 if (enc
== encoding
)
4541 eventPtr
= entityTextPtr
;
4542 result
= XML_ERROR_INVALID_TOKEN
;
4543 goto endEntityValue
;
4544 case XML_TOK_INVALID
:
4545 if (enc
== encoding
)
4547 result
= XML_ERROR_INVALID_TOKEN
;
4548 goto endEntityValue
;
4550 if (enc
== encoding
)
4551 eventPtr
= entityTextPtr
;
4552 result
= XML_ERROR_UNEXPECTED_STATE
;
4553 goto endEntityValue
;
4555 entityTextPtr
= next
;
4559 prologState
.inEntityValue
= oldInEntityValue
;
4560 #endif /* XML_DTD */
4564 static void FASTCALL
4565 normalizeLines(XML_Char
*s
)
4569 if (*s
== XML_T('\0'))
4588 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4589 const char *start
, const char *end
)
4591 const XML_Char
*target
;
4594 if (!processingInstructionHandler
) {
4596 reportDefault(parser
, enc
, start
, end
);
4599 start
+= enc
->minBytesPerChar
* 2;
4600 tem
= start
+ XmlNameLength(enc
, start
);
4601 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4604 poolFinish(&tempPool
);
4605 data
= poolStoreString(&tempPool
, enc
,
4607 end
- enc
->minBytesPerChar
*2);
4610 normalizeLines(data
);
4611 processingInstructionHandler(handlerArg
, target
, data
);
4612 poolClear(&tempPool
);
4617 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4618 const char *start
, const char *end
)
4621 if (!commentHandler
) {
4623 reportDefault(parser
, enc
, start
, end
);
4626 data
= poolStoreString(&tempPool
,
4628 start
+ enc
->minBytesPerChar
* 4,
4629 end
- enc
->minBytesPerChar
* 3);
4632 normalizeLines(data
);
4633 commentHandler(handlerArg
, data
);
4634 poolClear(&tempPool
);
4639 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4640 const char *s
, const char *end
)
4642 if (MUST_CONVERT(enc
, s
)) {
4643 const char **eventPP
;
4644 const char **eventEndPP
;
4645 if (enc
== encoding
) {
4646 eventPP
= &eventPtr
;
4647 eventEndPP
= &eventEndPtr
;
4650 eventPP
= &(openInternalEntities
->internalEventPtr
);
4651 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4654 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4655 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4657 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4662 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4667 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4668 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4670 DEFAULT_ATTRIBUTE
*att
;
4671 if (value
|| isId
) {
4672 /* The handling of default attributes gets messed up if we have
4673 a default which duplicates a non-default. */
4675 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4676 if (attId
== type
->defaultAtts
[i
].id
)
4678 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4679 type
->idAtt
= attId
;
4681 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4682 if (type
->allocDefaultAtts
== 0) {
4683 type
->allocDefaultAtts
= 8;
4684 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
4685 * sizeof(DEFAULT_ATTRIBUTE
));
4686 if (!type
->defaultAtts
)
4690 DEFAULT_ATTRIBUTE
*temp
;
4691 int count
= type
->allocDefaultAtts
* 2;
4692 temp
= (DEFAULT_ATTRIBUTE
*)
4693 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4696 type
->allocDefaultAtts
= count
;
4697 type
->defaultAtts
= temp
;
4700 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4703 att
->isCdata
= isCdata
;
4705 attId
->maybeTokenized
= XML_TRUE
;
4706 type
->nDefaultAtts
+= 1;
4711 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4713 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4714 const XML_Char
*name
;
4715 for (name
= elementType
->name
; *name
; name
++) {
4716 if (*name
== XML_T(':')) {
4719 for (s
= elementType
->name
; s
!= name
; s
++) {
4720 if (!poolAppendChar(&dtd
->pool
, *s
))
4723 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4725 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4729 if (prefix
->name
== poolStart(&dtd
->pool
))
4730 poolFinish(&dtd
->pool
);
4732 poolDiscard(&dtd
->pool
);
4733 elementType
->prefix
= prefix
;
4740 static ATTRIBUTE_ID
*
4741 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4742 const char *start
, const char *end
)
4744 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4746 const XML_Char
*name
;
4747 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4749 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
4753 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4756 if (id
->name
!= name
)
4757 poolDiscard(&dtd
->pool
);
4759 poolFinish(&dtd
->pool
);
4762 else if (name
[0] == XML_T('x')
4763 && name
[1] == XML_T('m')
4764 && name
[2] == XML_T('l')
4765 && name
[3] == XML_T('n')
4766 && name
[4] == XML_T('s')
4767 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4768 if (name
[5] == XML_T('\0'))
4769 id
->prefix
= &dtd
->defaultPrefix
;
4771 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
4772 id
->xmlns
= XML_TRUE
;
4776 for (i
= 0; name
[i
]; i
++) {
4777 if (name
[i
] == XML_T(':')) {
4779 for (j
= 0; j
< i
; j
++) {
4780 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
4783 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4785 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4787 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
4788 poolFinish(&dtd
->pool
);
4790 poolDiscard(&dtd
->pool
);
4799 #define CONTEXT_SEP XML_T('\f')
4801 static const XML_Char
*
4802 getContext(XML_Parser parser
)
4804 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4805 HASH_TABLE_ITER iter
;
4806 XML_Bool needSep
= XML_FALSE
;
4808 if (dtd
->defaultPrefix
.binding
) {
4811 if (!poolAppendChar(&tempPool
, XML_T('=')))
4813 len
= dtd
->defaultPrefix
.binding
->uriLen
;
4814 if (namespaceSeparator
!= XML_T('\0'))
4816 for (i
= 0; i
< len
; i
++)
4817 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
4822 hashTableIterInit(&iter
, &(dtd
->prefixes
));
4827 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4830 if (!prefix
->binding
)
4832 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4834 for (s
= prefix
->name
; *s
; s
++)
4835 if (!poolAppendChar(&tempPool
, *s
))
4837 if (!poolAppendChar(&tempPool
, XML_T('=')))
4839 len
= prefix
->binding
->uriLen
;
4840 if (namespaceSeparator
!= XML_T('\0'))
4842 for (i
= 0; i
< len
; i
++)
4843 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4849 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
4852 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4857 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4859 for (s
= e
->name
; *s
; s
++)
4860 if (!poolAppendChar(&tempPool
, *s
))
4865 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4867 return tempPool
.start
;
4871 setContext(XML_Parser parser
, const XML_Char
*context
)
4873 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4874 const XML_Char
*s
= context
;
4876 while (*context
!= XML_T('\0')) {
4877 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4879 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4881 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
4884 if (*s
!= XML_T('\0'))
4887 poolDiscard(&tempPool
);
4889 else if (*s
== XML_T('=')) {
4891 if (poolLength(&tempPool
) == 0)
4892 prefix
= &dtd
->defaultPrefix
;
4894 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4896 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
4900 if (prefix
->name
== poolStart(&tempPool
)) {
4901 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
4905 poolDiscard(&tempPool
);
4907 for (context
= s
+ 1;
4908 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4910 if (!poolAppendChar(&tempPool
, *context
))
4912 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4914 if (addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4915 &inheritedBindings
) != XML_ERROR_NONE
)
4917 poolDiscard(&tempPool
);
4918 if (*context
!= XML_T('\0'))
4923 if (!poolAppendChar(&tempPool
, *s
))
4931 static void FASTCALL
4932 normalizePublicId(XML_Char
*publicId
)
4934 XML_Char
*p
= publicId
;
4936 for (s
= publicId
; *s
; s
++) {
4941 if (p
!= publicId
&& p
[-1] != 0x20)
4948 if (p
!= publicId
&& p
[-1] == 0x20)
4954 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
4956 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
4959 poolInit(&(p
->pool
), ms
);
4961 poolInit(&(p
->entityValuePool
), ms
);
4962 #endif /* XML_DTD */
4963 hashTableInit(&(p
->generalEntities
), ms
);
4964 hashTableInit(&(p
->elementTypes
), ms
);
4965 hashTableInit(&(p
->attributeIds
), ms
);
4966 hashTableInit(&(p
->prefixes
), ms
);
4968 p
->paramEntityRead
= XML_FALSE
;
4969 hashTableInit(&(p
->paramEntities
), ms
);
4970 #endif /* XML_DTD */
4971 p
->defaultPrefix
.name
= NULL
;
4972 p
->defaultPrefix
.binding
= NULL
;
4974 p
->in_eldecl
= XML_FALSE
;
4975 p
->scaffIndex
= NULL
;
4980 p
->contentStringLen
= 0;
4982 p
->keepProcessing
= XML_TRUE
;
4983 p
->hasParamEntityRefs
= XML_FALSE
;
4984 p
->standalone
= XML_FALSE
;
4989 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
4991 HASH_TABLE_ITER iter
;
4992 hashTableIterInit(&iter
, &(p
->elementTypes
));
4994 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4997 if (e
->allocDefaultAtts
!= 0)
4998 ms
->free_fcn(e
->defaultAtts
);
5000 hashTableClear(&(p
->generalEntities
));
5002 p
->paramEntityRead
= XML_FALSE
;
5003 hashTableClear(&(p
->paramEntities
));
5004 #endif /* XML_DTD */
5005 hashTableClear(&(p
->elementTypes
));
5006 hashTableClear(&(p
->attributeIds
));
5007 hashTableClear(&(p
->prefixes
));
5008 poolClear(&(p
->pool
));
5010 poolClear(&(p
->entityValuePool
));
5011 #endif /* XML_DTD */
5012 p
->defaultPrefix
.name
= NULL
;
5013 p
->defaultPrefix
.binding
= NULL
;
5015 p
->in_eldecl
= XML_FALSE
;
5016 if (p
->scaffIndex
) {
5017 ms
->free_fcn(p
->scaffIndex
);
5018 p
->scaffIndex
= NULL
;
5021 ms
->free_fcn(p
->scaffold
);
5027 p
->contentStringLen
= 0;
5029 p
->keepProcessing
= XML_TRUE
;
5030 p
->hasParamEntityRefs
= XML_FALSE
;
5031 p
->standalone
= XML_FALSE
;
5035 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5037 HASH_TABLE_ITER iter
;
5038 hashTableIterInit(&iter
, &(p
->elementTypes
));
5040 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5043 if (e
->allocDefaultAtts
!= 0)
5044 ms
->free_fcn(e
->defaultAtts
);
5046 hashTableDestroy(&(p
->generalEntities
));
5048 hashTableDestroy(&(p
->paramEntities
));
5049 #endif /* XML_DTD */
5050 hashTableDestroy(&(p
->elementTypes
));
5051 hashTableDestroy(&(p
->attributeIds
));
5052 hashTableDestroy(&(p
->prefixes
));
5053 poolDestroy(&(p
->pool
));
5055 poolDestroy(&(p
->entityValuePool
));
5056 #endif /* XML_DTD */
5059 ms
->free_fcn(p
->scaffIndex
);
5061 ms
->free_fcn(p
->scaffold
);
5066 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5067 The new DTD has already been initialized.
5070 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5072 HASH_TABLE_ITER iter
;
5074 /* Copy the prefix table. */
5076 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5078 const XML_Char
*name
;
5079 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5082 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5085 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5089 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5091 /* Copy the attribute id table. */
5095 const XML_Char
*name
;
5096 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5100 /* Remember to allocate the scratch byte before the name. */
5101 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5103 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5107 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5108 sizeof(ATTRIBUTE_ID
));
5111 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5113 newA
->xmlns
= oldA
->xmlns
;
5114 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5115 newA
->prefix
= &newDtd
->defaultPrefix
;
5117 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5118 oldA
->prefix
->name
, 0);
5122 /* Copy the element type table. */
5124 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5129 const XML_Char
*name
;
5130 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5133 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5136 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5137 sizeof(ELEMENT_TYPE
));
5140 if (oldE
->nDefaultAtts
) {
5141 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5142 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5143 if (!newE
->defaultAtts
) {
5149 newE
->idAtt
= (ATTRIBUTE_ID
*)
5150 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5151 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5153 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5154 oldE
->prefix
->name
, 0);
5155 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5156 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5157 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5158 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5159 if (oldE
->defaultAtts
[i
].value
) {
5160 newE
->defaultAtts
[i
].value
5161 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5162 if (!newE
->defaultAtts
[i
].value
)
5166 newE
->defaultAtts
[i
].value
= NULL
;
5170 /* Copy the entity tables. */
5171 if (!copyEntityTable(&(newDtd
->generalEntities
),
5173 &(oldDtd
->generalEntities
)))
5177 if (!copyEntityTable(&(newDtd
->paramEntities
),
5179 &(oldDtd
->paramEntities
)))
5181 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5182 #endif /* XML_DTD */
5184 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5185 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5186 newDtd
->standalone
= oldDtd
->standalone
;
5188 /* Don't want deep copying for scaffolding */
5189 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5190 newDtd
->scaffold
= oldDtd
->scaffold
;
5191 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5192 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5193 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5194 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5200 copyEntityTable(HASH_TABLE
*newTable
,
5201 STRING_POOL
*newPool
,
5202 const HASH_TABLE
*oldTable
)
5204 HASH_TABLE_ITER iter
;
5205 const XML_Char
*cachedOldBase
= NULL
;
5206 const XML_Char
*cachedNewBase
= NULL
;
5208 hashTableIterInit(&iter
, oldTable
);
5212 const XML_Char
*name
;
5213 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5216 name
= poolCopyString(newPool
, oldE
->name
);
5219 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5222 if (oldE
->systemId
) {
5223 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5226 newE
->systemId
= tem
;
5228 if (oldE
->base
== cachedOldBase
)
5229 newE
->base
= cachedNewBase
;
5231 cachedOldBase
= oldE
->base
;
5232 tem
= poolCopyString(newPool
, cachedOldBase
);
5235 cachedNewBase
= newE
->base
= tem
;
5238 if (oldE
->publicId
) {
5239 tem
= poolCopyString(newPool
, oldE
->publicId
);
5242 newE
->publicId
= tem
;
5246 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5250 newE
->textPtr
= tem
;
5251 newE
->textLen
= oldE
->textLen
;
5253 if (oldE
->notation
) {
5254 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5257 newE
->notation
= tem
;
5259 newE
->is_param
= oldE
->is_param
;
5260 newE
->is_internal
= oldE
->is_internal
;
5265 #define INIT_SIZE 64
5268 keyeq(KEY s1
, KEY s2
)
5270 for (; *s1
== *s2
; s1
++, s2
++)
5276 static unsigned long FASTCALL
5279 unsigned long h
= 0;
5281 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5286 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5289 if (table
->size
== 0) {
5294 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5295 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5298 memset(table
->v
, 0, tsize
);
5299 table
->size
= INIT_SIZE
;
5300 table
->usedLim
= INIT_SIZE
/ 2;
5301 i
= hash(name
) & (table
->size
- 1);
5304 unsigned long h
= hash(name
);
5305 for (i
= h
& (table
->size
- 1);
5307 i
== 0 ? i
= table
->size
- 1 : --i
) {
5308 if (keyeq(name
, table
->v
[i
]->name
))
5313 if (table
->used
== table
->usedLim
) {
5314 /* check for overflow */
5315 size_t newSize
= table
->size
* 2;
5316 size_t tsize
= newSize
* sizeof(NAMED
*);
5317 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5320 memset(newV
, 0, tsize
);
5321 for (i
= 0; i
< table
->size
; i
++)
5324 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5326 j
== 0 ? j
= newSize
- 1 : --j
)
5328 newV
[j
] = table
->v
[i
];
5330 table
->mem
->free_fcn(table
->v
);
5332 table
->size
= newSize
;
5333 table
->usedLim
= newSize
/2;
5334 for (i
= h
& (table
->size
- 1);
5336 i
== 0 ? i
= table
->size
- 1 : --i
)
5340 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5343 memset(table
->v
[i
], 0, createSize
);
5344 table
->v
[i
]->name
= name
;
5349 static void FASTCALL
5350 hashTableClear(HASH_TABLE
*table
)
5353 for (i
= 0; i
< table
->size
; i
++) {
5354 NAMED
*p
= table
->v
[i
];
5356 table
->mem
->free_fcn(p
);
5360 table
->usedLim
= table
->size
/ 2;
5364 static void FASTCALL
5365 hashTableDestroy(HASH_TABLE
*table
)
5368 for (i
= 0; i
< table
->size
; i
++) {
5369 NAMED
*p
= table
->v
[i
];
5371 table
->mem
->free_fcn(p
);
5374 table
->mem
->free_fcn(table
->v
);
5377 static void FASTCALL
5378 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5387 static void FASTCALL
5388 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5391 iter
->end
= iter
->p
+ table
->size
;
5394 static NAMED
* FASTCALL
5395 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5397 while (iter
->p
!= iter
->end
) {
5398 NAMED
*tem
= *(iter
->p
)++;
5405 static void FASTCALL
5406 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5408 pool
->blocks
= NULL
;
5409 pool
->freeBlocks
= NULL
;
5416 static void FASTCALL
5417 poolClear(STRING_POOL
*pool
)
5419 if (!pool
->freeBlocks
)
5420 pool
->freeBlocks
= pool
->blocks
;
5422 BLOCK
*p
= pool
->blocks
;
5424 BLOCK
*tem
= p
->next
;
5425 p
->next
= pool
->freeBlocks
;
5426 pool
->freeBlocks
= p
;
5430 pool
->blocks
= NULL
;
5436 static void FASTCALL
5437 poolDestroy(STRING_POOL
*pool
)
5439 BLOCK
*p
= pool
->blocks
;
5441 BLOCK
*tem
= p
->next
;
5442 pool
->mem
->free_fcn(p
);
5445 p
= pool
->freeBlocks
;
5447 BLOCK
*tem
= p
->next
;
5448 pool
->mem
->free_fcn(p
);
5454 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5455 const char *ptr
, const char *end
)
5457 if (!pool
->ptr
&& !poolGrow(pool
))
5460 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5463 if (!poolGrow(pool
))
5469 static const XML_Char
* FASTCALL
5470 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5473 if (!poolAppendChar(pool
, *s
))
5481 static const XML_Char
*
5482 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5484 if (!pool
->ptr
&& !poolGrow(pool
))
5486 for (; n
> 0; --n
, s
++) {
5487 if (!poolAppendChar(pool
, *s
))
5495 static const XML_Char
* FASTCALL
5496 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5499 if (!poolAppendChar(pool
, *s
))
5507 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5508 const char *ptr
, const char *end
)
5510 if (!poolAppend(pool
, enc
, ptr
, end
))
5512 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5518 static XML_Bool FASTCALL
5519 poolGrow(STRING_POOL
*pool
)
5521 if (pool
->freeBlocks
) {
5522 if (pool
->start
== 0) {
5523 pool
->blocks
= pool
->freeBlocks
;
5524 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5525 pool
->blocks
->next
= NULL
;
5526 pool
->start
= pool
->blocks
->s
;
5527 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5528 pool
->ptr
= pool
->start
;
5531 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
5532 BLOCK
*tem
= pool
->freeBlocks
->next
;
5533 pool
->freeBlocks
->next
= pool
->blocks
;
5534 pool
->blocks
= pool
->freeBlocks
;
5535 pool
->freeBlocks
= tem
;
5536 memcpy(pool
->blocks
->s
, pool
->start
,
5537 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
5538 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5539 pool
->start
= pool
->blocks
->s
;
5540 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5544 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5545 int blockSize
= (pool
->end
- pool
->start
)*2;
5546 pool
->blocks
= (BLOCK
*)
5547 pool
->mem
->realloc_fcn(pool
->blocks
,
5549 + blockSize
* sizeof(XML_Char
)));
5550 if (pool
->blocks
== NULL
)
5552 pool
->blocks
->size
= blockSize
;
5553 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5554 pool
->start
= pool
->blocks
->s
;
5555 pool
->end
= pool
->start
+ blockSize
;
5559 int blockSize
= pool
->end
- pool
->start
;
5560 if (blockSize
< INIT_BLOCK_SIZE
)
5561 blockSize
= INIT_BLOCK_SIZE
;
5564 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5565 + blockSize
* sizeof(XML_Char
));
5568 tem
->size
= blockSize
;
5569 tem
->next
= pool
->blocks
;
5571 if (pool
->ptr
!= pool
->start
)
5572 memcpy(tem
->s
, pool
->start
,
5573 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5574 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5575 pool
->start
= tem
->s
;
5576 pool
->end
= tem
->s
+ blockSize
;
5582 nextScaffoldPart(XML_Parser parser
)
5584 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5585 CONTENT_SCAFFOLD
* me
;
5588 if (!dtd
->scaffIndex
) {
5589 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
5590 if (!dtd
->scaffIndex
)
5592 dtd
->scaffIndex
[0] = 0;
5595 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
5596 CONTENT_SCAFFOLD
*temp
;
5597 if (dtd
->scaffold
) {
5598 temp
= (CONTENT_SCAFFOLD
*)
5599 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5602 dtd
->scaffSize
*= 2;
5605 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
5606 * sizeof(CONTENT_SCAFFOLD
));
5609 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5611 dtd
->scaffold
= temp
;
5613 next
= dtd
->scaffCount
++;
5614 me
= &dtd
->scaffold
[next
];
5615 if (dtd
->scaffLevel
) {
5616 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
5617 if (parent
->lastchild
) {
5618 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
5620 if (!parent
->childcnt
)
5621 parent
->firstchild
= next
;
5622 parent
->lastchild
= next
;
5625 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5630 build_node(XML_Parser parser
,
5633 XML_Content
**contpos
,
5636 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5637 dest
->type
= dtd
->scaffold
[src_node
].type
;
5638 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
5639 if (dest
->type
== XML_CTYPE_NAME
) {
5640 const XML_Char
*src
;
5641 dest
->name
= *strpos
;
5642 src
= dtd
->scaffold
[src_node
].name
;
5644 *(*strpos
)++ = *src
;
5649 dest
->numchildren
= 0;
5650 dest
->children
= NULL
;
5655 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
5656 dest
->children
= *contpos
;
5657 *contpos
+= dest
->numchildren
;
5658 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
5659 i
< dest
->numchildren
;
5660 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
5661 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5667 static XML_Content
*
5668 build_model (XML_Parser parser
)
5670 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5674 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
5675 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
5677 ret
= (XML_Content
*)MALLOC(allocsize
);
5681 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
5684 build_node(parser
, 0, ret
, &cpos
, &str
);
5688 static ELEMENT_TYPE
*
5689 getElementType(XML_Parser parser
,
5690 const ENCODING
*enc
,
5694 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5695 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
5700 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5703 if (ret
->name
!= name
)
5704 poolDiscard(&dtd
->pool
);
5706 poolFinish(&dtd
->pool
);
5707 if (!setElementTypePrefix(parser
, ret
))