1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
8 #ifdef COMPILED_FROM_DSP
10 #include "winconfig.h"
15 #include "os2config.h"
18 #elif defined(MACOS_CLASSIC)
20 #include "macconfig.h"
25 #include "expat_config.h"
28 #define XMLPARSEAPI(type) type __cdecl
36 #endif /* ndef COMPILED_FROM_DSP */
39 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
40 #define XmlConvert XmlUtf16Convert
41 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
42 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
43 #define XmlEncode XmlUtf16Encode
44 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
45 typedef unsigned short ICHAR
;
47 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
48 #define XmlConvert XmlUtf8Convert
49 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
50 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
51 #define XmlEncode XmlUtf8Encode
52 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
59 #define XmlInitEncodingNS XmlInitEncoding
60 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
61 #undef XmlGetInternalEncodingNS
62 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
63 #define XmlParseXmlDeclNS XmlParseXmlDecl
69 #ifdef XML_UNICODE_WCHAR_T
70 #define XML_T(x) (const wchar_t)x
71 #define XML_L(x) L ## x
73 #define XML_T(x) (const unsigned short)x
84 /* Round up n to be a multiple of sz, where sz is a power of 2. */
85 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
87 /* Handle the case where memmove() doesn't exist. */
90 #define memmove(d,s,l) bcopy((s),(d),(l))
92 #error memmove does not exist on this platform, nor is a substitute available
93 #endif /* HAVE_BCOPY */
94 #endif /* HAVE_MEMMOVE */
100 typedef const XML_Char
*KEY
;
111 const XML_Memory_Handling_Suite
*mem
;
119 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
120 #define INIT_DATA_BUF_SIZE 1024
121 #define INIT_ATTS_SIZE 16
122 #define INIT_BLOCK_SIZE 1024
123 #define INIT_BUFFER_SIZE 1024
125 #define EXPAND_SPARE 24
127 typedef struct binding
{
128 struct prefix
*prefix
;
129 struct binding
*nextTagBinding
;
130 struct binding
*prevPrefixBinding
;
131 const struct attribute_id
*attId
;
137 typedef struct prefix
{
138 const XML_Char
*name
;
144 const XML_Char
*localPart
;
145 const XML_Char
*prefix
;
151 /* TAG represents an open element.
152 The name of the element is stored in both the document and API
153 encodings. The memory buffer 'buf' is a separately-allocated
154 memory area which stores the name. During the XML_Parse()/
155 XMLParseBuffer() when the element is open, the memory for the 'raw'
156 version of the name (in the document encoding) is shared with the
157 document buffer. If the element is open across calls to
158 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
159 contain the 'raw' name as well.
161 A parser re-uses these structures, maintaining a list of allocated
162 TAG objects in a free list.
165 struct tag
*parent
; /* parent of this element */
166 const char *rawName
; /* tagName in the original encoding */
168 TAG_NAME name
; /* tagName in the API encoding */
169 char *buf
; /* buffer for name components */
170 char *bufEnd
; /* end of the buffer */
175 const XML_Char
*name
;
176 const XML_Char
*textPtr
;
178 const XML_Char
*systemId
;
179 const XML_Char
*base
;
180 const XML_Char
*publicId
;
181 const XML_Char
*notation
;
184 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
188 enum XML_Content_Type type
;
189 enum XML_Content_Quant quant
;
190 const XML_Char
* name
;
197 #define INIT_SCAFFOLD_ELEMENTS 32
199 typedef struct block
{
211 const XML_Memory_Handling_Suite
*mem
;
214 /* The XML_Char before the name is used to determine whether
215 an attribute has been specified. */
216 typedef struct attribute_id
{
219 XML_Bool maybeTokenized
;
224 const ATTRIBUTE_ID
*id
;
226 const XML_Char
*value
;
230 const XML_Char
*name
;
232 const ATTRIBUTE_ID
*idAtt
;
234 int allocDefaultAtts
;
235 DEFAULT_ATTRIBUTE
*defaultAtts
;
239 HASH_TABLE generalEntities
;
240 HASH_TABLE elementTypes
;
241 HASH_TABLE attributeIds
;
244 STRING_POOL entityValuePool
;
245 /* false once a parameter entity reference has been skipped */
246 XML_Bool keepProcessing
;
247 /* true once an internal or external PE reference has been encountered;
248 this includes the reference to an external subset */
249 XML_Bool hasParamEntityRefs
;
252 /* indicates if external PE has been read */
253 XML_Bool paramEntityRead
;
254 HASH_TABLE paramEntities
;
256 PREFIX defaultPrefix
;
257 /* === scaffolding for building content model === */
259 CONTENT_SCAFFOLD
*scaffold
;
260 unsigned contentStringLen
;
267 typedef struct open_internal_entity
{
268 const char *internalEventPtr
;
269 const char *internalEventEndPtr
;
270 struct open_internal_entity
*next
;
272 } OPEN_INTERNAL_ENTITY
;
274 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
277 const char **endPtr
);
279 static Processor prologProcessor
;
280 static Processor prologInitProcessor
;
281 static Processor contentProcessor
;
282 static Processor cdataSectionProcessor
;
284 static Processor ignoreSectionProcessor
;
285 static Processor externalParEntProcessor
;
286 static Processor externalParEntInitProcessor
;
287 static Processor entityValueProcessor
;
288 static Processor entityValueInitProcessor
;
290 static Processor epilogProcessor
;
291 static Processor errorProcessor
;
292 static Processor externalEntityInitProcessor
;
293 static Processor externalEntityInitProcessor2
;
294 static Processor externalEntityInitProcessor3
;
295 static Processor externalEntityContentProcessor
;
297 static enum XML_Error
298 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
299 static enum XML_Error
300 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
301 const char *, const char *);
302 static enum XML_Error
303 initializeEncoding(XML_Parser parser
);
304 static enum XML_Error
305 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
306 const char *end
, int tok
, const char *next
, const char **nextPtr
);
307 static enum XML_Error
308 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
309 static enum XML_Error
310 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
311 const char *start
, const char *end
, const char **endPtr
);
312 static enum XML_Error
313 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
314 const char *end
, const char **nextPtr
);
316 static enum XML_Error
317 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
318 const char *end
, const char **nextPtr
);
321 static enum XML_Error
322 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
323 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
324 static enum XML_Error
325 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
326 const XML_Char
*uri
, BINDING
**bindingsPtr
);
328 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
329 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
331 static enum XML_Error
332 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
333 const char *, const char *, STRING_POOL
*);
334 static enum XML_Error
335 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
336 const char *, const char *, STRING_POOL
*);
337 static ATTRIBUTE_ID
*
338 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
341 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
342 static enum XML_Error
343 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
346 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
347 const char *start
, const char *end
);
349 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
352 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
355 static const XML_Char
* getContext(XML_Parser parser
);
357 setContext(XML_Parser parser
, const XML_Char
*context
);
359 static void FASTCALL
normalizePublicId(XML_Char
*s
);
361 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
362 /* do not call if parentParser != NULL */
363 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
365 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
367 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
369 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
372 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
374 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
375 static void FASTCALL
hashTableClear(HASH_TABLE
*);
376 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
378 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
379 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
382 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
383 static void FASTCALL
poolClear(STRING_POOL
*);
384 static void FASTCALL
poolDestroy(STRING_POOL
*);
386 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
387 const char *ptr
, const char *end
);
389 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
390 const char *ptr
, const char *end
);
391 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
392 static const XML_Char
* FASTCALL
393 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
394 static const XML_Char
*
395 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
396 static const XML_Char
* FASTCALL
397 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
399 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
400 static XML_Content
* build_model(XML_Parser parser
);
401 static ELEMENT_TYPE
*
402 getElementType(XML_Parser parser
, const ENCODING
*enc
,
403 const char *ptr
, const char *end
);
406 parserCreate(const XML_Char
*encodingName
,
407 const XML_Memory_Handling_Suite
*memsuite
,
408 const XML_Char
*nameSep
,
411 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
413 #define poolStart(pool) ((pool)->start)
414 #define poolEnd(pool) ((pool)->ptr)
415 #define poolLength(pool) ((pool)->ptr - (pool)->start)
416 #define poolChop(pool) ((void)--(pool->ptr))
417 #define poolLastChar(pool) (((pool)->ptr)[-1])
418 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
419 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
420 #define poolAppendChar(pool, c) \
421 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
423 : ((*((pool)->ptr)++ = c), 1))
425 struct XML_ParserStruct
{
426 /* The first member must be userData so that the XML_GetUserData
431 const XML_Memory_Handling_Suite m_mem
;
432 /* first character to be parsed */
433 const char *m_bufferPtr
;
434 /* past last character to be parsed */
436 /* allocated end of buffer */
437 const char *m_bufferLim
;
438 long m_parseEndByteIndex
;
439 const char *m_parseEndPtr
;
441 XML_Char
*m_dataBufEnd
;
442 XML_StartElementHandler m_startElementHandler
;
443 XML_EndElementHandler m_endElementHandler
;
444 XML_CharacterDataHandler m_characterDataHandler
;
445 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
446 XML_CommentHandler m_commentHandler
;
447 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
448 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
449 XML_DefaultHandler m_defaultHandler
;
450 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
451 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
452 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
453 XML_NotationDeclHandler m_notationDeclHandler
;
454 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
455 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
456 XML_NotStandaloneHandler m_notStandaloneHandler
;
457 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
458 XML_Parser m_externalEntityRefHandlerArg
;
459 XML_SkippedEntityHandler m_skippedEntityHandler
;
460 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
461 XML_ElementDeclHandler m_elementDeclHandler
;
462 XML_AttlistDeclHandler m_attlistDeclHandler
;
463 XML_EntityDeclHandler m_entityDeclHandler
;
464 XML_XmlDeclHandler m_xmlDeclHandler
;
465 const ENCODING
*m_encoding
;
466 INIT_ENCODING m_initEncoding
;
467 const ENCODING
*m_internalEncoding
;
468 const XML_Char
*m_protocolEncodingName
;
470 XML_Bool m_ns_triplets
;
471 void *m_unknownEncodingMem
;
472 void *m_unknownEncodingData
;
473 void *m_unknownEncodingHandlerData
;
474 void (*m_unknownEncodingRelease
)(void *);
475 PROLOG_STATE m_prologState
;
476 Processor
*m_processor
;
477 enum XML_Error m_errorCode
;
478 const char *m_eventPtr
;
479 const char *m_eventEndPtr
;
480 const char *m_positionPtr
;
481 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
482 XML_Bool m_defaultExpandInternalEntities
;
484 ENTITY
*m_declEntity
;
485 const XML_Char
*m_doctypeName
;
486 const XML_Char
*m_doctypeSysid
;
487 const XML_Char
*m_doctypePubid
;
488 const XML_Char
*m_declAttributeType
;
489 const XML_Char
*m_declNotationName
;
490 const XML_Char
*m_declNotationPublicId
;
491 ELEMENT_TYPE
*m_declElementType
;
492 ATTRIBUTE_ID
*m_declAttributeId
;
493 XML_Bool m_declAttributeIsCdata
;
494 XML_Bool m_declAttributeIsId
;
496 const XML_Char
*m_curBase
;
499 BINDING
*m_inheritedBindings
;
500 BINDING
*m_freeBindingList
;
502 int m_nSpecifiedAtts
;
506 STRING_POOL m_tempPool
;
507 STRING_POOL m_temp2Pool
;
508 char *m_groupConnector
;
509 unsigned m_groupSize
;
510 XML_Char m_namespaceSeparator
;
511 XML_Parser m_parentParser
;
513 XML_Bool m_isParamEntity
;
514 XML_Bool m_useForeignDTD
;
515 enum XML_ParamEntityParsing m_paramEntityParsing
;
519 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
520 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
521 #define FREE(p) (parser->m_mem.free_fcn((p)))
523 #define userData (parser->m_userData)
524 #define handlerArg (parser->m_handlerArg)
525 #define startElementHandler (parser->m_startElementHandler)
526 #define endElementHandler (parser->m_endElementHandler)
527 #define characterDataHandler (parser->m_characterDataHandler)
528 #define processingInstructionHandler \
529 (parser->m_processingInstructionHandler)
530 #define commentHandler (parser->m_commentHandler)
531 #define startCdataSectionHandler \
532 (parser->m_startCdataSectionHandler)
533 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
534 #define defaultHandler (parser->m_defaultHandler)
535 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
536 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
537 #define unparsedEntityDeclHandler \
538 (parser->m_unparsedEntityDeclHandler)
539 #define notationDeclHandler (parser->m_notationDeclHandler)
540 #define startNamespaceDeclHandler \
541 (parser->m_startNamespaceDeclHandler)
542 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
543 #define notStandaloneHandler (parser->m_notStandaloneHandler)
544 #define externalEntityRefHandler \
545 (parser->m_externalEntityRefHandler)
546 #define externalEntityRefHandlerArg \
547 (parser->m_externalEntityRefHandlerArg)
548 #define internalEntityRefHandler \
549 (parser->m_internalEntityRefHandler)
550 #define skippedEntityHandler (parser->m_skippedEntityHandler)
551 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
552 #define elementDeclHandler (parser->m_elementDeclHandler)
553 #define attlistDeclHandler (parser->m_attlistDeclHandler)
554 #define entityDeclHandler (parser->m_entityDeclHandler)
555 #define xmlDeclHandler (parser->m_xmlDeclHandler)
556 #define encoding (parser->m_encoding)
557 #define initEncoding (parser->m_initEncoding)
558 #define internalEncoding (parser->m_internalEncoding)
559 #define unknownEncodingMem (parser->m_unknownEncodingMem)
560 #define unknownEncodingData (parser->m_unknownEncodingData)
561 #define unknownEncodingHandlerData \
562 (parser->m_unknownEncodingHandlerData)
563 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
564 #define protocolEncodingName (parser->m_protocolEncodingName)
565 #define ns (parser->m_ns)
566 #define ns_triplets (parser->m_ns_triplets)
567 #define prologState (parser->m_prologState)
568 #define processor (parser->m_processor)
569 #define errorCode (parser->m_errorCode)
570 #define eventPtr (parser->m_eventPtr)
571 #define eventEndPtr (parser->m_eventEndPtr)
572 #define positionPtr (parser->m_positionPtr)
573 #define position (parser->m_position)
574 #define openInternalEntities (parser->m_openInternalEntities)
575 #define defaultExpandInternalEntities \
576 (parser->m_defaultExpandInternalEntities)
577 #define tagLevel (parser->m_tagLevel)
578 #define buffer (parser->m_buffer)
579 #define bufferPtr (parser->m_bufferPtr)
580 #define bufferEnd (parser->m_bufferEnd)
581 #define parseEndByteIndex (parser->m_parseEndByteIndex)
582 #define parseEndPtr (parser->m_parseEndPtr)
583 #define bufferLim (parser->m_bufferLim)
584 #define dataBuf (parser->m_dataBuf)
585 #define dataBufEnd (parser->m_dataBufEnd)
586 #define _dtd (parser->m_dtd)
587 #define curBase (parser->m_curBase)
588 #define declEntity (parser->m_declEntity)
589 #define doctypeName (parser->m_doctypeName)
590 #define doctypeSysid (parser->m_doctypeSysid)
591 #define doctypePubid (parser->m_doctypePubid)
592 #define declAttributeType (parser->m_declAttributeType)
593 #define declNotationName (parser->m_declNotationName)
594 #define declNotationPublicId (parser->m_declNotationPublicId)
595 #define declElementType (parser->m_declElementType)
596 #define declAttributeId (parser->m_declAttributeId)
597 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
598 #define declAttributeIsId (parser->m_declAttributeIsId)
599 #define freeTagList (parser->m_freeTagList)
600 #define freeBindingList (parser->m_freeBindingList)
601 #define inheritedBindings (parser->m_inheritedBindings)
602 #define tagStack (parser->m_tagStack)
603 #define atts (parser->m_atts)
604 #define attsSize (parser->m_attsSize)
605 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
606 #define idAttIndex (parser->m_idAttIndex)
607 #define tempPool (parser->m_tempPool)
608 #define temp2Pool (parser->m_temp2Pool)
609 #define groupConnector (parser->m_groupConnector)
610 #define groupSize (parser->m_groupSize)
611 #define namespaceSeparator (parser->m_namespaceSeparator)
612 #define parentParser (parser->m_parentParser)
614 #define isParamEntity (parser->m_isParamEntity)
615 #define useForeignDTD (parser->m_useForeignDTD)
616 #define paramEntityParsing (parser->m_paramEntityParsing)
624 (processor != externalParEntInitProcessor) \
626 (processor != externalEntityInitProcessor)) \
628 (processor != prologInitProcessor))
631 XML_ParserCreate(const XML_Char
*encodingName
)
633 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
637 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
641 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
644 static const XML_Char implicitContext
[] = {
645 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
646 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
647 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
648 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
652 XML_ParserCreate_MM(const XML_Char
*encodingName
,
653 const XML_Memory_Handling_Suite
*memsuite
,
654 const XML_Char
*nameSep
)
656 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
657 if (parser
!= NULL
&& ns
) {
658 /* implicit context only set for root parser, since child
659 parsers (i.e. external entity parsers) will inherit it
661 if (!setContext(parser
, implicitContext
)) {
662 XML_ParserFree(parser
);
670 parserCreate(const XML_Char
*encodingName
,
671 const XML_Memory_Handling_Suite
*memsuite
,
672 const XML_Char
*nameSep
,
678 XML_Memory_Handling_Suite
*mtemp
;
679 parser
= (XML_Parser
)
680 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
681 if (parser
!= NULL
) {
682 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
683 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
684 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
685 mtemp
->free_fcn
= memsuite
->free_fcn
;
689 XML_Memory_Handling_Suite
*mtemp
;
690 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
691 if (parser
!= NULL
) {
692 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
693 mtemp
->malloc_fcn
= malloc
;
694 mtemp
->realloc_fcn
= realloc
;
695 mtemp
->free_fcn
= free
;
705 attsSize
= INIT_ATTS_SIZE
;
706 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
711 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
712 if (dataBuf
== NULL
) {
717 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
722 _dtd
= dtdCreate(&parser
->m_mem
);
731 freeBindingList
= NULL
;
735 groupConnector
= NULL
;
737 unknownEncodingHandler
= NULL
;
738 unknownEncodingHandlerData
= NULL
;
740 namespaceSeparator
= '!';
742 ns_triplets
= XML_FALSE
;
744 poolInit(&tempPool
, &(parser
->m_mem
));
745 poolInit(&temp2Pool
, &(parser
->m_mem
));
746 parserInit(parser
, encodingName
);
748 if (encodingName
&& !protocolEncodingName
) {
749 XML_ParserFree(parser
);
755 internalEncoding
= XmlGetInternalEncodingNS();
756 namespaceSeparator
= *nameSep
;
759 internalEncoding
= XmlGetInternalEncoding();
766 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
768 processor
= prologInitProcessor
;
769 XmlPrologStateInit(&prologState
);
770 protocolEncodingName
= (encodingName
!= NULL
771 ? poolCopyString(&tempPool
, encodingName
)
774 XmlInitEncoding(&initEncoding
, &encoding
, 0);
777 startElementHandler
= NULL
;
778 endElementHandler
= NULL
;
779 characterDataHandler
= NULL
;
780 processingInstructionHandler
= NULL
;
781 commentHandler
= NULL
;
782 startCdataSectionHandler
= NULL
;
783 endCdataSectionHandler
= NULL
;
784 defaultHandler
= NULL
;
785 startDoctypeDeclHandler
= NULL
;
786 endDoctypeDeclHandler
= NULL
;
787 unparsedEntityDeclHandler
= NULL
;
788 notationDeclHandler
= NULL
;
789 startNamespaceDeclHandler
= NULL
;
790 endNamespaceDeclHandler
= NULL
;
791 notStandaloneHandler
= NULL
;
792 externalEntityRefHandler
= NULL
;
793 externalEntityRefHandlerArg
= parser
;
794 skippedEntityHandler
= NULL
;
795 elementDeclHandler
= NULL
;
796 attlistDeclHandler
= NULL
;
797 entityDeclHandler
= NULL
;
798 xmlDeclHandler
= NULL
;
801 parseEndByteIndex
= 0;
803 declElementType
= NULL
;
804 declAttributeId
= NULL
;
809 declAttributeType
= NULL
;
810 declNotationName
= NULL
;
811 declNotationPublicId
= NULL
;
812 declAttributeIsCdata
= XML_FALSE
;
813 declAttributeIsId
= XML_FALSE
;
814 memset(&position
, 0, sizeof(POSITION
));
815 errorCode
= XML_ERROR_NONE
;
819 openInternalEntities
= 0;
820 defaultExpandInternalEntities
= XML_TRUE
;
823 inheritedBindings
= NULL
;
825 unknownEncodingMem
= NULL
;
826 unknownEncodingRelease
= NULL
;
827 unknownEncodingData
= NULL
;
830 isParamEntity
= XML_FALSE
;
831 useForeignDTD
= XML_FALSE
;
832 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
836 /* moves list of bindings to freeBindingList */
838 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
841 BINDING
*b
= bindings
;
842 bindings
= bindings
->nextTagBinding
;
843 b
->nextTagBinding
= freeBindingList
;
849 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
854 /* move tagStack to freeTagList */
859 tag
->parent
= freeTagList
;
860 moveToFreeBindingList(parser
, tag
->bindings
);
861 tag
->bindings
= NULL
;
864 moveToFreeBindingList(parser
, inheritedBindings
);
865 if (unknownEncodingMem
)
866 FREE(unknownEncodingMem
);
867 if (unknownEncodingRelease
)
868 unknownEncodingRelease(unknownEncodingData
);
869 poolClear(&tempPool
);
870 poolClear(&temp2Pool
);
871 parserInit(parser
, encodingName
);
872 dtdReset(_dtd
, &parser
->m_mem
);
873 return setContext(parser
, implicitContext
);
877 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
879 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
880 XXX There's no way for the caller to determine which of the
881 XXX possible error cases caused the XML_STATUS_ERROR return.
884 return XML_STATUS_ERROR
;
885 if (encodingName
== NULL
)
886 protocolEncodingName
= NULL
;
888 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
889 if (!protocolEncodingName
)
890 return XML_STATUS_ERROR
;
892 return XML_STATUS_OK
;
896 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
897 const XML_Char
*context
,
898 const XML_Char
*encodingName
)
900 XML_Parser parser
= oldParser
;
903 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
904 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
905 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
906 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
907 = processingInstructionHandler
;
908 XML_CommentHandler oldCommentHandler
= commentHandler
;
909 XML_StartCdataSectionHandler oldStartCdataSectionHandler
910 = startCdataSectionHandler
;
911 XML_EndCdataSectionHandler oldEndCdataSectionHandler
912 = endCdataSectionHandler
;
913 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
914 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
915 = unparsedEntityDeclHandler
;
916 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
917 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
918 = startNamespaceDeclHandler
;
919 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
920 = endNamespaceDeclHandler
;
921 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
922 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
923 = externalEntityRefHandler
;
924 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
925 XML_UnknownEncodingHandler oldUnknownEncodingHandler
926 = unknownEncodingHandler
;
927 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
928 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
929 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
930 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
931 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
933 void *oldUserData
= userData
;
934 void *oldHandlerArg
= handlerArg
;
935 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
936 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
938 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
939 int oldInEntityValue
= prologState
.inEntityValue
;
941 XML_Bool oldns_triplets
= ns_triplets
;
948 /* Note that the magical uses of the pre-processor to make field
949 access look more like C++ require that `parser' be overwritten
950 here. This makes this function more painful to follow than it
955 *tmp
= namespaceSeparator
;
956 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
959 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
965 startElementHandler
= oldStartElementHandler
;
966 endElementHandler
= oldEndElementHandler
;
967 characterDataHandler
= oldCharacterDataHandler
;
968 processingInstructionHandler
= oldProcessingInstructionHandler
;
969 commentHandler
= oldCommentHandler
;
970 startCdataSectionHandler
= oldStartCdataSectionHandler
;
971 endCdataSectionHandler
= oldEndCdataSectionHandler
;
972 defaultHandler
= oldDefaultHandler
;
973 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
974 notationDeclHandler
= oldNotationDeclHandler
;
975 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
976 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
977 notStandaloneHandler
= oldNotStandaloneHandler
;
978 externalEntityRefHandler
= oldExternalEntityRefHandler
;
979 skippedEntityHandler
= oldSkippedEntityHandler
;
980 unknownEncodingHandler
= oldUnknownEncodingHandler
;
981 elementDeclHandler
= oldElementDeclHandler
;
982 attlistDeclHandler
= oldAttlistDeclHandler
;
983 entityDeclHandler
= oldEntityDeclHandler
;
984 xmlDeclHandler
= oldXmlDeclHandler
;
985 declElementType
= oldDeclElementType
;
986 userData
= oldUserData
;
987 if (oldUserData
== oldHandlerArg
)
988 handlerArg
= userData
;
991 if (oldExternalEntityRefHandlerArg
!= oldParser
)
992 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
993 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
994 ns_triplets
= oldns_triplets
;
995 parentParser
= oldParser
;
997 paramEntityParsing
= oldParamEntityParsing
;
998 prologState
.inEntityValue
= oldInEntityValue
;
1000 #endif /* XML_DTD */
1001 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1002 || !setContext(parser
, context
)) {
1003 XML_ParserFree(parser
);
1006 processor
= externalEntityInitProcessor
;
1010 /* The DTD instance referenced by _dtd is shared between the document's
1011 root parser and external PE parsers, therefore one does not need to
1012 call setContext. In addition, one also *must* not call setContext,
1013 because this would overwrite existing prefix->binding pointers in
1014 _dtd with ones that get destroyed with the external PE parser.
1015 This would leave those prefixes with dangling pointers.
1017 isParamEntity
= XML_TRUE
;
1018 XmlPrologStateInitExternalEntity(&prologState
);
1019 processor
= externalParEntInitProcessor
;
1021 #endif /* XML_DTD */
1025 static void FASTCALL
1026 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1029 BINDING
*b
= bindings
;
1032 bindings
= b
->nextTagBinding
;
1039 XML_ParserFree(XML_Parser parser
)
1043 if (tagStack
== NULL
) {
1044 if (freeTagList
== NULL
)
1046 tagStack
= freeTagList
;
1050 tagStack
= tagStack
->parent
;
1052 destroyBindings(p
->bindings
, parser
);
1055 destroyBindings(freeBindingList
, parser
);
1056 destroyBindings(inheritedBindings
, parser
);
1057 poolDestroy(&tempPool
);
1058 poolDestroy(&temp2Pool
);
1060 /* external parameter entity parsers share the DTD structure
1061 parser->m_dtd with the root parser, so we must not destroy it
1063 if (!isParamEntity
&& _dtd
)
1066 #endif /* XML_DTD */
1067 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1070 FREE(groupConnector
);
1074 if (unknownEncodingMem
)
1075 FREE(unknownEncodingMem
);
1076 if (unknownEncodingRelease
)
1077 unknownEncodingRelease(unknownEncodingData
);
1082 XML_UseParserAsHandlerArg(XML_Parser parser
)
1084 handlerArg
= parser
;
1088 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1091 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1093 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1094 useForeignDTD
= useDTD
;
1095 return XML_ERROR_NONE
;
1097 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1102 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1104 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1107 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1111 XML_SetUserData(XML_Parser parser
, void *p
)
1113 if (handlerArg
== userData
)
1114 handlerArg
= userData
= p
;
1120 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1123 p
= poolCopyString(&_dtd
->pool
, p
);
1125 return XML_STATUS_ERROR
;
1130 return XML_STATUS_OK
;
1134 XML_GetBase(XML_Parser parser
)
1140 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1142 return nSpecifiedAtts
;
1146 XML_GetIdAttributeIndex(XML_Parser parser
)
1152 XML_SetElementHandler(XML_Parser parser
,
1153 XML_StartElementHandler start
,
1154 XML_EndElementHandler end
)
1156 startElementHandler
= start
;
1157 endElementHandler
= end
;
1161 XML_SetStartElementHandler(XML_Parser parser
,
1162 XML_StartElementHandler start
) {
1163 startElementHandler
= start
;
1167 XML_SetEndElementHandler(XML_Parser parser
,
1168 XML_EndElementHandler end
) {
1169 endElementHandler
= end
;
1173 XML_SetCharacterDataHandler(XML_Parser parser
,
1174 XML_CharacterDataHandler handler
)
1176 characterDataHandler
= handler
;
1180 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1181 XML_ProcessingInstructionHandler handler
)
1183 processingInstructionHandler
= handler
;
1187 XML_SetCommentHandler(XML_Parser parser
,
1188 XML_CommentHandler handler
)
1190 commentHandler
= handler
;
1194 XML_SetCdataSectionHandler(XML_Parser parser
,
1195 XML_StartCdataSectionHandler start
,
1196 XML_EndCdataSectionHandler end
)
1198 startCdataSectionHandler
= start
;
1199 endCdataSectionHandler
= end
;
1203 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1204 XML_StartCdataSectionHandler start
) {
1205 startCdataSectionHandler
= start
;
1209 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1210 XML_EndCdataSectionHandler end
) {
1211 endCdataSectionHandler
= end
;
1215 XML_SetDefaultHandler(XML_Parser parser
,
1216 XML_DefaultHandler handler
)
1218 defaultHandler
= handler
;
1219 defaultExpandInternalEntities
= XML_FALSE
;
1223 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1224 XML_DefaultHandler handler
)
1226 defaultHandler
= handler
;
1227 defaultExpandInternalEntities
= XML_TRUE
;
1231 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1232 XML_StartDoctypeDeclHandler start
,
1233 XML_EndDoctypeDeclHandler end
)
1235 startDoctypeDeclHandler
= start
;
1236 endDoctypeDeclHandler
= end
;
1240 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1241 XML_StartDoctypeDeclHandler start
) {
1242 startDoctypeDeclHandler
= start
;
1246 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1247 XML_EndDoctypeDeclHandler end
) {
1248 endDoctypeDeclHandler
= end
;
1252 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1253 XML_UnparsedEntityDeclHandler handler
)
1255 unparsedEntityDeclHandler
= handler
;
1259 XML_SetNotationDeclHandler(XML_Parser parser
,
1260 XML_NotationDeclHandler handler
)
1262 notationDeclHandler
= handler
;
1266 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1267 XML_StartNamespaceDeclHandler start
,
1268 XML_EndNamespaceDeclHandler end
)
1270 startNamespaceDeclHandler
= start
;
1271 endNamespaceDeclHandler
= end
;
1275 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1276 XML_StartNamespaceDeclHandler start
) {
1277 startNamespaceDeclHandler
= start
;
1281 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1282 XML_EndNamespaceDeclHandler end
) {
1283 endNamespaceDeclHandler
= end
;
1287 XML_SetNotStandaloneHandler(XML_Parser parser
,
1288 XML_NotStandaloneHandler handler
)
1290 notStandaloneHandler
= handler
;
1294 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1295 XML_ExternalEntityRefHandler handler
)
1297 externalEntityRefHandler
= handler
;
1301 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1304 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1306 externalEntityRefHandlerArg
= parser
;
1310 XML_SetSkippedEntityHandler(XML_Parser parser
,
1311 XML_SkippedEntityHandler handler
)
1313 skippedEntityHandler
= handler
;
1317 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1318 XML_UnknownEncodingHandler handler
,
1321 unknownEncodingHandler
= handler
;
1322 unknownEncodingHandlerData
= data
;
1326 XML_SetElementDeclHandler(XML_Parser parser
,
1327 XML_ElementDeclHandler eldecl
)
1329 elementDeclHandler
= eldecl
;
1333 XML_SetAttlistDeclHandler(XML_Parser parser
,
1334 XML_AttlistDeclHandler attdecl
)
1336 attlistDeclHandler
= attdecl
;
1340 XML_SetEntityDeclHandler(XML_Parser parser
,
1341 XML_EntityDeclHandler handler
)
1343 entityDeclHandler
= handler
;
1347 XML_SetXmlDeclHandler(XML_Parser parser
,
1348 XML_XmlDeclHandler handler
) {
1349 xmlDeclHandler
= handler
;
1353 XML_SetParamEntityParsing(XML_Parser parser
,
1354 enum XML_ParamEntityParsing peParsing
)
1356 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1360 paramEntityParsing
= peParsing
;
1363 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1368 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1372 return XML_STATUS_OK
;
1373 positionPtr
= bufferPtr
;
1374 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1375 if (errorCode
== XML_ERROR_NONE
)
1376 return XML_STATUS_OK
;
1377 eventEndPtr
= eventPtr
;
1378 processor
= errorProcessor
;
1379 return XML_STATUS_ERROR
;
1381 #ifndef XML_CONTEXT_BYTES
1382 else if (bufferPtr
== bufferEnd
) {
1385 parseEndByteIndex
+= len
;
1388 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1389 if (errorCode
== XML_ERROR_NONE
)
1390 return XML_STATUS_OK
;
1391 eventEndPtr
= eventPtr
;
1392 processor
= errorProcessor
;
1393 return XML_STATUS_ERROR
;
1395 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1396 if (errorCode
!= XML_ERROR_NONE
) {
1397 eventEndPtr
= eventPtr
;
1398 processor
= errorProcessor
;
1399 return XML_STATUS_ERROR
;
1401 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1403 nLeftOver
= s
+ len
- end
;
1405 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1406 /* FIXME avoid integer overflow */
1408 temp
= (buffer
== NULL
1409 ? (char *)MALLOC(len
* 2)
1410 : (char *)REALLOC(buffer
, len
* 2));
1412 errorCode
= XML_ERROR_NO_MEMORY
;
1413 return XML_STATUS_ERROR
;
1417 errorCode
= XML_ERROR_NO_MEMORY
;
1418 eventPtr
= eventEndPtr
= NULL
;
1419 processor
= errorProcessor
;
1420 return XML_STATUS_ERROR
;
1422 bufferLim
= buffer
+ len
* 2;
1424 memcpy(buffer
, end
, nLeftOver
);
1426 bufferEnd
= buffer
+ nLeftOver
;
1428 return XML_STATUS_OK
;
1430 #endif /* not defined XML_CONTEXT_BYTES */
1432 void *buff
= XML_GetBuffer(parser
, len
);
1434 return XML_STATUS_ERROR
;
1436 memcpy(buff
, s
, len
);
1437 return XML_ParseBuffer(parser
, len
, isFinal
);
1443 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1445 const char *start
= bufferPtr
;
1446 positionPtr
= start
;
1448 parseEndByteIndex
+= len
;
1449 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1450 isFinal
? (const char **)NULL
: &bufferPtr
);
1451 if (errorCode
== XML_ERROR_NONE
) {
1453 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1454 positionPtr
= bufferPtr
;
1456 return XML_STATUS_OK
;
1459 eventEndPtr
= eventPtr
;
1460 processor
= errorProcessor
;
1461 return XML_STATUS_ERROR
;
1466 XML_GetBuffer(XML_Parser parser
, int len
)
1468 if (len
> bufferLim
- bufferEnd
) {
1469 /* FIXME avoid integer overflow */
1470 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1471 #ifdef XML_CONTEXT_BYTES
1472 int keep
= bufferPtr
- buffer
;
1474 if (keep
> XML_CONTEXT_BYTES
)
1475 keep
= XML_CONTEXT_BYTES
;
1477 #endif /* defined XML_CONTEXT_BYTES */
1478 if (neededSize
<= bufferLim
- buffer
) {
1479 #ifdef XML_CONTEXT_BYTES
1480 if (keep
< bufferPtr
- buffer
) {
1481 int offset
= (bufferPtr
- buffer
) - keep
;
1482 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1483 bufferEnd
-= offset
;
1484 bufferPtr
-= offset
;
1487 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1488 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1490 #endif /* not defined XML_CONTEXT_BYTES */
1494 int bufferSize
= bufferLim
- bufferPtr
;
1495 if (bufferSize
== 0)
1496 bufferSize
= INIT_BUFFER_SIZE
;
1499 } while (bufferSize
< neededSize
);
1500 newBuf
= (char *)MALLOC(bufferSize
);
1502 errorCode
= XML_ERROR_NO_MEMORY
;
1505 bufferLim
= newBuf
+ bufferSize
;
1506 #ifdef XML_CONTEXT_BYTES
1508 int keep
= bufferPtr
- buffer
;
1509 if (keep
> XML_CONTEXT_BYTES
)
1510 keep
= XML_CONTEXT_BYTES
;
1511 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1514 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1515 bufferPtr
= buffer
+ keep
;
1518 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1519 bufferPtr
= buffer
= newBuf
;
1523 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1526 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1527 bufferPtr
= buffer
= newBuf
;
1528 #endif /* not defined XML_CONTEXT_BYTES */
1535 XML_GetErrorCode(XML_Parser parser
)
1541 XML_GetCurrentByteIndex(XML_Parser parser
)
1544 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1549 XML_GetCurrentByteCount(XML_Parser parser
)
1551 if (eventEndPtr
&& eventPtr
)
1552 return eventEndPtr
- eventPtr
;
1557 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1559 #ifdef XML_CONTEXT_BYTES
1560 if (eventPtr
&& buffer
) {
1561 *offset
= eventPtr
- buffer
;
1562 *size
= bufferEnd
- buffer
;
1565 #endif /* defined XML_CONTEXT_BYTES */
1570 XML_GetCurrentLineNumber(XML_Parser parser
)
1573 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1574 positionPtr
= eventPtr
;
1576 return position
.lineNumber
+ 1;
1580 XML_GetCurrentColumnNumber(XML_Parser parser
)
1583 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1584 positionPtr
= eventPtr
;
1586 return position
.columnNumber
;
1590 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1596 XML_MemMalloc(XML_Parser parser
, size_t size
)
1598 return MALLOC(size
);
1602 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1604 return REALLOC(ptr
, size
);
1608 XML_MemFree(XML_Parser parser
, void *ptr
)
1614 XML_DefaultCurrent(XML_Parser parser
)
1616 if (defaultHandler
) {
1617 if (openInternalEntities
)
1618 reportDefault(parser
,
1620 openInternalEntities
->internalEventPtr
,
1621 openInternalEntities
->internalEventEndPtr
);
1623 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1628 XML_ErrorString(enum XML_Error code
)
1630 static const XML_LChar
*message
[] = {
1632 XML_L("out of memory"),
1633 XML_L("syntax error"),
1634 XML_L("no element found"),
1635 XML_L("not well-formed (invalid token)"),
1636 XML_L("unclosed token"),
1637 XML_L("partial character"),
1638 XML_L("mismatched tag"),
1639 XML_L("duplicate attribute"),
1640 XML_L("junk after document element"),
1641 XML_L("illegal parameter entity reference"),
1642 XML_L("undefined entity"),
1643 XML_L("recursive entity reference"),
1644 XML_L("asynchronous entity"),
1645 XML_L("reference to invalid character number"),
1646 XML_L("reference to binary entity"),
1647 XML_L("reference to external entity in attribute"),
1648 XML_L("xml declaration not at start of external entity"),
1649 XML_L("unknown encoding"),
1650 XML_L("encoding specified in XML declaration is incorrect"),
1651 XML_L("unclosed CDATA section"),
1652 XML_L("error in processing external entity reference"),
1653 XML_L("document is not standalone"),
1654 XML_L("unexpected parser state - please send a bug report"),
1655 XML_L("entity declared in parameter entity"),
1656 XML_L("requested feature requires XML_DTD support in Expat"),
1657 XML_L("cannot change setting once parsing has begun")
1659 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1660 return message
[code
];
1665 XML_ExpatVersion(void) {
1667 /* V1 is used to string-ize the version number. However, it would
1668 string-ize the actual version macro *names* unless we get them
1669 substituted before being passed to V1. CPP is defined to expand
1670 a macro, then rescan for more expansions. Thus, we use V2 to expand
1671 the version macros, then CPP will expand the resulting V1() macro
1672 with the correct numerals. */
1673 /* ### I'm assuming cpp is portable in this respect... */
1675 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1676 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1678 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1685 XML_ExpatVersionInfo(void)
1687 XML_Expat_Version version
;
1689 version
.major
= XML_MAJOR_VERSION
;
1690 version
.minor
= XML_MINOR_VERSION
;
1691 version
.micro
= XML_MICRO_VERSION
;
1697 XML_GetFeatureList(void)
1699 static XML_Feature features
[] = {
1700 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1701 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1703 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1705 #ifdef XML_UNICODE_WCHAR_T
1706 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1709 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1711 #ifdef XML_CONTEXT_BYTES
1712 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1716 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1718 {XML_FEATURE_END
, NULL
}
1721 features
[0].value
= sizeof(XML_Char
);
1722 features
[1].value
= sizeof(XML_LChar
);
1726 /* Initially tag->rawName always points into the parse buffer;
1727 for those TAG instances opened while the current parse buffer was
1728 processed, and not yet closed, we need to store tag->rawName in a more
1729 permanent location, since the parse buffer is about to be discarded.
1732 storeRawNames(XML_Parser parser
)
1734 TAG
*tag
= tagStack
;
1737 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1738 char *rawNameBuf
= tag
->buf
+ nameLen
;
1739 /* Stop if already stored. Since tagStack is a stack, we can stop
1740 at the first entry that has already been copied; everything
1741 below it in the stack is already been accounted for in a
1742 previous call to this function.
1744 if (tag
->rawName
== rawNameBuf
)
1746 /* For re-use purposes we need to ensure that the
1747 size of tag->buf is a multiple of sizeof(XML_Char).
1749 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1750 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1751 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1754 /* if tag->name.str points to tag->buf (only when namespace
1755 processing is off) then we have to update it
1757 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1758 tag
->name
.str
= (XML_Char
*)temp
;
1759 /* if tag->name.localPart is set (when namespace processing is on)
1760 then update it as well, since it will always point into tag->buf
1762 if (tag
->name
.localPart
)
1763 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1764 (XML_Char
*)tag
->buf
);
1766 tag
->bufEnd
= temp
+ bufSize
;
1767 rawNameBuf
= temp
+ nameLen
;
1769 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1770 tag
->rawName
= rawNameBuf
;
1776 static enum XML_Error PTRCALL
1777 contentProcessor(XML_Parser parser
,
1780 const char **endPtr
)
1782 enum XML_Error result
=
1783 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1784 if (result
!= XML_ERROR_NONE
)
1786 if (!storeRawNames(parser
))
1787 return XML_ERROR_NO_MEMORY
;
1791 static enum XML_Error PTRCALL
1792 externalEntityInitProcessor(XML_Parser parser
,
1795 const char **endPtr
)
1797 enum XML_Error result
= initializeEncoding(parser
);
1798 if (result
!= XML_ERROR_NONE
)
1800 processor
= externalEntityInitProcessor2
;
1801 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1804 static enum XML_Error PTRCALL
1805 externalEntityInitProcessor2(XML_Parser parser
,
1808 const char **endPtr
)
1810 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1811 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1814 /* If we are at the end of the buffer, this would cause the next stage,
1815 i.e. externalEntityInitProcessor3, to pass control directly to
1816 doContent (by detecting XML_TOK_NONE) without processing any xml text
1817 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1819 if (next
== end
&& endPtr
) {
1821 return XML_ERROR_NONE
;
1825 case XML_TOK_PARTIAL
:
1828 return XML_ERROR_NONE
;
1831 return XML_ERROR_UNCLOSED_TOKEN
;
1832 case XML_TOK_PARTIAL_CHAR
:
1835 return XML_ERROR_NONE
;
1838 return XML_ERROR_PARTIAL_CHAR
;
1840 processor
= externalEntityInitProcessor3
;
1841 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1844 static enum XML_Error PTRCALL
1845 externalEntityInitProcessor3(XML_Parser parser
,
1848 const char **endPtr
)
1850 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1851 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1853 case XML_TOK_XML_DECL
:
1855 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1856 if (result
!= XML_ERROR_NONE
)
1861 case XML_TOK_PARTIAL
:
1864 return XML_ERROR_NONE
;
1867 return XML_ERROR_UNCLOSED_TOKEN
;
1868 case XML_TOK_PARTIAL_CHAR
:
1871 return XML_ERROR_NONE
;
1874 return XML_ERROR_PARTIAL_CHAR
;
1876 processor
= externalEntityContentProcessor
;
1878 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1881 static enum XML_Error PTRCALL
1882 externalEntityContentProcessor(XML_Parser parser
,
1885 const char **endPtr
)
1887 enum XML_Error result
=
1888 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1889 if (result
!= XML_ERROR_NONE
)
1891 if (!storeRawNames(parser
))
1892 return XML_ERROR_NO_MEMORY
;
1896 static enum XML_Error
1897 doContent(XML_Parser parser
,
1899 const ENCODING
*enc
,
1902 const char **nextPtr
)
1904 DTD
* const dtd
= _dtd
; /* save one level of indirection */
1905 const char **eventPP
;
1906 const char **eventEndPP
;
1907 if (enc
== encoding
) {
1908 eventPP
= &eventPtr
;
1909 eventEndPP
= &eventEndPtr
;
1912 eventPP
= &(openInternalEntities
->internalEventPtr
);
1913 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1917 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1918 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1921 case XML_TOK_TRAILING_CR
:
1924 return XML_ERROR_NONE
;
1927 if (characterDataHandler
) {
1929 characterDataHandler(handlerArg
, &c
, 1);
1931 else if (defaultHandler
)
1932 reportDefault(parser
, enc
, s
, end
);
1933 if (startTagLevel
== 0)
1934 return XML_ERROR_NO_ELEMENTS
;
1935 if (tagLevel
!= startTagLevel
)
1936 return XML_ERROR_ASYNC_ENTITY
;
1937 return XML_ERROR_NONE
;
1941 return XML_ERROR_NONE
;
1943 if (startTagLevel
> 0) {
1944 if (tagLevel
!= startTagLevel
)
1945 return XML_ERROR_ASYNC_ENTITY
;
1946 return XML_ERROR_NONE
;
1948 return XML_ERROR_NO_ELEMENTS
;
1949 case XML_TOK_INVALID
:
1951 return XML_ERROR_INVALID_TOKEN
;
1952 case XML_TOK_PARTIAL
:
1955 return XML_ERROR_NONE
;
1957 return XML_ERROR_UNCLOSED_TOKEN
;
1958 case XML_TOK_PARTIAL_CHAR
:
1961 return XML_ERROR_NONE
;
1963 return XML_ERROR_PARTIAL_CHAR
;
1964 case XML_TOK_ENTITY_REF
:
1966 const XML_Char
*name
;
1968 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1969 s
+ enc
->minBytesPerChar
,
1970 next
- enc
->minBytesPerChar
);
1972 if (characterDataHandler
)
1973 characterDataHandler(handlerArg
, &ch
, 1);
1974 else if (defaultHandler
)
1975 reportDefault(parser
, enc
, s
, next
);
1978 name
= poolStoreString(&dtd
->pool
, enc
,
1979 s
+ enc
->minBytesPerChar
,
1980 next
- enc
->minBytesPerChar
);
1982 return XML_ERROR_NO_MEMORY
;
1983 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
1984 poolDiscard(&dtd
->pool
);
1985 /* First, determine if a check for an existing declaration is needed;
1986 if yes, check that the entity exists, and that it is internal,
1987 otherwise call the skipped entity or default handler.
1989 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
1991 return XML_ERROR_UNDEFINED_ENTITY
;
1992 else if (!entity
->is_internal
)
1993 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
1996 if (skippedEntityHandler
)
1997 skippedEntityHandler(handlerArg
, name
, 0);
1998 else if (defaultHandler
)
1999 reportDefault(parser
, enc
, s
, next
);
2003 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2004 if (entity
->notation
)
2005 return XML_ERROR_BINARY_ENTITY_REF
;
2006 if (entity
->textPtr
) {
2007 enum XML_Error result
;
2008 OPEN_INTERNAL_ENTITY openEntity
;
2009 if (!defaultExpandInternalEntities
) {
2010 if (skippedEntityHandler
)
2011 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2012 else if (defaultHandler
)
2013 reportDefault(parser
, enc
, s
, next
);
2016 entity
->open
= XML_TRUE
;
2017 openEntity
.next
= openInternalEntities
;
2018 openInternalEntities
= &openEntity
;
2019 openEntity
.entity
= entity
;
2020 openEntity
.internalEventPtr
= NULL
;
2021 openEntity
.internalEventEndPtr
= NULL
;
2022 result
= doContent(parser
,
2025 (char *)entity
->textPtr
,
2026 (char *)(entity
->textPtr
+ entity
->textLen
),
2028 entity
->open
= XML_FALSE
;
2029 openInternalEntities
= openEntity
.next
;
2033 else if (externalEntityRefHandler
) {
2034 const XML_Char
*context
;
2035 entity
->open
= XML_TRUE
;
2036 context
= getContext(parser
);
2037 entity
->open
= XML_FALSE
;
2039 return XML_ERROR_NO_MEMORY
;
2040 if (!externalEntityRefHandler((XML_Parser
)externalEntityRefHandlerArg
,
2045 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2046 poolDiscard(&tempPool
);
2048 else if (defaultHandler
)
2049 reportDefault(parser
, enc
, s
, next
);
2052 case XML_TOK_START_TAG_NO_ATTS
:
2054 case XML_TOK_START_TAG_WITH_ATTS
:
2057 enum XML_Error result
;
2061 freeTagList
= freeTagList
->parent
;
2064 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2066 return XML_ERROR_NO_MEMORY
;
2067 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2070 return XML_ERROR_NO_MEMORY
;
2072 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2074 tag
->bindings
= NULL
;
2075 tag
->parent
= tagStack
;
2077 tag
->name
.localPart
= NULL
;
2078 tag
->name
.prefix
= NULL
;
2079 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2080 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2083 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2084 const char *fromPtr
= tag
->rawName
;
2085 toPtr
= (XML_Char
*)tag
->buf
;
2090 &fromPtr
, rawNameEnd
,
2091 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2092 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2093 if (fromPtr
== rawNameEnd
) {
2094 tag
->name
.strLen
= convLen
;
2097 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2099 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2101 return XML_ERROR_NO_MEMORY
;
2103 tag
->bufEnd
= temp
+ bufSize
;
2104 toPtr
= (XML_Char
*)temp
+ convLen
;
2108 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2109 *toPtr
= XML_T('\0');
2110 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2113 if (startElementHandler
)
2114 startElementHandler(handlerArg
, tag
->name
.str
,
2115 (const XML_Char
**)atts
);
2116 else if (defaultHandler
)
2117 reportDefault(parser
, enc
, s
, next
);
2118 poolClear(&tempPool
);
2121 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2123 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2125 const char *rawName
= s
+ enc
->minBytesPerChar
;
2126 enum XML_Error result
;
2127 BINDING
*bindings
= NULL
;
2128 XML_Bool noElmHandlers
= XML_TRUE
;
2130 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2131 rawName
+ XmlNameLength(enc
, rawName
));
2133 return XML_ERROR_NO_MEMORY
;
2134 poolFinish(&tempPool
);
2135 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2138 poolFinish(&tempPool
);
2139 if (startElementHandler
) {
2140 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2141 noElmHandlers
= XML_FALSE
;
2143 if (endElementHandler
) {
2144 if (startElementHandler
)
2145 *eventPP
= *eventEndPP
;
2146 endElementHandler(handlerArg
, name
.str
);
2147 noElmHandlers
= XML_FALSE
;
2149 if (noElmHandlers
&& defaultHandler
)
2150 reportDefault(parser
, enc
, s
, next
);
2151 poolClear(&tempPool
);
2153 BINDING
*b
= bindings
;
2154 if (endNamespaceDeclHandler
)
2155 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2156 bindings
= bindings
->nextTagBinding
;
2157 b
->nextTagBinding
= freeBindingList
;
2158 freeBindingList
= b
;
2159 b
->prefix
->binding
= b
->prevPrefixBinding
;
2163 return epilogProcessor(parser
, next
, end
, nextPtr
);
2165 case XML_TOK_END_TAG
:
2166 if (tagLevel
== startTagLevel
)
2167 return XML_ERROR_ASYNC_ENTITY
;
2170 const char *rawName
;
2171 TAG
*tag
= tagStack
;
2172 tagStack
= tag
->parent
;
2173 tag
->parent
= freeTagList
;
2175 rawName
= s
+ enc
->minBytesPerChar
*2;
2176 len
= XmlNameLength(enc
, rawName
);
2177 if (len
!= tag
->rawNameLength
2178 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2180 return XML_ERROR_TAG_MISMATCH
;
2183 if (endElementHandler
) {
2184 const XML_Char
*localPart
;
2185 const XML_Char
*prefix
;
2187 localPart
= tag
->name
.localPart
;
2188 if (ns
&& localPart
) {
2189 /* localPart and prefix may have been overwritten in
2190 tag->name.str, since this points to the binding->uri
2191 buffer which gets re-used; so we have to add them again
2193 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2194 /* don't need to check for space - already done in storeAtts() */
2195 while (*localPart
) *uri
++ = *localPart
++;
2196 prefix
= (XML_Char
*)tag
->name
.prefix
;
2197 if (ns_triplets
&& prefix
) {
2198 *uri
++ = namespaceSeparator
;
2199 while (*prefix
) *uri
++ = *prefix
++;
2203 endElementHandler(handlerArg
, tag
->name
.str
);
2205 else if (defaultHandler
)
2206 reportDefault(parser
, enc
, s
, next
);
2207 while (tag
->bindings
) {
2208 BINDING
*b
= tag
->bindings
;
2209 if (endNamespaceDeclHandler
)
2210 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2211 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2212 b
->nextTagBinding
= freeBindingList
;
2213 freeBindingList
= b
;
2214 b
->prefix
->binding
= b
->prevPrefixBinding
;
2217 return epilogProcessor(parser
, next
, end
, nextPtr
);
2220 case XML_TOK_CHAR_REF
:
2222 int n
= XmlCharRefNumber(enc
, s
);
2224 return XML_ERROR_BAD_CHAR_REF
;
2225 if (characterDataHandler
) {
2226 XML_Char buf
[XML_ENCODE_MAX
];
2227 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2229 else if (defaultHandler
)
2230 reportDefault(parser
, enc
, s
, next
);
2233 case XML_TOK_XML_DECL
:
2234 return XML_ERROR_MISPLACED_XML_PI
;
2235 case XML_TOK_DATA_NEWLINE
:
2236 if (characterDataHandler
) {
2238 characterDataHandler(handlerArg
, &c
, 1);
2240 else if (defaultHandler
)
2241 reportDefault(parser
, enc
, s
, next
);
2243 case XML_TOK_CDATA_SECT_OPEN
:
2245 enum XML_Error result
;
2246 if (startCdataSectionHandler
)
2247 startCdataSectionHandler(handlerArg
);
2249 /* Suppose you doing a transformation on a document that involves
2250 changing only the character data. You set up a defaultHandler
2251 and a characterDataHandler. The defaultHandler simply copies
2252 characters through. The characterDataHandler does the
2253 transformation and writes the characters out escaping them as
2254 necessary. This case will fail to work if we leave out the
2255 following two lines (because & and < inside CDATA sections will
2256 be incorrectly escaped).
2258 However, now we have a start/endCdataSectionHandler, so it seems
2259 easier to let the user deal with this.
2261 else if (characterDataHandler
)
2262 characterDataHandler(handlerArg
, dataBuf
, 0);
2264 else if (defaultHandler
)
2265 reportDefault(parser
, enc
, s
, next
);
2266 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2268 processor
= cdataSectionProcessor
;
2273 case XML_TOK_TRAILING_RSQB
:
2276 return XML_ERROR_NONE
;
2278 if (characterDataHandler
) {
2279 if (MUST_CONVERT(enc
, s
)) {
2280 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2281 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2282 characterDataHandler(handlerArg
, dataBuf
,
2283 dataPtr
- (ICHAR
*)dataBuf
);
2286 characterDataHandler(handlerArg
,
2288 (XML_Char
*)end
- (XML_Char
*)s
);
2290 else if (defaultHandler
)
2291 reportDefault(parser
, enc
, s
, end
);
2292 if (startTagLevel
== 0) {
2294 return XML_ERROR_NO_ELEMENTS
;
2296 if (tagLevel
!= startTagLevel
) {
2298 return XML_ERROR_ASYNC_ENTITY
;
2300 return XML_ERROR_NONE
;
2301 case XML_TOK_DATA_CHARS
:
2302 if (characterDataHandler
) {
2303 if (MUST_CONVERT(enc
, s
)) {
2305 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2306 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2308 characterDataHandler(handlerArg
, dataBuf
,
2309 dataPtr
- (ICHAR
*)dataBuf
);
2316 characterDataHandler(handlerArg
,
2318 (XML_Char
*)next
- (XML_Char
*)s
);
2320 else if (defaultHandler
)
2321 reportDefault(parser
, enc
, s
, next
);
2324 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2325 return XML_ERROR_NO_MEMORY
;
2327 case XML_TOK_COMMENT
:
2328 if (!reportComment(parser
, enc
, s
, next
))
2329 return XML_ERROR_NO_MEMORY
;
2333 reportDefault(parser
, enc
, s
, next
);
2336 *eventPP
= s
= next
;
2341 /* Precondition: all arguments must be non-NULL;
2343 - normalize attributes
2344 - check attributes for well-formedness
2345 - generate namespace aware attribute names (URI, prefix)
2346 - build list of attributes for startElementHandler
2347 - default attributes
2348 - process namespace declarations (check and report them)
2349 - generate namespace aware element name (URI, prefix)
2351 static enum XML_Error
2352 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2353 const char *attStr
, TAG_NAME
*tagNamePtr
,
2354 BINDING
**bindingsPtr
)
2356 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2357 ELEMENT_TYPE
*elementType
= NULL
;
2358 int nDefaultAtts
= 0;
2359 const XML_Char
**appAtts
; /* the attribute list for the application */
2367 const XML_Char
*localPart
;
2369 /* lookup the element type name */
2370 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2372 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2374 return XML_ERROR_NO_MEMORY
;
2375 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2376 sizeof(ELEMENT_TYPE
));
2378 return XML_ERROR_NO_MEMORY
;
2379 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2380 return XML_ERROR_NO_MEMORY
;
2382 nDefaultAtts
= elementType
->nDefaultAtts
;
2384 /* get the attributes from the tokenizer */
2385 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2386 if (n
+ nDefaultAtts
> attsSize
) {
2387 int oldAttsSize
= attsSize
;
2389 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2390 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2392 return XML_ERROR_NO_MEMORY
;
2394 if (n
> oldAttsSize
)
2395 XmlGetAttributes(enc
, attStr
, n
, atts
);
2398 appAtts
= (const XML_Char
**)atts
;
2399 for (i
= 0; i
< n
; i
++) {
2400 /* add the name and value to the attribute list */
2401 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2403 + XmlNameLength(enc
, atts
[i
].name
));
2405 return XML_ERROR_NO_MEMORY
;
2406 /* detect duplicate attributes */
2407 if ((attId
->name
)[-1]) {
2408 if (enc
== encoding
)
2409 eventPtr
= atts
[i
].name
;
2410 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2412 (attId
->name
)[-1] = 1;
2413 appAtts
[attIndex
++] = attId
->name
;
2414 if (!atts
[i
].normalized
) {
2415 enum XML_Error result
;
2416 XML_Bool isCdata
= XML_TRUE
;
2418 /* figure out whether declared as other than CDATA */
2419 if (attId
->maybeTokenized
) {
2421 for (j
= 0; j
< nDefaultAtts
; j
++) {
2422 if (attId
== elementType
->defaultAtts
[j
].id
) {
2423 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2429 /* normalize the attribute value */
2430 result
= storeAttributeValue(parser
, enc
, isCdata
,
2431 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2435 appAtts
[attIndex
] = poolStart(&tempPool
);
2436 poolFinish(&tempPool
);
2439 /* the value did not need normalizing */
2440 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2442 if (appAtts
[attIndex
] == 0)
2443 return XML_ERROR_NO_MEMORY
;
2444 poolFinish(&tempPool
);
2446 /* handle prefixed attribute names */
2447 if (attId
->prefix
) {
2449 /* deal with namespace declarations here */
2450 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2451 appAtts
[attIndex
], bindingsPtr
);
2457 /* deal with other prefixed names later */
2460 (attId
->name
)[-1] = 2;
2467 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2468 nSpecifiedAtts
= attIndex
;
2469 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2470 for (i
= 0; i
< attIndex
; i
+= 2)
2471 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2479 /* do attribute defaulting */
2480 for (i
= 0; i
< nDefaultAtts
; i
++) {
2481 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2482 if (!(da
->id
->name
)[-1] && da
->value
) {
2483 if (da
->id
->prefix
) {
2484 if (da
->id
->xmlns
) {
2485 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2486 da
->value
, bindingsPtr
);
2491 (da
->id
->name
)[-1] = 2;
2493 appAtts
[attIndex
++] = da
->id
->name
;
2494 appAtts
[attIndex
++] = da
->value
;
2498 (da
->id
->name
)[-1] = 1;
2499 appAtts
[attIndex
++] = da
->id
->name
;
2500 appAtts
[attIndex
++] = da
->value
;
2504 appAtts
[attIndex
] = 0;
2508 /* expand prefixed attribute names */
2509 for (; i
< attIndex
; i
+= 2) {
2510 if (appAtts
[i
][-1] == 2) {
2512 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2513 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, appAtts
[i
], 0);
2514 if (id
->prefix
->binding
) {
2516 const BINDING
*b
= id
->prefix
->binding
;
2517 const XML_Char
*s
= appAtts
[i
];
2518 for (j
= 0; j
< b
->uriLen
; j
++) {
2519 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2520 return XML_ERROR_NO_MEMORY
;
2522 while (*s
++ != XML_T(':'))
2525 if (!poolAppendChar(&tempPool
, *s
))
2526 return XML_ERROR_NO_MEMORY
;
2529 tempPool
.ptr
[-1] = namespaceSeparator
;
2530 s
= b
->prefix
->name
;
2532 if (!poolAppendChar(&tempPool
, *s
))
2533 return XML_ERROR_NO_MEMORY
;
2537 appAtts
[i
] = poolStart(&tempPool
);
2538 poolFinish(&tempPool
);
2544 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2547 /* clear the flags that say whether attributes were specified */
2548 for (; i
< attIndex
; i
+= 2)
2549 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2550 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2551 binding
->attId
->name
[-1] = 0;
2553 /* expand the element type name */
2554 if (elementType
->prefix
) {
2555 binding
= elementType
->prefix
->binding
;
2557 return XML_ERROR_NONE
;
2558 localPart
= tagNamePtr
->str
;
2559 while (*localPart
++ != XML_T(':'))
2562 else if (dtd
->defaultPrefix
.binding
) {
2563 binding
= dtd
->defaultPrefix
.binding
;
2564 localPart
= tagNamePtr
->str
;
2567 return XML_ERROR_NONE
;
2569 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2570 for (; binding
->prefix
->name
[prefixLen
++];)
2573 tagNamePtr
->localPart
= localPart
;
2574 tagNamePtr
->uriLen
= binding
->uriLen
;
2575 tagNamePtr
->prefix
= binding
->prefix
->name
;
2576 tagNamePtr
->prefixLen
= prefixLen
;
2577 for (i
= 0; localPart
[i
++];)
2579 n
= i
+ binding
->uriLen
+ prefixLen
;
2580 if (n
> binding
->uriAlloc
) {
2582 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2584 return XML_ERROR_NO_MEMORY
;
2585 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2586 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2587 for (p
= tagStack
; p
; p
= p
->parent
)
2588 if (p
->name
.str
== binding
->uri
)
2593 uri
= binding
->uri
+ binding
->uriLen
;
2594 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2596 uri
= uri
+ (i
- 1);
2597 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2598 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2600 tagNamePtr
->str
= binding
->uri
;
2601 return XML_ERROR_NONE
;
2604 /* addBinding() overwrites the value of prefix->binding without checking.
2605 Therefore one must keep track of the old value outside of addBinding().
2607 static enum XML_Error
2608 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2609 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2614 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2615 if (*uri
== XML_T('\0') && prefix
->name
)
2616 return XML_ERROR_SYNTAX
;
2618 for (len
= 0; uri
[len
]; len
++)
2620 if (namespaceSeparator
)
2622 if (freeBindingList
) {
2623 b
= freeBindingList
;
2624 if (len
> b
->uriAlloc
) {
2625 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2626 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2628 return XML_ERROR_NO_MEMORY
;
2630 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2632 freeBindingList
= b
->nextTagBinding
;
2635 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2637 return XML_ERROR_NO_MEMORY
;
2638 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2641 return XML_ERROR_NO_MEMORY
;
2643 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2646 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2647 if (namespaceSeparator
)
2648 b
->uri
[len
- 1] = namespaceSeparator
;
2651 b
->prevPrefixBinding
= prefix
->binding
;
2652 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2653 prefix
->binding
= NULL
;
2655 prefix
->binding
= b
;
2656 b
->nextTagBinding
= *bindingsPtr
;
2658 if (startNamespaceDeclHandler
)
2659 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2660 prefix
->binding
? uri
: 0);
2661 return XML_ERROR_NONE
;
2664 /* The idea here is to avoid using stack for each CDATA section when
2665 the whole file is parsed with one call.
2667 static enum XML_Error PTRCALL
2668 cdataSectionProcessor(XML_Parser parser
,
2671 const char **endPtr
)
2673 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2676 if (parentParser
) { /* we are parsing an external entity */
2677 processor
= externalEntityContentProcessor
;
2678 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2681 processor
= contentProcessor
;
2682 return contentProcessor(parser
, start
, end
, endPtr
);
2688 /* startPtr gets set to non-null is the section is closed, and to null if
2689 the section is not yet closed.
2691 static enum XML_Error
2692 doCdataSection(XML_Parser parser
,
2693 const ENCODING
*enc
,
2694 const char **startPtr
,
2696 const char **nextPtr
)
2698 const char *s
= *startPtr
;
2699 const char **eventPP
;
2700 const char **eventEndPP
;
2701 if (enc
== encoding
) {
2702 eventPP
= &eventPtr
;
2704 eventEndPP
= &eventEndPtr
;
2707 eventPP
= &(openInternalEntities
->internalEventPtr
);
2708 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2714 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2717 case XML_TOK_CDATA_SECT_CLOSE
:
2718 if (endCdataSectionHandler
)
2719 endCdataSectionHandler(handlerArg
);
2721 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2722 else if (characterDataHandler
)
2723 characterDataHandler(handlerArg
, dataBuf
, 0);
2725 else if (defaultHandler
)
2726 reportDefault(parser
, enc
, s
, next
);
2728 return XML_ERROR_NONE
;
2729 case XML_TOK_DATA_NEWLINE
:
2730 if (characterDataHandler
) {
2732 characterDataHandler(handlerArg
, &c
, 1);
2734 else if (defaultHandler
)
2735 reportDefault(parser
, enc
, s
, next
);
2737 case XML_TOK_DATA_CHARS
:
2738 if (characterDataHandler
) {
2739 if (MUST_CONVERT(enc
, s
)) {
2741 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2742 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2744 characterDataHandler(handlerArg
, dataBuf
,
2745 dataPtr
- (ICHAR
*)dataBuf
);
2752 characterDataHandler(handlerArg
,
2754 (XML_Char
*)next
- (XML_Char
*)s
);
2756 else if (defaultHandler
)
2757 reportDefault(parser
, enc
, s
, next
);
2759 case XML_TOK_INVALID
:
2761 return XML_ERROR_INVALID_TOKEN
;
2762 case XML_TOK_PARTIAL_CHAR
:
2765 return XML_ERROR_NONE
;
2767 return XML_ERROR_PARTIAL_CHAR
;
2768 case XML_TOK_PARTIAL
:
2772 return XML_ERROR_NONE
;
2774 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2777 return XML_ERROR_UNEXPECTED_STATE
;
2779 *eventPP
= s
= next
;
2786 /* The idea here is to avoid using stack for each IGNORE section when
2787 the whole file is parsed with one call.
2789 static enum XML_Error PTRCALL
2790 ignoreSectionProcessor(XML_Parser parser
,
2793 const char **endPtr
)
2795 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2798 processor
= prologProcessor
;
2799 return prologProcessor(parser
, start
, end
, endPtr
);
2804 /* startPtr gets set to non-null is the section is closed, and to null
2805 if the section is not yet closed.
2807 static enum XML_Error
2808 doIgnoreSection(XML_Parser parser
,
2809 const ENCODING
*enc
,
2810 const char **startPtr
,
2812 const char **nextPtr
)
2816 const char *s
= *startPtr
;
2817 const char **eventPP
;
2818 const char **eventEndPP
;
2819 if (enc
== encoding
) {
2820 eventPP
= &eventPtr
;
2822 eventEndPP
= &eventEndPtr
;
2825 eventPP
= &(openInternalEntities
->internalEventPtr
);
2826 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2830 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2833 case XML_TOK_IGNORE_SECT
:
2835 reportDefault(parser
, enc
, s
, next
);
2837 return XML_ERROR_NONE
;
2838 case XML_TOK_INVALID
:
2840 return XML_ERROR_INVALID_TOKEN
;
2841 case XML_TOK_PARTIAL_CHAR
:
2844 return XML_ERROR_NONE
;
2846 return XML_ERROR_PARTIAL_CHAR
;
2847 case XML_TOK_PARTIAL
:
2851 return XML_ERROR_NONE
;
2853 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2856 return XML_ERROR_UNEXPECTED_STATE
;
2861 #endif /* XML_DTD */
2863 static enum XML_Error
2864 initializeEncoding(XML_Parser parser
)
2868 char encodingBuf
[128];
2869 if (!protocolEncodingName
)
2873 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2874 if (i
== sizeof(encodingBuf
) - 1
2875 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2876 encodingBuf
[0] = '\0';
2879 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2881 encodingBuf
[i
] = '\0';
2885 s
= protocolEncodingName
;
2887 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2888 return XML_ERROR_NONE
;
2889 return handleUnknownEncoding(parser
, protocolEncodingName
);
2892 static enum XML_Error
2893 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2894 const char *s
, const char *next
)
2896 const char *encodingName
= NULL
;
2897 const XML_Char
*storedEncName
= NULL
;
2898 const ENCODING
*newEncoding
= NULL
;
2899 const char *version
= NULL
;
2900 const char *versionend
;
2901 const XML_Char
*storedversion
= NULL
;
2902 int standalone
= -1;
2905 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2915 return XML_ERROR_SYNTAX
;
2916 if (!isGeneralTextEntity
&& standalone
== 1) {
2917 _dtd
->standalone
= XML_TRUE
;
2919 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2920 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2921 #endif /* XML_DTD */
2923 if (xmlDeclHandler
) {
2924 if (encodingName
!= NULL
) {
2925 storedEncName
= poolStoreString(&temp2Pool
,
2929 + XmlNameLength(encoding
, encodingName
));
2931 return XML_ERROR_NO_MEMORY
;
2932 poolFinish(&temp2Pool
);
2935 storedversion
= poolStoreString(&temp2Pool
,
2938 versionend
- encoding
->minBytesPerChar
);
2940 return XML_ERROR_NO_MEMORY
;
2942 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2944 else if (defaultHandler
)
2945 reportDefault(parser
, encoding
, s
, next
);
2946 if (protocolEncodingName
== NULL
) {
2948 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2949 eventPtr
= encodingName
;
2950 return XML_ERROR_INCORRECT_ENCODING
;
2952 encoding
= newEncoding
;
2954 else if (encodingName
) {
2955 enum XML_Error result
;
2956 if (!storedEncName
) {
2957 storedEncName
= poolStoreString(
2958 &temp2Pool
, encoding
, encodingName
,
2959 encodingName
+ XmlNameLength(encoding
, encodingName
));
2961 return XML_ERROR_NO_MEMORY
;
2963 result
= handleUnknownEncoding(parser
, storedEncName
);
2964 poolClear(&temp2Pool
);
2965 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2966 eventPtr
= encodingName
;
2971 if (storedEncName
|| storedversion
)
2972 poolClear(&temp2Pool
);
2974 return XML_ERROR_NONE
;
2977 static enum XML_Error
2978 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2980 if (unknownEncodingHandler
) {
2983 for (i
= 0; i
< 256; i
++)
2985 info
.convert
= NULL
;
2987 info
.release
= NULL
;
2988 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2991 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2992 if (!unknownEncodingMem
) {
2994 info
.release(info
.data
);
2995 return XML_ERROR_NO_MEMORY
;
2998 ? XmlInitUnknownEncodingNS
2999 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3004 unknownEncodingData
= info
.data
;
3005 unknownEncodingRelease
= info
.release
;
3007 return XML_ERROR_NONE
;
3010 if (info
.release
!= NULL
)
3011 info
.release(info
.data
);
3013 return XML_ERROR_UNKNOWN_ENCODING
;
3016 static enum XML_Error PTRCALL
3017 prologInitProcessor(XML_Parser parser
,
3020 const char **nextPtr
)
3022 enum XML_Error result
= initializeEncoding(parser
);
3023 if (result
!= XML_ERROR_NONE
)
3025 processor
= prologProcessor
;
3026 return prologProcessor(parser
, s
, end
, nextPtr
);
3031 static enum XML_Error PTRCALL
3032 externalParEntInitProcessor(XML_Parser parser
,
3035 const char **nextPtr
)
3037 enum XML_Error result
= initializeEncoding(parser
);
3038 if (result
!= XML_ERROR_NONE
)
3041 /* we know now that XML_Parse(Buffer) has been called,
3042 so we consider the external parameter entity read */
3043 _dtd
->paramEntityRead
= XML_TRUE
;
3045 if (prologState
.inEntityValue
) {
3046 processor
= entityValueInitProcessor
;
3047 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3050 processor
= externalParEntProcessor
;
3051 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3055 static enum XML_Error PTRCALL
3056 entityValueInitProcessor(XML_Parser parser
,
3059 const char **nextPtr
)
3061 const char *start
= s
;
3062 const char *next
= s
;
3066 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3068 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3070 return XML_ERROR_NONE
;
3073 case XML_TOK_INVALID
:
3074 return XML_ERROR_INVALID_TOKEN
;
3075 case XML_TOK_PARTIAL
:
3076 return XML_ERROR_UNCLOSED_TOKEN
;
3077 case XML_TOK_PARTIAL_CHAR
:
3078 return XML_ERROR_PARTIAL_CHAR
;
3079 case XML_TOK_NONE
: /* start == end */
3083 return storeEntityValue(parser
, encoding
, s
, end
);
3085 else if (tok
== XML_TOK_XML_DECL
) {
3086 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
3087 if (result
!= XML_ERROR_NONE
)
3089 if (nextPtr
) *nextPtr
= next
;
3090 /* stop scanning for text declaration - we found one */
3091 processor
= entityValueProcessor
;
3092 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3094 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3095 return XML_TOK_NONE on the next call, which would then cause the
3096 function to exit with *nextPtr set to s - that is what we want for other
3097 tokens, but not for the BOM - we would rather like to skip it;
3098 then, when this routine is entered the next time, XmlPrologTok will
3099 return XML_TOK_INVALID, since the BOM is still in the buffer
3101 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3103 return XML_ERROR_NONE
;
3109 static enum XML_Error PTRCALL
3110 externalParEntProcessor(XML_Parser parser
,
3113 const char **nextPtr
)
3115 const char *start
= s
;
3116 const char *next
= s
;
3119 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3121 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3123 return XML_ERROR_NONE
;
3126 case XML_TOK_INVALID
:
3127 return XML_ERROR_INVALID_TOKEN
;
3128 case XML_TOK_PARTIAL
:
3129 return XML_ERROR_UNCLOSED_TOKEN
;
3130 case XML_TOK_PARTIAL_CHAR
:
3131 return XML_ERROR_PARTIAL_CHAR
;
3132 case XML_TOK_NONE
: /* start == end */
3137 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3138 However, when parsing an external subset, doProlog will not accept a BOM
3139 as valid, and report a syntax error, so we have to skip the BOM
3141 else if (tok
== XML_TOK_BOM
) {
3143 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3146 processor
= prologProcessor
;
3147 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3150 static enum XML_Error PTRCALL
3151 entityValueProcessor(XML_Parser parser
,
3154 const char **nextPtr
)
3156 const char *start
= s
;
3157 const char *next
= s
;
3158 const ENCODING
*enc
= encoding
;
3162 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3164 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3166 return XML_ERROR_NONE
;
3169 case XML_TOK_INVALID
:
3170 return XML_ERROR_INVALID_TOKEN
;
3171 case XML_TOK_PARTIAL
:
3172 return XML_ERROR_UNCLOSED_TOKEN
;
3173 case XML_TOK_PARTIAL_CHAR
:
3174 return XML_ERROR_PARTIAL_CHAR
;
3175 case XML_TOK_NONE
: /* start == end */
3179 return storeEntityValue(parser
, enc
, s
, end
);
3185 #endif /* XML_DTD */
3187 static enum XML_Error PTRCALL
3188 prologProcessor(XML_Parser parser
,
3191 const char **nextPtr
)
3193 const char *next
= s
;
3194 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3195 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3198 static enum XML_Error
3199 doProlog(XML_Parser parser
,
3200 const ENCODING
*enc
,
3205 const char **nextPtr
)
3208 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3209 #endif /* XML_DTD */
3210 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3211 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3212 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3213 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3214 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3215 static const XML_Char atypeENTITIES
[] =
3216 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3217 static const XML_Char atypeNMTOKEN
[] = {
3218 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3219 static const XML_Char atypeNMTOKENS
[] = {
3220 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3221 static const XML_Char notationPrefix
[] = {
3222 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3223 static const XML_Char enumValueSep
[] = { '|', '\0' };
3224 static const XML_Char enumValueStart
[] = { '(', '\0' };
3226 DTD
* const dtd
= _dtd
; /* save one level of indirection */
3228 const char **eventPP
;
3229 const char **eventEndPP
;
3230 enum XML_Content_Quant quant
;
3232 if (enc
== encoding
) {
3233 eventPP
= &eventPtr
;
3234 eventEndPP
= &eventEndPtr
;
3237 eventPP
= &(openInternalEntities
->internalEventPtr
);
3238 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3242 XML_Bool handleDefault
= XML_TRUE
;
3246 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3248 return XML_ERROR_NONE
;
3251 case XML_TOK_INVALID
:
3253 return XML_ERROR_INVALID_TOKEN
;
3254 case XML_TOK_PARTIAL
:
3255 return XML_ERROR_UNCLOSED_TOKEN
;
3256 case XML_TOK_PARTIAL_CHAR
:
3257 return XML_ERROR_PARTIAL_CHAR
;
3260 if (enc
!= encoding
)
3261 return XML_ERROR_NONE
;
3262 if (isParamEntity
) {
3263 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3265 return XML_ERROR_SYNTAX
;
3266 return XML_ERROR_NONE
;
3268 #endif /* XML_DTD */
3269 return XML_ERROR_NO_ELEMENTS
;
3276 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3278 case XML_ROLE_XML_DECL
:
3280 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3281 if (result
!= XML_ERROR_NONE
)
3284 handleDefault
= XML_FALSE
;
3287 case XML_ROLE_DOCTYPE_NAME
:
3288 if (startDoctypeDeclHandler
) {
3289 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3291 return XML_ERROR_NO_MEMORY
;
3292 poolFinish(&tempPool
);
3293 doctypePubid
= NULL
;
3294 handleDefault
= XML_FALSE
;
3296 doctypeSysid
= NULL
; /* always initialize to NULL */
3298 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3299 if (startDoctypeDeclHandler
) {
3300 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3303 poolClear(&tempPool
);
3304 handleDefault
= XML_FALSE
;
3308 case XML_ROLE_TEXT_DECL
:
3310 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3311 if (result
!= XML_ERROR_NONE
)
3314 handleDefault
= XML_FALSE
;
3317 #endif /* XML_DTD */
3318 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3320 useForeignDTD
= XML_FALSE
;
3321 #endif /* XML_DTD */
3322 dtd
->hasParamEntityRefs
= XML_TRUE
;
3323 if (startDoctypeDeclHandler
) {
3324 doctypePubid
= poolStoreString(&tempPool
, enc
,
3325 s
+ enc
->minBytesPerChar
,
3326 next
- enc
->minBytesPerChar
);
3328 return XML_ERROR_NO_MEMORY
;
3329 poolFinish(&tempPool
);
3330 handleDefault
= XML_FALSE
;
3333 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3337 return XML_ERROR_NO_MEMORY
;
3338 #endif /* XML_DTD */
3340 case XML_ROLE_ENTITY_PUBLIC_ID
:
3341 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3342 return XML_ERROR_SYNTAX
;
3343 if (dtd
->keepProcessing
&& declEntity
) {
3344 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3346 s
+ enc
->minBytesPerChar
,
3347 next
- enc
->minBytesPerChar
);
3349 return XML_ERROR_NO_MEMORY
;
3350 normalizePublicId(tem
);
3351 declEntity
->publicId
= tem
;
3352 poolFinish(&dtd
->pool
);
3353 if (entityDeclHandler
)
3354 handleDefault
= XML_FALSE
;
3357 case XML_ROLE_DOCTYPE_CLOSE
:
3359 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3360 doctypeSysid
, doctypePubid
, 0);
3361 poolClear(&tempPool
);
3362 handleDefault
= XML_FALSE
;
3364 /* doctypeSysid will be non-NULL in the case of a previous
3365 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3366 was not set, indicating an external subset
3369 if (doctypeSysid
|| useForeignDTD
) {
3370 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3371 if (paramEntityParsing
&& externalEntityRefHandler
) {
3372 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3376 return XML_ERROR_NO_MEMORY
;
3378 entity
->base
= curBase
;
3379 dtd
->paramEntityRead
= XML_FALSE
;
3380 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3385 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3386 if (dtd
->paramEntityRead
&&
3388 notStandaloneHandler
&&
3389 !notStandaloneHandler(handlerArg
))
3390 return XML_ERROR_NOT_STANDALONE
;
3391 /* end of DTD - no need to update dtd->keepProcessing */
3393 useForeignDTD
= XML_FALSE
;
3395 #endif /* XML_DTD */
3396 if (endDoctypeDeclHandler
) {
3397 endDoctypeDeclHandler(handlerArg
);
3398 handleDefault
= XML_FALSE
;
3401 case XML_ROLE_INSTANCE_START
:
3403 /* if there is no DOCTYPE declaration then now is the
3404 last chance to read the foreign DTD
3406 if (useForeignDTD
) {
3407 dtd
->hasParamEntityRefs
= XML_TRUE
;
3408 if (paramEntityParsing
&& externalEntityRefHandler
) {
3409 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3413 return XML_ERROR_NO_MEMORY
;
3414 entity
->base
= curBase
;
3415 dtd
->paramEntityRead
= XML_FALSE
;
3416 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3421 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3422 if (dtd
->paramEntityRead
&&
3424 notStandaloneHandler
&&
3425 !notStandaloneHandler(handlerArg
))
3426 return XML_ERROR_NOT_STANDALONE
;
3427 /* end of DTD - no need to update dtd->keepProcessing */
3430 #endif /* XML_DTD */
3431 processor
= contentProcessor
;
3432 return contentProcessor(parser
, s
, end
, nextPtr
);
3433 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3434 declElementType
= getElementType(parser
, enc
, s
, next
);
3435 if (!declElementType
)
3436 return XML_ERROR_NO_MEMORY
;
3437 goto checkAttListDeclHandler
;
3438 case XML_ROLE_ATTRIBUTE_NAME
:
3439 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3440 if (!declAttributeId
)
3441 return XML_ERROR_NO_MEMORY
;
3442 declAttributeIsCdata
= XML_FALSE
;
3443 declAttributeType
= NULL
;
3444 declAttributeIsId
= XML_FALSE
;
3445 goto checkAttListDeclHandler
;
3446 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3447 declAttributeIsCdata
= XML_TRUE
;
3448 declAttributeType
= atypeCDATA
;
3449 goto checkAttListDeclHandler
;
3450 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3451 declAttributeIsId
= XML_TRUE
;
3452 declAttributeType
= atypeID
;
3453 goto checkAttListDeclHandler
;
3454 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3455 declAttributeType
= atypeIDREF
;
3456 goto checkAttListDeclHandler
;
3457 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3458 declAttributeType
= atypeIDREFS
;
3459 goto checkAttListDeclHandler
;
3460 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3461 declAttributeType
= atypeENTITY
;
3462 goto checkAttListDeclHandler
;
3463 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3464 declAttributeType
= atypeENTITIES
;
3465 goto checkAttListDeclHandler
;
3466 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3467 declAttributeType
= atypeNMTOKEN
;
3468 goto checkAttListDeclHandler
;
3469 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3470 declAttributeType
= atypeNMTOKENS
;
3471 checkAttListDeclHandler
:
3472 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3473 handleDefault
= XML_FALSE
;
3475 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3476 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3477 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3478 const XML_Char
*prefix
;
3479 if (declAttributeType
) {
3480 prefix
= enumValueSep
;
3483 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3487 if (!poolAppendString(&tempPool
, prefix
))
3488 return XML_ERROR_NO_MEMORY
;
3489 if (!poolAppend(&tempPool
, enc
, s
, next
))
3490 return XML_ERROR_NO_MEMORY
;
3491 declAttributeType
= tempPool
.start
;
3492 handleDefault
= XML_FALSE
;
3495 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3496 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3497 if (dtd
->keepProcessing
) {
3498 if (!defineAttribute(declElementType
, declAttributeId
,
3499 declAttributeIsCdata
, declAttributeIsId
, 0,
3501 return XML_ERROR_NO_MEMORY
;
3502 if (attlistDeclHandler
&& declAttributeType
) {
3503 if (*declAttributeType
== XML_T('(')
3504 || (*declAttributeType
== XML_T('N')
3505 && declAttributeType
[1] == XML_T('O'))) {
3506 /* Enumerated or Notation type */
3507 if (!poolAppendChar(&tempPool
, XML_T(')'))
3508 || !poolAppendChar(&tempPool
, XML_T('\0')))
3509 return XML_ERROR_NO_MEMORY
;
3510 declAttributeType
= tempPool
.start
;
3511 poolFinish(&tempPool
);
3514 attlistDeclHandler(handlerArg
, declElementType
->name
,
3515 declAttributeId
->name
, declAttributeType
,
3516 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3517 poolClear(&tempPool
);
3518 handleDefault
= XML_FALSE
;
3522 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3523 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3524 if (dtd
->keepProcessing
) {
3525 const XML_Char
*attVal
;
3526 enum XML_Error result
3527 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3528 s
+ enc
->minBytesPerChar
,
3529 next
- enc
->minBytesPerChar
,
3533 attVal
= poolStart(&dtd
->pool
);
3534 poolFinish(&dtd
->pool
);
3535 /* ID attributes aren't allowed to have a default */
3536 if (!defineAttribute(declElementType
, declAttributeId
,
3537 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3538 return XML_ERROR_NO_MEMORY
;
3539 if (attlistDeclHandler
&& declAttributeType
) {
3540 if (*declAttributeType
== XML_T('(')
3541 || (*declAttributeType
== XML_T('N')
3542 && declAttributeType
[1] == XML_T('O'))) {
3543 /* Enumerated or Notation type */
3544 if (!poolAppendChar(&tempPool
, XML_T(')'))
3545 || !poolAppendChar(&tempPool
, XML_T('\0')))
3546 return XML_ERROR_NO_MEMORY
;
3547 declAttributeType
= tempPool
.start
;
3548 poolFinish(&tempPool
);
3551 attlistDeclHandler(handlerArg
, declElementType
->name
,
3552 declAttributeId
->name
, declAttributeType
,
3554 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3555 poolClear(&tempPool
);
3556 handleDefault
= XML_FALSE
;
3560 case XML_ROLE_ENTITY_VALUE
:
3561 if (dtd
->keepProcessing
) {
3562 enum XML_Error result
= storeEntityValue(parser
, enc
,
3563 s
+ enc
->minBytesPerChar
,
3564 next
- enc
->minBytesPerChar
);
3566 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3567 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3568 poolFinish(&dtd
->entityValuePool
);
3569 if (entityDeclHandler
) {
3571 entityDeclHandler(handlerArg
,
3573 declEntity
->is_param
,
3574 declEntity
->textPtr
,
3575 declEntity
->textLen
,
3577 handleDefault
= XML_FALSE
;
3581 poolDiscard(&dtd
->entityValuePool
);
3582 if (result
!= XML_ERROR_NONE
)
3586 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3588 useForeignDTD
= XML_FALSE
;
3589 #endif /* XML_DTD */
3590 dtd
->hasParamEntityRefs
= XML_TRUE
;
3591 if (startDoctypeDeclHandler
) {
3592 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3593 s
+ enc
->minBytesPerChar
,
3594 next
- enc
->minBytesPerChar
);
3595 if (doctypeSysid
== NULL
)
3596 return XML_ERROR_NO_MEMORY
;
3597 poolFinish(&tempPool
);
3598 handleDefault
= XML_FALSE
;
3602 /* use externalSubsetName to make doctypeSysid non-NULL
3603 for the case where no startDoctypeDeclHandler is set */
3604 doctypeSysid
= externalSubsetName
;
3605 #endif /* XML_DTD */
3606 if (!dtd
->standalone
3608 && !paramEntityParsing
3609 #endif /* XML_DTD */
3610 && notStandaloneHandler
3611 && !notStandaloneHandler(handlerArg
))
3612 return XML_ERROR_NOT_STANDALONE
;
3617 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3621 return XML_ERROR_NO_MEMORY
;
3622 declEntity
->publicId
= NULL
;
3625 #endif /* XML_DTD */
3626 case XML_ROLE_ENTITY_SYSTEM_ID
:
3627 if (dtd
->keepProcessing
&& declEntity
) {
3628 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
3629 s
+ enc
->minBytesPerChar
,
3630 next
- enc
->minBytesPerChar
);
3631 if (!declEntity
->systemId
)
3632 return XML_ERROR_NO_MEMORY
;
3633 declEntity
->base
= curBase
;
3634 poolFinish(&dtd
->pool
);
3635 if (entityDeclHandler
)
3636 handleDefault
= XML_FALSE
;
3639 case XML_ROLE_ENTITY_COMPLETE
:
3640 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
3642 entityDeclHandler(handlerArg
,
3644 declEntity
->is_param
,
3647 declEntity
->systemId
,
3648 declEntity
->publicId
,
3650 handleDefault
= XML_FALSE
;
3653 case XML_ROLE_ENTITY_NOTATION_NAME
:
3654 if (dtd
->keepProcessing
&& declEntity
) {
3655 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3656 if (!declEntity
->notation
)
3657 return XML_ERROR_NO_MEMORY
;
3658 poolFinish(&dtd
->pool
);
3659 if (unparsedEntityDeclHandler
) {
3661 unparsedEntityDeclHandler(handlerArg
,
3664 declEntity
->systemId
,
3665 declEntity
->publicId
,
3666 declEntity
->notation
);
3667 handleDefault
= XML_FALSE
;
3669 else if (entityDeclHandler
) {
3671 entityDeclHandler(handlerArg
,
3675 declEntity
->systemId
,
3676 declEntity
->publicId
,
3677 declEntity
->notation
);
3678 handleDefault
= XML_FALSE
;
3682 case XML_ROLE_GENERAL_ENTITY_NAME
:
3684 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3688 if (dtd
->keepProcessing
) {
3689 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3691 return XML_ERROR_NO_MEMORY
;
3692 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
3695 return XML_ERROR_NO_MEMORY
;
3696 if (declEntity
->name
!= name
) {
3697 poolDiscard(&dtd
->pool
);
3701 poolFinish(&dtd
->pool
);
3702 declEntity
->publicId
= NULL
;
3703 declEntity
->is_param
= XML_FALSE
;
3704 /* if we have a parent parser or are reading an internal parameter
3705 entity, then the entity declaration is not considered "internal"
3707 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3708 if (entityDeclHandler
)
3709 handleDefault
= XML_FALSE
;
3713 poolDiscard(&dtd
->pool
);
3718 case XML_ROLE_PARAM_ENTITY_NAME
:
3720 if (dtd
->keepProcessing
) {
3721 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3723 return XML_ERROR_NO_MEMORY
;
3724 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3725 name
, sizeof(ENTITY
));
3727 return XML_ERROR_NO_MEMORY
;
3728 if (declEntity
->name
!= name
) {
3729 poolDiscard(&dtd
->pool
);
3733 poolFinish(&dtd
->pool
);
3734 declEntity
->publicId
= NULL
;
3735 declEntity
->is_param
= XML_TRUE
;
3736 /* if we have a parent parser or are reading an internal parameter
3737 entity, then the entity declaration is not considered "internal"
3739 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3740 if (entityDeclHandler
)
3741 handleDefault
= XML_FALSE
;
3745 poolDiscard(&dtd
->pool
);
3748 #else /* not XML_DTD */
3750 #endif /* XML_DTD */
3752 case XML_ROLE_NOTATION_NAME
:
3753 declNotationPublicId
= NULL
;
3754 declNotationName
= NULL
;
3755 if (notationDeclHandler
) {
3756 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3757 if (!declNotationName
)
3758 return XML_ERROR_NO_MEMORY
;
3759 poolFinish(&tempPool
);
3760 handleDefault
= XML_FALSE
;
3763 case XML_ROLE_NOTATION_PUBLIC_ID
:
3764 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3765 return XML_ERROR_SYNTAX
;
3766 if (declNotationName
) { /* means notationDeclHandler != NULL */
3767 XML_Char
*tem
= poolStoreString(&tempPool
,
3769 s
+ enc
->minBytesPerChar
,
3770 next
- enc
->minBytesPerChar
);
3772 return XML_ERROR_NO_MEMORY
;
3773 normalizePublicId(tem
);
3774 declNotationPublicId
= tem
;
3775 poolFinish(&tempPool
);
3776 handleDefault
= XML_FALSE
;
3779 case XML_ROLE_NOTATION_SYSTEM_ID
:
3780 if (declNotationName
&& notationDeclHandler
) {
3781 const XML_Char
*systemId
3782 = poolStoreString(&tempPool
, enc
,
3783 s
+ enc
->minBytesPerChar
,
3784 next
- enc
->minBytesPerChar
);
3786 return XML_ERROR_NO_MEMORY
;
3788 notationDeclHandler(handlerArg
,
3792 declNotationPublicId
);
3793 handleDefault
= XML_FALSE
;
3795 poolClear(&tempPool
);
3797 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3798 if (declNotationPublicId
&& notationDeclHandler
) {
3800 notationDeclHandler(handlerArg
,
3804 declNotationPublicId
);
3805 handleDefault
= XML_FALSE
;
3807 poolClear(&tempPool
);
3809 case XML_ROLE_ERROR
:
3811 case XML_TOK_PARAM_ENTITY_REF
:
3812 return XML_ERROR_PARAM_ENTITY_REF
;
3813 case XML_TOK_XML_DECL
:
3814 return XML_ERROR_MISPLACED_XML_PI
;
3816 return XML_ERROR_SYNTAX
;
3819 case XML_ROLE_IGNORE_SECT
:
3821 enum XML_Error result
;
3823 reportDefault(parser
, enc
, s
, next
);
3824 handleDefault
= XML_FALSE
;
3825 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3827 processor
= ignoreSectionProcessor
;
3832 #endif /* XML_DTD */
3833 case XML_ROLE_GROUP_OPEN
:
3834 if (prologState
.level
>= groupSize
) {
3836 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
3838 return XML_ERROR_NO_MEMORY
;
3839 groupConnector
= temp
;
3840 if (dtd
->scaffIndex
) {
3841 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
3842 groupSize
* sizeof(int));
3844 return XML_ERROR_NO_MEMORY
;
3845 dtd
->scaffIndex
= temp
;
3849 groupConnector
= (char *)MALLOC(groupSize
= 32);
3850 if (!groupConnector
)
3851 return XML_ERROR_NO_MEMORY
;
3854 groupConnector
[prologState
.level
] = 0;
3855 if (dtd
->in_eldecl
) {
3856 int myindex
= nextScaffoldPart(parser
);
3858 return XML_ERROR_NO_MEMORY
;
3859 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
3861 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3862 if (elementDeclHandler
)
3863 handleDefault
= XML_FALSE
;
3866 case XML_ROLE_GROUP_SEQUENCE
:
3867 if (groupConnector
[prologState
.level
] == '|')
3868 return XML_ERROR_SYNTAX
;
3869 groupConnector
[prologState
.level
] = ',';
3870 if (dtd
->in_eldecl
&& elementDeclHandler
)
3871 handleDefault
= XML_FALSE
;
3873 case XML_ROLE_GROUP_CHOICE
:
3874 if (groupConnector
[prologState
.level
] == ',')
3875 return XML_ERROR_SYNTAX
;
3877 && !groupConnector
[prologState
.level
]
3878 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3881 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3883 if (elementDeclHandler
)
3884 handleDefault
= XML_FALSE
;
3886 groupConnector
[prologState
.level
] = '|';
3888 case XML_ROLE_PARAM_ENTITY_REF
:
3890 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3891 /* PE references in internal subset are
3892 not allowed within declarations */
3893 if (prologState
.documentEntity
&&
3894 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3895 return XML_ERROR_PARAM_ENTITY_REF
;
3896 dtd
->hasParamEntityRefs
= XML_TRUE
;
3897 if (!paramEntityParsing
)
3898 dtd
->keepProcessing
= dtd
->standalone
;
3900 const XML_Char
*name
;
3902 name
= poolStoreString(&dtd
->pool
, enc
,
3903 s
+ enc
->minBytesPerChar
,
3904 next
- enc
->minBytesPerChar
);
3906 return XML_ERROR_NO_MEMORY
;
3907 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
3908 poolDiscard(&dtd
->pool
);
3909 /* first, determine if a check for an existing declaration is needed;
3910 if yes, check that the entity exists, and that it is internal,
3911 otherwise call the skipped entity handler
3913 if (prologState
.documentEntity
&&
3915 ? !openInternalEntities
3916 : !dtd
->hasParamEntityRefs
)) {
3918 return XML_ERROR_UNDEFINED_ENTITY
;
3919 else if (!entity
->is_internal
)
3920 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3923 dtd
->keepProcessing
= dtd
->standalone
;
3924 /* cannot report skipped entities in declarations */
3925 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3926 skippedEntityHandler(handlerArg
, name
, 1);
3927 handleDefault
= XML_FALSE
;
3932 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3933 if (entity
->textPtr
) {
3934 enum XML_Error result
;
3935 result
= processInternalParamEntity(parser
, entity
);
3936 if (result
!= XML_ERROR_NONE
)
3938 handleDefault
= XML_FALSE
;
3941 if (externalEntityRefHandler
) {
3942 dtd
->paramEntityRead
= XML_FALSE
;
3943 entity
->open
= XML_TRUE
;
3944 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3948 entity
->publicId
)) {
3949 entity
->open
= XML_FALSE
;
3950 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3952 entity
->open
= XML_FALSE
;
3953 handleDefault
= XML_FALSE
;
3954 if (!dtd
->paramEntityRead
) {
3955 dtd
->keepProcessing
= dtd
->standalone
;
3960 dtd
->keepProcessing
= dtd
->standalone
;
3964 #endif /* XML_DTD */
3965 if (!dtd
->standalone
&&
3966 notStandaloneHandler
&&
3967 !notStandaloneHandler(handlerArg
))
3968 return XML_ERROR_NOT_STANDALONE
;
3971 /* Element declaration stuff */
3973 case XML_ROLE_ELEMENT_NAME
:
3974 if (elementDeclHandler
) {
3975 declElementType
= getElementType(parser
, enc
, s
, next
);
3976 if (!declElementType
)
3977 return XML_ERROR_NO_MEMORY
;
3978 dtd
->scaffLevel
= 0;
3979 dtd
->scaffCount
= 0;
3980 dtd
->in_eldecl
= XML_TRUE
;
3981 handleDefault
= XML_FALSE
;
3985 case XML_ROLE_CONTENT_ANY
:
3986 case XML_ROLE_CONTENT_EMPTY
:
3987 if (dtd
->in_eldecl
) {
3988 if (elementDeclHandler
) {
3989 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3991 return XML_ERROR_NO_MEMORY
;
3992 content
->quant
= XML_CQUANT_NONE
;
3993 content
->name
= NULL
;
3994 content
->numchildren
= 0;
3995 content
->children
= NULL
;
3996 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4000 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4001 handleDefault
= XML_FALSE
;
4003 dtd
->in_eldecl
= XML_FALSE
;
4007 case XML_ROLE_CONTENT_PCDATA
:
4008 if (dtd
->in_eldecl
) {
4009 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4011 if (elementDeclHandler
)
4012 handleDefault
= XML_FALSE
;
4016 case XML_ROLE_CONTENT_ELEMENT
:
4017 quant
= XML_CQUANT_NONE
;
4018 goto elementContent
;
4019 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4020 quant
= XML_CQUANT_OPT
;
4021 goto elementContent
;
4022 case XML_ROLE_CONTENT_ELEMENT_REP
:
4023 quant
= XML_CQUANT_REP
;
4024 goto elementContent
;
4025 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4026 quant
= XML_CQUANT_PLUS
;
4028 if (dtd
->in_eldecl
) {
4030 const XML_Char
*name
;
4032 const char *nxt
= (quant
== XML_CQUANT_NONE
4034 : next
- enc
->minBytesPerChar
);
4035 int myindex
= nextScaffoldPart(parser
);
4037 return XML_ERROR_NO_MEMORY
;
4038 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4039 dtd
->scaffold
[myindex
].quant
= quant
;
4040 el
= getElementType(parser
, enc
, s
, nxt
);
4042 return XML_ERROR_NO_MEMORY
;
4044 dtd
->scaffold
[myindex
].name
= name
;
4046 for (; name
[nameLen
++]; )
4048 dtd
->contentStringLen
+= nameLen
;
4049 if (elementDeclHandler
)
4050 handleDefault
= XML_FALSE
;
4054 case XML_ROLE_GROUP_CLOSE
:
4055 quant
= XML_CQUANT_NONE
;
4057 case XML_ROLE_GROUP_CLOSE_OPT
:
4058 quant
= XML_CQUANT_OPT
;
4060 case XML_ROLE_GROUP_CLOSE_REP
:
4061 quant
= XML_CQUANT_REP
;
4063 case XML_ROLE_GROUP_CLOSE_PLUS
:
4064 quant
= XML_CQUANT_PLUS
;
4066 if (dtd
->in_eldecl
) {
4067 if (elementDeclHandler
)
4068 handleDefault
= XML_FALSE
;
4070 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4071 if (dtd
->scaffLevel
== 0) {
4072 if (!handleDefault
) {
4073 XML_Content
*model
= build_model(parser
);
4075 return XML_ERROR_NO_MEMORY
;
4077 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4079 dtd
->in_eldecl
= XML_FALSE
;
4080 dtd
->contentStringLen
= 0;
4084 /* End element declaration stuff */
4087 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4088 return XML_ERROR_NO_MEMORY
;
4089 handleDefault
= XML_FALSE
;
4091 case XML_ROLE_COMMENT
:
4092 if (!reportComment(parser
, enc
, s
, next
))
4093 return XML_ERROR_NO_MEMORY
;
4094 handleDefault
= XML_FALSE
;
4099 handleDefault
= XML_FALSE
;
4103 case XML_ROLE_DOCTYPE_NONE
:
4104 if (startDoctypeDeclHandler
)
4105 handleDefault
= XML_FALSE
;
4107 case XML_ROLE_ENTITY_NONE
:
4108 if (dtd
->keepProcessing
&& entityDeclHandler
)
4109 handleDefault
= XML_FALSE
;
4111 case XML_ROLE_NOTATION_NONE
:
4112 if (notationDeclHandler
)
4113 handleDefault
= XML_FALSE
;
4115 case XML_ROLE_ATTLIST_NONE
:
4116 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4117 handleDefault
= XML_FALSE
;
4119 case XML_ROLE_ELEMENT_NONE
:
4120 if (elementDeclHandler
)
4121 handleDefault
= XML_FALSE
;
4123 } /* end of big switch */
4125 if (handleDefault
&& defaultHandler
)
4126 reportDefault(parser
, enc
, s
, next
);
4129 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4134 static enum XML_Error PTRCALL
4135 epilogProcessor(XML_Parser parser
,
4138 const char **nextPtr
)
4140 processor
= epilogProcessor
;
4143 const char *next
= NULL
;
4144 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4147 /* report partial linebreak - it might be the last token */
4148 case -XML_TOK_PROLOG_S
:
4149 if (defaultHandler
) {
4151 reportDefault(parser
, encoding
, s
, next
);
4155 return XML_ERROR_NONE
;
4159 return XML_ERROR_NONE
;
4160 case XML_TOK_PROLOG_S
:
4162 reportDefault(parser
, encoding
, s
, next
);
4165 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4166 return XML_ERROR_NO_MEMORY
;
4168 case XML_TOK_COMMENT
:
4169 if (!reportComment(parser
, encoding
, s
, next
))
4170 return XML_ERROR_NO_MEMORY
;
4172 case XML_TOK_INVALID
:
4174 return XML_ERROR_INVALID_TOKEN
;
4175 case XML_TOK_PARTIAL
:
4178 return XML_ERROR_NONE
;
4180 return XML_ERROR_UNCLOSED_TOKEN
;
4181 case XML_TOK_PARTIAL_CHAR
:
4184 return XML_ERROR_NONE
;
4186 return XML_ERROR_PARTIAL_CHAR
;
4188 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4190 eventPtr
= s
= next
;
4196 static enum XML_Error
4197 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4199 const char *s
, *end
, *next
;
4201 enum XML_Error result
;
4202 OPEN_INTERNAL_ENTITY openEntity
;
4203 entity
->open
= XML_TRUE
;
4204 openEntity
.next
= openInternalEntities
;
4205 openInternalEntities
= &openEntity
;
4206 openEntity
.entity
= entity
;
4207 openEntity
.internalEventPtr
= NULL
;
4208 openEntity
.internalEventEndPtr
= NULL
;
4209 s
= (char *)entity
->textPtr
;
4210 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4211 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4212 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4213 entity
->open
= XML_FALSE
;
4214 openInternalEntities
= openEntity
.next
;
4218 #endif /* XML_DTD */
4220 static enum XML_Error PTRCALL
4221 errorProcessor(XML_Parser parser
,
4224 const char **nextPtr
)
4229 static enum XML_Error
4230 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4231 const char *ptr
, const char *end
,
4234 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4238 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4240 if (!poolAppendChar(pool
, XML_T('\0')))
4241 return XML_ERROR_NO_MEMORY
;
4242 return XML_ERROR_NONE
;
4245 static enum XML_Error
4246 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4247 const char *ptr
, const char *end
,
4250 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4253 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4256 return XML_ERROR_NONE
;
4257 case XML_TOK_INVALID
:
4258 if (enc
== encoding
)
4260 return XML_ERROR_INVALID_TOKEN
;
4261 case XML_TOK_PARTIAL
:
4262 if (enc
== encoding
)
4264 return XML_ERROR_INVALID_TOKEN
;
4265 case XML_TOK_CHAR_REF
:
4267 XML_Char buf
[XML_ENCODE_MAX
];
4269 int n
= XmlCharRefNumber(enc
, ptr
);
4271 if (enc
== encoding
)
4273 return XML_ERROR_BAD_CHAR_REF
;
4276 && n
== 0x20 /* space */
4277 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4279 n
= XmlEncode(n
, (ICHAR
*)buf
);
4281 if (enc
== encoding
)
4283 return XML_ERROR_BAD_CHAR_REF
;
4285 for (i
= 0; i
< n
; i
++) {
4286 if (!poolAppendChar(pool
, buf
[i
]))
4287 return XML_ERROR_NO_MEMORY
;
4291 case XML_TOK_DATA_CHARS
:
4292 if (!poolAppend(pool
, enc
, ptr
, next
))
4293 return XML_ERROR_NO_MEMORY
;
4295 case XML_TOK_TRAILING_CR
:
4296 next
= ptr
+ enc
->minBytesPerChar
;
4298 case XML_TOK_ATTRIBUTE_VALUE_S
:
4299 case XML_TOK_DATA_NEWLINE
:
4300 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4302 if (!poolAppendChar(pool
, 0x20))
4303 return XML_ERROR_NO_MEMORY
;
4305 case XML_TOK_ENTITY_REF
:
4307 const XML_Char
*name
;
4309 char checkEntityDecl
;
4310 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4311 ptr
+ enc
->minBytesPerChar
,
4312 next
- enc
->minBytesPerChar
);
4314 if (!poolAppendChar(pool
, ch
))
4315 return XML_ERROR_NO_MEMORY
;
4318 name
= poolStoreString(&temp2Pool
, enc
,
4319 ptr
+ enc
->minBytesPerChar
,
4320 next
- enc
->minBytesPerChar
);
4322 return XML_ERROR_NO_MEMORY
;
4323 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4324 poolDiscard(&temp2Pool
);
4325 /* first, determine if a check for an existing declaration is needed;
4326 if yes, check that the entity exists, and that it is internal,
4327 otherwise call the default handler (if called from content)
4329 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4332 prologState
.documentEntity
&&
4333 #endif /* XML_DTD */
4335 ? !openInternalEntities
4336 : !dtd
->hasParamEntityRefs
);
4337 else /* if (pool == &tempPool): we are called from content */
4338 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4339 if (checkEntityDecl
) {
4341 return XML_ERROR_UNDEFINED_ENTITY
;
4342 else if (!entity
->is_internal
)
4343 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4346 /* cannot report skipped entity here - see comments on
4347 skippedEntityHandler
4348 if (skippedEntityHandler)
4349 skippedEntityHandler(handlerArg, name, 0);
4351 if ((pool
== &tempPool
) && defaultHandler
)
4352 reportDefault(parser
, enc
, ptr
, next
);
4356 if (enc
== encoding
)
4358 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4360 if (entity
->notation
) {
4361 if (enc
== encoding
)
4363 return XML_ERROR_BINARY_ENTITY_REF
;
4365 if (!entity
->textPtr
) {
4366 if (enc
== encoding
)
4368 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4371 enum XML_Error result
;
4372 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4373 entity
->open
= XML_TRUE
;
4374 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4375 (char *)entity
->textPtr
,
4376 (char *)textEnd
, pool
);
4377 entity
->open
= XML_FALSE
;
4384 if (enc
== encoding
)
4386 return XML_ERROR_UNEXPECTED_STATE
;
4393 static enum XML_Error
4394 storeEntityValue(XML_Parser parser
,
4395 const ENCODING
*enc
,
4396 const char *entityTextPtr
,
4397 const char *entityTextEnd
)
4399 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4400 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4401 enum XML_Error result
= XML_ERROR_NONE
;
4403 int oldInEntityValue
= prologState
.inEntityValue
;
4404 prologState
.inEntityValue
= 1;
4405 #endif /* XML_DTD */
4406 /* never return Null for the value argument in EntityDeclHandler,
4407 since this would indicate an external entity; therefore we
4408 have to make sure that entityValuePool.start is not null */
4409 if (!pool
->blocks
) {
4410 if (!poolGrow(pool
))
4411 return XML_ERROR_NO_MEMORY
;
4416 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4418 case XML_TOK_PARAM_ENTITY_REF
:
4420 if (isParamEntity
|| enc
!= encoding
) {
4421 const XML_Char
*name
;
4423 name
= poolStoreString(&tempPool
, enc
,
4424 entityTextPtr
+ enc
->minBytesPerChar
,
4425 next
- enc
->minBytesPerChar
);
4427 result
= XML_ERROR_NO_MEMORY
;
4428 goto endEntityValue
;
4430 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4431 poolDiscard(&tempPool
);
4433 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4434 /* cannot report skipped entity here - see comments on
4435 skippedEntityHandler
4436 if (skippedEntityHandler)
4437 skippedEntityHandler(handlerArg, name, 0);
4439 dtd
->keepProcessing
= dtd
->standalone
;
4440 goto endEntityValue
;
4443 if (enc
== encoding
)
4444 eventPtr
= entityTextPtr
;
4445 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4446 goto endEntityValue
;
4448 if (entity
->systemId
) {
4449 if (externalEntityRefHandler
) {
4450 dtd
->paramEntityRead
= XML_FALSE
;
4451 entity
->open
= XML_TRUE
;
4452 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4456 entity
->publicId
)) {
4457 entity
->open
= XML_FALSE
;
4458 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4459 goto endEntityValue
;
4461 entity
->open
= XML_FALSE
;
4462 if (!dtd
->paramEntityRead
)
4463 dtd
->keepProcessing
= dtd
->standalone
;
4466 dtd
->keepProcessing
= dtd
->standalone
;
4469 entity
->open
= XML_TRUE
;
4470 result
= storeEntityValue(parser
,
4472 (char *)entity
->textPtr
,
4473 (char *)(entity
->textPtr
4474 + entity
->textLen
));
4475 entity
->open
= XML_FALSE
;
4477 goto endEntityValue
;
4481 #endif /* XML_DTD */
4482 /* in the internal subset, PE references are not legal
4483 within markup declarations, e.g entity values in this case */
4484 eventPtr
= entityTextPtr
;
4485 result
= XML_ERROR_PARAM_ENTITY_REF
;
4486 goto endEntityValue
;
4488 result
= XML_ERROR_NONE
;
4489 goto endEntityValue
;
4490 case XML_TOK_ENTITY_REF
:
4491 case XML_TOK_DATA_CHARS
:
4492 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4493 result
= XML_ERROR_NO_MEMORY
;
4494 goto endEntityValue
;
4497 case XML_TOK_TRAILING_CR
:
4498 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4500 case XML_TOK_DATA_NEWLINE
:
4501 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4502 result
= XML_ERROR_NO_MEMORY
;
4503 goto endEntityValue
;
4505 *(pool
->ptr
)++ = 0xA;
4507 case XML_TOK_CHAR_REF
:
4509 XML_Char buf
[XML_ENCODE_MAX
];
4511 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4513 if (enc
== encoding
)
4514 eventPtr
= entityTextPtr
;
4515 result
= XML_ERROR_BAD_CHAR_REF
;
4516 goto endEntityValue
;
4518 n
= XmlEncode(n
, (ICHAR
*)buf
);
4520 if (enc
== encoding
)
4521 eventPtr
= entityTextPtr
;
4522 result
= XML_ERROR_BAD_CHAR_REF
;
4523 goto endEntityValue
;
4525 for (i
= 0; i
< n
; i
++) {
4526 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4527 result
= XML_ERROR_NO_MEMORY
;
4528 goto endEntityValue
;
4530 *(pool
->ptr
)++ = buf
[i
];
4534 case XML_TOK_PARTIAL
:
4535 if (enc
== encoding
)
4536 eventPtr
= entityTextPtr
;
4537 result
= XML_ERROR_INVALID_TOKEN
;
4538 goto endEntityValue
;
4539 case XML_TOK_INVALID
:
4540 if (enc
== encoding
)
4542 result
= XML_ERROR_INVALID_TOKEN
;
4543 goto endEntityValue
;
4545 if (enc
== encoding
)
4546 eventPtr
= entityTextPtr
;
4547 result
= XML_ERROR_UNEXPECTED_STATE
;
4548 goto endEntityValue
;
4550 entityTextPtr
= next
;
4554 prologState
.inEntityValue
= oldInEntityValue
;
4555 #endif /* XML_DTD */
4559 static void FASTCALL
4560 normalizeLines(XML_Char
*s
)
4564 if (*s
== XML_T('\0'))
4583 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4584 const char *start
, const char *end
)
4586 const XML_Char
*target
;
4589 if (!processingInstructionHandler
) {
4591 reportDefault(parser
, enc
, start
, end
);
4594 start
+= enc
->minBytesPerChar
* 2;
4595 tem
= start
+ XmlNameLength(enc
, start
);
4596 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4599 poolFinish(&tempPool
);
4600 data
= poolStoreString(&tempPool
, enc
,
4602 end
- enc
->minBytesPerChar
*2);
4605 normalizeLines(data
);
4606 processingInstructionHandler(handlerArg
, target
, data
);
4607 poolClear(&tempPool
);
4612 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4613 const char *start
, const char *end
)
4616 if (!commentHandler
) {
4618 reportDefault(parser
, enc
, start
, end
);
4621 data
= poolStoreString(&tempPool
,
4623 start
+ enc
->minBytesPerChar
* 4,
4624 end
- enc
->minBytesPerChar
* 3);
4627 normalizeLines(data
);
4628 commentHandler(handlerArg
, data
);
4629 poolClear(&tempPool
);
4634 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4635 const char *s
, const char *end
)
4637 if (MUST_CONVERT(enc
, s
)) {
4638 const char **eventPP
;
4639 const char **eventEndPP
;
4640 if (enc
== encoding
) {
4641 eventPP
= &eventPtr
;
4642 eventEndPP
= &eventEndPtr
;
4645 eventPP
= &(openInternalEntities
->internalEventPtr
);
4646 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4649 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4650 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4652 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4657 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4662 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4663 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4665 DEFAULT_ATTRIBUTE
*att
;
4666 if (value
|| isId
) {
4667 /* The handling of default attributes gets messed up if we have
4668 a default which duplicates a non-default. */
4670 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4671 if (attId
== type
->defaultAtts
[i
].id
)
4673 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4674 type
->idAtt
= attId
;
4676 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4677 if (type
->allocDefaultAtts
== 0) {
4678 type
->allocDefaultAtts
= 8;
4679 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
4680 * sizeof(DEFAULT_ATTRIBUTE
));
4681 if (!type
->defaultAtts
)
4685 DEFAULT_ATTRIBUTE
*temp
;
4686 int count
= type
->allocDefaultAtts
* 2;
4687 temp
= (DEFAULT_ATTRIBUTE
*)
4688 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4691 type
->allocDefaultAtts
= count
;
4692 type
->defaultAtts
= temp
;
4695 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4698 att
->isCdata
= isCdata
;
4700 attId
->maybeTokenized
= XML_TRUE
;
4701 type
->nDefaultAtts
+= 1;
4706 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4708 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4709 const XML_Char
*name
;
4710 for (name
= elementType
->name
; *name
; name
++) {
4711 if (*name
== XML_T(':')) {
4714 for (s
= elementType
->name
; s
!= name
; s
++) {
4715 if (!poolAppendChar(&dtd
->pool
, *s
))
4718 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4720 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4724 if (prefix
->name
== poolStart(&dtd
->pool
))
4725 poolFinish(&dtd
->pool
);
4727 poolDiscard(&dtd
->pool
);
4728 elementType
->prefix
= prefix
;
4735 static ATTRIBUTE_ID
*
4736 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4737 const char *start
, const char *end
)
4739 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4741 const XML_Char
*name
;
4742 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4744 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
4748 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4751 if (id
->name
!= name
)
4752 poolDiscard(&dtd
->pool
);
4754 poolFinish(&dtd
->pool
);
4757 else if (name
[0] == XML_T('x')
4758 && name
[1] == XML_T('m')
4759 && name
[2] == XML_T('l')
4760 && name
[3] == XML_T('n')
4761 && name
[4] == XML_T('s')
4762 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4763 if (name
[5] == XML_T('\0'))
4764 id
->prefix
= &dtd
->defaultPrefix
;
4766 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
4767 id
->xmlns
= XML_TRUE
;
4771 for (i
= 0; name
[i
]; i
++) {
4772 if (name
[i
] == XML_T(':')) {
4774 for (j
= 0; j
< i
; j
++) {
4775 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
4778 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4780 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4782 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
4783 poolFinish(&dtd
->pool
);
4785 poolDiscard(&dtd
->pool
);
4794 #define CONTEXT_SEP XML_T('\f')
4796 static const XML_Char
*
4797 getContext(XML_Parser parser
)
4799 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4800 HASH_TABLE_ITER iter
;
4801 XML_Bool needSep
= XML_FALSE
;
4803 if (dtd
->defaultPrefix
.binding
) {
4806 if (!poolAppendChar(&tempPool
, XML_T('=')))
4808 len
= dtd
->defaultPrefix
.binding
->uriLen
;
4809 if (namespaceSeparator
!= XML_T('\0'))
4811 for (i
= 0; i
< len
; i
++)
4812 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
4817 hashTableIterInit(&iter
, &(dtd
->prefixes
));
4822 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4825 if (!prefix
->binding
)
4827 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4829 for (s
= prefix
->name
; *s
; s
++)
4830 if (!poolAppendChar(&tempPool
, *s
))
4832 if (!poolAppendChar(&tempPool
, XML_T('=')))
4834 len
= prefix
->binding
->uriLen
;
4835 if (namespaceSeparator
!= XML_T('\0'))
4837 for (i
= 0; i
< len
; i
++)
4838 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4844 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
4847 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4852 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4854 for (s
= e
->name
; *s
; s
++)
4855 if (!poolAppendChar(&tempPool
, *s
))
4860 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4862 return tempPool
.start
;
4866 setContext(XML_Parser parser
, const XML_Char
*context
)
4868 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4869 const XML_Char
*s
= context
;
4871 while (*context
!= XML_T('\0')) {
4872 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4874 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4876 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
4879 if (*s
!= XML_T('\0'))
4882 poolDiscard(&tempPool
);
4884 else if (*s
== XML_T('=')) {
4886 if (poolLength(&tempPool
) == 0)
4887 prefix
= &dtd
->defaultPrefix
;
4889 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4891 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
4895 if (prefix
->name
== poolStart(&tempPool
)) {
4896 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
4900 poolDiscard(&tempPool
);
4902 for (context
= s
+ 1;
4903 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4905 if (!poolAppendChar(&tempPool
, *context
))
4907 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4909 if (addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4910 &inheritedBindings
) != XML_ERROR_NONE
)
4912 poolDiscard(&tempPool
);
4913 if (*context
!= XML_T('\0'))
4918 if (!poolAppendChar(&tempPool
, *s
))
4926 static void FASTCALL
4927 normalizePublicId(XML_Char
*publicId
)
4929 XML_Char
*p
= publicId
;
4931 for (s
= publicId
; *s
; s
++) {
4936 if (p
!= publicId
&& p
[-1] != 0x20)
4943 if (p
!= publicId
&& p
[-1] == 0x20)
4949 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
4951 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
4954 poolInit(&(p
->pool
), ms
);
4956 poolInit(&(p
->entityValuePool
), ms
);
4957 #endif /* XML_DTD */
4958 hashTableInit(&(p
->generalEntities
), ms
);
4959 hashTableInit(&(p
->elementTypes
), ms
);
4960 hashTableInit(&(p
->attributeIds
), ms
);
4961 hashTableInit(&(p
->prefixes
), ms
);
4963 p
->paramEntityRead
= XML_FALSE
;
4964 hashTableInit(&(p
->paramEntities
), ms
);
4965 #endif /* XML_DTD */
4966 p
->defaultPrefix
.name
= NULL
;
4967 p
->defaultPrefix
.binding
= NULL
;
4969 p
->in_eldecl
= XML_FALSE
;
4970 p
->scaffIndex
= NULL
;
4975 p
->contentStringLen
= 0;
4977 p
->keepProcessing
= XML_TRUE
;
4978 p
->hasParamEntityRefs
= XML_FALSE
;
4979 p
->standalone
= XML_FALSE
;
4984 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
4986 HASH_TABLE_ITER iter
;
4987 hashTableIterInit(&iter
, &(p
->elementTypes
));
4989 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4992 if (e
->allocDefaultAtts
!= 0)
4993 ms
->free_fcn(e
->defaultAtts
);
4995 hashTableClear(&(p
->generalEntities
));
4997 p
->paramEntityRead
= XML_FALSE
;
4998 hashTableClear(&(p
->paramEntities
));
4999 #endif /* XML_DTD */
5000 hashTableClear(&(p
->elementTypes
));
5001 hashTableClear(&(p
->attributeIds
));
5002 hashTableClear(&(p
->prefixes
));
5003 poolClear(&(p
->pool
));
5005 poolClear(&(p
->entityValuePool
));
5006 #endif /* XML_DTD */
5007 p
->defaultPrefix
.name
= NULL
;
5008 p
->defaultPrefix
.binding
= NULL
;
5010 p
->in_eldecl
= XML_FALSE
;
5011 if (p
->scaffIndex
) {
5012 ms
->free_fcn(p
->scaffIndex
);
5013 p
->scaffIndex
= NULL
;
5016 ms
->free_fcn(p
->scaffold
);
5022 p
->contentStringLen
= 0;
5024 p
->keepProcessing
= XML_TRUE
;
5025 p
->hasParamEntityRefs
= XML_FALSE
;
5026 p
->standalone
= XML_FALSE
;
5030 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5032 HASH_TABLE_ITER iter
;
5033 hashTableIterInit(&iter
, &(p
->elementTypes
));
5035 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5038 if (e
->allocDefaultAtts
!= 0)
5039 ms
->free_fcn(e
->defaultAtts
);
5041 hashTableDestroy(&(p
->generalEntities
));
5043 hashTableDestroy(&(p
->paramEntities
));
5044 #endif /* XML_DTD */
5045 hashTableDestroy(&(p
->elementTypes
));
5046 hashTableDestroy(&(p
->attributeIds
));
5047 hashTableDestroy(&(p
->prefixes
));
5048 poolDestroy(&(p
->pool
));
5050 poolDestroy(&(p
->entityValuePool
));
5051 #endif /* XML_DTD */
5054 ms
->free_fcn(p
->scaffIndex
);
5056 ms
->free_fcn(p
->scaffold
);
5061 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5062 The new DTD has already been initialized.
5065 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5067 HASH_TABLE_ITER iter
;
5069 /* Copy the prefix table. */
5071 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5073 const XML_Char
*name
;
5074 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5077 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5080 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5084 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5086 /* Copy the attribute id table. */
5090 const XML_Char
*name
;
5091 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5095 /* Remember to allocate the scratch byte before the name. */
5096 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5098 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5102 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5103 sizeof(ATTRIBUTE_ID
));
5106 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5108 newA
->xmlns
= oldA
->xmlns
;
5109 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5110 newA
->prefix
= &newDtd
->defaultPrefix
;
5112 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5113 oldA
->prefix
->name
, 0);
5117 /* Copy the element type table. */
5119 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5124 const XML_Char
*name
;
5125 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5128 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5131 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5132 sizeof(ELEMENT_TYPE
));
5135 if (oldE
->nDefaultAtts
) {
5136 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5137 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5138 if (!newE
->defaultAtts
) {
5144 newE
->idAtt
= (ATTRIBUTE_ID
*)
5145 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5146 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5148 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5149 oldE
->prefix
->name
, 0);
5150 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5151 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5152 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5153 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5154 if (oldE
->defaultAtts
[i
].value
) {
5155 newE
->defaultAtts
[i
].value
5156 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5157 if (!newE
->defaultAtts
[i
].value
)
5161 newE
->defaultAtts
[i
].value
= NULL
;
5165 /* Copy the entity tables. */
5166 if (!copyEntityTable(&(newDtd
->generalEntities
),
5168 &(oldDtd
->generalEntities
)))
5172 if (!copyEntityTable(&(newDtd
->paramEntities
),
5174 &(oldDtd
->paramEntities
)))
5176 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5177 #endif /* XML_DTD */
5179 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5180 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5181 newDtd
->standalone
= oldDtd
->standalone
;
5183 /* Don't want deep copying for scaffolding */
5184 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5185 newDtd
->scaffold
= oldDtd
->scaffold
;
5186 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5187 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5188 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5189 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5195 copyEntityTable(HASH_TABLE
*newTable
,
5196 STRING_POOL
*newPool
,
5197 const HASH_TABLE
*oldTable
)
5199 HASH_TABLE_ITER iter
;
5200 const XML_Char
*cachedOldBase
= NULL
;
5201 const XML_Char
*cachedNewBase
= NULL
;
5203 hashTableIterInit(&iter
, oldTable
);
5207 const XML_Char
*name
;
5208 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5211 name
= poolCopyString(newPool
, oldE
->name
);
5214 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5217 if (oldE
->systemId
) {
5218 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5221 newE
->systemId
= tem
;
5223 if (oldE
->base
== cachedOldBase
)
5224 newE
->base
= cachedNewBase
;
5226 cachedOldBase
= oldE
->base
;
5227 tem
= poolCopyString(newPool
, cachedOldBase
);
5230 cachedNewBase
= newE
->base
= tem
;
5233 if (oldE
->publicId
) {
5234 tem
= poolCopyString(newPool
, oldE
->publicId
);
5237 newE
->publicId
= tem
;
5241 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5245 newE
->textPtr
= tem
;
5246 newE
->textLen
= oldE
->textLen
;
5248 if (oldE
->notation
) {
5249 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5252 newE
->notation
= tem
;
5254 newE
->is_param
= oldE
->is_param
;
5255 newE
->is_internal
= oldE
->is_internal
;
5260 #define INIT_SIZE 64
5263 keyeq(KEY s1
, KEY s2
)
5265 for (; *s1
== *s2
; s1
++, s2
++)
5271 static unsigned long FASTCALL
5274 unsigned long h
= 0;
5276 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5281 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5284 if (table
->size
== 0) {
5289 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5290 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5293 memset(table
->v
, 0, tsize
);
5294 table
->size
= INIT_SIZE
;
5295 table
->usedLim
= INIT_SIZE
/ 2;
5296 i
= hash(name
) & (table
->size
- 1);
5299 unsigned long h
= hash(name
);
5300 for (i
= h
& (table
->size
- 1);
5302 i
== 0 ? i
= table
->size
- 1 : --i
) {
5303 if (keyeq(name
, table
->v
[i
]->name
))
5308 if (table
->used
== table
->usedLim
) {
5309 /* check for overflow */
5310 size_t newSize
= table
->size
* 2;
5311 size_t tsize
= newSize
* sizeof(NAMED
*);
5312 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5315 memset(newV
, 0, tsize
);
5316 for (i
= 0; i
< table
->size
; i
++)
5319 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5321 j
== 0 ? j
= newSize
- 1 : --j
)
5323 newV
[j
] = table
->v
[i
];
5325 table
->mem
->free_fcn(table
->v
);
5327 table
->size
= newSize
;
5328 table
->usedLim
= newSize
/2;
5329 for (i
= h
& (table
->size
- 1);
5331 i
== 0 ? i
= table
->size
- 1 : --i
)
5335 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5338 memset(table
->v
[i
], 0, createSize
);
5339 table
->v
[i
]->name
= name
;
5344 static void FASTCALL
5345 hashTableClear(HASH_TABLE
*table
)
5348 for (i
= 0; i
< table
->size
; i
++) {
5349 NAMED
*p
= table
->v
[i
];
5351 table
->mem
->free_fcn(p
);
5355 table
->usedLim
= table
->size
/ 2;
5359 static void FASTCALL
5360 hashTableDestroy(HASH_TABLE
*table
)
5363 for (i
= 0; i
< table
->size
; i
++) {
5364 NAMED
*p
= table
->v
[i
];
5366 table
->mem
->free_fcn(p
);
5369 table
->mem
->free_fcn(table
->v
);
5372 static void FASTCALL
5373 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5382 static void FASTCALL
5383 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5386 iter
->end
= iter
->p
+ table
->size
;
5389 static NAMED
* FASTCALL
5390 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5392 while (iter
->p
!= iter
->end
) {
5393 NAMED
*tem
= *(iter
->p
)++;
5400 static void FASTCALL
5401 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5403 pool
->blocks
= NULL
;
5404 pool
->freeBlocks
= NULL
;
5411 static void FASTCALL
5412 poolClear(STRING_POOL
*pool
)
5414 if (!pool
->freeBlocks
)
5415 pool
->freeBlocks
= pool
->blocks
;
5417 BLOCK
*p
= pool
->blocks
;
5419 BLOCK
*tem
= p
->next
;
5420 p
->next
= pool
->freeBlocks
;
5421 pool
->freeBlocks
= p
;
5425 pool
->blocks
= NULL
;
5431 static void FASTCALL
5432 poolDestroy(STRING_POOL
*pool
)
5434 BLOCK
*p
= pool
->blocks
;
5436 BLOCK
*tem
= p
->next
;
5437 pool
->mem
->free_fcn(p
);
5440 p
= pool
->freeBlocks
;
5442 BLOCK
*tem
= p
->next
;
5443 pool
->mem
->free_fcn(p
);
5449 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5450 const char *ptr
, const char *end
)
5452 if (!pool
->ptr
&& !poolGrow(pool
))
5455 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5458 if (!poolGrow(pool
))
5464 static const XML_Char
* FASTCALL
5465 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5468 if (!poolAppendChar(pool
, *s
))
5476 static const XML_Char
*
5477 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5479 if (!pool
->ptr
&& !poolGrow(pool
))
5481 for (; n
> 0; --n
, s
++) {
5482 if (!poolAppendChar(pool
, *s
))
5490 static const XML_Char
* FASTCALL
5491 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5494 if (!poolAppendChar(pool
, *s
))
5502 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5503 const char *ptr
, const char *end
)
5505 if (!poolAppend(pool
, enc
, ptr
, end
))
5507 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5513 static XML_Bool FASTCALL
5514 poolGrow(STRING_POOL
*pool
)
5516 if (pool
->freeBlocks
) {
5517 if (pool
->start
== 0) {
5518 pool
->blocks
= pool
->freeBlocks
;
5519 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5520 pool
->blocks
->next
= NULL
;
5521 pool
->start
= pool
->blocks
->s
;
5522 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5523 pool
->ptr
= pool
->start
;
5526 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
5527 BLOCK
*tem
= pool
->freeBlocks
->next
;
5528 pool
->freeBlocks
->next
= pool
->blocks
;
5529 pool
->blocks
= pool
->freeBlocks
;
5530 pool
->freeBlocks
= tem
;
5531 memcpy(pool
->blocks
->s
, pool
->start
,
5532 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
5533 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5534 pool
->start
= pool
->blocks
->s
;
5535 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5539 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5540 int blockSize
= (pool
->end
- pool
->start
)*2;
5541 pool
->blocks
= (BLOCK
*)
5542 pool
->mem
->realloc_fcn(pool
->blocks
,
5544 + blockSize
* sizeof(XML_Char
)));
5545 if (pool
->blocks
== NULL
)
5547 pool
->blocks
->size
= blockSize
;
5548 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5549 pool
->start
= pool
->blocks
->s
;
5550 pool
->end
= pool
->start
+ blockSize
;
5554 int blockSize
= pool
->end
- pool
->start
;
5555 if (blockSize
< INIT_BLOCK_SIZE
)
5556 blockSize
= INIT_BLOCK_SIZE
;
5559 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5560 + blockSize
* sizeof(XML_Char
));
5563 tem
->size
= blockSize
;
5564 tem
->next
= pool
->blocks
;
5566 if (pool
->ptr
!= pool
->start
)
5567 memcpy(tem
->s
, pool
->start
,
5568 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5569 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5570 pool
->start
= tem
->s
;
5571 pool
->end
= tem
->s
+ blockSize
;
5577 nextScaffoldPart(XML_Parser parser
)
5579 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5580 CONTENT_SCAFFOLD
* me
;
5583 if (!dtd
->scaffIndex
) {
5584 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
5585 if (!dtd
->scaffIndex
)
5587 dtd
->scaffIndex
[0] = 0;
5590 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
5591 CONTENT_SCAFFOLD
*temp
;
5592 if (dtd
->scaffold
) {
5593 temp
= (CONTENT_SCAFFOLD
*)
5594 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5597 dtd
->scaffSize
*= 2;
5600 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
5601 * sizeof(CONTENT_SCAFFOLD
));
5604 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5606 dtd
->scaffold
= temp
;
5608 next
= dtd
->scaffCount
++;
5609 me
= &dtd
->scaffold
[next
];
5610 if (dtd
->scaffLevel
) {
5611 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
5612 if (parent
->lastchild
) {
5613 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
5615 if (!parent
->childcnt
)
5616 parent
->firstchild
= next
;
5617 parent
->lastchild
= next
;
5620 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5625 build_node(XML_Parser parser
,
5628 XML_Content
**contpos
,
5631 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5632 dest
->type
= dtd
->scaffold
[src_node
].type
;
5633 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
5634 if (dest
->type
== XML_CTYPE_NAME
) {
5635 const XML_Char
*src
;
5636 dest
->name
= *strpos
;
5637 src
= dtd
->scaffold
[src_node
].name
;
5639 *(*strpos
)++ = *src
;
5644 dest
->numchildren
= 0;
5645 dest
->children
= NULL
;
5650 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
5651 dest
->children
= *contpos
;
5652 *contpos
+= dest
->numchildren
;
5653 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
5654 i
< dest
->numchildren
;
5655 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
5656 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5662 static XML_Content
*
5663 build_model (XML_Parser parser
)
5665 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5669 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
5670 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
5672 ret
= (XML_Content
*)MALLOC(allocsize
);
5676 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
5679 build_node(parser
, 0, ret
, &cpos
, &str
);
5683 static ELEMENT_TYPE
*
5684 getElementType(XML_Parser parser
,
5685 const ENCODING
*enc
,
5689 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5690 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
5695 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5698 if (ret
->name
!= name
)
5699 poolDiscard(&dtd
->pool
);
5701 poolFinish(&dtd
->pool
);
5702 if (!setElementTypePrefix(parser
, ret
))