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