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"
11 #define XMLPARSEAPI(type) type __cdecl
15 #elif defined(MACOS_CLASSIC)
17 #include "macconfig.h"
22 #include <expat_config.h>
25 #define XMLPARSEAPI(type) type __cdecl
33 #endif /* ndef COMPILED_FROM_DSP */
36 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
37 #define XmlConvert XmlUtf16Convert
38 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
39 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
40 #define XmlEncode XmlUtf16Encode
41 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
42 typedef unsigned short ICHAR
;
44 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
45 #define XmlConvert XmlUtf8Convert
46 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
47 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
48 #define XmlEncode XmlUtf8Encode
49 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
56 #define XmlInitEncodingNS XmlInitEncoding
57 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
58 #undef XmlGetInternalEncodingNS
59 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
60 #define XmlParseXmlDeclNS XmlParseXmlDecl
66 #ifdef XML_UNICODE_WCHAR_T
67 #define XML_T(x) (const wchar_t)x
68 #define XML_L(x) L ## x
70 #define XML_T(x) (const unsigned short)x
81 /* Round up n to be a multiple of sz, where sz is a power of 2. */
82 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
84 /* Handle the case where memmove() doesn't exist. */
87 #define memmove(d,s,l) bcopy((s),(d),(l))
89 #error memmove does not exist on this platform, nor is a substitute available
90 #endif /* HAVE_BCOPY */
91 #endif /* HAVE_MEMMOVE */
97 typedef const XML_Char
*KEY
;
108 const XML_Memory_Handling_Suite
*mem
;
116 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
117 #define INIT_DATA_BUF_SIZE 1024
118 #define INIT_ATTS_SIZE 16
119 #define INIT_BLOCK_SIZE 1024
120 #define INIT_BUFFER_SIZE 1024
122 #define EXPAND_SPARE 24
124 typedef struct binding
{
125 struct prefix
*prefix
;
126 struct binding
*nextTagBinding
;
127 struct binding
*prevPrefixBinding
;
128 const struct attribute_id
*attId
;
134 typedef struct prefix
{
135 const XML_Char
*name
;
141 const XML_Char
*localPart
;
142 const XML_Char
*prefix
;
148 /* TAG represents an open element.
149 The name of the element is stored in both the document and API
150 encodings. The memory buffer 'buf' is a separately-allocated
151 memory area which stores the name. During the XML_Parse()/
152 XMLParseBuffer() when the element is open, the memory for the 'raw'
153 version of the name (in the document encoding) is shared with the
154 document buffer. If the element is open across calls to
155 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
156 contain the 'raw' name as well.
158 A parser re-uses these structures, maintaining a list of allocated
159 TAG objects in a free list.
162 struct tag
*parent
; /* parent of this element */
163 const char *rawName
; /* tagName in the original encoding */
165 TAG_NAME name
; /* tagName in the API encoding */
166 char *buf
; /* buffer for name components */
167 char *bufEnd
; /* end of the buffer */
172 const XML_Char
*name
;
173 const XML_Char
*textPtr
;
175 const XML_Char
*systemId
;
176 const XML_Char
*base
;
177 const XML_Char
*publicId
;
178 const XML_Char
*notation
;
181 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
185 enum XML_Content_Type type
;
186 enum XML_Content_Quant quant
;
187 const XML_Char
* name
;
194 #define INIT_SCAFFOLD_ELEMENTS 32
196 typedef struct block
{
208 const XML_Memory_Handling_Suite
*mem
;
211 /* The XML_Char before the name is used to determine whether
212 an attribute has been specified. */
213 typedef struct attribute_id
{
216 XML_Bool maybeTokenized
;
221 const ATTRIBUTE_ID
*id
;
223 const XML_Char
*value
;
227 const XML_Char
*name
;
229 const ATTRIBUTE_ID
*idAtt
;
231 int allocDefaultAtts
;
232 DEFAULT_ATTRIBUTE
*defaultAtts
;
236 HASH_TABLE generalEntities
;
237 HASH_TABLE elementTypes
;
238 HASH_TABLE attributeIds
;
241 STRING_POOL entityValuePool
;
242 /* false once a parameter entity reference has been skipped */
243 XML_Bool keepProcessing
;
244 /* true once an internal or external PE reference has been encountered;
245 this includes the reference to an external subset */
246 XML_Bool hasParamEntityRefs
;
249 /* indicates if external PE has been read */
250 XML_Bool paramEntityRead
;
251 HASH_TABLE paramEntities
;
253 PREFIX defaultPrefix
;
254 /* === scaffolding for building content model === */
256 CONTENT_SCAFFOLD
*scaffold
;
257 unsigned contentStringLen
;
264 typedef struct open_internal_entity
{
265 const char *internalEventPtr
;
266 const char *internalEventEndPtr
;
267 struct open_internal_entity
*next
;
269 } OPEN_INTERNAL_ENTITY
;
271 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
274 const char **endPtr
);
276 static Processor prologProcessor
;
277 static Processor prologInitProcessor
;
278 static Processor contentProcessor
;
279 static Processor cdataSectionProcessor
;
281 static Processor ignoreSectionProcessor
;
282 static Processor externalParEntProcessor
;
283 static Processor externalParEntInitProcessor
;
284 static Processor entityValueProcessor
;
285 static Processor entityValueInitProcessor
;
287 static Processor epilogProcessor
;
288 static Processor errorProcessor
;
289 static Processor externalEntityInitProcessor
;
290 static Processor externalEntityInitProcessor2
;
291 static Processor externalEntityInitProcessor3
;
292 static Processor externalEntityContentProcessor
;
294 static enum XML_Error
295 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
296 static enum XML_Error
297 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
298 const char *, const char *);
299 static enum XML_Error
300 initializeEncoding(XML_Parser parser
);
301 static enum XML_Error
302 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
303 const char *end
, int tok
, const char *next
, const char **nextPtr
);
304 static enum XML_Error
305 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
306 static enum XML_Error
307 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
308 const char *start
, const char *end
, const char **endPtr
);
309 static enum XML_Error
310 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
311 const char *end
, const char **nextPtr
);
313 static enum XML_Error
314 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
315 const char *end
, const char **nextPtr
);
318 static enum XML_Error
319 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
320 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
321 static enum XML_Error
322 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
323 const XML_Char
*uri
, BINDING
**bindingsPtr
);
325 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
326 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
328 static enum XML_Error
329 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
330 const char *, const char *, STRING_POOL
*);
331 static enum XML_Error
332 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
333 const char *, const char *, STRING_POOL
*);
334 static ATTRIBUTE_ID
*
335 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
338 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
339 static enum XML_Error
340 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
343 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
344 const char *start
, const char *end
);
346 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
349 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
352 static const XML_Char
* getContext(XML_Parser parser
);
354 setContext(XML_Parser parser
, const XML_Char
*context
);
356 static void FASTCALL
normalizePublicId(XML_Char
*s
);
358 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
359 /* do not call if parentParser != NULL */
360 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
362 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
364 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
366 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
369 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
371 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
372 static void FASTCALL
hashTableClear(HASH_TABLE
*);
373 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
375 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
376 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
379 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
380 static void FASTCALL
poolClear(STRING_POOL
*);
381 static void FASTCALL
poolDestroy(STRING_POOL
*);
383 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
384 const char *ptr
, const char *end
);
386 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
387 const char *ptr
, const char *end
);
388 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
389 static const XML_Char
* FASTCALL
390 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
391 static const XML_Char
*
392 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
393 static const XML_Char
* FASTCALL
394 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
396 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
397 static XML_Content
* build_model(XML_Parser parser
);
398 static ELEMENT_TYPE
*
399 getElementType(XML_Parser parser
, const ENCODING
*enc
,
400 const char *ptr
, const char *end
);
403 parserCreate(const XML_Char
*encodingName
,
404 const XML_Memory_Handling_Suite
*memsuite
,
405 const XML_Char
*nameSep
,
408 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
410 #define poolStart(pool) ((pool)->start)
411 #define poolEnd(pool) ((pool)->ptr)
412 #define poolLength(pool) ((pool)->ptr - (pool)->start)
413 #define poolChop(pool) ((void)--(pool->ptr))
414 #define poolLastChar(pool) (((pool)->ptr)[-1])
415 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
416 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
417 #define poolAppendChar(pool, c) \
418 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
420 : ((*((pool)->ptr)++ = c), 1))
422 struct XML_ParserStruct
{
423 /* The first member must be userData so that the XML_GetUserData
428 const XML_Memory_Handling_Suite m_mem
;
429 /* first character to be parsed */
430 const char *m_bufferPtr
;
431 /* past last character to be parsed */
433 /* allocated end of buffer */
434 const char *m_bufferLim
;
435 long m_parseEndByteIndex
;
436 const char *m_parseEndPtr
;
438 XML_Char
*m_dataBufEnd
;
439 XML_StartElementHandler m_startElementHandler
;
440 XML_EndElementHandler m_endElementHandler
;
441 XML_CharacterDataHandler m_characterDataHandler
;
442 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
443 XML_CommentHandler m_commentHandler
;
444 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
445 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
446 XML_DefaultHandler m_defaultHandler
;
447 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
448 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
449 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
450 XML_NotationDeclHandler m_notationDeclHandler
;
451 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
452 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
453 XML_NotStandaloneHandler m_notStandaloneHandler
;
454 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
455 XML_Parser m_externalEntityRefHandlerArg
;
456 XML_SkippedEntityHandler m_skippedEntityHandler
;
457 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
458 XML_ElementDeclHandler m_elementDeclHandler
;
459 XML_AttlistDeclHandler m_attlistDeclHandler
;
460 XML_EntityDeclHandler m_entityDeclHandler
;
461 XML_XmlDeclHandler m_xmlDeclHandler
;
462 const ENCODING
*m_encoding
;
463 INIT_ENCODING m_initEncoding
;
464 const ENCODING
*m_internalEncoding
;
465 const XML_Char
*m_protocolEncodingName
;
467 XML_Bool m_ns_triplets
;
468 void *m_unknownEncodingMem
;
469 void *m_unknownEncodingData
;
470 void *m_unknownEncodingHandlerData
;
471 void (*m_unknownEncodingRelease
)(void *);
472 PROLOG_STATE m_prologState
;
473 Processor
*m_processor
;
474 enum XML_Error m_errorCode
;
475 const char *m_eventPtr
;
476 const char *m_eventEndPtr
;
477 const char *m_positionPtr
;
478 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
479 XML_Bool m_defaultExpandInternalEntities
;
481 ENTITY
*m_declEntity
;
482 const XML_Char
*m_doctypeName
;
483 const XML_Char
*m_doctypeSysid
;
484 const XML_Char
*m_doctypePubid
;
485 const XML_Char
*m_declAttributeType
;
486 const XML_Char
*m_declNotationName
;
487 const XML_Char
*m_declNotationPublicId
;
488 ELEMENT_TYPE
*m_declElementType
;
489 ATTRIBUTE_ID
*m_declAttributeId
;
490 XML_Bool m_declAttributeIsCdata
;
491 XML_Bool m_declAttributeIsId
;
493 const XML_Char
*m_curBase
;
496 BINDING
*m_inheritedBindings
;
497 BINDING
*m_freeBindingList
;
499 int m_nSpecifiedAtts
;
503 STRING_POOL m_tempPool
;
504 STRING_POOL m_temp2Pool
;
505 char *m_groupConnector
;
506 unsigned m_groupSize
;
507 XML_Char m_namespaceSeparator
;
508 XML_Parser m_parentParser
;
510 XML_Bool m_isParamEntity
;
511 XML_Bool m_useForeignDTD
;
512 enum XML_ParamEntityParsing m_paramEntityParsing
;
516 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
517 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
518 #define FREE(p) (parser->m_mem.free_fcn((p)))
520 #define userData (parser->m_userData)
521 #define handlerArg (parser->m_handlerArg)
522 #define startElementHandler (parser->m_startElementHandler)
523 #define endElementHandler (parser->m_endElementHandler)
524 #define characterDataHandler (parser->m_characterDataHandler)
525 #define processingInstructionHandler \
526 (parser->m_processingInstructionHandler)
527 #define commentHandler (parser->m_commentHandler)
528 #define startCdataSectionHandler \
529 (parser->m_startCdataSectionHandler)
530 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
531 #define defaultHandler (parser->m_defaultHandler)
532 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
533 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
534 #define unparsedEntityDeclHandler \
535 (parser->m_unparsedEntityDeclHandler)
536 #define notationDeclHandler (parser->m_notationDeclHandler)
537 #define startNamespaceDeclHandler \
538 (parser->m_startNamespaceDeclHandler)
539 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
540 #define notStandaloneHandler (parser->m_notStandaloneHandler)
541 #define externalEntityRefHandler \
542 (parser->m_externalEntityRefHandler)
543 #define externalEntityRefHandlerArg \
544 (parser->m_externalEntityRefHandlerArg)
545 #define internalEntityRefHandler \
546 (parser->m_internalEntityRefHandler)
547 #define skippedEntityHandler (parser->m_skippedEntityHandler)
548 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
549 #define elementDeclHandler (parser->m_elementDeclHandler)
550 #define attlistDeclHandler (parser->m_attlistDeclHandler)
551 #define entityDeclHandler (parser->m_entityDeclHandler)
552 #define xmlDeclHandler (parser->m_xmlDeclHandler)
553 #define encoding (parser->m_encoding)
554 #define initEncoding (parser->m_initEncoding)
555 #define internalEncoding (parser->m_internalEncoding)
556 #define unknownEncodingMem (parser->m_unknownEncodingMem)
557 #define unknownEncodingData (parser->m_unknownEncodingData)
558 #define unknownEncodingHandlerData \
559 (parser->m_unknownEncodingHandlerData)
560 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
561 #define protocolEncodingName (parser->m_protocolEncodingName)
562 #define ns (parser->m_ns)
563 #define ns_triplets (parser->m_ns_triplets)
564 #define prologState (parser->m_prologState)
565 #define processor (parser->m_processor)
566 #define errorCode (parser->m_errorCode)
567 #define eventPtr (parser->m_eventPtr)
568 #define eventEndPtr (parser->m_eventEndPtr)
569 #define positionPtr (parser->m_positionPtr)
570 #define position (parser->m_position)
571 #define openInternalEntities (parser->m_openInternalEntities)
572 #define defaultExpandInternalEntities \
573 (parser->m_defaultExpandInternalEntities)
574 #define tagLevel (parser->m_tagLevel)
575 #define buffer (parser->m_buffer)
576 #define bufferPtr (parser->m_bufferPtr)
577 #define bufferEnd (parser->m_bufferEnd)
578 #define parseEndByteIndex (parser->m_parseEndByteIndex)
579 #define parseEndPtr (parser->m_parseEndPtr)
580 #define bufferLim (parser->m_bufferLim)
581 #define dataBuf (parser->m_dataBuf)
582 #define dataBufEnd (parser->m_dataBufEnd)
583 #define _dtd (parser->m_dtd)
584 #define curBase (parser->m_curBase)
585 #define declEntity (parser->m_declEntity)
586 #define doctypeName (parser->m_doctypeName)
587 #define doctypeSysid (parser->m_doctypeSysid)
588 #define doctypePubid (parser->m_doctypePubid)
589 #define declAttributeType (parser->m_declAttributeType)
590 #define declNotationName (parser->m_declNotationName)
591 #define declNotationPublicId (parser->m_declNotationPublicId)
592 #define declElementType (parser->m_declElementType)
593 #define declAttributeId (parser->m_declAttributeId)
594 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
595 #define declAttributeIsId (parser->m_declAttributeIsId)
596 #define freeTagList (parser->m_freeTagList)
597 #define freeBindingList (parser->m_freeBindingList)
598 #define inheritedBindings (parser->m_inheritedBindings)
599 #define tagStack (parser->m_tagStack)
600 #define atts (parser->m_atts)
601 #define attsSize (parser->m_attsSize)
602 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
603 #define idAttIndex (parser->m_idAttIndex)
604 #define tempPool (parser->m_tempPool)
605 #define temp2Pool (parser->m_temp2Pool)
606 #define groupConnector (parser->m_groupConnector)
607 #define groupSize (parser->m_groupSize)
608 #define namespaceSeparator (parser->m_namespaceSeparator)
609 #define parentParser (parser->m_parentParser)
611 #define isParamEntity (parser->m_isParamEntity)
612 #define useForeignDTD (parser->m_useForeignDTD)
613 #define paramEntityParsing (parser->m_paramEntityParsing)
621 (processor != externalParEntInitProcessor) \
623 (processor != externalEntityInitProcessor)) \
625 (processor != prologInitProcessor))
628 XML_ParserCreate(const XML_Char
*encodingName
)
630 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
634 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
638 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
641 static const XML_Char implicitContext
[] = {
642 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
643 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
644 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
645 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
649 XML_ParserCreate_MM(const XML_Char
*encodingName
,
650 const XML_Memory_Handling_Suite
*memsuite
,
651 const XML_Char
*nameSep
)
653 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
654 if (parser
!= NULL
&& ns
) {
655 /* implicit context only set for root parser, since child
656 parsers (i.e. external entity parsers) will inherit it
658 if (!setContext(parser
, implicitContext
)) {
659 XML_ParserFree(parser
);
667 parserCreate(const XML_Char
*encodingName
,
668 const XML_Memory_Handling_Suite
*memsuite
,
669 const XML_Char
*nameSep
,
675 XML_Memory_Handling_Suite
*mtemp
;
676 parser
= (XML_Parser
)
677 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
678 if (parser
!= NULL
) {
679 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
680 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
681 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
682 mtemp
->free_fcn
= memsuite
->free_fcn
;
686 XML_Memory_Handling_Suite
*mtemp
;
687 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
688 if (parser
!= NULL
) {
689 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
690 mtemp
->malloc_fcn
= malloc
;
691 mtemp
->realloc_fcn
= realloc
;
692 mtemp
->free_fcn
= free
;
702 attsSize
= INIT_ATTS_SIZE
;
703 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
708 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
709 if (dataBuf
== NULL
) {
714 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
719 _dtd
= dtdCreate(&parser
->m_mem
);
728 freeBindingList
= NULL
;
732 groupConnector
= NULL
;
734 unknownEncodingHandler
= NULL
;
735 unknownEncodingHandlerData
= NULL
;
737 namespaceSeparator
= '!';
739 ns_triplets
= XML_FALSE
;
741 poolInit(&tempPool
, &(parser
->m_mem
));
742 poolInit(&temp2Pool
, &(parser
->m_mem
));
743 parserInit(parser
, encodingName
);
745 if (encodingName
&& !protocolEncodingName
) {
746 XML_ParserFree(parser
);
752 internalEncoding
= XmlGetInternalEncodingNS();
753 namespaceSeparator
= *nameSep
;
756 internalEncoding
= XmlGetInternalEncoding();
763 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
765 processor
= prologInitProcessor
;
766 XmlPrologStateInit(&prologState
);
767 protocolEncodingName
= (encodingName
!= NULL
768 ? poolCopyString(&tempPool
, encodingName
)
771 XmlInitEncoding(&initEncoding
, &encoding
, 0);
774 startElementHandler
= NULL
;
775 endElementHandler
= NULL
;
776 characterDataHandler
= NULL
;
777 processingInstructionHandler
= NULL
;
778 commentHandler
= NULL
;
779 startCdataSectionHandler
= NULL
;
780 endCdataSectionHandler
= NULL
;
781 defaultHandler
= NULL
;
782 startDoctypeDeclHandler
= NULL
;
783 endDoctypeDeclHandler
= NULL
;
784 unparsedEntityDeclHandler
= NULL
;
785 notationDeclHandler
= NULL
;
786 startNamespaceDeclHandler
= NULL
;
787 endNamespaceDeclHandler
= NULL
;
788 notStandaloneHandler
= NULL
;
789 externalEntityRefHandler
= NULL
;
790 externalEntityRefHandlerArg
= parser
;
791 skippedEntityHandler
= NULL
;
792 elementDeclHandler
= NULL
;
793 attlistDeclHandler
= NULL
;
794 entityDeclHandler
= NULL
;
795 xmlDeclHandler
= NULL
;
798 parseEndByteIndex
= 0;
800 declElementType
= NULL
;
801 declAttributeId
= NULL
;
806 declAttributeType
= NULL
;
807 declNotationName
= NULL
;
808 declNotationPublicId
= NULL
;
809 declAttributeIsCdata
= XML_FALSE
;
810 declAttributeIsId
= XML_FALSE
;
811 memset(&position
, 0, sizeof(POSITION
));
812 errorCode
= XML_ERROR_NONE
;
816 openInternalEntities
= 0;
817 defaultExpandInternalEntities
= XML_TRUE
;
820 inheritedBindings
= NULL
;
822 unknownEncodingMem
= NULL
;
823 unknownEncodingRelease
= NULL
;
824 unknownEncodingData
= NULL
;
827 isParamEntity
= XML_FALSE
;
828 useForeignDTD
= XML_FALSE
;
829 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
833 /* moves list of bindings to freeBindingList */
835 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
838 BINDING
*b
= bindings
;
839 bindings
= bindings
->nextTagBinding
;
840 b
->nextTagBinding
= freeBindingList
;
846 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
851 /* move tagStack to freeTagList */
856 tag
->parent
= freeTagList
;
857 moveToFreeBindingList(parser
, tag
->bindings
);
858 tag
->bindings
= NULL
;
861 moveToFreeBindingList(parser
, inheritedBindings
);
862 if (unknownEncodingMem
)
863 FREE(unknownEncodingMem
);
864 if (unknownEncodingRelease
)
865 unknownEncodingRelease(unknownEncodingData
);
866 poolClear(&tempPool
);
867 poolClear(&temp2Pool
);
868 parserInit(parser
, encodingName
);
869 dtdReset(_dtd
, &parser
->m_mem
);
870 return setContext(parser
, implicitContext
);
874 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
876 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
877 XXX There's no way for the caller to determine which of the
878 XXX possible error cases caused the XML_STATUS_ERROR return.
881 return XML_STATUS_ERROR
;
882 if (encodingName
== NULL
)
883 protocolEncodingName
= NULL
;
885 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
886 if (!protocolEncodingName
)
887 return XML_STATUS_ERROR
;
889 return XML_STATUS_OK
;
893 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
894 const XML_Char
*context
,
895 const XML_Char
*encodingName
)
897 XML_Parser parser
= oldParser
;
900 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
901 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
902 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
903 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
904 = processingInstructionHandler
;
905 XML_CommentHandler oldCommentHandler
= commentHandler
;
906 XML_StartCdataSectionHandler oldStartCdataSectionHandler
907 = startCdataSectionHandler
;
908 XML_EndCdataSectionHandler oldEndCdataSectionHandler
909 = endCdataSectionHandler
;
910 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
911 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
912 = unparsedEntityDeclHandler
;
913 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
914 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
915 = startNamespaceDeclHandler
;
916 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
917 = endNamespaceDeclHandler
;
918 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
919 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
920 = externalEntityRefHandler
;
921 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
922 XML_UnknownEncodingHandler oldUnknownEncodingHandler
923 = unknownEncodingHandler
;
924 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
925 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
926 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
927 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
928 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
930 void *oldUserData
= userData
;
931 void *oldHandlerArg
= handlerArg
;
932 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
933 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
935 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
936 int oldInEntityValue
= prologState
.inEntityValue
;
938 XML_Bool oldns_triplets
= ns_triplets
;
945 /* Note that the magical uses of the pre-processor to make field
946 access look more like C++ require that `parser' be overwritten
947 here. This makes this function more painful to follow than it
952 *tmp
= namespaceSeparator
;
953 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
956 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
962 startElementHandler
= oldStartElementHandler
;
963 endElementHandler
= oldEndElementHandler
;
964 characterDataHandler
= oldCharacterDataHandler
;
965 processingInstructionHandler
= oldProcessingInstructionHandler
;
966 commentHandler
= oldCommentHandler
;
967 startCdataSectionHandler
= oldStartCdataSectionHandler
;
968 endCdataSectionHandler
= oldEndCdataSectionHandler
;
969 defaultHandler
= oldDefaultHandler
;
970 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
971 notationDeclHandler
= oldNotationDeclHandler
;
972 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
973 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
974 notStandaloneHandler
= oldNotStandaloneHandler
;
975 externalEntityRefHandler
= oldExternalEntityRefHandler
;
976 skippedEntityHandler
= oldSkippedEntityHandler
;
977 unknownEncodingHandler
= oldUnknownEncodingHandler
;
978 elementDeclHandler
= oldElementDeclHandler
;
979 attlistDeclHandler
= oldAttlistDeclHandler
;
980 entityDeclHandler
= oldEntityDeclHandler
;
981 xmlDeclHandler
= oldXmlDeclHandler
;
982 declElementType
= oldDeclElementType
;
983 userData
= oldUserData
;
984 if (oldUserData
== oldHandlerArg
)
985 handlerArg
= userData
;
988 if (oldExternalEntityRefHandlerArg
!= oldParser
)
989 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
990 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
991 ns_triplets
= oldns_triplets
;
992 parentParser
= oldParser
;
994 paramEntityParsing
= oldParamEntityParsing
;
995 prologState
.inEntityValue
= oldInEntityValue
;
998 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
999 || !setContext(parser
, context
)) {
1000 XML_ParserFree(parser
);
1003 processor
= externalEntityInitProcessor
;
1007 /* The DTD instance referenced by _dtd is shared between the document's
1008 root parser and external PE parsers, therefore one does not need to
1009 call setContext. In addition, one also *must* not call setContext,
1010 because this would overwrite existing prefix->binding pointers in
1011 _dtd with ones that get destroyed with the external PE parser.
1012 This would leave those prefixes with dangling pointers.
1014 isParamEntity
= XML_TRUE
;
1015 XmlPrologStateInitExternalEntity(&prologState
);
1016 processor
= externalParEntInitProcessor
;
1018 #endif /* XML_DTD */
1022 static void FASTCALL
1023 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1026 BINDING
*b
= bindings
;
1029 bindings
= b
->nextTagBinding
;
1036 XML_ParserFree(XML_Parser parser
)
1040 if (tagStack
== NULL
) {
1041 if (freeTagList
== NULL
)
1043 tagStack
= freeTagList
;
1047 tagStack
= tagStack
->parent
;
1049 destroyBindings(p
->bindings
, parser
);
1052 destroyBindings(freeBindingList
, parser
);
1053 destroyBindings(inheritedBindings
, parser
);
1054 poolDestroy(&tempPool
);
1055 poolDestroy(&temp2Pool
);
1057 /* external parameter entity parsers share the DTD structure
1058 parser->m_dtd with the root parser, so we must not destroy it
1060 if (!isParamEntity
&& _dtd
)
1063 #endif /* XML_DTD */
1064 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1067 FREE(groupConnector
);
1071 if (unknownEncodingMem
)
1072 FREE(unknownEncodingMem
);
1073 if (unknownEncodingRelease
)
1074 unknownEncodingRelease(unknownEncodingData
);
1079 XML_UseParserAsHandlerArg(XML_Parser parser
)
1081 handlerArg
= parser
;
1085 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1088 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1090 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1091 useForeignDTD
= useDTD
;
1092 return XML_ERROR_NONE
;
1094 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1099 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1101 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1104 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1108 XML_SetUserData(XML_Parser parser
, void *p
)
1110 if (handlerArg
== userData
)
1111 handlerArg
= userData
= p
;
1117 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1120 p
= poolCopyString(&_dtd
->pool
, p
);
1122 return XML_STATUS_ERROR
;
1127 return XML_STATUS_OK
;
1131 XML_GetBase(XML_Parser parser
)
1137 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1139 return nSpecifiedAtts
;
1143 XML_GetIdAttributeIndex(XML_Parser parser
)
1149 XML_SetElementHandler(XML_Parser parser
,
1150 XML_StartElementHandler start
,
1151 XML_EndElementHandler end
)
1153 startElementHandler
= start
;
1154 endElementHandler
= end
;
1158 XML_SetStartElementHandler(XML_Parser parser
,
1159 XML_StartElementHandler start
) {
1160 startElementHandler
= start
;
1164 XML_SetEndElementHandler(XML_Parser parser
,
1165 XML_EndElementHandler end
) {
1166 endElementHandler
= end
;
1170 XML_SetCharacterDataHandler(XML_Parser parser
,
1171 XML_CharacterDataHandler handler
)
1173 characterDataHandler
= handler
;
1177 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1178 XML_ProcessingInstructionHandler handler
)
1180 processingInstructionHandler
= handler
;
1184 XML_SetCommentHandler(XML_Parser parser
,
1185 XML_CommentHandler handler
)
1187 commentHandler
= handler
;
1191 XML_SetCdataSectionHandler(XML_Parser parser
,
1192 XML_StartCdataSectionHandler start
,
1193 XML_EndCdataSectionHandler end
)
1195 startCdataSectionHandler
= start
;
1196 endCdataSectionHandler
= end
;
1200 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1201 XML_StartCdataSectionHandler start
) {
1202 startCdataSectionHandler
= start
;
1206 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1207 XML_EndCdataSectionHandler end
) {
1208 endCdataSectionHandler
= end
;
1212 XML_SetDefaultHandler(XML_Parser parser
,
1213 XML_DefaultHandler handler
)
1215 defaultHandler
= handler
;
1216 defaultExpandInternalEntities
= XML_FALSE
;
1220 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1221 XML_DefaultHandler handler
)
1223 defaultHandler
= handler
;
1224 defaultExpandInternalEntities
= XML_TRUE
;
1228 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1229 XML_StartDoctypeDeclHandler start
,
1230 XML_EndDoctypeDeclHandler end
)
1232 startDoctypeDeclHandler
= start
;
1233 endDoctypeDeclHandler
= end
;
1237 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1238 XML_StartDoctypeDeclHandler start
) {
1239 startDoctypeDeclHandler
= start
;
1243 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1244 XML_EndDoctypeDeclHandler end
) {
1245 endDoctypeDeclHandler
= end
;
1249 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1250 XML_UnparsedEntityDeclHandler handler
)
1252 unparsedEntityDeclHandler
= handler
;
1256 XML_SetNotationDeclHandler(XML_Parser parser
,
1257 XML_NotationDeclHandler handler
)
1259 notationDeclHandler
= handler
;
1263 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1264 XML_StartNamespaceDeclHandler start
,
1265 XML_EndNamespaceDeclHandler end
)
1267 startNamespaceDeclHandler
= start
;
1268 endNamespaceDeclHandler
= end
;
1272 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1273 XML_StartNamespaceDeclHandler start
) {
1274 startNamespaceDeclHandler
= start
;
1278 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1279 XML_EndNamespaceDeclHandler end
) {
1280 endNamespaceDeclHandler
= end
;
1284 XML_SetNotStandaloneHandler(XML_Parser parser
,
1285 XML_NotStandaloneHandler handler
)
1287 notStandaloneHandler
= handler
;
1291 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1292 XML_ExternalEntityRefHandler handler
)
1294 externalEntityRefHandler
= handler
;
1298 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1301 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1303 externalEntityRefHandlerArg
= parser
;
1307 XML_SetSkippedEntityHandler(XML_Parser parser
,
1308 XML_SkippedEntityHandler handler
)
1310 skippedEntityHandler
= handler
;
1314 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1315 XML_UnknownEncodingHandler handler
,
1318 unknownEncodingHandler
= handler
;
1319 unknownEncodingHandlerData
= data
;
1323 XML_SetElementDeclHandler(XML_Parser parser
,
1324 XML_ElementDeclHandler eldecl
)
1326 elementDeclHandler
= eldecl
;
1330 XML_SetAttlistDeclHandler(XML_Parser parser
,
1331 XML_AttlistDeclHandler attdecl
)
1333 attlistDeclHandler
= attdecl
;
1337 XML_SetEntityDeclHandler(XML_Parser parser
,
1338 XML_EntityDeclHandler handler
)
1340 entityDeclHandler
= handler
;
1344 XML_SetXmlDeclHandler(XML_Parser parser
,
1345 XML_XmlDeclHandler handler
) {
1346 xmlDeclHandler
= handler
;
1350 XML_SetParamEntityParsing(XML_Parser parser
,
1351 enum XML_ParamEntityParsing peParsing
)
1353 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1357 paramEntityParsing
= peParsing
;
1360 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1365 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1369 return XML_STATUS_OK
;
1370 positionPtr
= bufferPtr
;
1371 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1372 if (errorCode
== XML_ERROR_NONE
)
1373 return XML_STATUS_OK
;
1374 eventEndPtr
= eventPtr
;
1375 processor
= errorProcessor
;
1376 return XML_STATUS_ERROR
;
1378 #ifndef XML_CONTEXT_BYTES
1379 else if (bufferPtr
== bufferEnd
) {
1382 parseEndByteIndex
+= len
;
1385 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1386 if (errorCode
== XML_ERROR_NONE
)
1387 return XML_STATUS_OK
;
1388 eventEndPtr
= eventPtr
;
1389 processor
= errorProcessor
;
1390 return XML_STATUS_ERROR
;
1392 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1393 if (errorCode
!= XML_ERROR_NONE
) {
1394 eventEndPtr
= eventPtr
;
1395 processor
= errorProcessor
;
1396 return XML_STATUS_ERROR
;
1398 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1400 nLeftOver
= s
+ len
- end
;
1402 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1403 /* FIXME avoid integer overflow */
1405 temp
= (buffer
== NULL
1406 ? (char *)MALLOC(len
* 2)
1407 : (char *)REALLOC(buffer
, len
* 2));
1409 errorCode
= XML_ERROR_NO_MEMORY
;
1410 return XML_STATUS_ERROR
;
1414 errorCode
= XML_ERROR_NO_MEMORY
;
1415 eventPtr
= eventEndPtr
= NULL
;
1416 processor
= errorProcessor
;
1417 return XML_STATUS_ERROR
;
1419 bufferLim
= buffer
+ len
* 2;
1421 memcpy(buffer
, end
, nLeftOver
);
1423 bufferEnd
= buffer
+ nLeftOver
;
1425 return XML_STATUS_OK
;
1427 #endif /* not defined XML_CONTEXT_BYTES */
1429 void *buff
= XML_GetBuffer(parser
, len
);
1431 return XML_STATUS_ERROR
;
1433 memcpy(buff
, s
, len
);
1434 return XML_ParseBuffer(parser
, len
, isFinal
);
1440 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1442 const char *start
= bufferPtr
;
1443 positionPtr
= start
;
1445 parseEndByteIndex
+= len
;
1446 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1447 isFinal
? (const char **)NULL
: &bufferPtr
);
1448 if (errorCode
== XML_ERROR_NONE
) {
1450 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1451 positionPtr
= bufferPtr
;
1453 return XML_STATUS_OK
;
1456 eventEndPtr
= eventPtr
;
1457 processor
= errorProcessor
;
1458 return XML_STATUS_ERROR
;
1463 XML_GetBuffer(XML_Parser parser
, int len
)
1465 if (len
> bufferLim
- bufferEnd
) {
1466 /* FIXME avoid integer overflow */
1467 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1468 #ifdef XML_CONTEXT_BYTES
1469 int keep
= bufferPtr
- buffer
;
1471 if (keep
> XML_CONTEXT_BYTES
)
1472 keep
= XML_CONTEXT_BYTES
;
1474 #endif /* defined XML_CONTEXT_BYTES */
1475 if (neededSize
<= bufferLim
- buffer
) {
1476 #ifdef XML_CONTEXT_BYTES
1477 if (keep
< bufferPtr
- buffer
) {
1478 int offset
= (bufferPtr
- buffer
) - keep
;
1479 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1480 bufferEnd
-= offset
;
1481 bufferPtr
-= offset
;
1484 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1485 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1487 #endif /* not defined XML_CONTEXT_BYTES */
1491 int bufferSize
= bufferLim
- bufferPtr
;
1492 if (bufferSize
== 0)
1493 bufferSize
= INIT_BUFFER_SIZE
;
1496 } while (bufferSize
< neededSize
);
1497 newBuf
= (char *)MALLOC(bufferSize
);
1499 errorCode
= XML_ERROR_NO_MEMORY
;
1502 bufferLim
= newBuf
+ bufferSize
;
1503 #ifdef XML_CONTEXT_BYTES
1505 int keep
= bufferPtr
- buffer
;
1506 if (keep
> XML_CONTEXT_BYTES
)
1507 keep
= XML_CONTEXT_BYTES
;
1508 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1511 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1512 bufferPtr
= buffer
+ keep
;
1515 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1516 bufferPtr
= buffer
= newBuf
;
1520 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1523 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1524 bufferPtr
= buffer
= newBuf
;
1525 #endif /* not defined XML_CONTEXT_BYTES */
1532 XML_GetErrorCode(XML_Parser parser
)
1538 XML_GetCurrentByteIndex(XML_Parser parser
)
1541 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1546 XML_GetCurrentByteCount(XML_Parser parser
)
1548 if (eventEndPtr
&& eventPtr
)
1549 return eventEndPtr
- eventPtr
;
1554 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1556 #ifdef XML_CONTEXT_BYTES
1557 if (eventPtr
&& buffer
) {
1558 *offset
= eventPtr
- buffer
;
1559 *size
= bufferEnd
- buffer
;
1562 #endif /* defined XML_CONTEXT_BYTES */
1567 XML_GetCurrentLineNumber(XML_Parser parser
)
1570 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1571 positionPtr
= eventPtr
;
1573 return position
.lineNumber
+ 1;
1577 XML_GetCurrentColumnNumber(XML_Parser parser
)
1580 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1581 positionPtr
= eventPtr
;
1583 return position
.columnNumber
;
1587 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1593 XML_MemMalloc(XML_Parser parser
, size_t size
)
1595 return MALLOC(size
);
1599 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1601 return REALLOC(ptr
, size
);
1605 XML_MemFree(XML_Parser parser
, void *ptr
)
1611 XML_DefaultCurrent(XML_Parser parser
)
1613 if (defaultHandler
) {
1614 if (openInternalEntities
)
1615 reportDefault(parser
,
1617 openInternalEntities
->internalEventPtr
,
1618 openInternalEntities
->internalEventEndPtr
);
1620 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1625 XML_ErrorString(enum XML_Error code
)
1627 static const XML_LChar
*message
[] = {
1629 XML_L("out of memory"),
1630 XML_L("syntax error"),
1631 XML_L("no element found"),
1632 XML_L("not well-formed (invalid token)"),
1633 XML_L("unclosed token"),
1634 XML_L("partial character"),
1635 XML_L("mismatched tag"),
1636 XML_L("duplicate attribute"),
1637 XML_L("junk after document element"),
1638 XML_L("illegal parameter entity reference"),
1639 XML_L("undefined entity"),
1640 XML_L("recursive entity reference"),
1641 XML_L("asynchronous entity"),
1642 XML_L("reference to invalid character number"),
1643 XML_L("reference to binary entity"),
1644 XML_L("reference to external entity in attribute"),
1645 XML_L("xml declaration not at start of external entity"),
1646 XML_L("unknown encoding"),
1647 XML_L("encoding specified in XML declaration is incorrect"),
1648 XML_L("unclosed CDATA section"),
1649 XML_L("error in processing external entity reference"),
1650 XML_L("document is not standalone"),
1651 XML_L("unexpected parser state - please send a bug report"),
1652 XML_L("entity declared in parameter entity"),
1653 XML_L("requested feature requires XML_DTD support in Expat"),
1654 XML_L("cannot change setting once parsing has begun")
1656 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1657 return message
[code
];
1662 XML_ExpatVersion(void) {
1664 /* V1 is used to string-ize the version number. However, it would
1665 string-ize the actual version macro *names* unless we get them
1666 substituted before being passed to V1. CPP is defined to expand
1667 a macro, then rescan for more expansions. Thus, we use V2 to expand
1668 the version macros, then CPP will expand the resulting V1() macro
1669 with the correct numerals. */
1670 /* ### I'm assuming cpp is portable in this respect... */
1672 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1673 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1675 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1682 XML_ExpatVersionInfo(void)
1684 XML_Expat_Version version
;
1686 version
.major
= XML_MAJOR_VERSION
;
1687 version
.minor
= XML_MINOR_VERSION
;
1688 version
.micro
= XML_MICRO_VERSION
;
1694 XML_GetFeatureList(void)
1696 static XML_Feature features
[] = {
1697 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1698 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1700 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1702 #ifdef XML_UNICODE_WCHAR_T
1703 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1706 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1708 #ifdef XML_CONTEXT_BYTES
1709 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1713 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1715 {XML_FEATURE_END
, NULL
}
1718 features
[0].value
= sizeof(XML_Char
);
1719 features
[1].value
= sizeof(XML_LChar
);
1723 /* Initially tag->rawName always points into the parse buffer;
1724 for those TAG instances opened while the current parse buffer was
1725 processed, and not yet closed, we need to store tag->rawName in a more
1726 permanent location, since the parse buffer is about to be discarded.
1729 storeRawNames(XML_Parser parser
)
1731 TAG
*tag
= tagStack
;
1734 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1735 char *rawNameBuf
= tag
->buf
+ nameLen
;
1736 /* Stop if already stored. Since tagStack is a stack, we can stop
1737 at the first entry that has already been copied; everything
1738 below it in the stack is already been accounted for in a
1739 previous call to this function.
1741 if (tag
->rawName
== rawNameBuf
)
1743 /* For re-use purposes we need to ensure that the
1744 size of tag->buf is a multiple of sizeof(XML_Char).
1746 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1747 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1748 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1751 /* if tag->name.str points to tag->buf (only when namespace
1752 processing is off) then we have to update it
1754 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1755 tag
->name
.str
= (XML_Char
*)temp
;
1756 /* if tag->name.localPart is set (when namespace processing is on)
1757 then update it as well, since it will always point into tag->buf
1759 if (tag
->name
.localPart
)
1760 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1761 (XML_Char
*)tag
->buf
);
1763 tag
->bufEnd
= temp
+ bufSize
;
1764 rawNameBuf
= temp
+ nameLen
;
1766 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1767 tag
->rawName
= rawNameBuf
;
1773 static enum XML_Error PTRCALL
1774 contentProcessor(XML_Parser parser
,
1777 const char **endPtr
)
1779 enum XML_Error result
=
1780 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1781 if (result
!= XML_ERROR_NONE
)
1783 if (!storeRawNames(parser
))
1784 return XML_ERROR_NO_MEMORY
;
1788 static enum XML_Error PTRCALL
1789 externalEntityInitProcessor(XML_Parser parser
,
1792 const char **endPtr
)
1794 enum XML_Error result
= initializeEncoding(parser
);
1795 if (result
!= XML_ERROR_NONE
)
1797 processor
= externalEntityInitProcessor2
;
1798 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1801 static enum XML_Error PTRCALL
1802 externalEntityInitProcessor2(XML_Parser parser
,
1805 const char **endPtr
)
1807 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1808 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1811 /* If we are at the end of the buffer, this would cause the next stage,
1812 i.e. externalEntityInitProcessor3, to pass control directly to
1813 doContent (by detecting XML_TOK_NONE) without processing any xml text
1814 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1816 if (next
== end
&& endPtr
) {
1818 return XML_ERROR_NONE
;
1822 case XML_TOK_PARTIAL
:
1825 return XML_ERROR_NONE
;
1828 return XML_ERROR_UNCLOSED_TOKEN
;
1829 case XML_TOK_PARTIAL_CHAR
:
1832 return XML_ERROR_NONE
;
1835 return XML_ERROR_PARTIAL_CHAR
;
1837 processor
= externalEntityInitProcessor3
;
1838 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1841 static enum XML_Error PTRCALL
1842 externalEntityInitProcessor3(XML_Parser parser
,
1845 const char **endPtr
)
1847 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1848 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1850 case XML_TOK_XML_DECL
:
1852 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1853 if (result
!= XML_ERROR_NONE
)
1858 case XML_TOK_PARTIAL
:
1861 return XML_ERROR_NONE
;
1864 return XML_ERROR_UNCLOSED_TOKEN
;
1865 case XML_TOK_PARTIAL_CHAR
:
1868 return XML_ERROR_NONE
;
1871 return XML_ERROR_PARTIAL_CHAR
;
1873 processor
= externalEntityContentProcessor
;
1875 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1878 static enum XML_Error PTRCALL
1879 externalEntityContentProcessor(XML_Parser parser
,
1882 const char **endPtr
)
1884 enum XML_Error result
=
1885 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1886 if (result
!= XML_ERROR_NONE
)
1888 if (!storeRawNames(parser
))
1889 return XML_ERROR_NO_MEMORY
;
1893 static enum XML_Error
1894 doContent(XML_Parser parser
,
1896 const ENCODING
*enc
,
1899 const char **nextPtr
)
1901 DTD
* const dtd
= _dtd
; /* save one level of indirection */
1902 const char **eventPP
;
1903 const char **eventEndPP
;
1904 if (enc
== encoding
) {
1905 eventPP
= &eventPtr
;
1906 eventEndPP
= &eventEndPtr
;
1909 eventPP
= &(openInternalEntities
->internalEventPtr
);
1910 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1914 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1915 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1918 case XML_TOK_TRAILING_CR
:
1921 return XML_ERROR_NONE
;
1924 if (characterDataHandler
) {
1926 characterDataHandler(handlerArg
, &c
, 1);
1928 else if (defaultHandler
)
1929 reportDefault(parser
, enc
, s
, end
);
1930 if (startTagLevel
== 0)
1931 return XML_ERROR_NO_ELEMENTS
;
1932 if (tagLevel
!= startTagLevel
)
1933 return XML_ERROR_ASYNC_ENTITY
;
1934 return XML_ERROR_NONE
;
1938 return XML_ERROR_NONE
;
1940 if (startTagLevel
> 0) {
1941 if (tagLevel
!= startTagLevel
)
1942 return XML_ERROR_ASYNC_ENTITY
;
1943 return XML_ERROR_NONE
;
1945 return XML_ERROR_NO_ELEMENTS
;
1946 case XML_TOK_INVALID
:
1948 return XML_ERROR_INVALID_TOKEN
;
1949 case XML_TOK_PARTIAL
:
1952 return XML_ERROR_NONE
;
1954 return XML_ERROR_UNCLOSED_TOKEN
;
1955 case XML_TOK_PARTIAL_CHAR
:
1958 return XML_ERROR_NONE
;
1960 return XML_ERROR_PARTIAL_CHAR
;
1961 case XML_TOK_ENTITY_REF
:
1963 const XML_Char
*name
;
1965 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1966 s
+ enc
->minBytesPerChar
,
1967 next
- enc
->minBytesPerChar
);
1969 if (characterDataHandler
)
1970 characterDataHandler(handlerArg
, &ch
, 1);
1971 else if (defaultHandler
)
1972 reportDefault(parser
, enc
, s
, next
);
1975 name
= poolStoreString(&dtd
->pool
, enc
,
1976 s
+ enc
->minBytesPerChar
,
1977 next
- enc
->minBytesPerChar
);
1979 return XML_ERROR_NO_MEMORY
;
1980 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
1981 poolDiscard(&dtd
->pool
);
1982 /* First, determine if a check for an existing declaration is needed;
1983 if yes, check that the entity exists, and that it is internal,
1984 otherwise call the skipped entity or default handler.
1986 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
1988 return XML_ERROR_UNDEFINED_ENTITY
;
1989 else if (!entity
->is_internal
)
1990 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
1993 if (skippedEntityHandler
)
1994 skippedEntityHandler(handlerArg
, name
, 0);
1995 else if (defaultHandler
)
1996 reportDefault(parser
, enc
, s
, next
);
2000 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2001 if (entity
->notation
)
2002 return XML_ERROR_BINARY_ENTITY_REF
;
2003 if (entity
->textPtr
) {
2004 enum XML_Error result
;
2005 OPEN_INTERNAL_ENTITY openEntity
;
2006 if (!defaultExpandInternalEntities
) {
2007 if (skippedEntityHandler
)
2008 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2009 else if (defaultHandler
)
2010 reportDefault(parser
, enc
, s
, next
);
2013 entity
->open
= XML_TRUE
;
2014 openEntity
.next
= openInternalEntities
;
2015 openInternalEntities
= &openEntity
;
2016 openEntity
.entity
= entity
;
2017 openEntity
.internalEventPtr
= NULL
;
2018 openEntity
.internalEventEndPtr
= NULL
;
2019 result
= doContent(parser
,
2022 (char *)entity
->textPtr
,
2023 (char *)(entity
->textPtr
+ entity
->textLen
),
2025 entity
->open
= XML_FALSE
;
2026 openInternalEntities
= openEntity
.next
;
2030 else if (externalEntityRefHandler
) {
2031 const XML_Char
*context
;
2032 entity
->open
= XML_TRUE
;
2033 context
= getContext(parser
);
2034 entity
->open
= XML_FALSE
;
2036 return XML_ERROR_NO_MEMORY
;
2037 if (!externalEntityRefHandler((XML_Parser
)externalEntityRefHandlerArg
,
2042 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2043 poolDiscard(&tempPool
);
2045 else if (defaultHandler
)
2046 reportDefault(parser
, enc
, s
, next
);
2049 case XML_TOK_START_TAG_NO_ATTS
:
2051 case XML_TOK_START_TAG_WITH_ATTS
:
2054 enum XML_Error result
;
2058 freeTagList
= freeTagList
->parent
;
2061 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2063 return XML_ERROR_NO_MEMORY
;
2064 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2067 return XML_ERROR_NO_MEMORY
;
2069 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2071 tag
->bindings
= NULL
;
2072 tag
->parent
= tagStack
;
2074 tag
->name
.localPart
= NULL
;
2075 tag
->name
.prefix
= NULL
;
2076 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2077 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2080 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2081 const char *fromPtr
= tag
->rawName
;
2082 toPtr
= (XML_Char
*)tag
->buf
;
2087 &fromPtr
, rawNameEnd
,
2088 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2089 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2090 if (fromPtr
== rawNameEnd
) {
2091 tag
->name
.strLen
= convLen
;
2094 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2096 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2098 return XML_ERROR_NO_MEMORY
;
2100 tag
->bufEnd
= temp
+ bufSize
;
2101 toPtr
= (XML_Char
*)temp
+ convLen
;
2105 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2106 *toPtr
= XML_T('\0');
2107 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2110 if (startElementHandler
)
2111 startElementHandler(handlerArg
, tag
->name
.str
,
2112 (const XML_Char
**)atts
);
2113 else if (defaultHandler
)
2114 reportDefault(parser
, enc
, s
, next
);
2115 poolClear(&tempPool
);
2118 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2120 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2122 const char *rawName
= s
+ enc
->minBytesPerChar
;
2123 enum XML_Error result
;
2124 BINDING
*bindings
= NULL
;
2125 XML_Bool noElmHandlers
= XML_TRUE
;
2127 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2128 rawName
+ XmlNameLength(enc
, rawName
));
2130 return XML_ERROR_NO_MEMORY
;
2131 poolFinish(&tempPool
);
2132 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2135 poolFinish(&tempPool
);
2136 if (startElementHandler
) {
2137 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2138 noElmHandlers
= XML_FALSE
;
2140 if (endElementHandler
) {
2141 if (startElementHandler
)
2142 *eventPP
= *eventEndPP
;
2143 endElementHandler(handlerArg
, name
.str
);
2144 noElmHandlers
= XML_FALSE
;
2146 if (noElmHandlers
&& defaultHandler
)
2147 reportDefault(parser
, enc
, s
, next
);
2148 poolClear(&tempPool
);
2150 BINDING
*b
= bindings
;
2151 if (endNamespaceDeclHandler
)
2152 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2153 bindings
= bindings
->nextTagBinding
;
2154 b
->nextTagBinding
= freeBindingList
;
2155 freeBindingList
= b
;
2156 b
->prefix
->binding
= b
->prevPrefixBinding
;
2160 return epilogProcessor(parser
, next
, end
, nextPtr
);
2162 case XML_TOK_END_TAG
:
2163 if (tagLevel
== startTagLevel
)
2164 return XML_ERROR_ASYNC_ENTITY
;
2167 const char *rawName
;
2168 TAG
*tag
= tagStack
;
2169 tagStack
= tag
->parent
;
2170 tag
->parent
= freeTagList
;
2172 rawName
= s
+ enc
->minBytesPerChar
*2;
2173 len
= XmlNameLength(enc
, rawName
);
2174 if (len
!= tag
->rawNameLength
2175 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2177 return XML_ERROR_TAG_MISMATCH
;
2180 if (endElementHandler
) {
2181 const XML_Char
*localPart
;
2182 const XML_Char
*prefix
;
2184 localPart
= tag
->name
.localPart
;
2185 if (ns
&& localPart
) {
2186 /* localPart and prefix may have been overwritten in
2187 tag->name.str, since this points to the binding->uri
2188 buffer which gets re-used; so we have to add them again
2190 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2191 /* don't need to check for space - already done in storeAtts() */
2192 while (*localPart
) *uri
++ = *localPart
++;
2193 prefix
= (XML_Char
*)tag
->name
.prefix
;
2194 if (ns_triplets
&& prefix
) {
2195 *uri
++ = namespaceSeparator
;
2196 while (*prefix
) *uri
++ = *prefix
++;
2200 endElementHandler(handlerArg
, tag
->name
.str
);
2202 else if (defaultHandler
)
2203 reportDefault(parser
, enc
, s
, next
);
2204 while (tag
->bindings
) {
2205 BINDING
*b
= tag
->bindings
;
2206 if (endNamespaceDeclHandler
)
2207 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2208 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2209 b
->nextTagBinding
= freeBindingList
;
2210 freeBindingList
= b
;
2211 b
->prefix
->binding
= b
->prevPrefixBinding
;
2214 return epilogProcessor(parser
, next
, end
, nextPtr
);
2217 case XML_TOK_CHAR_REF
:
2219 int n
= XmlCharRefNumber(enc
, s
);
2221 return XML_ERROR_BAD_CHAR_REF
;
2222 if (characterDataHandler
) {
2223 XML_Char buf
[XML_ENCODE_MAX
];
2224 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2226 else if (defaultHandler
)
2227 reportDefault(parser
, enc
, s
, next
);
2230 case XML_TOK_XML_DECL
:
2231 return XML_ERROR_MISPLACED_XML_PI
;
2232 case XML_TOK_DATA_NEWLINE
:
2233 if (characterDataHandler
) {
2235 characterDataHandler(handlerArg
, &c
, 1);
2237 else if (defaultHandler
)
2238 reportDefault(parser
, enc
, s
, next
);
2240 case XML_TOK_CDATA_SECT_OPEN
:
2242 enum XML_Error result
;
2243 if (startCdataSectionHandler
)
2244 startCdataSectionHandler(handlerArg
);
2246 /* Suppose you doing a transformation on a document that involves
2247 changing only the character data. You set up a defaultHandler
2248 and a characterDataHandler. The defaultHandler simply copies
2249 characters through. The characterDataHandler does the
2250 transformation and writes the characters out escaping them as
2251 necessary. This case will fail to work if we leave out the
2252 following two lines (because & and < inside CDATA sections will
2253 be incorrectly escaped).
2255 However, now we have a start/endCdataSectionHandler, so it seems
2256 easier to let the user deal with this.
2258 else if (characterDataHandler
)
2259 characterDataHandler(handlerArg
, dataBuf
, 0);
2261 else if (defaultHandler
)
2262 reportDefault(parser
, enc
, s
, next
);
2263 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2265 processor
= cdataSectionProcessor
;
2270 case XML_TOK_TRAILING_RSQB
:
2273 return XML_ERROR_NONE
;
2275 if (characterDataHandler
) {
2276 if (MUST_CONVERT(enc
, s
)) {
2277 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2278 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2279 characterDataHandler(handlerArg
, dataBuf
,
2280 dataPtr
- (ICHAR
*)dataBuf
);
2283 characterDataHandler(handlerArg
,
2285 (XML_Char
*)end
- (XML_Char
*)s
);
2287 else if (defaultHandler
)
2288 reportDefault(parser
, enc
, s
, end
);
2289 if (startTagLevel
== 0) {
2291 return XML_ERROR_NO_ELEMENTS
;
2293 if (tagLevel
!= startTagLevel
) {
2295 return XML_ERROR_ASYNC_ENTITY
;
2297 return XML_ERROR_NONE
;
2298 case XML_TOK_DATA_CHARS
:
2299 if (characterDataHandler
) {
2300 if (MUST_CONVERT(enc
, s
)) {
2302 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2303 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2305 characterDataHandler(handlerArg
, dataBuf
,
2306 dataPtr
- (ICHAR
*)dataBuf
);
2313 characterDataHandler(handlerArg
,
2315 (XML_Char
*)next
- (XML_Char
*)s
);
2317 else if (defaultHandler
)
2318 reportDefault(parser
, enc
, s
, next
);
2321 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2322 return XML_ERROR_NO_MEMORY
;
2324 case XML_TOK_COMMENT
:
2325 if (!reportComment(parser
, enc
, s
, next
))
2326 return XML_ERROR_NO_MEMORY
;
2330 reportDefault(parser
, enc
, s
, next
);
2333 *eventPP
= s
= next
;
2338 /* Precondition: all arguments must be non-NULL;
2340 - normalize attributes
2341 - check attributes for well-formedness
2342 - generate namespace aware attribute names (URI, prefix)
2343 - build list of attributes for startElementHandler
2344 - default attributes
2345 - process namespace declarations (check and report them)
2346 - generate namespace aware element name (URI, prefix)
2348 static enum XML_Error
2349 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2350 const char *attStr
, TAG_NAME
*tagNamePtr
,
2351 BINDING
**bindingsPtr
)
2353 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2354 ELEMENT_TYPE
*elementType
= NULL
;
2355 int nDefaultAtts
= 0;
2356 const XML_Char
**appAtts
; /* the attribute list for the application */
2364 const XML_Char
*localPart
;
2366 /* lookup the element type name */
2367 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2369 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2371 return XML_ERROR_NO_MEMORY
;
2372 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2373 sizeof(ELEMENT_TYPE
));
2375 return XML_ERROR_NO_MEMORY
;
2376 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2377 return XML_ERROR_NO_MEMORY
;
2379 nDefaultAtts
= elementType
->nDefaultAtts
;
2381 /* get the attributes from the tokenizer */
2382 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2383 if (n
+ nDefaultAtts
> attsSize
) {
2384 int oldAttsSize
= attsSize
;
2386 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2387 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2389 return XML_ERROR_NO_MEMORY
;
2391 if (n
> oldAttsSize
)
2392 XmlGetAttributes(enc
, attStr
, n
, atts
);
2395 appAtts
= (const XML_Char
**)atts
;
2396 for (i
= 0; i
< n
; i
++) {
2397 /* add the name and value to the attribute list */
2398 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2400 + XmlNameLength(enc
, atts
[i
].name
));
2402 return XML_ERROR_NO_MEMORY
;
2403 /* detect duplicate attributes */
2404 if ((attId
->name
)[-1]) {
2405 if (enc
== encoding
)
2406 eventPtr
= atts
[i
].name
;
2407 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2409 (attId
->name
)[-1] = 1;
2410 appAtts
[attIndex
++] = attId
->name
;
2411 if (!atts
[i
].normalized
) {
2412 enum XML_Error result
;
2413 XML_Bool isCdata
= XML_TRUE
;
2415 /* figure out whether declared as other than CDATA */
2416 if (attId
->maybeTokenized
) {
2418 for (j
= 0; j
< nDefaultAtts
; j
++) {
2419 if (attId
== elementType
->defaultAtts
[j
].id
) {
2420 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2426 /* normalize the attribute value */
2427 result
= storeAttributeValue(parser
, enc
, isCdata
,
2428 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2432 appAtts
[attIndex
] = poolStart(&tempPool
);
2433 poolFinish(&tempPool
);
2436 /* the value did not need normalizing */
2437 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2439 if (appAtts
[attIndex
] == 0)
2440 return XML_ERROR_NO_MEMORY
;
2441 poolFinish(&tempPool
);
2443 /* handle prefixed attribute names */
2444 if (attId
->prefix
) {
2446 /* deal with namespace declarations here */
2447 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2448 appAtts
[attIndex
], bindingsPtr
);
2454 /* deal with other prefixed names later */
2457 (attId
->name
)[-1] = 2;
2464 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2465 nSpecifiedAtts
= attIndex
;
2466 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2467 for (i
= 0; i
< attIndex
; i
+= 2)
2468 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2476 /* do attribute defaulting */
2477 for (i
= 0; i
< nDefaultAtts
; i
++) {
2478 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2479 if (!(da
->id
->name
)[-1] && da
->value
) {
2480 if (da
->id
->prefix
) {
2481 if (da
->id
->xmlns
) {
2482 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2483 da
->value
, bindingsPtr
);
2488 (da
->id
->name
)[-1] = 2;
2490 appAtts
[attIndex
++] = da
->id
->name
;
2491 appAtts
[attIndex
++] = da
->value
;
2495 (da
->id
->name
)[-1] = 1;
2496 appAtts
[attIndex
++] = da
->id
->name
;
2497 appAtts
[attIndex
++] = da
->value
;
2501 appAtts
[attIndex
] = 0;
2505 /* expand prefixed attribute names */
2506 for (; i
< attIndex
; i
+= 2) {
2507 if (appAtts
[i
][-1] == 2) {
2509 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2510 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, appAtts
[i
], 0);
2511 if (id
->prefix
->binding
) {
2513 const BINDING
*b
= id
->prefix
->binding
;
2514 const XML_Char
*s
= appAtts
[i
];
2515 for (j
= 0; j
< b
->uriLen
; j
++) {
2516 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2517 return XML_ERROR_NO_MEMORY
;
2519 while (*s
++ != XML_T(':'))
2522 if (!poolAppendChar(&tempPool
, *s
))
2523 return XML_ERROR_NO_MEMORY
;
2526 tempPool
.ptr
[-1] = namespaceSeparator
;
2527 s
= b
->prefix
->name
;
2529 if (!poolAppendChar(&tempPool
, *s
))
2530 return XML_ERROR_NO_MEMORY
;
2534 appAtts
[i
] = poolStart(&tempPool
);
2535 poolFinish(&tempPool
);
2541 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2544 /* clear the flags that say whether attributes were specified */
2545 for (; i
< attIndex
; i
+= 2)
2546 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2547 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2548 binding
->attId
->name
[-1] = 0;
2550 /* expand the element type name */
2551 if (elementType
->prefix
) {
2552 binding
= elementType
->prefix
->binding
;
2554 return XML_ERROR_NONE
;
2555 localPart
= tagNamePtr
->str
;
2556 while (*localPart
++ != XML_T(':'))
2559 else if (dtd
->defaultPrefix
.binding
) {
2560 binding
= dtd
->defaultPrefix
.binding
;
2561 localPart
= tagNamePtr
->str
;
2564 return XML_ERROR_NONE
;
2566 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2567 for (; binding
->prefix
->name
[prefixLen
++];)
2570 tagNamePtr
->localPart
= localPart
;
2571 tagNamePtr
->uriLen
= binding
->uriLen
;
2572 tagNamePtr
->prefix
= binding
->prefix
->name
;
2573 tagNamePtr
->prefixLen
= prefixLen
;
2574 for (i
= 0; localPart
[i
++];)
2576 n
= i
+ binding
->uriLen
+ prefixLen
;
2577 if (n
> binding
->uriAlloc
) {
2579 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2581 return XML_ERROR_NO_MEMORY
;
2582 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2583 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2584 for (p
= tagStack
; p
; p
= p
->parent
)
2585 if (p
->name
.str
== binding
->uri
)
2590 uri
= binding
->uri
+ binding
->uriLen
;
2591 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2593 uri
= uri
+ (i
- 1);
2594 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2595 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2597 tagNamePtr
->str
= binding
->uri
;
2598 return XML_ERROR_NONE
;
2601 /* addBinding() overwrites the value of prefix->binding without checking.
2602 Therefore one must keep track of the old value outside of addBinding().
2604 static enum XML_Error
2605 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2606 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2611 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2612 if (*uri
== XML_T('\0') && prefix
->name
)
2613 return XML_ERROR_SYNTAX
;
2615 for (len
= 0; uri
[len
]; len
++)
2617 if (namespaceSeparator
)
2619 if (freeBindingList
) {
2620 b
= freeBindingList
;
2621 if (len
> b
->uriAlloc
) {
2622 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2623 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2625 return XML_ERROR_NO_MEMORY
;
2627 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2629 freeBindingList
= b
->nextTagBinding
;
2632 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2634 return XML_ERROR_NO_MEMORY
;
2635 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2638 return XML_ERROR_NO_MEMORY
;
2640 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2643 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2644 if (namespaceSeparator
)
2645 b
->uri
[len
- 1] = namespaceSeparator
;
2648 b
->prevPrefixBinding
= prefix
->binding
;
2649 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2650 prefix
->binding
= NULL
;
2652 prefix
->binding
= b
;
2653 b
->nextTagBinding
= *bindingsPtr
;
2655 if (startNamespaceDeclHandler
)
2656 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2657 prefix
->binding
? uri
: 0);
2658 return XML_ERROR_NONE
;
2661 /* The idea here is to avoid using stack for each CDATA section when
2662 the whole file is parsed with one call.
2664 static enum XML_Error PTRCALL
2665 cdataSectionProcessor(XML_Parser parser
,
2668 const char **endPtr
)
2670 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2673 if (parentParser
) { /* we are parsing an external entity */
2674 processor
= externalEntityContentProcessor
;
2675 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2678 processor
= contentProcessor
;
2679 return contentProcessor(parser
, start
, end
, endPtr
);
2685 /* startPtr gets set to non-null is the section is closed, and to null if
2686 the section is not yet closed.
2688 static enum XML_Error
2689 doCdataSection(XML_Parser parser
,
2690 const ENCODING
*enc
,
2691 const char **startPtr
,
2693 const char **nextPtr
)
2695 const char *s
= *startPtr
;
2696 const char **eventPP
;
2697 const char **eventEndPP
;
2698 if (enc
== encoding
) {
2699 eventPP
= &eventPtr
;
2701 eventEndPP
= &eventEndPtr
;
2704 eventPP
= &(openInternalEntities
->internalEventPtr
);
2705 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2711 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2714 case XML_TOK_CDATA_SECT_CLOSE
:
2715 if (endCdataSectionHandler
)
2716 endCdataSectionHandler(handlerArg
);
2718 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2719 else if (characterDataHandler
)
2720 characterDataHandler(handlerArg
, dataBuf
, 0);
2722 else if (defaultHandler
)
2723 reportDefault(parser
, enc
, s
, next
);
2725 return XML_ERROR_NONE
;
2726 case XML_TOK_DATA_NEWLINE
:
2727 if (characterDataHandler
) {
2729 characterDataHandler(handlerArg
, &c
, 1);
2731 else if (defaultHandler
)
2732 reportDefault(parser
, enc
, s
, next
);
2734 case XML_TOK_DATA_CHARS
:
2735 if (characterDataHandler
) {
2736 if (MUST_CONVERT(enc
, s
)) {
2738 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2739 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2741 characterDataHandler(handlerArg
, dataBuf
,
2742 dataPtr
- (ICHAR
*)dataBuf
);
2749 characterDataHandler(handlerArg
,
2751 (XML_Char
*)next
- (XML_Char
*)s
);
2753 else if (defaultHandler
)
2754 reportDefault(parser
, enc
, s
, next
);
2756 case XML_TOK_INVALID
:
2758 return XML_ERROR_INVALID_TOKEN
;
2759 case XML_TOK_PARTIAL_CHAR
:
2762 return XML_ERROR_NONE
;
2764 return XML_ERROR_PARTIAL_CHAR
;
2765 case XML_TOK_PARTIAL
:
2769 return XML_ERROR_NONE
;
2771 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2774 return XML_ERROR_UNEXPECTED_STATE
;
2776 *eventPP
= s
= next
;
2783 /* The idea here is to avoid using stack for each IGNORE section when
2784 the whole file is parsed with one call.
2786 static enum XML_Error PTRCALL
2787 ignoreSectionProcessor(XML_Parser parser
,
2790 const char **endPtr
)
2792 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2795 processor
= prologProcessor
;
2796 return prologProcessor(parser
, start
, end
, endPtr
);
2801 /* startPtr gets set to non-null is the section is closed, and to null
2802 if the section is not yet closed.
2804 static enum XML_Error
2805 doIgnoreSection(XML_Parser parser
,
2806 const ENCODING
*enc
,
2807 const char **startPtr
,
2809 const char **nextPtr
)
2813 const char *s
= *startPtr
;
2814 const char **eventPP
;
2815 const char **eventEndPP
;
2816 if (enc
== encoding
) {
2817 eventPP
= &eventPtr
;
2819 eventEndPP
= &eventEndPtr
;
2822 eventPP
= &(openInternalEntities
->internalEventPtr
);
2823 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2827 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2830 case XML_TOK_IGNORE_SECT
:
2832 reportDefault(parser
, enc
, s
, next
);
2834 return XML_ERROR_NONE
;
2835 case XML_TOK_INVALID
:
2837 return XML_ERROR_INVALID_TOKEN
;
2838 case XML_TOK_PARTIAL_CHAR
:
2841 return XML_ERROR_NONE
;
2843 return XML_ERROR_PARTIAL_CHAR
;
2844 case XML_TOK_PARTIAL
:
2848 return XML_ERROR_NONE
;
2850 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2853 return XML_ERROR_UNEXPECTED_STATE
;
2858 #endif /* XML_DTD */
2860 static enum XML_Error
2861 initializeEncoding(XML_Parser parser
)
2865 char encodingBuf
[128];
2866 if (!protocolEncodingName
)
2870 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2871 if (i
== sizeof(encodingBuf
) - 1
2872 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2873 encodingBuf
[0] = '\0';
2876 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2878 encodingBuf
[i
] = '\0';
2882 s
= protocolEncodingName
;
2884 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2885 return XML_ERROR_NONE
;
2886 return handleUnknownEncoding(parser
, protocolEncodingName
);
2889 static enum XML_Error
2890 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2891 const char *s
, const char *next
)
2893 const char *encodingName
= NULL
;
2894 const XML_Char
*storedEncName
= NULL
;
2895 const ENCODING
*newEncoding
= NULL
;
2896 const char *version
= NULL
;
2897 const char *versionend
;
2898 const XML_Char
*storedversion
= NULL
;
2899 int standalone
= -1;
2902 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2912 return XML_ERROR_SYNTAX
;
2913 if (!isGeneralTextEntity
&& standalone
== 1) {
2914 _dtd
->standalone
= XML_TRUE
;
2916 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2917 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2918 #endif /* XML_DTD */
2920 if (xmlDeclHandler
) {
2921 if (encodingName
!= NULL
) {
2922 storedEncName
= poolStoreString(&temp2Pool
,
2926 + XmlNameLength(encoding
, encodingName
));
2928 return XML_ERROR_NO_MEMORY
;
2929 poolFinish(&temp2Pool
);
2932 storedversion
= poolStoreString(&temp2Pool
,
2935 versionend
- encoding
->minBytesPerChar
);
2937 return XML_ERROR_NO_MEMORY
;
2939 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2941 else if (defaultHandler
)
2942 reportDefault(parser
, encoding
, s
, next
);
2943 if (protocolEncodingName
== NULL
) {
2945 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2946 eventPtr
= encodingName
;
2947 return XML_ERROR_INCORRECT_ENCODING
;
2949 encoding
= newEncoding
;
2951 else if (encodingName
) {
2952 enum XML_Error result
;
2953 if (!storedEncName
) {
2954 storedEncName
= poolStoreString(
2955 &temp2Pool
, encoding
, encodingName
,
2956 encodingName
+ XmlNameLength(encoding
, encodingName
));
2958 return XML_ERROR_NO_MEMORY
;
2960 result
= handleUnknownEncoding(parser
, storedEncName
);
2961 poolClear(&temp2Pool
);
2962 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2963 eventPtr
= encodingName
;
2968 if (storedEncName
|| storedversion
)
2969 poolClear(&temp2Pool
);
2971 return XML_ERROR_NONE
;
2974 static enum XML_Error
2975 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2977 if (unknownEncodingHandler
) {
2980 for (i
= 0; i
< 256; i
++)
2982 info
.convert
= NULL
;
2984 info
.release
= NULL
;
2985 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2988 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2989 if (!unknownEncodingMem
) {
2991 info
.release(info
.data
);
2992 return XML_ERROR_NO_MEMORY
;
2995 ? XmlInitUnknownEncodingNS
2996 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3001 unknownEncodingData
= info
.data
;
3002 unknownEncodingRelease
= info
.release
;
3004 return XML_ERROR_NONE
;
3007 if (info
.release
!= NULL
)
3008 info
.release(info
.data
);
3010 return XML_ERROR_UNKNOWN_ENCODING
;
3013 static enum XML_Error PTRCALL
3014 prologInitProcessor(XML_Parser parser
,
3017 const char **nextPtr
)
3019 enum XML_Error result
= initializeEncoding(parser
);
3020 if (result
!= XML_ERROR_NONE
)
3022 processor
= prologProcessor
;
3023 return prologProcessor(parser
, s
, end
, nextPtr
);
3028 static enum XML_Error PTRCALL
3029 externalParEntInitProcessor(XML_Parser parser
,
3032 const char **nextPtr
)
3034 enum XML_Error result
= initializeEncoding(parser
);
3035 if (result
!= XML_ERROR_NONE
)
3038 /* we know now that XML_Parse(Buffer) has been called,
3039 so we consider the external parameter entity read */
3040 _dtd
->paramEntityRead
= XML_TRUE
;
3042 if (prologState
.inEntityValue
) {
3043 processor
= entityValueInitProcessor
;
3044 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3047 processor
= externalParEntProcessor
;
3048 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3052 static enum XML_Error PTRCALL
3053 entityValueInitProcessor(XML_Parser parser
,
3056 const char **nextPtr
)
3058 const char *start
= s
;
3059 const char *next
= s
;
3063 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3065 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3067 return XML_ERROR_NONE
;
3070 case XML_TOK_INVALID
:
3071 return XML_ERROR_INVALID_TOKEN
;
3072 case XML_TOK_PARTIAL
:
3073 return XML_ERROR_UNCLOSED_TOKEN
;
3074 case XML_TOK_PARTIAL_CHAR
:
3075 return XML_ERROR_PARTIAL_CHAR
;
3076 case XML_TOK_NONE
: /* start == end */
3080 return storeEntityValue(parser
, encoding
, s
, end
);
3082 else if (tok
== XML_TOK_XML_DECL
) {
3083 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
3084 if (result
!= XML_ERROR_NONE
)
3086 if (nextPtr
) *nextPtr
= next
;
3087 /* stop scanning for text declaration - we found one */
3088 processor
= entityValueProcessor
;
3089 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3091 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3092 return XML_TOK_NONE on the next call, which would then cause the
3093 function to exit with *nextPtr set to s - that is what we want for other
3094 tokens, but not for the BOM - we would rather like to skip it;
3095 then, when this routine is entered the next time, XmlPrologTok will
3096 return XML_TOK_INVALID, since the BOM is still in the buffer
3098 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3100 return XML_ERROR_NONE
;
3106 static enum XML_Error PTRCALL
3107 externalParEntProcessor(XML_Parser parser
,
3110 const char **nextPtr
)
3112 const char *start
= s
;
3113 const char *next
= s
;
3116 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3118 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3120 return XML_ERROR_NONE
;
3123 case XML_TOK_INVALID
:
3124 return XML_ERROR_INVALID_TOKEN
;
3125 case XML_TOK_PARTIAL
:
3126 return XML_ERROR_UNCLOSED_TOKEN
;
3127 case XML_TOK_PARTIAL_CHAR
:
3128 return XML_ERROR_PARTIAL_CHAR
;
3129 case XML_TOK_NONE
: /* start == end */
3134 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3135 However, when parsing an external subset, doProlog will not accept a BOM
3136 as valid, and report a syntax error, so we have to skip the BOM
3138 else if (tok
== XML_TOK_BOM
) {
3140 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3143 processor
= prologProcessor
;
3144 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3147 static enum XML_Error PTRCALL
3148 entityValueProcessor(XML_Parser parser
,
3151 const char **nextPtr
)
3153 const char *start
= s
;
3154 const char *next
= s
;
3155 const ENCODING
*enc
= encoding
;
3159 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3161 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3163 return XML_ERROR_NONE
;
3166 case XML_TOK_INVALID
:
3167 return XML_ERROR_INVALID_TOKEN
;
3168 case XML_TOK_PARTIAL
:
3169 return XML_ERROR_UNCLOSED_TOKEN
;
3170 case XML_TOK_PARTIAL_CHAR
:
3171 return XML_ERROR_PARTIAL_CHAR
;
3172 case XML_TOK_NONE
: /* start == end */
3176 return storeEntityValue(parser
, enc
, s
, end
);
3182 #endif /* XML_DTD */
3184 static enum XML_Error PTRCALL
3185 prologProcessor(XML_Parser parser
,
3188 const char **nextPtr
)
3190 const char *next
= s
;
3191 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3192 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3195 static enum XML_Error
3196 doProlog(XML_Parser parser
,
3197 const ENCODING
*enc
,
3202 const char **nextPtr
)
3205 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3206 #endif /* XML_DTD */
3207 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3208 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3209 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3210 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3211 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3212 static const XML_Char atypeENTITIES
[] =
3213 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3214 static const XML_Char atypeNMTOKEN
[] = {
3215 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3216 static const XML_Char atypeNMTOKENS
[] = {
3217 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3218 static const XML_Char notationPrefix
[] = {
3219 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3220 static const XML_Char enumValueSep
[] = { '|', '\0' };
3221 static const XML_Char enumValueStart
[] = { '(', '\0' };
3223 DTD
* const dtd
= _dtd
; /* save one level of indirection */
3225 const char **eventPP
;
3226 const char **eventEndPP
;
3227 enum XML_Content_Quant quant
;
3229 if (enc
== encoding
) {
3230 eventPP
= &eventPtr
;
3231 eventEndPP
= &eventEndPtr
;
3234 eventPP
= &(openInternalEntities
->internalEventPtr
);
3235 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3239 XML_Bool handleDefault
= XML_TRUE
;
3243 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3245 return XML_ERROR_NONE
;
3248 case XML_TOK_INVALID
:
3250 return XML_ERROR_INVALID_TOKEN
;
3251 case XML_TOK_PARTIAL
:
3252 return XML_ERROR_UNCLOSED_TOKEN
;
3253 case XML_TOK_PARTIAL_CHAR
:
3254 return XML_ERROR_PARTIAL_CHAR
;
3257 if (enc
!= encoding
)
3258 return XML_ERROR_NONE
;
3259 if (isParamEntity
) {
3260 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3262 return XML_ERROR_SYNTAX
;
3263 return XML_ERROR_NONE
;
3265 #endif /* XML_DTD */
3266 return XML_ERROR_NO_ELEMENTS
;
3273 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3275 case XML_ROLE_XML_DECL
:
3277 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3278 if (result
!= XML_ERROR_NONE
)
3281 handleDefault
= XML_FALSE
;
3284 case XML_ROLE_DOCTYPE_NAME
:
3285 if (startDoctypeDeclHandler
) {
3286 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3288 return XML_ERROR_NO_MEMORY
;
3289 poolFinish(&tempPool
);
3290 doctypePubid
= NULL
;
3291 handleDefault
= XML_FALSE
;
3293 doctypeSysid
= NULL
; /* always initialize to NULL */
3295 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3296 if (startDoctypeDeclHandler
) {
3297 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3300 poolClear(&tempPool
);
3301 handleDefault
= XML_FALSE
;
3305 case XML_ROLE_TEXT_DECL
:
3307 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3308 if (result
!= XML_ERROR_NONE
)
3311 handleDefault
= XML_FALSE
;
3314 #endif /* XML_DTD */
3315 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3317 useForeignDTD
= XML_FALSE
;
3318 #endif /* XML_DTD */
3319 dtd
->hasParamEntityRefs
= XML_TRUE
;
3320 if (startDoctypeDeclHandler
) {
3321 doctypePubid
= poolStoreString(&tempPool
, enc
,
3322 s
+ enc
->minBytesPerChar
,
3323 next
- enc
->minBytesPerChar
);
3325 return XML_ERROR_NO_MEMORY
;
3326 poolFinish(&tempPool
);
3327 handleDefault
= XML_FALSE
;
3330 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3334 return XML_ERROR_NO_MEMORY
;
3335 #endif /* XML_DTD */
3337 case XML_ROLE_ENTITY_PUBLIC_ID
:
3338 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3339 return XML_ERROR_SYNTAX
;
3340 if (dtd
->keepProcessing
&& declEntity
) {
3341 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3343 s
+ enc
->minBytesPerChar
,
3344 next
- enc
->minBytesPerChar
);
3346 return XML_ERROR_NO_MEMORY
;
3347 normalizePublicId(tem
);
3348 declEntity
->publicId
= tem
;
3349 poolFinish(&dtd
->pool
);
3350 if (entityDeclHandler
)
3351 handleDefault
= XML_FALSE
;
3354 case XML_ROLE_DOCTYPE_CLOSE
:
3356 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3357 doctypeSysid
, doctypePubid
, 0);
3358 poolClear(&tempPool
);
3359 handleDefault
= XML_FALSE
;
3361 /* doctypeSysid will be non-NULL in the case of a previous
3362 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3363 was not set, indicating an external subset
3366 if (doctypeSysid
|| useForeignDTD
) {
3367 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3368 if (paramEntityParsing
&& externalEntityRefHandler
) {
3369 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3373 return XML_ERROR_NO_MEMORY
;
3375 entity
->base
= curBase
;
3376 dtd
->paramEntityRead
= XML_FALSE
;
3377 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3382 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3383 if (dtd
->paramEntityRead
&&
3385 notStandaloneHandler
&&
3386 !notStandaloneHandler(handlerArg
))
3387 return XML_ERROR_NOT_STANDALONE
;
3388 /* end of DTD - no need to update dtd->keepProcessing */
3390 useForeignDTD
= XML_FALSE
;
3392 #endif /* XML_DTD */
3393 if (endDoctypeDeclHandler
) {
3394 endDoctypeDeclHandler(handlerArg
);
3395 handleDefault
= XML_FALSE
;
3398 case XML_ROLE_INSTANCE_START
:
3400 /* if there is no DOCTYPE declaration then now is the
3401 last chance to read the foreign DTD
3403 if (useForeignDTD
) {
3404 dtd
->hasParamEntityRefs
= XML_TRUE
;
3405 if (paramEntityParsing
&& externalEntityRefHandler
) {
3406 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3410 return XML_ERROR_NO_MEMORY
;
3411 entity
->base
= curBase
;
3412 dtd
->paramEntityRead
= XML_FALSE
;
3413 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3418 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3419 if (dtd
->paramEntityRead
&&
3421 notStandaloneHandler
&&
3422 !notStandaloneHandler(handlerArg
))
3423 return XML_ERROR_NOT_STANDALONE
;
3424 /* end of DTD - no need to update dtd->keepProcessing */
3427 #endif /* XML_DTD */
3428 processor
= contentProcessor
;
3429 return contentProcessor(parser
, s
, end
, nextPtr
);
3430 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3431 declElementType
= getElementType(parser
, enc
, s
, next
);
3432 if (!declElementType
)
3433 return XML_ERROR_NO_MEMORY
;
3434 goto checkAttListDeclHandler
;
3435 case XML_ROLE_ATTRIBUTE_NAME
:
3436 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3437 if (!declAttributeId
)
3438 return XML_ERROR_NO_MEMORY
;
3439 declAttributeIsCdata
= XML_FALSE
;
3440 declAttributeType
= NULL
;
3441 declAttributeIsId
= XML_FALSE
;
3442 goto checkAttListDeclHandler
;
3443 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3444 declAttributeIsCdata
= XML_TRUE
;
3445 declAttributeType
= atypeCDATA
;
3446 goto checkAttListDeclHandler
;
3447 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3448 declAttributeIsId
= XML_TRUE
;
3449 declAttributeType
= atypeID
;
3450 goto checkAttListDeclHandler
;
3451 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3452 declAttributeType
= atypeIDREF
;
3453 goto checkAttListDeclHandler
;
3454 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3455 declAttributeType
= atypeIDREFS
;
3456 goto checkAttListDeclHandler
;
3457 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3458 declAttributeType
= atypeENTITY
;
3459 goto checkAttListDeclHandler
;
3460 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3461 declAttributeType
= atypeENTITIES
;
3462 goto checkAttListDeclHandler
;
3463 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3464 declAttributeType
= atypeNMTOKEN
;
3465 goto checkAttListDeclHandler
;
3466 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3467 declAttributeType
= atypeNMTOKENS
;
3468 checkAttListDeclHandler
:
3469 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3470 handleDefault
= XML_FALSE
;
3472 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3473 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3474 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3475 const XML_Char
*prefix
;
3476 if (declAttributeType
) {
3477 prefix
= enumValueSep
;
3480 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3484 if (!poolAppendString(&tempPool
, prefix
))
3485 return XML_ERROR_NO_MEMORY
;
3486 if (!poolAppend(&tempPool
, enc
, s
, next
))
3487 return XML_ERROR_NO_MEMORY
;
3488 declAttributeType
= tempPool
.start
;
3489 handleDefault
= XML_FALSE
;
3492 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3493 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3494 if (dtd
->keepProcessing
) {
3495 if (!defineAttribute(declElementType
, declAttributeId
,
3496 declAttributeIsCdata
, declAttributeIsId
, 0,
3498 return XML_ERROR_NO_MEMORY
;
3499 if (attlistDeclHandler
&& declAttributeType
) {
3500 if (*declAttributeType
== XML_T('(')
3501 || (*declAttributeType
== XML_T('N')
3502 && declAttributeType
[1] == XML_T('O'))) {
3503 /* Enumerated or Notation type */
3504 if (!poolAppendChar(&tempPool
, XML_T(')'))
3505 || !poolAppendChar(&tempPool
, XML_T('\0')))
3506 return XML_ERROR_NO_MEMORY
;
3507 declAttributeType
= tempPool
.start
;
3508 poolFinish(&tempPool
);
3511 attlistDeclHandler(handlerArg
, declElementType
->name
,
3512 declAttributeId
->name
, declAttributeType
,
3513 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3514 poolClear(&tempPool
);
3515 handleDefault
= XML_FALSE
;
3519 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3520 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3521 if (dtd
->keepProcessing
) {
3522 const XML_Char
*attVal
;
3523 enum XML_Error result
3524 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3525 s
+ enc
->minBytesPerChar
,
3526 next
- enc
->minBytesPerChar
,
3530 attVal
= poolStart(&dtd
->pool
);
3531 poolFinish(&dtd
->pool
);
3532 /* ID attributes aren't allowed to have a default */
3533 if (!defineAttribute(declElementType
, declAttributeId
,
3534 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3535 return XML_ERROR_NO_MEMORY
;
3536 if (attlistDeclHandler
&& declAttributeType
) {
3537 if (*declAttributeType
== XML_T('(')
3538 || (*declAttributeType
== XML_T('N')
3539 && declAttributeType
[1] == XML_T('O'))) {
3540 /* Enumerated or Notation type */
3541 if (!poolAppendChar(&tempPool
, XML_T(')'))
3542 || !poolAppendChar(&tempPool
, XML_T('\0')))
3543 return XML_ERROR_NO_MEMORY
;
3544 declAttributeType
= tempPool
.start
;
3545 poolFinish(&tempPool
);
3548 attlistDeclHandler(handlerArg
, declElementType
->name
,
3549 declAttributeId
->name
, declAttributeType
,
3551 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3552 poolClear(&tempPool
);
3553 handleDefault
= XML_FALSE
;
3557 case XML_ROLE_ENTITY_VALUE
:
3558 if (dtd
->keepProcessing
) {
3559 enum XML_Error result
= storeEntityValue(parser
, enc
,
3560 s
+ enc
->minBytesPerChar
,
3561 next
- enc
->minBytesPerChar
);
3563 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3564 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3565 poolFinish(&dtd
->entityValuePool
);
3566 if (entityDeclHandler
) {
3568 entityDeclHandler(handlerArg
,
3570 declEntity
->is_param
,
3571 declEntity
->textPtr
,
3572 declEntity
->textLen
,
3574 handleDefault
= XML_FALSE
;
3578 poolDiscard(&dtd
->entityValuePool
);
3579 if (result
!= XML_ERROR_NONE
)
3583 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3585 useForeignDTD
= XML_FALSE
;
3586 #endif /* XML_DTD */
3587 dtd
->hasParamEntityRefs
= XML_TRUE
;
3588 if (startDoctypeDeclHandler
) {
3589 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3590 s
+ enc
->minBytesPerChar
,
3591 next
- enc
->minBytesPerChar
);
3592 if (doctypeSysid
== NULL
)
3593 return XML_ERROR_NO_MEMORY
;
3594 poolFinish(&tempPool
);
3595 handleDefault
= XML_FALSE
;
3599 /* use externalSubsetName to make doctypeSysid non-NULL
3600 for the case where no startDoctypeDeclHandler is set */
3601 doctypeSysid
= externalSubsetName
;
3602 #endif /* XML_DTD */
3603 if (!dtd
->standalone
3605 && !paramEntityParsing
3606 #endif /* XML_DTD */
3607 && notStandaloneHandler
3608 && !notStandaloneHandler(handlerArg
))
3609 return XML_ERROR_NOT_STANDALONE
;
3614 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3618 return XML_ERROR_NO_MEMORY
;
3619 declEntity
->publicId
= NULL
;
3622 #endif /* XML_DTD */
3623 case XML_ROLE_ENTITY_SYSTEM_ID
:
3624 if (dtd
->keepProcessing
&& declEntity
) {
3625 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
3626 s
+ enc
->minBytesPerChar
,
3627 next
- enc
->minBytesPerChar
);
3628 if (!declEntity
->systemId
)
3629 return XML_ERROR_NO_MEMORY
;
3630 declEntity
->base
= curBase
;
3631 poolFinish(&dtd
->pool
);
3632 if (entityDeclHandler
)
3633 handleDefault
= XML_FALSE
;
3636 case XML_ROLE_ENTITY_COMPLETE
:
3637 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
3639 entityDeclHandler(handlerArg
,
3641 declEntity
->is_param
,
3644 declEntity
->systemId
,
3645 declEntity
->publicId
,
3647 handleDefault
= XML_FALSE
;
3650 case XML_ROLE_ENTITY_NOTATION_NAME
:
3651 if (dtd
->keepProcessing
&& declEntity
) {
3652 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3653 if (!declEntity
->notation
)
3654 return XML_ERROR_NO_MEMORY
;
3655 poolFinish(&dtd
->pool
);
3656 if (unparsedEntityDeclHandler
) {
3658 unparsedEntityDeclHandler(handlerArg
,
3661 declEntity
->systemId
,
3662 declEntity
->publicId
,
3663 declEntity
->notation
);
3664 handleDefault
= XML_FALSE
;
3666 else if (entityDeclHandler
) {
3668 entityDeclHandler(handlerArg
,
3672 declEntity
->systemId
,
3673 declEntity
->publicId
,
3674 declEntity
->notation
);
3675 handleDefault
= XML_FALSE
;
3679 case XML_ROLE_GENERAL_ENTITY_NAME
:
3681 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3685 if (dtd
->keepProcessing
) {
3686 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3688 return XML_ERROR_NO_MEMORY
;
3689 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
3692 return XML_ERROR_NO_MEMORY
;
3693 if (declEntity
->name
!= name
) {
3694 poolDiscard(&dtd
->pool
);
3698 poolFinish(&dtd
->pool
);
3699 declEntity
->publicId
= NULL
;
3700 declEntity
->is_param
= XML_FALSE
;
3701 /* if we have a parent parser or are reading an internal parameter
3702 entity, then the entity declaration is not considered "internal"
3704 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3705 if (entityDeclHandler
)
3706 handleDefault
= XML_FALSE
;
3710 poolDiscard(&dtd
->pool
);
3715 case XML_ROLE_PARAM_ENTITY_NAME
:
3717 if (dtd
->keepProcessing
) {
3718 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3720 return XML_ERROR_NO_MEMORY
;
3721 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3722 name
, sizeof(ENTITY
));
3724 return XML_ERROR_NO_MEMORY
;
3725 if (declEntity
->name
!= name
) {
3726 poolDiscard(&dtd
->pool
);
3730 poolFinish(&dtd
->pool
);
3731 declEntity
->publicId
= NULL
;
3732 declEntity
->is_param
= XML_TRUE
;
3733 /* if we have a parent parser or are reading an internal parameter
3734 entity, then the entity declaration is not considered "internal"
3736 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3737 if (entityDeclHandler
)
3738 handleDefault
= XML_FALSE
;
3742 poolDiscard(&dtd
->pool
);
3745 #else /* not XML_DTD */
3747 #endif /* XML_DTD */
3749 case XML_ROLE_NOTATION_NAME
:
3750 declNotationPublicId
= NULL
;
3751 declNotationName
= NULL
;
3752 if (notationDeclHandler
) {
3753 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3754 if (!declNotationName
)
3755 return XML_ERROR_NO_MEMORY
;
3756 poolFinish(&tempPool
);
3757 handleDefault
= XML_FALSE
;
3760 case XML_ROLE_NOTATION_PUBLIC_ID
:
3761 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3762 return XML_ERROR_SYNTAX
;
3763 if (declNotationName
) { /* means notationDeclHandler != NULL */
3764 XML_Char
*tem
= poolStoreString(&tempPool
,
3766 s
+ enc
->minBytesPerChar
,
3767 next
- enc
->minBytesPerChar
);
3769 return XML_ERROR_NO_MEMORY
;
3770 normalizePublicId(tem
);
3771 declNotationPublicId
= tem
;
3772 poolFinish(&tempPool
);
3773 handleDefault
= XML_FALSE
;
3776 case XML_ROLE_NOTATION_SYSTEM_ID
:
3777 if (declNotationName
&& notationDeclHandler
) {
3778 const XML_Char
*systemId
3779 = poolStoreString(&tempPool
, enc
,
3780 s
+ enc
->minBytesPerChar
,
3781 next
- enc
->minBytesPerChar
);
3783 return XML_ERROR_NO_MEMORY
;
3785 notationDeclHandler(handlerArg
,
3789 declNotationPublicId
);
3790 handleDefault
= XML_FALSE
;
3792 poolClear(&tempPool
);
3794 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3795 if (declNotationPublicId
&& notationDeclHandler
) {
3797 notationDeclHandler(handlerArg
,
3801 declNotationPublicId
);
3802 handleDefault
= XML_FALSE
;
3804 poolClear(&tempPool
);
3806 case XML_ROLE_ERROR
:
3808 case XML_TOK_PARAM_ENTITY_REF
:
3809 return XML_ERROR_PARAM_ENTITY_REF
;
3810 case XML_TOK_XML_DECL
:
3811 return XML_ERROR_MISPLACED_XML_PI
;
3813 return XML_ERROR_SYNTAX
;
3816 case XML_ROLE_IGNORE_SECT
:
3818 enum XML_Error result
;
3820 reportDefault(parser
, enc
, s
, next
);
3821 handleDefault
= XML_FALSE
;
3822 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3824 processor
= ignoreSectionProcessor
;
3829 #endif /* XML_DTD */
3830 case XML_ROLE_GROUP_OPEN
:
3831 if (prologState
.level
>= groupSize
) {
3833 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
3835 return XML_ERROR_NO_MEMORY
;
3836 groupConnector
= temp
;
3837 if (dtd
->scaffIndex
) {
3838 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
3839 groupSize
* sizeof(int));
3841 return XML_ERROR_NO_MEMORY
;
3842 dtd
->scaffIndex
= temp
;
3846 groupConnector
= (char *)MALLOC(groupSize
= 32);
3847 if (!groupConnector
)
3848 return XML_ERROR_NO_MEMORY
;
3851 groupConnector
[prologState
.level
] = 0;
3852 if (dtd
->in_eldecl
) {
3853 int myindex
= nextScaffoldPart(parser
);
3855 return XML_ERROR_NO_MEMORY
;
3856 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
3858 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3859 if (elementDeclHandler
)
3860 handleDefault
= XML_FALSE
;
3863 case XML_ROLE_GROUP_SEQUENCE
:
3864 if (groupConnector
[prologState
.level
] == '|')
3865 return XML_ERROR_SYNTAX
;
3866 groupConnector
[prologState
.level
] = ',';
3867 if (dtd
->in_eldecl
&& elementDeclHandler
)
3868 handleDefault
= XML_FALSE
;
3870 case XML_ROLE_GROUP_CHOICE
:
3871 if (groupConnector
[prologState
.level
] == ',')
3872 return XML_ERROR_SYNTAX
;
3874 && !groupConnector
[prologState
.level
]
3875 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3878 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3880 if (elementDeclHandler
)
3881 handleDefault
= XML_FALSE
;
3883 groupConnector
[prologState
.level
] = '|';
3885 case XML_ROLE_PARAM_ENTITY_REF
:
3887 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3888 /* PE references in internal subset are
3889 not allowed within declarations */
3890 if (prologState
.documentEntity
&&
3891 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3892 return XML_ERROR_PARAM_ENTITY_REF
;
3893 dtd
->hasParamEntityRefs
= XML_TRUE
;
3894 if (!paramEntityParsing
)
3895 dtd
->keepProcessing
= dtd
->standalone
;
3897 const XML_Char
*name
;
3899 name
= poolStoreString(&dtd
->pool
, enc
,
3900 s
+ enc
->minBytesPerChar
,
3901 next
- enc
->minBytesPerChar
);
3903 return XML_ERROR_NO_MEMORY
;
3904 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
3905 poolDiscard(&dtd
->pool
);
3906 /* first, determine if a check for an existing declaration is needed;
3907 if yes, check that the entity exists, and that it is internal,
3908 otherwise call the skipped entity handler
3910 if (prologState
.documentEntity
&&
3912 ? !openInternalEntities
3913 : !dtd
->hasParamEntityRefs
)) {
3915 return XML_ERROR_UNDEFINED_ENTITY
;
3916 else if (!entity
->is_internal
)
3917 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3920 dtd
->keepProcessing
= dtd
->standalone
;
3921 /* cannot report skipped entities in declarations */
3922 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3923 skippedEntityHandler(handlerArg
, name
, 1);
3924 handleDefault
= XML_FALSE
;
3929 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3930 if (entity
->textPtr
) {
3931 enum XML_Error result
;
3932 result
= processInternalParamEntity(parser
, entity
);
3933 if (result
!= XML_ERROR_NONE
)
3935 handleDefault
= XML_FALSE
;
3938 if (externalEntityRefHandler
) {
3939 dtd
->paramEntityRead
= XML_FALSE
;
3940 entity
->open
= XML_TRUE
;
3941 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3945 entity
->publicId
)) {
3946 entity
->open
= XML_FALSE
;
3947 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3949 entity
->open
= XML_FALSE
;
3950 handleDefault
= XML_FALSE
;
3951 if (!dtd
->paramEntityRead
) {
3952 dtd
->keepProcessing
= dtd
->standalone
;
3957 dtd
->keepProcessing
= dtd
->standalone
;
3961 #endif /* XML_DTD */
3962 if (!dtd
->standalone
&&
3963 notStandaloneHandler
&&
3964 !notStandaloneHandler(handlerArg
))
3965 return XML_ERROR_NOT_STANDALONE
;
3968 /* Element declaration stuff */
3970 case XML_ROLE_ELEMENT_NAME
:
3971 if (elementDeclHandler
) {
3972 declElementType
= getElementType(parser
, enc
, s
, next
);
3973 if (!declElementType
)
3974 return XML_ERROR_NO_MEMORY
;
3975 dtd
->scaffLevel
= 0;
3976 dtd
->scaffCount
= 0;
3977 dtd
->in_eldecl
= XML_TRUE
;
3978 handleDefault
= XML_FALSE
;
3982 case XML_ROLE_CONTENT_ANY
:
3983 case XML_ROLE_CONTENT_EMPTY
:
3984 if (dtd
->in_eldecl
) {
3985 if (elementDeclHandler
) {
3986 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3988 return XML_ERROR_NO_MEMORY
;
3989 content
->quant
= XML_CQUANT_NONE
;
3990 content
->name
= NULL
;
3991 content
->numchildren
= 0;
3992 content
->children
= NULL
;
3993 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
3997 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
3998 handleDefault
= XML_FALSE
;
4000 dtd
->in_eldecl
= XML_FALSE
;
4004 case XML_ROLE_CONTENT_PCDATA
:
4005 if (dtd
->in_eldecl
) {
4006 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4008 if (elementDeclHandler
)
4009 handleDefault
= XML_FALSE
;
4013 case XML_ROLE_CONTENT_ELEMENT
:
4014 quant
= XML_CQUANT_NONE
;
4015 goto elementContent
;
4016 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4017 quant
= XML_CQUANT_OPT
;
4018 goto elementContent
;
4019 case XML_ROLE_CONTENT_ELEMENT_REP
:
4020 quant
= XML_CQUANT_REP
;
4021 goto elementContent
;
4022 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4023 quant
= XML_CQUANT_PLUS
;
4025 if (dtd
->in_eldecl
) {
4027 const XML_Char
*name
;
4029 const char *nxt
= (quant
== XML_CQUANT_NONE
4031 : next
- enc
->minBytesPerChar
);
4032 int myindex
= nextScaffoldPart(parser
);
4034 return XML_ERROR_NO_MEMORY
;
4035 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4036 dtd
->scaffold
[myindex
].quant
= quant
;
4037 el
= getElementType(parser
, enc
, s
, nxt
);
4039 return XML_ERROR_NO_MEMORY
;
4041 dtd
->scaffold
[myindex
].name
= name
;
4043 for (; name
[nameLen
++]; );
4044 dtd
->contentStringLen
+= nameLen
;
4045 if (elementDeclHandler
)
4046 handleDefault
= XML_FALSE
;
4050 case XML_ROLE_GROUP_CLOSE
:
4051 quant
= XML_CQUANT_NONE
;
4053 case XML_ROLE_GROUP_CLOSE_OPT
:
4054 quant
= XML_CQUANT_OPT
;
4056 case XML_ROLE_GROUP_CLOSE_REP
:
4057 quant
= XML_CQUANT_REP
;
4059 case XML_ROLE_GROUP_CLOSE_PLUS
:
4060 quant
= XML_CQUANT_PLUS
;
4062 if (dtd
->in_eldecl
) {
4063 if (elementDeclHandler
)
4064 handleDefault
= XML_FALSE
;
4066 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4067 if (dtd
->scaffLevel
== 0) {
4068 if (!handleDefault
) {
4069 XML_Content
*model
= build_model(parser
);
4071 return XML_ERROR_NO_MEMORY
;
4073 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4075 dtd
->in_eldecl
= XML_FALSE
;
4076 dtd
->contentStringLen
= 0;
4080 /* End element declaration stuff */
4083 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4084 return XML_ERROR_NO_MEMORY
;
4085 handleDefault
= XML_FALSE
;
4087 case XML_ROLE_COMMENT
:
4088 if (!reportComment(parser
, enc
, s
, next
))
4089 return XML_ERROR_NO_MEMORY
;
4090 handleDefault
= XML_FALSE
;
4095 handleDefault
= XML_FALSE
;
4099 case XML_ROLE_DOCTYPE_NONE
:
4100 if (startDoctypeDeclHandler
)
4101 handleDefault
= XML_FALSE
;
4103 case XML_ROLE_ENTITY_NONE
:
4104 if (dtd
->keepProcessing
&& entityDeclHandler
)
4105 handleDefault
= XML_FALSE
;
4107 case XML_ROLE_NOTATION_NONE
:
4108 if (notationDeclHandler
)
4109 handleDefault
= XML_FALSE
;
4111 case XML_ROLE_ATTLIST_NONE
:
4112 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4113 handleDefault
= XML_FALSE
;
4115 case XML_ROLE_ELEMENT_NONE
:
4116 if (elementDeclHandler
)
4117 handleDefault
= XML_FALSE
;
4119 } /* end of big switch */
4121 if (handleDefault
&& defaultHandler
)
4122 reportDefault(parser
, enc
, s
, next
);
4125 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4130 static enum XML_Error PTRCALL
4131 epilogProcessor(XML_Parser parser
,
4134 const char **nextPtr
)
4136 processor
= epilogProcessor
;
4139 const char *next
= NULL
;
4140 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4143 /* report partial linebreak - it might be the last token */
4144 case -XML_TOK_PROLOG_S
:
4145 if (defaultHandler
) {
4147 reportDefault(parser
, encoding
, s
, next
);
4151 return XML_ERROR_NONE
;
4155 return XML_ERROR_NONE
;
4156 case XML_TOK_PROLOG_S
:
4158 reportDefault(parser
, encoding
, s
, next
);
4161 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4162 return XML_ERROR_NO_MEMORY
;
4164 case XML_TOK_COMMENT
:
4165 if (!reportComment(parser
, encoding
, s
, next
))
4166 return XML_ERROR_NO_MEMORY
;
4168 case XML_TOK_INVALID
:
4170 return XML_ERROR_INVALID_TOKEN
;
4171 case XML_TOK_PARTIAL
:
4174 return XML_ERROR_NONE
;
4176 return XML_ERROR_UNCLOSED_TOKEN
;
4177 case XML_TOK_PARTIAL_CHAR
:
4180 return XML_ERROR_NONE
;
4182 return XML_ERROR_PARTIAL_CHAR
;
4184 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4186 eventPtr
= s
= next
;
4192 static enum XML_Error
4193 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4195 const char *s
, *end
, *next
;
4197 enum XML_Error result
;
4198 OPEN_INTERNAL_ENTITY openEntity
;
4199 entity
->open
= XML_TRUE
;
4200 openEntity
.next
= openInternalEntities
;
4201 openInternalEntities
= &openEntity
;
4202 openEntity
.entity
= entity
;
4203 openEntity
.internalEventPtr
= NULL
;
4204 openEntity
.internalEventEndPtr
= NULL
;
4205 s
= (char *)entity
->textPtr
;
4206 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4207 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4208 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4209 entity
->open
= XML_FALSE
;
4210 openInternalEntities
= openEntity
.next
;
4214 #endif /* XML_DTD */
4216 static enum XML_Error PTRCALL
4217 errorProcessor(XML_Parser parser
,
4220 const char **nextPtr
)
4225 static enum XML_Error
4226 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4227 const char *ptr
, const char *end
,
4230 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4234 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4236 if (!poolAppendChar(pool
, XML_T('\0')))
4237 return XML_ERROR_NO_MEMORY
;
4238 return XML_ERROR_NONE
;
4241 static enum XML_Error
4242 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4243 const char *ptr
, const char *end
,
4246 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4249 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4252 return XML_ERROR_NONE
;
4253 case XML_TOK_INVALID
:
4254 if (enc
== encoding
)
4256 return XML_ERROR_INVALID_TOKEN
;
4257 case XML_TOK_PARTIAL
:
4258 if (enc
== encoding
)
4260 return XML_ERROR_INVALID_TOKEN
;
4261 case XML_TOK_CHAR_REF
:
4263 XML_Char buf
[XML_ENCODE_MAX
];
4265 int n
= XmlCharRefNumber(enc
, ptr
);
4267 if (enc
== encoding
)
4269 return XML_ERROR_BAD_CHAR_REF
;
4272 && n
== 0x20 /* space */
4273 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4275 n
= XmlEncode(n
, (ICHAR
*)buf
);
4277 if (enc
== encoding
)
4279 return XML_ERROR_BAD_CHAR_REF
;
4281 for (i
= 0; i
< n
; i
++) {
4282 if (!poolAppendChar(pool
, buf
[i
]))
4283 return XML_ERROR_NO_MEMORY
;
4287 case XML_TOK_DATA_CHARS
:
4288 if (!poolAppend(pool
, enc
, ptr
, next
))
4289 return XML_ERROR_NO_MEMORY
;
4291 case XML_TOK_TRAILING_CR
:
4292 next
= ptr
+ enc
->minBytesPerChar
;
4294 case XML_TOK_ATTRIBUTE_VALUE_S
:
4295 case XML_TOK_DATA_NEWLINE
:
4296 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4298 if (!poolAppendChar(pool
, 0x20))
4299 return XML_ERROR_NO_MEMORY
;
4301 case XML_TOK_ENTITY_REF
:
4303 const XML_Char
*name
;
4305 char checkEntityDecl
;
4306 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4307 ptr
+ enc
->minBytesPerChar
,
4308 next
- enc
->minBytesPerChar
);
4310 if (!poolAppendChar(pool
, ch
))
4311 return XML_ERROR_NO_MEMORY
;
4314 name
= poolStoreString(&temp2Pool
, enc
,
4315 ptr
+ enc
->minBytesPerChar
,
4316 next
- enc
->minBytesPerChar
);
4318 return XML_ERROR_NO_MEMORY
;
4319 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4320 poolDiscard(&temp2Pool
);
4321 /* first, determine if a check for an existing declaration is needed;
4322 if yes, check that the entity exists, and that it is internal,
4323 otherwise call the default handler (if called from content)
4325 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4328 prologState
.documentEntity
&&
4329 #endif /* XML_DTD */
4331 ? !openInternalEntities
4332 : !dtd
->hasParamEntityRefs
);
4333 else /* if (pool == &tempPool): we are called from content */
4334 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4335 if (checkEntityDecl
) {
4337 return XML_ERROR_UNDEFINED_ENTITY
;
4338 else if (!entity
->is_internal
)
4339 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4342 /* cannot report skipped entity here - see comments on
4343 skippedEntityHandler
4344 if (skippedEntityHandler)
4345 skippedEntityHandler(handlerArg, name, 0);
4347 if ((pool
== &tempPool
) && defaultHandler
)
4348 reportDefault(parser
, enc
, ptr
, next
);
4352 if (enc
== encoding
)
4354 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4356 if (entity
->notation
) {
4357 if (enc
== encoding
)
4359 return XML_ERROR_BINARY_ENTITY_REF
;
4361 if (!entity
->textPtr
) {
4362 if (enc
== encoding
)
4364 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4367 enum XML_Error result
;
4368 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4369 entity
->open
= XML_TRUE
;
4370 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4371 (char *)entity
->textPtr
,
4372 (char *)textEnd
, pool
);
4373 entity
->open
= XML_FALSE
;
4380 if (enc
== encoding
)
4382 return XML_ERROR_UNEXPECTED_STATE
;
4389 static enum XML_Error
4390 storeEntityValue(XML_Parser parser
,
4391 const ENCODING
*enc
,
4392 const char *entityTextPtr
,
4393 const char *entityTextEnd
)
4395 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4396 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4397 enum XML_Error result
= XML_ERROR_NONE
;
4399 int oldInEntityValue
= prologState
.inEntityValue
;
4400 prologState
.inEntityValue
= 1;
4401 #endif /* XML_DTD */
4402 /* never return Null for the value argument in EntityDeclHandler,
4403 since this would indicate an external entity; therefore we
4404 have to make sure that entityValuePool.start is not null */
4405 if (!pool
->blocks
) {
4406 if (!poolGrow(pool
))
4407 return XML_ERROR_NO_MEMORY
;
4412 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4414 case XML_TOK_PARAM_ENTITY_REF
:
4416 if (isParamEntity
|| enc
!= encoding
) {
4417 const XML_Char
*name
;
4419 name
= poolStoreString(&tempPool
, enc
,
4420 entityTextPtr
+ enc
->minBytesPerChar
,
4421 next
- enc
->minBytesPerChar
);
4423 result
= XML_ERROR_NO_MEMORY
;
4424 goto endEntityValue
;
4426 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4427 poolDiscard(&tempPool
);
4429 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4430 /* cannot report skipped entity here - see comments on
4431 skippedEntityHandler
4432 if (skippedEntityHandler)
4433 skippedEntityHandler(handlerArg, name, 0);
4435 dtd
->keepProcessing
= dtd
->standalone
;
4436 goto endEntityValue
;
4439 if (enc
== encoding
)
4440 eventPtr
= entityTextPtr
;
4441 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4442 goto endEntityValue
;
4444 if (entity
->systemId
) {
4445 if (externalEntityRefHandler
) {
4446 dtd
->paramEntityRead
= XML_FALSE
;
4447 entity
->open
= XML_TRUE
;
4448 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4452 entity
->publicId
)) {
4453 entity
->open
= XML_FALSE
;
4454 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4455 goto endEntityValue
;
4457 entity
->open
= XML_FALSE
;
4458 if (!dtd
->paramEntityRead
)
4459 dtd
->keepProcessing
= dtd
->standalone
;
4462 dtd
->keepProcessing
= dtd
->standalone
;
4465 entity
->open
= XML_TRUE
;
4466 result
= storeEntityValue(parser
,
4468 (char *)entity
->textPtr
,
4469 (char *)(entity
->textPtr
4470 + entity
->textLen
));
4471 entity
->open
= XML_FALSE
;
4473 goto endEntityValue
;
4477 #endif /* XML_DTD */
4478 /* in the internal subset, PE references are not legal
4479 within markup declarations, e.g entity values in this case */
4480 eventPtr
= entityTextPtr
;
4481 result
= XML_ERROR_PARAM_ENTITY_REF
;
4482 goto endEntityValue
;
4484 result
= XML_ERROR_NONE
;
4485 goto endEntityValue
;
4486 case XML_TOK_ENTITY_REF
:
4487 case XML_TOK_DATA_CHARS
:
4488 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4489 result
= XML_ERROR_NO_MEMORY
;
4490 goto endEntityValue
;
4493 case XML_TOK_TRAILING_CR
:
4494 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4496 case XML_TOK_DATA_NEWLINE
:
4497 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4498 result
= XML_ERROR_NO_MEMORY
;
4499 goto endEntityValue
;
4501 *(pool
->ptr
)++ = 0xA;
4503 case XML_TOK_CHAR_REF
:
4505 XML_Char buf
[XML_ENCODE_MAX
];
4507 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4509 if (enc
== encoding
)
4510 eventPtr
= entityTextPtr
;
4511 result
= XML_ERROR_BAD_CHAR_REF
;
4512 goto endEntityValue
;
4514 n
= XmlEncode(n
, (ICHAR
*)buf
);
4516 if (enc
== encoding
)
4517 eventPtr
= entityTextPtr
;
4518 result
= XML_ERROR_BAD_CHAR_REF
;
4519 goto endEntityValue
;
4521 for (i
= 0; i
< n
; i
++) {
4522 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4523 result
= XML_ERROR_NO_MEMORY
;
4524 goto endEntityValue
;
4526 *(pool
->ptr
)++ = buf
[i
];
4530 case XML_TOK_PARTIAL
:
4531 if (enc
== encoding
)
4532 eventPtr
= entityTextPtr
;
4533 result
= XML_ERROR_INVALID_TOKEN
;
4534 goto endEntityValue
;
4535 case XML_TOK_INVALID
:
4536 if (enc
== encoding
)
4538 result
= XML_ERROR_INVALID_TOKEN
;
4539 goto endEntityValue
;
4541 if (enc
== encoding
)
4542 eventPtr
= entityTextPtr
;
4543 result
= XML_ERROR_UNEXPECTED_STATE
;
4544 goto endEntityValue
;
4546 entityTextPtr
= next
;
4550 prologState
.inEntityValue
= oldInEntityValue
;
4551 #endif /* XML_DTD */
4555 static void FASTCALL
4556 normalizeLines(XML_Char
*s
)
4560 if (*s
== XML_T('\0'))
4579 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4580 const char *start
, const char *end
)
4582 const XML_Char
*target
;
4585 if (!processingInstructionHandler
) {
4587 reportDefault(parser
, enc
, start
, end
);
4590 start
+= enc
->minBytesPerChar
* 2;
4591 tem
= start
+ XmlNameLength(enc
, start
);
4592 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4595 poolFinish(&tempPool
);
4596 data
= poolStoreString(&tempPool
, enc
,
4598 end
- enc
->minBytesPerChar
*2);
4601 normalizeLines(data
);
4602 processingInstructionHandler(handlerArg
, target
, data
);
4603 poolClear(&tempPool
);
4608 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4609 const char *start
, const char *end
)
4612 if (!commentHandler
) {
4614 reportDefault(parser
, enc
, start
, end
);
4617 data
= poolStoreString(&tempPool
,
4619 start
+ enc
->minBytesPerChar
* 4,
4620 end
- enc
->minBytesPerChar
* 3);
4623 normalizeLines(data
);
4624 commentHandler(handlerArg
, data
);
4625 poolClear(&tempPool
);
4630 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4631 const char *s
, const char *end
)
4633 if (MUST_CONVERT(enc
, s
)) {
4634 const char **eventPP
;
4635 const char **eventEndPP
;
4636 if (enc
== encoding
) {
4637 eventPP
= &eventPtr
;
4638 eventEndPP
= &eventEndPtr
;
4641 eventPP
= &(openInternalEntities
->internalEventPtr
);
4642 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4645 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4646 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4648 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4653 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4658 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4659 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4661 DEFAULT_ATTRIBUTE
*att
;
4662 if (value
|| isId
) {
4663 /* The handling of default attributes gets messed up if we have
4664 a default which duplicates a non-default. */
4666 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4667 if (attId
== type
->defaultAtts
[i
].id
)
4669 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4670 type
->idAtt
= attId
;
4672 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4673 if (type
->allocDefaultAtts
== 0) {
4674 type
->allocDefaultAtts
= 8;
4675 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
4676 * sizeof(DEFAULT_ATTRIBUTE
));
4677 if (!type
->defaultAtts
)
4681 DEFAULT_ATTRIBUTE
*temp
;
4682 int count
= type
->allocDefaultAtts
* 2;
4683 temp
= (DEFAULT_ATTRIBUTE
*)
4684 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4687 type
->allocDefaultAtts
= count
;
4688 type
->defaultAtts
= temp
;
4691 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4694 att
->isCdata
= isCdata
;
4696 attId
->maybeTokenized
= XML_TRUE
;
4697 type
->nDefaultAtts
+= 1;
4702 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4704 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4705 const XML_Char
*name
;
4706 for (name
= elementType
->name
; *name
; name
++) {
4707 if (*name
== XML_T(':')) {
4710 for (s
= elementType
->name
; s
!= name
; s
++) {
4711 if (!poolAppendChar(&dtd
->pool
, *s
))
4714 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4716 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4720 if (prefix
->name
== poolStart(&dtd
->pool
))
4721 poolFinish(&dtd
->pool
);
4723 poolDiscard(&dtd
->pool
);
4724 elementType
->prefix
= prefix
;
4731 static ATTRIBUTE_ID
*
4732 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4733 const char *start
, const char *end
)
4735 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4737 const XML_Char
*name
;
4738 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4740 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
4744 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4747 if (id
->name
!= name
)
4748 poolDiscard(&dtd
->pool
);
4750 poolFinish(&dtd
->pool
);
4753 else if (name
[0] == XML_T('x')
4754 && name
[1] == XML_T('m')
4755 && name
[2] == XML_T('l')
4756 && name
[3] == XML_T('n')
4757 && name
[4] == XML_T('s')
4758 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4759 if (name
[5] == XML_T('\0'))
4760 id
->prefix
= &dtd
->defaultPrefix
;
4762 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
4763 id
->xmlns
= XML_TRUE
;
4767 for (i
= 0; name
[i
]; i
++) {
4768 if (name
[i
] == XML_T(':')) {
4770 for (j
= 0; j
< i
; j
++) {
4771 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
4774 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4776 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4778 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
4779 poolFinish(&dtd
->pool
);
4781 poolDiscard(&dtd
->pool
);
4790 #define CONTEXT_SEP XML_T('\f')
4792 static const XML_Char
*
4793 getContext(XML_Parser parser
)
4795 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4796 HASH_TABLE_ITER iter
;
4797 XML_Bool needSep
= XML_FALSE
;
4799 if (dtd
->defaultPrefix
.binding
) {
4802 if (!poolAppendChar(&tempPool
, XML_T('=')))
4804 len
= dtd
->defaultPrefix
.binding
->uriLen
;
4805 if (namespaceSeparator
!= XML_T('\0'))
4807 for (i
= 0; i
< len
; i
++)
4808 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
4813 hashTableIterInit(&iter
, &(dtd
->prefixes
));
4818 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4821 if (!prefix
->binding
)
4823 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4825 for (s
= prefix
->name
; *s
; s
++)
4826 if (!poolAppendChar(&tempPool
, *s
))
4828 if (!poolAppendChar(&tempPool
, XML_T('=')))
4830 len
= prefix
->binding
->uriLen
;
4831 if (namespaceSeparator
!= XML_T('\0'))
4833 for (i
= 0; i
< len
; i
++)
4834 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4840 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
4843 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4848 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4850 for (s
= e
->name
; *s
; s
++)
4851 if (!poolAppendChar(&tempPool
, *s
))
4856 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4858 return tempPool
.start
;
4862 setContext(XML_Parser parser
, const XML_Char
*context
)
4864 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4865 const XML_Char
*s
= context
;
4867 while (*context
!= XML_T('\0')) {
4868 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4870 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4872 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
4875 if (*s
!= XML_T('\0'))
4878 poolDiscard(&tempPool
);
4880 else if (*s
== XML_T('=')) {
4882 if (poolLength(&tempPool
) == 0)
4883 prefix
= &dtd
->defaultPrefix
;
4885 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4887 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
4891 if (prefix
->name
== poolStart(&tempPool
)) {
4892 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
4896 poolDiscard(&tempPool
);
4898 for (context
= s
+ 1;
4899 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4901 if (!poolAppendChar(&tempPool
, *context
))
4903 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4905 if (addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4906 &inheritedBindings
) != XML_ERROR_NONE
)
4908 poolDiscard(&tempPool
);
4909 if (*context
!= XML_T('\0'))
4914 if (!poolAppendChar(&tempPool
, *s
))
4922 static void FASTCALL
4923 normalizePublicId(XML_Char
*publicId
)
4925 XML_Char
*p
= publicId
;
4927 for (s
= publicId
; *s
; s
++) {
4932 if (p
!= publicId
&& p
[-1] != 0x20)
4939 if (p
!= publicId
&& p
[-1] == 0x20)
4945 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
4947 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
4950 poolInit(&(p
->pool
), ms
);
4952 poolInit(&(p
->entityValuePool
), ms
);
4953 #endif /* XML_DTD */
4954 hashTableInit(&(p
->generalEntities
), ms
);
4955 hashTableInit(&(p
->elementTypes
), ms
);
4956 hashTableInit(&(p
->attributeIds
), ms
);
4957 hashTableInit(&(p
->prefixes
), ms
);
4959 p
->paramEntityRead
= XML_FALSE
;
4960 hashTableInit(&(p
->paramEntities
), ms
);
4961 #endif /* XML_DTD */
4962 p
->defaultPrefix
.name
= NULL
;
4963 p
->defaultPrefix
.binding
= NULL
;
4965 p
->in_eldecl
= XML_FALSE
;
4966 p
->scaffIndex
= NULL
;
4971 p
->contentStringLen
= 0;
4973 p
->keepProcessing
= XML_TRUE
;
4974 p
->hasParamEntityRefs
= XML_FALSE
;
4975 p
->standalone
= XML_FALSE
;
4980 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
4982 HASH_TABLE_ITER iter
;
4983 hashTableIterInit(&iter
, &(p
->elementTypes
));
4985 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4988 if (e
->allocDefaultAtts
!= 0)
4989 ms
->free_fcn(e
->defaultAtts
);
4991 hashTableClear(&(p
->generalEntities
));
4993 p
->paramEntityRead
= XML_FALSE
;
4994 hashTableClear(&(p
->paramEntities
));
4995 #endif /* XML_DTD */
4996 hashTableClear(&(p
->elementTypes
));
4997 hashTableClear(&(p
->attributeIds
));
4998 hashTableClear(&(p
->prefixes
));
4999 poolClear(&(p
->pool
));
5001 poolClear(&(p
->entityValuePool
));
5002 #endif /* XML_DTD */
5003 p
->defaultPrefix
.name
= NULL
;
5004 p
->defaultPrefix
.binding
= NULL
;
5006 p
->in_eldecl
= XML_FALSE
;
5007 if (p
->scaffIndex
) {
5008 ms
->free_fcn(p
->scaffIndex
);
5009 p
->scaffIndex
= NULL
;
5012 ms
->free_fcn(p
->scaffold
);
5018 p
->contentStringLen
= 0;
5020 p
->keepProcessing
= XML_TRUE
;
5021 p
->hasParamEntityRefs
= XML_FALSE
;
5022 p
->standalone
= XML_FALSE
;
5026 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5028 HASH_TABLE_ITER iter
;
5029 hashTableIterInit(&iter
, &(p
->elementTypes
));
5031 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5034 if (e
->allocDefaultAtts
!= 0)
5035 ms
->free_fcn(e
->defaultAtts
);
5037 hashTableDestroy(&(p
->generalEntities
));
5039 hashTableDestroy(&(p
->paramEntities
));
5040 #endif /* XML_DTD */
5041 hashTableDestroy(&(p
->elementTypes
));
5042 hashTableDestroy(&(p
->attributeIds
));
5043 hashTableDestroy(&(p
->prefixes
));
5044 poolDestroy(&(p
->pool
));
5046 poolDestroy(&(p
->entityValuePool
));
5047 #endif /* XML_DTD */
5050 ms
->free_fcn(p
->scaffIndex
);
5052 ms
->free_fcn(p
->scaffold
);
5057 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5058 The new DTD has already been initialized.
5061 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5063 HASH_TABLE_ITER iter
;
5065 /* Copy the prefix table. */
5067 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5069 const XML_Char
*name
;
5070 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5073 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5076 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5080 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5082 /* Copy the attribute id table. */
5086 const XML_Char
*name
;
5087 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5091 /* Remember to allocate the scratch byte before the name. */
5092 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5094 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5098 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5099 sizeof(ATTRIBUTE_ID
));
5102 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5104 newA
->xmlns
= oldA
->xmlns
;
5105 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5106 newA
->prefix
= &newDtd
->defaultPrefix
;
5108 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5109 oldA
->prefix
->name
, 0);
5113 /* Copy the element type table. */
5115 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5120 const XML_Char
*name
;
5121 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5124 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5127 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5128 sizeof(ELEMENT_TYPE
));
5131 if (oldE
->nDefaultAtts
) {
5132 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5133 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5134 if (!newE
->defaultAtts
) {
5140 newE
->idAtt
= (ATTRIBUTE_ID
*)
5141 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5142 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5144 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5145 oldE
->prefix
->name
, 0);
5146 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5147 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5148 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5149 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5150 if (oldE
->defaultAtts
[i
].value
) {
5151 newE
->defaultAtts
[i
].value
5152 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5153 if (!newE
->defaultAtts
[i
].value
)
5157 newE
->defaultAtts
[i
].value
= NULL
;
5161 /* Copy the entity tables. */
5162 if (!copyEntityTable(&(newDtd
->generalEntities
),
5164 &(oldDtd
->generalEntities
)))
5168 if (!copyEntityTable(&(newDtd
->paramEntities
),
5170 &(oldDtd
->paramEntities
)))
5172 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5173 #endif /* XML_DTD */
5175 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5176 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5177 newDtd
->standalone
= oldDtd
->standalone
;
5179 /* Don't want deep copying for scaffolding */
5180 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5181 newDtd
->scaffold
= oldDtd
->scaffold
;
5182 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5183 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5184 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5185 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5191 copyEntityTable(HASH_TABLE
*newTable
,
5192 STRING_POOL
*newPool
,
5193 const HASH_TABLE
*oldTable
)
5195 HASH_TABLE_ITER iter
;
5196 const XML_Char
*cachedOldBase
= NULL
;
5197 const XML_Char
*cachedNewBase
= NULL
;
5199 hashTableIterInit(&iter
, oldTable
);
5203 const XML_Char
*name
;
5204 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5207 name
= poolCopyString(newPool
, oldE
->name
);
5210 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5213 if (oldE
->systemId
) {
5214 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5217 newE
->systemId
= tem
;
5219 if (oldE
->base
== cachedOldBase
)
5220 newE
->base
= cachedNewBase
;
5222 cachedOldBase
= oldE
->base
;
5223 tem
= poolCopyString(newPool
, cachedOldBase
);
5226 cachedNewBase
= newE
->base
= tem
;
5229 if (oldE
->publicId
) {
5230 tem
= poolCopyString(newPool
, oldE
->publicId
);
5233 newE
->publicId
= tem
;
5237 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5241 newE
->textPtr
= tem
;
5242 newE
->textLen
= oldE
->textLen
;
5244 if (oldE
->notation
) {
5245 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5248 newE
->notation
= tem
;
5250 newE
->is_param
= oldE
->is_param
;
5251 newE
->is_internal
= oldE
->is_internal
;
5256 #define INIT_SIZE 64
5259 keyeq(KEY s1
, KEY s2
)
5261 for (; *s1
== *s2
; s1
++, s2
++)
5267 static unsigned long FASTCALL
5270 unsigned long h
= 0;
5272 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5277 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5280 if (table
->size
== 0) {
5285 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5286 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5289 memset(table
->v
, 0, tsize
);
5290 table
->size
= INIT_SIZE
;
5291 table
->usedLim
= INIT_SIZE
/ 2;
5292 i
= hash(name
) & (table
->size
- 1);
5295 unsigned long h
= hash(name
);
5296 for (i
= h
& (table
->size
- 1);
5298 i
== 0 ? i
= table
->size
- 1 : --i
) {
5299 if (keyeq(name
, table
->v
[i
]->name
))
5304 if (table
->used
== table
->usedLim
) {
5305 /* check for overflow */
5306 size_t newSize
= table
->size
* 2;
5307 size_t tsize
= newSize
* sizeof(NAMED
*);
5308 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5311 memset(newV
, 0, tsize
);
5312 for (i
= 0; i
< table
->size
; i
++)
5315 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5317 j
== 0 ? j
= newSize
- 1 : --j
)
5319 newV
[j
] = table
->v
[i
];
5321 table
->mem
->free_fcn(table
->v
);
5323 table
->size
= newSize
;
5324 table
->usedLim
= newSize
/2;
5325 for (i
= h
& (table
->size
- 1);
5327 i
== 0 ? i
= table
->size
- 1 : --i
)
5331 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5334 memset(table
->v
[i
], 0, createSize
);
5335 table
->v
[i
]->name
= name
;
5340 static void FASTCALL
5341 hashTableClear(HASH_TABLE
*table
)
5344 for (i
= 0; i
< table
->size
; i
++) {
5345 NAMED
*p
= table
->v
[i
];
5347 table
->mem
->free_fcn(p
);
5351 table
->usedLim
= table
->size
/ 2;
5355 static void FASTCALL
5356 hashTableDestroy(HASH_TABLE
*table
)
5359 for (i
= 0; i
< table
->size
; i
++) {
5360 NAMED
*p
= table
->v
[i
];
5362 table
->mem
->free_fcn(p
);
5365 table
->mem
->free_fcn(table
->v
);
5368 static void FASTCALL
5369 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5378 static void FASTCALL
5379 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5382 iter
->end
= iter
->p
+ table
->size
;
5385 static NAMED
* FASTCALL
5386 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5388 while (iter
->p
!= iter
->end
) {
5389 NAMED
*tem
= *(iter
->p
)++;
5396 static void FASTCALL
5397 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5399 pool
->blocks
= NULL
;
5400 pool
->freeBlocks
= NULL
;
5407 static void FASTCALL
5408 poolClear(STRING_POOL
*pool
)
5410 if (!pool
->freeBlocks
)
5411 pool
->freeBlocks
= pool
->blocks
;
5413 BLOCK
*p
= pool
->blocks
;
5415 BLOCK
*tem
= p
->next
;
5416 p
->next
= pool
->freeBlocks
;
5417 pool
->freeBlocks
= p
;
5421 pool
->blocks
= NULL
;
5427 static void FASTCALL
5428 poolDestroy(STRING_POOL
*pool
)
5430 BLOCK
*p
= pool
->blocks
;
5432 BLOCK
*tem
= p
->next
;
5433 pool
->mem
->free_fcn(p
);
5436 p
= pool
->freeBlocks
;
5438 BLOCK
*tem
= p
->next
;
5439 pool
->mem
->free_fcn(p
);
5445 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5446 const char *ptr
, const char *end
)
5448 if (!pool
->ptr
&& !poolGrow(pool
))
5451 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5454 if (!poolGrow(pool
))
5460 static const XML_Char
* FASTCALL
5461 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5464 if (!poolAppendChar(pool
, *s
))
5472 static const XML_Char
*
5473 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5475 if (!pool
->ptr
&& !poolGrow(pool
))
5477 for (; n
> 0; --n
, s
++) {
5478 if (!poolAppendChar(pool
, *s
))
5486 static const XML_Char
* FASTCALL
5487 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5490 if (!poolAppendChar(pool
, *s
))
5498 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5499 const char *ptr
, const char *end
)
5501 if (!poolAppend(pool
, enc
, ptr
, end
))
5503 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5509 static XML_Bool FASTCALL
5510 poolGrow(STRING_POOL
*pool
)
5512 if (pool
->freeBlocks
) {
5513 if (pool
->start
== 0) {
5514 pool
->blocks
= pool
->freeBlocks
;
5515 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5516 pool
->blocks
->next
= NULL
;
5517 pool
->start
= pool
->blocks
->s
;
5518 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5519 pool
->ptr
= pool
->start
;
5522 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
5523 BLOCK
*tem
= pool
->freeBlocks
->next
;
5524 pool
->freeBlocks
->next
= pool
->blocks
;
5525 pool
->blocks
= pool
->freeBlocks
;
5526 pool
->freeBlocks
= tem
;
5527 memcpy(pool
->blocks
->s
, pool
->start
,
5528 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
5529 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5530 pool
->start
= pool
->blocks
->s
;
5531 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5535 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5536 int blockSize
= (pool
->end
- pool
->start
)*2;
5537 pool
->blocks
= (BLOCK
*)
5538 pool
->mem
->realloc_fcn(pool
->blocks
,
5540 + blockSize
* sizeof(XML_Char
)));
5541 if (pool
->blocks
== NULL
)
5543 pool
->blocks
->size
= blockSize
;
5544 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5545 pool
->start
= pool
->blocks
->s
;
5546 pool
->end
= pool
->start
+ blockSize
;
5550 int blockSize
= pool
->end
- pool
->start
;
5551 if (blockSize
< INIT_BLOCK_SIZE
)
5552 blockSize
= INIT_BLOCK_SIZE
;
5555 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5556 + blockSize
* sizeof(XML_Char
));
5559 tem
->size
= blockSize
;
5560 tem
->next
= pool
->blocks
;
5562 if (pool
->ptr
!= pool
->start
)
5563 memcpy(tem
->s
, pool
->start
,
5564 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5565 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5566 pool
->start
= tem
->s
;
5567 pool
->end
= tem
->s
+ blockSize
;
5573 nextScaffoldPart(XML_Parser parser
)
5575 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5576 CONTENT_SCAFFOLD
* me
;
5579 if (!dtd
->scaffIndex
) {
5580 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
5581 if (!dtd
->scaffIndex
)
5583 dtd
->scaffIndex
[0] = 0;
5586 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
5587 CONTENT_SCAFFOLD
*temp
;
5588 if (dtd
->scaffold
) {
5589 temp
= (CONTENT_SCAFFOLD
*)
5590 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5593 dtd
->scaffSize
*= 2;
5596 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
5597 * sizeof(CONTENT_SCAFFOLD
));
5600 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5602 dtd
->scaffold
= temp
;
5604 next
= dtd
->scaffCount
++;
5605 me
= &dtd
->scaffold
[next
];
5606 if (dtd
->scaffLevel
) {
5607 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
5608 if (parent
->lastchild
) {
5609 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
5611 if (!parent
->childcnt
)
5612 parent
->firstchild
= next
;
5613 parent
->lastchild
= next
;
5616 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5621 build_node(XML_Parser parser
,
5624 XML_Content
**contpos
,
5627 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5628 dest
->type
= dtd
->scaffold
[src_node
].type
;
5629 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
5630 if (dest
->type
== XML_CTYPE_NAME
) {
5631 const XML_Char
*src
;
5632 dest
->name
= *strpos
;
5633 src
= dtd
->scaffold
[src_node
].name
;
5635 *(*strpos
)++ = *src
;
5640 dest
->numchildren
= 0;
5641 dest
->children
= NULL
;
5646 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
5647 dest
->children
= *contpos
;
5648 *contpos
+= dest
->numchildren
;
5649 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
5650 i
< dest
->numchildren
;
5651 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
5652 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5658 static XML_Content
*
5659 build_model (XML_Parser parser
)
5661 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5665 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
5666 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
5668 ret
= (XML_Content
*)MALLOC(allocsize
);
5672 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
5675 build_node(parser
, 0, ret
, &cpos
, &str
);
5679 static ELEMENT_TYPE
*
5680 getElementType(XML_Parser parser
,
5681 const ENCODING
*enc
,
5685 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5686 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
5691 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5694 if (ret
->name
!= name
)
5695 poolDiscard(&dtd
->pool
);
5697 poolFinish(&dtd
->pool
);
5698 if (!setElementTypePrefix(parser
, ret
))