1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
8 #ifdef COMPILED_FROM_DSP
10 #include "winconfig.h"
11 #define XMLPARSEAPI(type) type __cdecl
15 #elif defined(MACOS_CLASSIC)
17 #include "macconfig.h"
23 #include <expat_config.h>
27 #define XMLPARSEAPI(type) type __cdecl
35 #endif /* ndef COMPILED_FROM_DSP */
38 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
39 #define XmlConvert XmlUtf16Convert
40 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
41 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
42 #define XmlEncode XmlUtf16Encode
43 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
44 typedef unsigned short ICHAR
;
46 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
47 #define XmlConvert XmlUtf8Convert
48 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
49 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
50 #define XmlEncode XmlUtf8Encode
51 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
58 #define XmlInitEncodingNS XmlInitEncoding
59 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
60 #undef XmlGetInternalEncodingNS
61 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
62 #define XmlParseXmlDeclNS XmlParseXmlDecl
68 #ifdef XML_UNICODE_WCHAR_T
69 #define XML_T(x) (const wchar_t)x
70 #define XML_L(x) L ## x
72 #define XML_T(x) (const unsigned short)x
83 /* Round up n to be a multiple of sz, where sz is a power of 2. */
84 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
90 typedef const XML_Char
*KEY
;
101 const XML_Memory_Handling_Suite
*mem
;
109 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
110 #define INIT_DATA_BUF_SIZE 1024
111 #define INIT_ATTS_SIZE 16
112 #define INIT_BLOCK_SIZE 1024
113 #define INIT_BUFFER_SIZE 1024
115 #define EXPAND_SPARE 24
117 typedef struct binding
{
118 struct prefix
*prefix
;
119 struct binding
*nextTagBinding
;
120 struct binding
*prevPrefixBinding
;
121 const struct attribute_id
*attId
;
127 typedef struct prefix
{
128 const XML_Char
*name
;
134 const XML_Char
*localPart
;
135 const XML_Char
*prefix
;
141 /* TAG represents an open element.
142 The name of the element is stored in both the document and API
143 encodings. The memory buffer 'buf' is a separately-allocated
144 memory area which stores the name. During the XML_Parse()/
145 XMLParseBuffer() when the element is open, the memory for the 'raw'
146 version of the name (in the document encoding) is shared with the
147 document buffer. If the element is open across calls to
148 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
149 contain the 'raw' name as well.
151 A parser re-uses these structures, maintaining a list of allocated
152 TAG objects in a free list.
155 struct tag
*parent
; /* parent of this element */
156 const char *rawName
; /* tagName in the original encoding */
158 TAG_NAME name
; /* tagName in the API encoding */
159 char *buf
; /* buffer for name components */
160 char *bufEnd
; /* end of the buffer */
165 const XML_Char
*name
;
166 const XML_Char
*textPtr
;
168 const XML_Char
*systemId
;
169 const XML_Char
*base
;
170 const XML_Char
*publicId
;
171 const XML_Char
*notation
;
174 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
178 enum XML_Content_Type type
;
179 enum XML_Content_Quant quant
;
180 const XML_Char
* name
;
187 #define INIT_SCAFFOLD_ELEMENTS 32
189 typedef struct block
{
201 const XML_Memory_Handling_Suite
*mem
;
204 /* The XML_Char before the name is used to determine whether
205 an attribute has been specified. */
206 typedef struct attribute_id
{
209 XML_Bool maybeTokenized
;
214 const ATTRIBUTE_ID
*id
;
216 const XML_Char
*value
;
220 const XML_Char
*name
;
222 const ATTRIBUTE_ID
*idAtt
;
224 int allocDefaultAtts
;
225 DEFAULT_ATTRIBUTE
*defaultAtts
;
229 HASH_TABLE generalEntities
;
230 HASH_TABLE elementTypes
;
231 HASH_TABLE attributeIds
;
234 STRING_POOL entityValuePool
;
235 /* false once a parameter entity reference has been skipped */
236 XML_Bool keepProcessing
;
237 /* true once an internal or external PE reference has been encountered;
238 this includes the reference to an external subset */
239 XML_Bool hasParamEntityRefs
;
242 /* indicates if external PE has been read */
243 XML_Bool paramEntityRead
;
244 HASH_TABLE paramEntities
;
246 PREFIX defaultPrefix
;
247 /* === scaffolding for building content model === */
249 CONTENT_SCAFFOLD
*scaffold
;
250 unsigned contentStringLen
;
257 typedef struct open_internal_entity
{
258 const char *internalEventPtr
;
259 const char *internalEventEndPtr
;
260 struct open_internal_entity
*next
;
262 } OPEN_INTERNAL_ENTITY
;
264 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
267 const char **endPtr
);
269 static Processor prologProcessor
;
270 static Processor prologInitProcessor
;
271 static Processor contentProcessor
;
272 static Processor cdataSectionProcessor
;
274 static Processor ignoreSectionProcessor
;
275 static Processor externalParEntProcessor
;
276 static Processor externalParEntInitProcessor
;
277 static Processor entityValueProcessor
;
278 static Processor entityValueInitProcessor
;
280 static Processor epilogProcessor
;
281 static Processor errorProcessor
;
282 static Processor externalEntityInitProcessor
;
283 static Processor externalEntityInitProcessor2
;
284 static Processor externalEntityInitProcessor3
;
285 static Processor externalEntityContentProcessor
;
287 static enum XML_Error
288 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
289 static enum XML_Error
290 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
291 const char *, const char *);
292 static enum XML_Error
293 initializeEncoding(XML_Parser parser
);
294 static enum XML_Error
295 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
296 const char *end
, int tok
, const char *next
, const char **nextPtr
);
297 static enum XML_Error
298 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
299 static enum XML_Error
300 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
301 const char *start
, const char *end
, const char **endPtr
);
302 static enum XML_Error
303 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
304 const char *end
, const char **nextPtr
);
306 static enum XML_Error
307 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
308 const char *end
, const char **nextPtr
);
311 static enum XML_Error
312 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
313 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
314 static enum XML_Error
315 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
316 const XML_Char
*uri
, BINDING
**bindingsPtr
);
318 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
319 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
321 static enum XML_Error
322 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
323 const char *, const char *, STRING_POOL
*);
324 static enum XML_Error
325 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
326 const char *, const char *, STRING_POOL
*);
327 static ATTRIBUTE_ID
*
328 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
331 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
332 static enum XML_Error
333 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
336 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
337 const char *start
, const char *end
);
339 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
342 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
345 static const XML_Char
* getContext(XML_Parser parser
);
347 setContext(XML_Parser parser
, const XML_Char
*context
);
349 static void FASTCALL
normalizePublicId(XML_Char
*s
);
351 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
352 /* do not call if parentParser != NULL */
353 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
355 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
357 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
359 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
362 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
364 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
365 static void FASTCALL
hashTableClear(HASH_TABLE
*);
366 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
368 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
369 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
372 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
373 static void FASTCALL
poolClear(STRING_POOL
*);
374 static void FASTCALL
poolDestroy(STRING_POOL
*);
376 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
377 const char *ptr
, const char *end
);
379 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
380 const char *ptr
, const char *end
);
381 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
382 static const XML_Char
* FASTCALL
383 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
384 static const XML_Char
*
385 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
386 static const XML_Char
* FASTCALL
387 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
389 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
390 static XML_Content
* build_model(XML_Parser parser
);
391 static ELEMENT_TYPE
*
392 getElementType(XML_Parser parser
, const ENCODING
*enc
,
393 const char *ptr
, const char *end
);
396 parserCreate(const XML_Char
*encodingName
,
397 const XML_Memory_Handling_Suite
*memsuite
,
398 const XML_Char
*nameSep
,
401 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
403 #define poolStart(pool) ((pool)->start)
404 #define poolEnd(pool) ((pool)->ptr)
405 #define poolLength(pool) ((pool)->ptr - (pool)->start)
406 #define poolChop(pool) ((void)--(pool->ptr))
407 #define poolLastChar(pool) (((pool)->ptr)[-1])
408 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
409 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
410 #define poolAppendChar(pool, c) \
411 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
413 : ((*((pool)->ptr)++ = c), 1))
415 struct XML_ParserStruct
{
416 /* The first member must be userData so that the XML_GetUserData
421 const XML_Memory_Handling_Suite m_mem
;
422 /* first character to be parsed */
423 const char *m_bufferPtr
;
424 /* past last character to be parsed */
426 /* allocated end of buffer */
427 const char *m_bufferLim
;
428 long m_parseEndByteIndex
;
429 const char *m_parseEndPtr
;
431 XML_Char
*m_dataBufEnd
;
432 XML_StartElementHandler m_startElementHandler
;
433 XML_EndElementHandler m_endElementHandler
;
434 XML_CharacterDataHandler m_characterDataHandler
;
435 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
436 XML_CommentHandler m_commentHandler
;
437 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
438 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
439 XML_DefaultHandler m_defaultHandler
;
440 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
441 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
442 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
443 XML_NotationDeclHandler m_notationDeclHandler
;
444 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
445 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
446 XML_NotStandaloneHandler m_notStandaloneHandler
;
447 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
448 XML_Parser m_externalEntityRefHandlerArg
;
449 XML_SkippedEntityHandler m_skippedEntityHandler
;
450 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
451 XML_ElementDeclHandler m_elementDeclHandler
;
452 XML_AttlistDeclHandler m_attlistDeclHandler
;
453 XML_EntityDeclHandler m_entityDeclHandler
;
454 XML_XmlDeclHandler m_xmlDeclHandler
;
455 const ENCODING
*m_encoding
;
456 INIT_ENCODING m_initEncoding
;
457 const ENCODING
*m_internalEncoding
;
458 const XML_Char
*m_protocolEncodingName
;
460 XML_Bool m_ns_triplets
;
461 void *m_unknownEncodingMem
;
462 void *m_unknownEncodingData
;
463 void *m_unknownEncodingHandlerData
;
464 void (*m_unknownEncodingRelease
)(void *);
465 PROLOG_STATE m_prologState
;
466 Processor
*m_processor
;
467 enum XML_Error m_errorCode
;
468 const char *m_eventPtr
;
469 const char *m_eventEndPtr
;
470 const char *m_positionPtr
;
471 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
472 XML_Bool m_defaultExpandInternalEntities
;
474 ENTITY
*m_declEntity
;
475 const XML_Char
*m_doctypeName
;
476 const XML_Char
*m_doctypeSysid
;
477 const XML_Char
*m_doctypePubid
;
478 const XML_Char
*m_declAttributeType
;
479 const XML_Char
*m_declNotationName
;
480 const XML_Char
*m_declNotationPublicId
;
481 ELEMENT_TYPE
*m_declElementType
;
482 ATTRIBUTE_ID
*m_declAttributeId
;
483 XML_Bool m_declAttributeIsCdata
;
484 XML_Bool m_declAttributeIsId
;
486 const XML_Char
*m_curBase
;
489 BINDING
*m_inheritedBindings
;
490 BINDING
*m_freeBindingList
;
492 int m_nSpecifiedAtts
;
496 STRING_POOL m_tempPool
;
497 STRING_POOL m_temp2Pool
;
498 char *m_groupConnector
;
499 unsigned m_groupSize
;
500 XML_Char m_namespaceSeparator
;
501 XML_Parser m_parentParser
;
503 XML_Bool m_isParamEntity
;
504 XML_Bool m_useForeignDTD
;
505 enum XML_ParamEntityParsing m_paramEntityParsing
;
509 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
510 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
511 #define FREE(p) (parser->m_mem.free_fcn((p)))
513 #define userData (parser->m_userData)
514 #define handlerArg (parser->m_handlerArg)
515 #define startElementHandler (parser->m_startElementHandler)
516 #define endElementHandler (parser->m_endElementHandler)
517 #define characterDataHandler (parser->m_characterDataHandler)
518 #define processingInstructionHandler \
519 (parser->m_processingInstructionHandler)
520 #define commentHandler (parser->m_commentHandler)
521 #define startCdataSectionHandler \
522 (parser->m_startCdataSectionHandler)
523 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
524 #define defaultHandler (parser->m_defaultHandler)
525 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
526 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
527 #define unparsedEntityDeclHandler \
528 (parser->m_unparsedEntityDeclHandler)
529 #define notationDeclHandler (parser->m_notationDeclHandler)
530 #define startNamespaceDeclHandler \
531 (parser->m_startNamespaceDeclHandler)
532 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
533 #define notStandaloneHandler (parser->m_notStandaloneHandler)
534 #define externalEntityRefHandler \
535 (parser->m_externalEntityRefHandler)
536 #define externalEntityRefHandlerArg \
537 (parser->m_externalEntityRefHandlerArg)
538 #define internalEntityRefHandler \
539 (parser->m_internalEntityRefHandler)
540 #define skippedEntityHandler (parser->m_skippedEntityHandler)
541 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
542 #define elementDeclHandler (parser->m_elementDeclHandler)
543 #define attlistDeclHandler (parser->m_attlistDeclHandler)
544 #define entityDeclHandler (parser->m_entityDeclHandler)
545 #define xmlDeclHandler (parser->m_xmlDeclHandler)
546 #define encoding (parser->m_encoding)
547 #define initEncoding (parser->m_initEncoding)
548 #define internalEncoding (parser->m_internalEncoding)
549 #define unknownEncodingMem (parser->m_unknownEncodingMem)
550 #define unknownEncodingData (parser->m_unknownEncodingData)
551 #define unknownEncodingHandlerData \
552 (parser->m_unknownEncodingHandlerData)
553 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
554 #define protocolEncodingName (parser->m_protocolEncodingName)
555 #define ns (parser->m_ns)
556 #define ns_triplets (parser->m_ns_triplets)
557 #define prologState (parser->m_prologState)
558 #define processor (parser->m_processor)
559 #define errorCode (parser->m_errorCode)
560 #define eventPtr (parser->m_eventPtr)
561 #define eventEndPtr (parser->m_eventEndPtr)
562 #define positionPtr (parser->m_positionPtr)
563 #define position (parser->m_position)
564 #define openInternalEntities (parser->m_openInternalEntities)
565 #define defaultExpandInternalEntities \
566 (parser->m_defaultExpandInternalEntities)
567 #define tagLevel (parser->m_tagLevel)
568 #define buffer (parser->m_buffer)
569 #define bufferPtr (parser->m_bufferPtr)
570 #define bufferEnd (parser->m_bufferEnd)
571 #define parseEndByteIndex (parser->m_parseEndByteIndex)
572 #define parseEndPtr (parser->m_parseEndPtr)
573 #define bufferLim (parser->m_bufferLim)
574 #define dataBuf (parser->m_dataBuf)
575 #define dataBufEnd (parser->m_dataBufEnd)
576 #define _dtd (parser->m_dtd)
577 #define curBase (parser->m_curBase)
578 #define declEntity (parser->m_declEntity)
579 #define doctypeName (parser->m_doctypeName)
580 #define doctypeSysid (parser->m_doctypeSysid)
581 #define doctypePubid (parser->m_doctypePubid)
582 #define declAttributeType (parser->m_declAttributeType)
583 #define declNotationName (parser->m_declNotationName)
584 #define declNotationPublicId (parser->m_declNotationPublicId)
585 #define declElementType (parser->m_declElementType)
586 #define declAttributeId (parser->m_declAttributeId)
587 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
588 #define declAttributeIsId (parser->m_declAttributeIsId)
589 #define freeTagList (parser->m_freeTagList)
590 #define freeBindingList (parser->m_freeBindingList)
591 #define inheritedBindings (parser->m_inheritedBindings)
592 #define tagStack (parser->m_tagStack)
593 #define atts (parser->m_atts)
594 #define attsSize (parser->m_attsSize)
595 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
596 #define idAttIndex (parser->m_idAttIndex)
597 #define tempPool (parser->m_tempPool)
598 #define temp2Pool (parser->m_temp2Pool)
599 #define groupConnector (parser->m_groupConnector)
600 #define groupSize (parser->m_groupSize)
601 #define namespaceSeparator (parser->m_namespaceSeparator)
602 #define parentParser (parser->m_parentParser)
604 #define isParamEntity (parser->m_isParamEntity)
605 #define useForeignDTD (parser->m_useForeignDTD)
606 #define paramEntityParsing (parser->m_paramEntityParsing)
614 (processor != externalParEntInitProcessor) \
616 (processor != externalEntityInitProcessor)) \
618 (processor != prologInitProcessor))
621 XML_ParserCreate(const XML_Char
*encodingName
)
623 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
627 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
631 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
634 static const XML_Char implicitContext
[] = {
635 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
636 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
637 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
638 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
642 XML_ParserCreate_MM(const XML_Char
*encodingName
,
643 const XML_Memory_Handling_Suite
*memsuite
,
644 const XML_Char
*nameSep
)
646 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
647 if (parser
!= NULL
&& ns
) {
648 /* implicit context only set for root parser, since child
649 parsers (i.e. external entity parsers) will inherit it
651 if (!setContext(parser
, implicitContext
)) {
652 XML_ParserFree(parser
);
660 parserCreate(const XML_Char
*encodingName
,
661 const XML_Memory_Handling_Suite
*memsuite
,
662 const XML_Char
*nameSep
,
668 XML_Memory_Handling_Suite
*mtemp
;
669 parser
= (XML_Parser
)
670 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
671 if (parser
!= NULL
) {
672 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
673 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
674 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
675 mtemp
->free_fcn
= memsuite
->free_fcn
;
679 XML_Memory_Handling_Suite
*mtemp
;
680 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
681 if (parser
!= NULL
) {
682 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
683 mtemp
->malloc_fcn
= malloc
;
684 mtemp
->realloc_fcn
= realloc
;
685 mtemp
->free_fcn
= free
;
695 attsSize
= INIT_ATTS_SIZE
;
696 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
701 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
702 if (dataBuf
== NULL
) {
707 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
712 _dtd
= dtdCreate(&parser
->m_mem
);
721 freeBindingList
= NULL
;
725 groupConnector
= NULL
;
727 unknownEncodingHandler
= NULL
;
728 unknownEncodingHandlerData
= NULL
;
730 namespaceSeparator
= '!';
732 ns_triplets
= XML_FALSE
;
734 poolInit(&tempPool
, &(parser
->m_mem
));
735 poolInit(&temp2Pool
, &(parser
->m_mem
));
736 parserInit(parser
, encodingName
);
738 if (encodingName
&& !protocolEncodingName
) {
739 XML_ParserFree(parser
);
745 internalEncoding
= XmlGetInternalEncodingNS();
746 namespaceSeparator
= *nameSep
;
749 internalEncoding
= XmlGetInternalEncoding();
756 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
758 processor
= prologInitProcessor
;
759 XmlPrologStateInit(&prologState
);
760 protocolEncodingName
= (encodingName
!= NULL
761 ? poolCopyString(&tempPool
, encodingName
)
764 XmlInitEncoding(&initEncoding
, &encoding
, 0);
767 startElementHandler
= NULL
;
768 endElementHandler
= NULL
;
769 characterDataHandler
= NULL
;
770 processingInstructionHandler
= NULL
;
771 commentHandler
= NULL
;
772 startCdataSectionHandler
= NULL
;
773 endCdataSectionHandler
= NULL
;
774 defaultHandler
= NULL
;
775 startDoctypeDeclHandler
= NULL
;
776 endDoctypeDeclHandler
= NULL
;
777 unparsedEntityDeclHandler
= NULL
;
778 notationDeclHandler
= NULL
;
779 startNamespaceDeclHandler
= NULL
;
780 endNamespaceDeclHandler
= NULL
;
781 notStandaloneHandler
= NULL
;
782 externalEntityRefHandler
= NULL
;
783 externalEntityRefHandlerArg
= parser
;
784 skippedEntityHandler
= NULL
;
785 elementDeclHandler
= NULL
;
786 attlistDeclHandler
= NULL
;
787 entityDeclHandler
= NULL
;
788 xmlDeclHandler
= NULL
;
791 parseEndByteIndex
= 0;
793 declElementType
= NULL
;
794 declAttributeId
= NULL
;
799 declAttributeType
= NULL
;
800 declNotationName
= NULL
;
801 declNotationPublicId
= NULL
;
802 declAttributeIsCdata
= XML_FALSE
;
803 declAttributeIsId
= XML_FALSE
;
804 memset(&position
, 0, sizeof(POSITION
));
805 errorCode
= XML_ERROR_NONE
;
809 openInternalEntities
= 0;
810 defaultExpandInternalEntities
= XML_TRUE
;
813 inheritedBindings
= NULL
;
815 unknownEncodingMem
= NULL
;
816 unknownEncodingRelease
= NULL
;
817 unknownEncodingData
= NULL
;
820 isParamEntity
= XML_FALSE
;
821 useForeignDTD
= XML_FALSE
;
822 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
826 /* moves list of bindings to freeBindingList */
828 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
831 BINDING
*b
= bindings
;
832 bindings
= bindings
->nextTagBinding
;
833 b
->nextTagBinding
= freeBindingList
;
839 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
844 /* move tagStack to freeTagList */
849 tag
->parent
= freeTagList
;
850 moveToFreeBindingList(parser
, tag
->bindings
);
851 tag
->bindings
= NULL
;
854 moveToFreeBindingList(parser
, inheritedBindings
);
855 if (unknownEncodingMem
)
856 FREE(unknownEncodingMem
);
857 if (unknownEncodingRelease
)
858 unknownEncodingRelease(unknownEncodingData
);
859 poolClear(&tempPool
);
860 poolClear(&temp2Pool
);
861 parserInit(parser
, encodingName
);
862 dtdReset(_dtd
, &parser
->m_mem
);
863 return setContext(parser
, implicitContext
);
867 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
869 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
870 XXX There's no way for the caller to determine which of the
871 XXX possible error cases caused the XML_STATUS_ERROR return.
874 return XML_STATUS_ERROR
;
875 if (encodingName
== NULL
)
876 protocolEncodingName
= NULL
;
878 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
879 if (!protocolEncodingName
)
880 return XML_STATUS_ERROR
;
882 return XML_STATUS_OK
;
886 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
887 const XML_Char
*context
,
888 const XML_Char
*encodingName
)
890 XML_Parser parser
= oldParser
;
893 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
894 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
895 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
896 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
897 = processingInstructionHandler
;
898 XML_CommentHandler oldCommentHandler
= commentHandler
;
899 XML_StartCdataSectionHandler oldStartCdataSectionHandler
900 = startCdataSectionHandler
;
901 XML_EndCdataSectionHandler oldEndCdataSectionHandler
902 = endCdataSectionHandler
;
903 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
904 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
905 = unparsedEntityDeclHandler
;
906 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
907 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
908 = startNamespaceDeclHandler
;
909 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
910 = endNamespaceDeclHandler
;
911 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
912 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
913 = externalEntityRefHandler
;
914 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
915 XML_UnknownEncodingHandler oldUnknownEncodingHandler
916 = unknownEncodingHandler
;
917 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
918 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
919 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
920 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
921 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
923 void *oldUserData
= userData
;
924 void *oldHandlerArg
= handlerArg
;
925 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
926 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
928 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
929 int oldInEntityValue
= prologState
.inEntityValue
;
931 XML_Bool oldns_triplets
= ns_triplets
;
938 /* Note that the magical uses of the pre-processor to make field
939 access look more like C++ require that `parser' be overwritten
940 here. This makes this function more painful to follow than it
945 *tmp
= namespaceSeparator
;
946 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
949 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
955 startElementHandler
= oldStartElementHandler
;
956 endElementHandler
= oldEndElementHandler
;
957 characterDataHandler
= oldCharacterDataHandler
;
958 processingInstructionHandler
= oldProcessingInstructionHandler
;
959 commentHandler
= oldCommentHandler
;
960 startCdataSectionHandler
= oldStartCdataSectionHandler
;
961 endCdataSectionHandler
= oldEndCdataSectionHandler
;
962 defaultHandler
= oldDefaultHandler
;
963 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
964 notationDeclHandler
= oldNotationDeclHandler
;
965 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
966 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
967 notStandaloneHandler
= oldNotStandaloneHandler
;
968 externalEntityRefHandler
= oldExternalEntityRefHandler
;
969 skippedEntityHandler
= oldSkippedEntityHandler
;
970 unknownEncodingHandler
= oldUnknownEncodingHandler
;
971 elementDeclHandler
= oldElementDeclHandler
;
972 attlistDeclHandler
= oldAttlistDeclHandler
;
973 entityDeclHandler
= oldEntityDeclHandler
;
974 xmlDeclHandler
= oldXmlDeclHandler
;
975 declElementType
= oldDeclElementType
;
976 userData
= oldUserData
;
977 if (oldUserData
== oldHandlerArg
)
978 handlerArg
= userData
;
981 if (oldExternalEntityRefHandlerArg
!= oldParser
)
982 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
983 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
984 ns_triplets
= oldns_triplets
;
985 parentParser
= oldParser
;
987 paramEntityParsing
= oldParamEntityParsing
;
988 prologState
.inEntityValue
= oldInEntityValue
;
991 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
992 || !setContext(parser
, context
)) {
993 XML_ParserFree(parser
);
996 processor
= externalEntityInitProcessor
;
1000 /* The DTD instance referenced by _dtd is shared between the document's
1001 root parser and external PE parsers, therefore one does not need to
1002 call setContext. In addition, one also *must* not call setContext,
1003 because this would overwrite existing prefix->binding pointers in
1004 _dtd with ones that get destroyed with the external PE parser.
1005 This would leave those prefixes with dangling pointers.
1007 isParamEntity
= XML_TRUE
;
1008 XmlPrologStateInitExternalEntity(&prologState
);
1009 processor
= externalParEntInitProcessor
;
1011 #endif /* XML_DTD */
1015 static void FASTCALL
1016 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1019 BINDING
*b
= bindings
;
1022 bindings
= b
->nextTagBinding
;
1029 XML_ParserFree(XML_Parser parser
)
1033 if (tagStack
== NULL
) {
1034 if (freeTagList
== NULL
)
1036 tagStack
= freeTagList
;
1040 tagStack
= tagStack
->parent
;
1042 destroyBindings(p
->bindings
, parser
);
1045 destroyBindings(freeBindingList
, parser
);
1046 destroyBindings(inheritedBindings
, parser
);
1047 poolDestroy(&tempPool
);
1048 poolDestroy(&temp2Pool
);
1050 /* external parameter entity parsers share the DTD structure
1051 parser->m_dtd with the root parser, so we must not destroy it
1053 if (!isParamEntity
&& _dtd
)
1056 #endif /* XML_DTD */
1057 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1060 FREE(groupConnector
);
1064 if (unknownEncodingMem
)
1065 FREE(unknownEncodingMem
);
1066 if (unknownEncodingRelease
)
1067 unknownEncodingRelease(unknownEncodingData
);
1072 XML_UseParserAsHandlerArg(XML_Parser parser
)
1074 handlerArg
= parser
;
1078 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1081 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1083 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1084 useForeignDTD
= useDTD
;
1085 return XML_ERROR_NONE
;
1087 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1092 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1094 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1097 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1101 XML_SetUserData(XML_Parser parser
, void *p
)
1103 if (handlerArg
== userData
)
1104 handlerArg
= userData
= p
;
1110 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1113 p
= poolCopyString(&_dtd
->pool
, p
);
1115 return XML_STATUS_ERROR
;
1120 return XML_STATUS_OK
;
1124 XML_GetBase(XML_Parser parser
)
1130 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1132 return nSpecifiedAtts
;
1136 XML_GetIdAttributeIndex(XML_Parser parser
)
1142 XML_SetElementHandler(XML_Parser parser
,
1143 XML_StartElementHandler start
,
1144 XML_EndElementHandler end
)
1146 startElementHandler
= start
;
1147 endElementHandler
= end
;
1151 XML_SetStartElementHandler(XML_Parser parser
,
1152 XML_StartElementHandler start
) {
1153 startElementHandler
= start
;
1157 XML_SetEndElementHandler(XML_Parser parser
,
1158 XML_EndElementHandler end
) {
1159 endElementHandler
= end
;
1163 XML_SetCharacterDataHandler(XML_Parser parser
,
1164 XML_CharacterDataHandler handler
)
1166 characterDataHandler
= handler
;
1170 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1171 XML_ProcessingInstructionHandler handler
)
1173 processingInstructionHandler
= handler
;
1177 XML_SetCommentHandler(XML_Parser parser
,
1178 XML_CommentHandler handler
)
1180 commentHandler
= handler
;
1184 XML_SetCdataSectionHandler(XML_Parser parser
,
1185 XML_StartCdataSectionHandler start
,
1186 XML_EndCdataSectionHandler end
)
1188 startCdataSectionHandler
= start
;
1189 endCdataSectionHandler
= end
;
1193 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1194 XML_StartCdataSectionHandler start
) {
1195 startCdataSectionHandler
= start
;
1199 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1200 XML_EndCdataSectionHandler end
) {
1201 endCdataSectionHandler
= end
;
1205 XML_SetDefaultHandler(XML_Parser parser
,
1206 XML_DefaultHandler handler
)
1208 defaultHandler
= handler
;
1209 defaultExpandInternalEntities
= XML_FALSE
;
1213 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1214 XML_DefaultHandler handler
)
1216 defaultHandler
= handler
;
1217 defaultExpandInternalEntities
= XML_TRUE
;
1221 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1222 XML_StartDoctypeDeclHandler start
,
1223 XML_EndDoctypeDeclHandler end
)
1225 startDoctypeDeclHandler
= start
;
1226 endDoctypeDeclHandler
= end
;
1230 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1231 XML_StartDoctypeDeclHandler start
) {
1232 startDoctypeDeclHandler
= start
;
1236 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1237 XML_EndDoctypeDeclHandler end
) {
1238 endDoctypeDeclHandler
= end
;
1242 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1243 XML_UnparsedEntityDeclHandler handler
)
1245 unparsedEntityDeclHandler
= handler
;
1249 XML_SetNotationDeclHandler(XML_Parser parser
,
1250 XML_NotationDeclHandler handler
)
1252 notationDeclHandler
= handler
;
1256 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1257 XML_StartNamespaceDeclHandler start
,
1258 XML_EndNamespaceDeclHandler end
)
1260 startNamespaceDeclHandler
= start
;
1261 endNamespaceDeclHandler
= end
;
1265 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1266 XML_StartNamespaceDeclHandler start
) {
1267 startNamespaceDeclHandler
= start
;
1271 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1272 XML_EndNamespaceDeclHandler end
) {
1273 endNamespaceDeclHandler
= end
;
1277 XML_SetNotStandaloneHandler(XML_Parser parser
,
1278 XML_NotStandaloneHandler handler
)
1280 notStandaloneHandler
= handler
;
1284 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1285 XML_ExternalEntityRefHandler handler
)
1287 externalEntityRefHandler
= handler
;
1291 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1294 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1296 externalEntityRefHandlerArg
= parser
;
1300 XML_SetSkippedEntityHandler(XML_Parser parser
,
1301 XML_SkippedEntityHandler handler
)
1303 skippedEntityHandler
= handler
;
1307 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1308 XML_UnknownEncodingHandler handler
,
1311 unknownEncodingHandler
= handler
;
1312 unknownEncodingHandlerData
= data
;
1316 XML_SetElementDeclHandler(XML_Parser parser
,
1317 XML_ElementDeclHandler eldecl
)
1319 elementDeclHandler
= eldecl
;
1323 XML_SetAttlistDeclHandler(XML_Parser parser
,
1324 XML_AttlistDeclHandler attdecl
)
1326 attlistDeclHandler
= attdecl
;
1330 XML_SetEntityDeclHandler(XML_Parser parser
,
1331 XML_EntityDeclHandler handler
)
1333 entityDeclHandler
= handler
;
1337 XML_SetXmlDeclHandler(XML_Parser parser
,
1338 XML_XmlDeclHandler handler
) {
1339 xmlDeclHandler
= handler
;
1343 XML_SetParamEntityParsing(XML_Parser parser
,
1344 enum XML_ParamEntityParsing peParsing
)
1346 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1350 paramEntityParsing
= peParsing
;
1353 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1358 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1362 return XML_STATUS_OK
;
1363 positionPtr
= bufferPtr
;
1364 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1365 if (errorCode
== XML_ERROR_NONE
)
1366 return XML_STATUS_OK
;
1367 eventEndPtr
= eventPtr
;
1368 processor
= errorProcessor
;
1369 return XML_STATUS_ERROR
;
1371 #ifndef XML_CONTEXT_BYTES
1372 else if (bufferPtr
== bufferEnd
) {
1375 parseEndByteIndex
+= len
;
1378 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1379 if (errorCode
== XML_ERROR_NONE
)
1380 return XML_STATUS_OK
;
1381 eventEndPtr
= eventPtr
;
1382 processor
= errorProcessor
;
1383 return XML_STATUS_ERROR
;
1385 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1386 if (errorCode
!= XML_ERROR_NONE
) {
1387 eventEndPtr
= eventPtr
;
1388 processor
= errorProcessor
;
1389 return XML_STATUS_ERROR
;
1391 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1393 nLeftOver
= s
+ len
- end
;
1395 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1396 /* FIXME avoid integer overflow */
1398 temp
= (buffer
== NULL
1399 ? (char *)MALLOC(len
* 2)
1400 : (char *)REALLOC(buffer
, len
* 2));
1402 errorCode
= XML_ERROR_NO_MEMORY
;
1403 return XML_STATUS_ERROR
;
1407 errorCode
= XML_ERROR_NO_MEMORY
;
1408 eventPtr
= eventEndPtr
= NULL
;
1409 processor
= errorProcessor
;
1410 return XML_STATUS_ERROR
;
1412 bufferLim
= buffer
+ len
* 2;
1414 memcpy(buffer
, end
, nLeftOver
);
1416 bufferEnd
= buffer
+ nLeftOver
;
1418 return XML_STATUS_OK
;
1420 #endif /* not defined XML_CONTEXT_BYTES */
1422 void *buff
= XML_GetBuffer(parser
, len
);
1424 return XML_STATUS_ERROR
;
1426 memcpy(buff
, s
, len
);
1427 return XML_ParseBuffer(parser
, len
, isFinal
);
1433 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1435 const char *start
= bufferPtr
;
1436 positionPtr
= start
;
1438 parseEndByteIndex
+= len
;
1439 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1440 isFinal
? (const char **)NULL
: &bufferPtr
);
1441 if (errorCode
== XML_ERROR_NONE
) {
1443 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1444 positionPtr
= bufferPtr
;
1446 return XML_STATUS_OK
;
1449 eventEndPtr
= eventPtr
;
1450 processor
= errorProcessor
;
1451 return XML_STATUS_ERROR
;
1456 XML_GetBuffer(XML_Parser parser
, int len
)
1458 if (len
> bufferLim
- bufferEnd
) {
1459 /* FIXME avoid integer overflow */
1460 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1461 #ifdef XML_CONTEXT_BYTES
1462 int keep
= bufferPtr
- buffer
;
1464 if (keep
> XML_CONTEXT_BYTES
)
1465 keep
= XML_CONTEXT_BYTES
;
1467 #endif /* defined XML_CONTEXT_BYTES */
1468 if (neededSize
<= bufferLim
- buffer
) {
1469 #ifdef XML_CONTEXT_BYTES
1470 if (keep
< bufferPtr
- buffer
) {
1471 int offset
= (bufferPtr
- buffer
) - keep
;
1472 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1473 bufferEnd
-= offset
;
1474 bufferPtr
-= offset
;
1477 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1478 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1480 #endif /* not defined XML_CONTEXT_BYTES */
1484 int bufferSize
= bufferLim
- bufferPtr
;
1485 if (bufferSize
== 0)
1486 bufferSize
= INIT_BUFFER_SIZE
;
1489 } while (bufferSize
< neededSize
);
1490 newBuf
= (char *)MALLOC(bufferSize
);
1492 errorCode
= XML_ERROR_NO_MEMORY
;
1495 bufferLim
= newBuf
+ bufferSize
;
1496 #ifdef XML_CONTEXT_BYTES
1498 int keep
= bufferPtr
- buffer
;
1499 if (keep
> XML_CONTEXT_BYTES
)
1500 keep
= XML_CONTEXT_BYTES
;
1501 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1504 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1505 bufferPtr
= buffer
+ keep
;
1508 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1509 bufferPtr
= buffer
= newBuf
;
1513 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1516 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1517 bufferPtr
= buffer
= newBuf
;
1518 #endif /* not defined XML_CONTEXT_BYTES */
1525 XML_GetErrorCode(XML_Parser parser
)
1531 XML_GetCurrentByteIndex(XML_Parser parser
)
1534 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1539 XML_GetCurrentByteCount(XML_Parser parser
)
1541 if (eventEndPtr
&& eventPtr
)
1542 return eventEndPtr
- eventPtr
;
1547 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1549 #ifdef XML_CONTEXT_BYTES
1550 if (eventPtr
&& buffer
) {
1551 *offset
= eventPtr
- buffer
;
1552 *size
= bufferEnd
- buffer
;
1555 #endif /* defined XML_CONTEXT_BYTES */
1560 XML_GetCurrentLineNumber(XML_Parser parser
)
1563 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1564 positionPtr
= eventPtr
;
1566 return position
.lineNumber
+ 1;
1570 XML_GetCurrentColumnNumber(XML_Parser parser
)
1573 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1574 positionPtr
= eventPtr
;
1576 return position
.columnNumber
;
1580 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1586 XML_MemMalloc(XML_Parser parser
, size_t size
)
1588 return MALLOC(size
);
1592 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1594 return REALLOC(ptr
, size
);
1598 XML_MemFree(XML_Parser parser
, void *ptr
)
1604 XML_DefaultCurrent(XML_Parser parser
)
1606 if (defaultHandler
) {
1607 if (openInternalEntities
)
1608 reportDefault(parser
,
1610 openInternalEntities
->internalEventPtr
,
1611 openInternalEntities
->internalEventEndPtr
);
1613 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1618 XML_ErrorString(enum XML_Error code
)
1620 static const XML_LChar
*message
[] = {
1622 XML_L("out of memory"),
1623 XML_L("syntax error"),
1624 XML_L("no element found"),
1625 XML_L("not well-formed (invalid token)"),
1626 XML_L("unclosed token"),
1627 XML_L("partial character"),
1628 XML_L("mismatched tag"),
1629 XML_L("duplicate attribute"),
1630 XML_L("junk after document element"),
1631 XML_L("illegal parameter entity reference"),
1632 XML_L("undefined entity"),
1633 XML_L("recursive entity reference"),
1634 XML_L("asynchronous entity"),
1635 XML_L("reference to invalid character number"),
1636 XML_L("reference to binary entity"),
1637 XML_L("reference to external entity in attribute"),
1638 XML_L("xml declaration not at start of external entity"),
1639 XML_L("unknown encoding"),
1640 XML_L("encoding specified in XML declaration is incorrect"),
1641 XML_L("unclosed CDATA section"),
1642 XML_L("error in processing external entity reference"),
1643 XML_L("document is not standalone"),
1644 XML_L("unexpected parser state - please send a bug report"),
1645 XML_L("entity declared in parameter entity"),
1646 XML_L("requested feature requires XML_DTD support in Expat"),
1647 XML_L("cannot change setting once parsing has begun")
1649 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1650 return message
[code
];
1655 XML_ExpatVersion(void) {
1657 /* V1 is used to string-ize the version number. However, it would
1658 string-ize the actual version macro *names* unless we get them
1659 substituted before being passed to V1. CPP is defined to expand
1660 a macro, then rescan for more expansions. Thus, we use V2 to expand
1661 the version macros, then CPP will expand the resulting V1() macro
1662 with the correct numerals. */
1663 /* ### I'm assuming cpp is portable in this respect... */
1665 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1666 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1668 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1675 XML_ExpatVersionInfo(void)
1677 XML_Expat_Version version
;
1679 version
.major
= XML_MAJOR_VERSION
;
1680 version
.minor
= XML_MINOR_VERSION
;
1681 version
.micro
= XML_MICRO_VERSION
;
1687 XML_GetFeatureList(void)
1689 static XML_Feature features
[] = {
1690 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1691 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1693 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1695 #ifdef XML_UNICODE_WCHAR_T
1696 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1699 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1701 #ifdef XML_CONTEXT_BYTES
1702 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1706 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1708 {XML_FEATURE_END
, NULL
}
1711 features
[0].value
= sizeof(XML_Char
);
1712 features
[1].value
= sizeof(XML_LChar
);
1716 /* Initially tag->rawName always points into the parse buffer;
1717 for those TAG instances opened while the current parse buffer was
1718 processed, and not yet closed, we need to store tag->rawName in a more
1719 permanent location, since the parse buffer is about to be discarded.
1722 storeRawNames(XML_Parser parser
)
1724 TAG
*tag
= tagStack
;
1727 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1728 char *rawNameBuf
= tag
->buf
+ nameLen
;
1729 /* Stop if already stored. Since tagStack is a stack, we can stop
1730 at the first entry that has already been copied; everything
1731 below it in the stack is already been accounted for in a
1732 previous call to this function.
1734 if (tag
->rawName
== rawNameBuf
)
1736 /* For re-use purposes we need to ensure that the
1737 size of tag->buf is a multiple of sizeof(XML_Char).
1739 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1740 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1741 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1744 /* if tag->name.str points to tag->buf (only when namespace
1745 processing is off) then we have to update it
1747 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1748 tag
->name
.str
= (XML_Char
*)temp
;
1749 /* if tag->name.localPart is set (when namespace processing is on)
1750 then update it as well, since it will always point into tag->buf
1752 if (tag
->name
.localPart
)
1753 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1754 (XML_Char
*)tag
->buf
);
1756 tag
->bufEnd
= temp
+ bufSize
;
1757 rawNameBuf
= temp
+ nameLen
;
1759 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1760 tag
->rawName
= rawNameBuf
;
1766 static enum XML_Error PTRCALL
1767 contentProcessor(XML_Parser parser
,
1770 const char **endPtr
)
1772 enum XML_Error result
=
1773 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1774 if (result
!= XML_ERROR_NONE
)
1776 if (!storeRawNames(parser
))
1777 return XML_ERROR_NO_MEMORY
;
1781 static enum XML_Error PTRCALL
1782 externalEntityInitProcessor(XML_Parser parser
,
1785 const char **endPtr
)
1787 enum XML_Error result
= initializeEncoding(parser
);
1788 if (result
!= XML_ERROR_NONE
)
1790 processor
= externalEntityInitProcessor2
;
1791 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1794 static enum XML_Error PTRCALL
1795 externalEntityInitProcessor2(XML_Parser parser
,
1798 const char **endPtr
)
1800 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1801 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1804 /* If we are at the end of the buffer, this would cause the next stage,
1805 i.e. externalEntityInitProcessor3, to pass control directly to
1806 doContent (by detecting XML_TOK_NONE) without processing any xml text
1807 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1809 if (next
== end
&& endPtr
) {
1811 return XML_ERROR_NONE
;
1815 case XML_TOK_PARTIAL
:
1818 return XML_ERROR_NONE
;
1821 return XML_ERROR_UNCLOSED_TOKEN
;
1822 case XML_TOK_PARTIAL_CHAR
:
1825 return XML_ERROR_NONE
;
1828 return XML_ERROR_PARTIAL_CHAR
;
1830 processor
= externalEntityInitProcessor3
;
1831 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1834 static enum XML_Error PTRCALL
1835 externalEntityInitProcessor3(XML_Parser parser
,
1838 const char **endPtr
)
1840 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1841 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1843 case XML_TOK_XML_DECL
:
1845 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1846 if (result
!= XML_ERROR_NONE
)
1851 case XML_TOK_PARTIAL
:
1854 return XML_ERROR_NONE
;
1857 return XML_ERROR_UNCLOSED_TOKEN
;
1858 case XML_TOK_PARTIAL_CHAR
:
1861 return XML_ERROR_NONE
;
1864 return XML_ERROR_PARTIAL_CHAR
;
1866 processor
= externalEntityContentProcessor
;
1868 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1871 static enum XML_Error PTRCALL
1872 externalEntityContentProcessor(XML_Parser parser
,
1875 const char **endPtr
)
1877 enum XML_Error result
=
1878 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1879 if (result
!= XML_ERROR_NONE
)
1881 if (!storeRawNames(parser
))
1882 return XML_ERROR_NO_MEMORY
;
1886 static enum XML_Error
1887 doContent(XML_Parser parser
,
1889 const ENCODING
*enc
,
1892 const char **nextPtr
)
1894 DTD
* const dtd
= _dtd
; /* save one level of indirection */
1895 const char **eventPP
;
1896 const char **eventEndPP
;
1897 if (enc
== encoding
) {
1898 eventPP
= &eventPtr
;
1899 eventEndPP
= &eventEndPtr
;
1902 eventPP
= &(openInternalEntities
->internalEventPtr
);
1903 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1907 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1908 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1911 case XML_TOK_TRAILING_CR
:
1914 return XML_ERROR_NONE
;
1917 if (characterDataHandler
) {
1919 characterDataHandler(handlerArg
, &c
, 1);
1921 else if (defaultHandler
)
1922 reportDefault(parser
, enc
, s
, end
);
1923 if (startTagLevel
== 0)
1924 return XML_ERROR_NO_ELEMENTS
;
1925 if (tagLevel
!= startTagLevel
)
1926 return XML_ERROR_ASYNC_ENTITY
;
1927 return XML_ERROR_NONE
;
1931 return XML_ERROR_NONE
;
1933 if (startTagLevel
> 0) {
1934 if (tagLevel
!= startTagLevel
)
1935 return XML_ERROR_ASYNC_ENTITY
;
1936 return XML_ERROR_NONE
;
1938 return XML_ERROR_NO_ELEMENTS
;
1939 case XML_TOK_INVALID
:
1941 return XML_ERROR_INVALID_TOKEN
;
1942 case XML_TOK_PARTIAL
:
1945 return XML_ERROR_NONE
;
1947 return XML_ERROR_UNCLOSED_TOKEN
;
1948 case XML_TOK_PARTIAL_CHAR
:
1951 return XML_ERROR_NONE
;
1953 return XML_ERROR_PARTIAL_CHAR
;
1954 case XML_TOK_ENTITY_REF
:
1956 const XML_Char
*name
;
1958 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1959 s
+ enc
->minBytesPerChar
,
1960 next
- enc
->minBytesPerChar
);
1962 if (characterDataHandler
)
1963 characterDataHandler(handlerArg
, &ch
, 1);
1964 else if (defaultHandler
)
1965 reportDefault(parser
, enc
, s
, next
);
1968 name
= poolStoreString(&dtd
->pool
, enc
,
1969 s
+ enc
->minBytesPerChar
,
1970 next
- enc
->minBytesPerChar
);
1972 return XML_ERROR_NO_MEMORY
;
1973 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
1974 poolDiscard(&dtd
->pool
);
1975 /* First, determine if a check for an existing declaration is needed;
1976 if yes, check that the entity exists, and that it is internal,
1977 otherwise call the skipped entity or default handler.
1979 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
1981 return XML_ERROR_UNDEFINED_ENTITY
;
1982 else if (!entity
->is_internal
)
1983 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
1986 if (skippedEntityHandler
)
1987 skippedEntityHandler(handlerArg
, name
, 0);
1988 else if (defaultHandler
)
1989 reportDefault(parser
, enc
, s
, next
);
1993 return XML_ERROR_RECURSIVE_ENTITY_REF
;
1994 if (entity
->notation
)
1995 return XML_ERROR_BINARY_ENTITY_REF
;
1996 if (entity
->textPtr
) {
1997 enum XML_Error result
;
1998 OPEN_INTERNAL_ENTITY openEntity
;
1999 if (!defaultExpandInternalEntities
) {
2000 if (skippedEntityHandler
)
2001 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2002 else if (defaultHandler
)
2003 reportDefault(parser
, enc
, s
, next
);
2006 entity
->open
= XML_TRUE
;
2007 openEntity
.next
= openInternalEntities
;
2008 openInternalEntities
= &openEntity
;
2009 openEntity
.entity
= entity
;
2010 openEntity
.internalEventPtr
= NULL
;
2011 openEntity
.internalEventEndPtr
= NULL
;
2012 result
= doContent(parser
,
2015 (char *)entity
->textPtr
,
2016 (char *)(entity
->textPtr
+ entity
->textLen
),
2018 entity
->open
= XML_FALSE
;
2019 openInternalEntities
= openEntity
.next
;
2023 else if (externalEntityRefHandler
) {
2024 const XML_Char
*context
;
2025 entity
->open
= XML_TRUE
;
2026 context
= getContext(parser
);
2027 entity
->open
= XML_FALSE
;
2029 return XML_ERROR_NO_MEMORY
;
2030 if (!externalEntityRefHandler((XML_Parser
)externalEntityRefHandlerArg
,
2035 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2036 poolDiscard(&tempPool
);
2038 else if (defaultHandler
)
2039 reportDefault(parser
, enc
, s
, next
);
2042 case XML_TOK_START_TAG_NO_ATTS
:
2044 case XML_TOK_START_TAG_WITH_ATTS
:
2047 enum XML_Error result
;
2051 freeTagList
= freeTagList
->parent
;
2054 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2056 return XML_ERROR_NO_MEMORY
;
2057 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2060 return XML_ERROR_NO_MEMORY
;
2062 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2064 tag
->bindings
= NULL
;
2065 tag
->parent
= tagStack
;
2067 tag
->name
.localPart
= NULL
;
2068 tag
->name
.prefix
= NULL
;
2069 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2070 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2073 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2074 const char *fromPtr
= tag
->rawName
;
2075 toPtr
= (XML_Char
*)tag
->buf
;
2080 &fromPtr
, rawNameEnd
,
2081 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2082 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2083 if (fromPtr
== rawNameEnd
) {
2084 tag
->name
.strLen
= convLen
;
2087 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2089 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2091 return XML_ERROR_NO_MEMORY
;
2093 tag
->bufEnd
= temp
+ bufSize
;
2094 toPtr
= (XML_Char
*)temp
+ convLen
;
2098 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2099 *toPtr
= XML_T('\0');
2100 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2103 if (startElementHandler
)
2104 startElementHandler(handlerArg
, tag
->name
.str
,
2105 (const XML_Char
**)atts
);
2106 else if (defaultHandler
)
2107 reportDefault(parser
, enc
, s
, next
);
2108 poolClear(&tempPool
);
2111 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2113 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2115 const char *rawName
= s
+ enc
->minBytesPerChar
;
2116 enum XML_Error result
;
2117 BINDING
*bindings
= NULL
;
2118 XML_Bool noElmHandlers
= XML_TRUE
;
2120 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2121 rawName
+ XmlNameLength(enc
, rawName
));
2123 return XML_ERROR_NO_MEMORY
;
2124 poolFinish(&tempPool
);
2125 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2128 poolFinish(&tempPool
);
2129 if (startElementHandler
) {
2130 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2131 noElmHandlers
= XML_FALSE
;
2133 if (endElementHandler
) {
2134 if (startElementHandler
)
2135 *eventPP
= *eventEndPP
;
2136 endElementHandler(handlerArg
, name
.str
);
2137 noElmHandlers
= XML_FALSE
;
2139 if (noElmHandlers
&& defaultHandler
)
2140 reportDefault(parser
, enc
, s
, next
);
2141 poolClear(&tempPool
);
2143 BINDING
*b
= bindings
;
2144 if (endNamespaceDeclHandler
)
2145 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2146 bindings
= bindings
->nextTagBinding
;
2147 b
->nextTagBinding
= freeBindingList
;
2148 freeBindingList
= b
;
2149 b
->prefix
->binding
= b
->prevPrefixBinding
;
2153 return epilogProcessor(parser
, next
, end
, nextPtr
);
2155 case XML_TOK_END_TAG
:
2156 if (tagLevel
== startTagLevel
)
2157 return XML_ERROR_ASYNC_ENTITY
;
2160 const char *rawName
;
2161 TAG
*tag
= tagStack
;
2162 tagStack
= tag
->parent
;
2163 tag
->parent
= freeTagList
;
2165 rawName
= s
+ enc
->minBytesPerChar
*2;
2166 len
= XmlNameLength(enc
, rawName
);
2167 if (len
!= tag
->rawNameLength
2168 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2170 return XML_ERROR_TAG_MISMATCH
;
2173 if (endElementHandler
) {
2174 const XML_Char
*localPart
;
2175 const XML_Char
*prefix
;
2177 localPart
= tag
->name
.localPart
;
2178 if (ns
&& localPart
) {
2179 /* localPart and prefix may have been overwritten in
2180 tag->name.str, since this points to the binding->uri
2181 buffer which gets re-used; so we have to add them again
2183 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2184 /* don't need to check for space - already done in storeAtts() */
2185 while (*localPart
) *uri
++ = *localPart
++;
2186 prefix
= (XML_Char
*)tag
->name
.prefix
;
2187 if (ns_triplets
&& prefix
) {
2188 *uri
++ = namespaceSeparator
;
2189 while (*prefix
) *uri
++ = *prefix
++;
2193 endElementHandler(handlerArg
, tag
->name
.str
);
2195 else if (defaultHandler
)
2196 reportDefault(parser
, enc
, s
, next
);
2197 while (tag
->bindings
) {
2198 BINDING
*b
= tag
->bindings
;
2199 if (endNamespaceDeclHandler
)
2200 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2201 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2202 b
->nextTagBinding
= freeBindingList
;
2203 freeBindingList
= b
;
2204 b
->prefix
->binding
= b
->prevPrefixBinding
;
2207 return epilogProcessor(parser
, next
, end
, nextPtr
);
2210 case XML_TOK_CHAR_REF
:
2212 int n
= XmlCharRefNumber(enc
, s
);
2214 return XML_ERROR_BAD_CHAR_REF
;
2215 if (characterDataHandler
) {
2216 XML_Char buf
[XML_ENCODE_MAX
];
2217 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2219 else if (defaultHandler
)
2220 reportDefault(parser
, enc
, s
, next
);
2223 case XML_TOK_XML_DECL
:
2224 return XML_ERROR_MISPLACED_XML_PI
;
2225 case XML_TOK_DATA_NEWLINE
:
2226 if (characterDataHandler
) {
2228 characterDataHandler(handlerArg
, &c
, 1);
2230 else if (defaultHandler
)
2231 reportDefault(parser
, enc
, s
, next
);
2233 case XML_TOK_CDATA_SECT_OPEN
:
2235 enum XML_Error result
;
2236 if (startCdataSectionHandler
)
2237 startCdataSectionHandler(handlerArg
);
2239 /* Suppose you doing a transformation on a document that involves
2240 changing only the character data. You set up a defaultHandler
2241 and a characterDataHandler. The defaultHandler simply copies
2242 characters through. The characterDataHandler does the
2243 transformation and writes the characters out escaping them as
2244 necessary. This case will fail to work if we leave out the
2245 following two lines (because & and < inside CDATA sections will
2246 be incorrectly escaped).
2248 However, now we have a start/endCdataSectionHandler, so it seems
2249 easier to let the user deal with this.
2251 else if (characterDataHandler
)
2252 characterDataHandler(handlerArg
, dataBuf
, 0);
2254 else if (defaultHandler
)
2255 reportDefault(parser
, enc
, s
, next
);
2256 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2258 processor
= cdataSectionProcessor
;
2263 case XML_TOK_TRAILING_RSQB
:
2266 return XML_ERROR_NONE
;
2268 if (characterDataHandler
) {
2269 if (MUST_CONVERT(enc
, s
)) {
2270 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2271 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2272 characterDataHandler(handlerArg
, dataBuf
,
2273 dataPtr
- (ICHAR
*)dataBuf
);
2276 characterDataHandler(handlerArg
,
2278 (XML_Char
*)end
- (XML_Char
*)s
);
2280 else if (defaultHandler
)
2281 reportDefault(parser
, enc
, s
, end
);
2282 if (startTagLevel
== 0) {
2284 return XML_ERROR_NO_ELEMENTS
;
2286 if (tagLevel
!= startTagLevel
) {
2288 return XML_ERROR_ASYNC_ENTITY
;
2290 return XML_ERROR_NONE
;
2291 case XML_TOK_DATA_CHARS
:
2292 if (characterDataHandler
) {
2293 if (MUST_CONVERT(enc
, s
)) {
2295 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2296 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2298 characterDataHandler(handlerArg
, dataBuf
,
2299 dataPtr
- (ICHAR
*)dataBuf
);
2306 characterDataHandler(handlerArg
,
2308 (XML_Char
*)next
- (XML_Char
*)s
);
2310 else if (defaultHandler
)
2311 reportDefault(parser
, enc
, s
, next
);
2314 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2315 return XML_ERROR_NO_MEMORY
;
2317 case XML_TOK_COMMENT
:
2318 if (!reportComment(parser
, enc
, s
, next
))
2319 return XML_ERROR_NO_MEMORY
;
2323 reportDefault(parser
, enc
, s
, next
);
2326 *eventPP
= s
= next
;
2331 /* Precondition: all arguments must be non-NULL;
2333 - normalize attributes
2334 - check attributes for well-formedness
2335 - generate namespace aware attribute names (URI, prefix)
2336 - build list of attributes for startElementHandler
2337 - default attributes
2338 - process namespace declarations (check and report them)
2339 - generate namespace aware element name (URI, prefix)
2341 static enum XML_Error
2342 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2343 const char *attStr
, TAG_NAME
*tagNamePtr
,
2344 BINDING
**bindingsPtr
)
2346 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2347 ELEMENT_TYPE
*elementType
= NULL
;
2348 int nDefaultAtts
= 0;
2349 const XML_Char
**appAtts
; /* the attribute list for the application */
2357 const XML_Char
*localPart
;
2359 /* lookup the element type name */
2360 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2362 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2364 return XML_ERROR_NO_MEMORY
;
2365 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2366 sizeof(ELEMENT_TYPE
));
2368 return XML_ERROR_NO_MEMORY
;
2369 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2370 return XML_ERROR_NO_MEMORY
;
2372 nDefaultAtts
= elementType
->nDefaultAtts
;
2374 /* get the attributes from the tokenizer */
2375 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2376 if (n
+ nDefaultAtts
> attsSize
) {
2377 int oldAttsSize
= attsSize
;
2379 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2380 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2382 return XML_ERROR_NO_MEMORY
;
2384 if (n
> oldAttsSize
)
2385 XmlGetAttributes(enc
, attStr
, n
, atts
);
2388 appAtts
= (const XML_Char
**)atts
;
2389 for (i
= 0; i
< n
; i
++) {
2390 /* add the name and value to the attribute list */
2391 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2393 + XmlNameLength(enc
, atts
[i
].name
));
2395 return XML_ERROR_NO_MEMORY
;
2396 /* detect duplicate attributes */
2397 if ((attId
->name
)[-1]) {
2398 if (enc
== encoding
)
2399 eventPtr
= atts
[i
].name
;
2400 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2402 (attId
->name
)[-1] = 1;
2403 appAtts
[attIndex
++] = attId
->name
;
2404 if (!atts
[i
].normalized
) {
2405 enum XML_Error result
;
2406 XML_Bool isCdata
= XML_TRUE
;
2408 /* figure out whether declared as other than CDATA */
2409 if (attId
->maybeTokenized
) {
2411 for (j
= 0; j
< nDefaultAtts
; j
++) {
2412 if (attId
== elementType
->defaultAtts
[j
].id
) {
2413 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2419 /* normalize the attribute value */
2420 result
= storeAttributeValue(parser
, enc
, isCdata
,
2421 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2425 appAtts
[attIndex
] = poolStart(&tempPool
);
2426 poolFinish(&tempPool
);
2429 /* the value did not need normalizing */
2430 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2432 if (appAtts
[attIndex
] == 0)
2433 return XML_ERROR_NO_MEMORY
;
2434 poolFinish(&tempPool
);
2436 /* handle prefixed attribute names */
2437 if (attId
->prefix
) {
2439 /* deal with namespace declarations here */
2440 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2441 appAtts
[attIndex
], bindingsPtr
);
2447 /* deal with other prefixed names later */
2450 (attId
->name
)[-1] = 2;
2457 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2458 nSpecifiedAtts
= attIndex
;
2459 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2460 for (i
= 0; i
< attIndex
; i
+= 2)
2461 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2469 /* do attribute defaulting */
2470 for (i
= 0; i
< nDefaultAtts
; i
++) {
2471 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2472 if (!(da
->id
->name
)[-1] && da
->value
) {
2473 if (da
->id
->prefix
) {
2474 if (da
->id
->xmlns
) {
2475 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2476 da
->value
, bindingsPtr
);
2481 (da
->id
->name
)[-1] = 2;
2483 appAtts
[attIndex
++] = da
->id
->name
;
2484 appAtts
[attIndex
++] = da
->value
;
2488 (da
->id
->name
)[-1] = 1;
2489 appAtts
[attIndex
++] = da
->id
->name
;
2490 appAtts
[attIndex
++] = da
->value
;
2494 appAtts
[attIndex
] = 0;
2498 /* expand prefixed attribute names */
2499 for (; i
< attIndex
; i
+= 2) {
2500 if (appAtts
[i
][-1] == 2) {
2502 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2503 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, appAtts
[i
], 0);
2504 if (id
->prefix
->binding
) {
2506 const BINDING
*b
= id
->prefix
->binding
;
2507 const XML_Char
*s
= appAtts
[i
];
2508 for (j
= 0; j
< b
->uriLen
; j
++) {
2509 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2510 return XML_ERROR_NO_MEMORY
;
2512 while (*s
++ != XML_T(':'))
2515 if (!poolAppendChar(&tempPool
, *s
))
2516 return XML_ERROR_NO_MEMORY
;
2519 tempPool
.ptr
[-1] = namespaceSeparator
;
2520 s
= b
->prefix
->name
;
2522 if (!poolAppendChar(&tempPool
, *s
))
2523 return XML_ERROR_NO_MEMORY
;
2527 appAtts
[i
] = poolStart(&tempPool
);
2528 poolFinish(&tempPool
);
2534 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2537 /* clear the flags that say whether attributes were specified */
2538 for (; i
< attIndex
; i
+= 2)
2539 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2540 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2541 binding
->attId
->name
[-1] = 0;
2543 /* expand the element type name */
2544 if (elementType
->prefix
) {
2545 binding
= elementType
->prefix
->binding
;
2547 return XML_ERROR_NONE
;
2548 localPart
= tagNamePtr
->str
;
2549 while (*localPart
++ != XML_T(':'))
2552 else if (dtd
->defaultPrefix
.binding
) {
2553 binding
= dtd
->defaultPrefix
.binding
;
2554 localPart
= tagNamePtr
->str
;
2557 return XML_ERROR_NONE
;
2559 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2560 for (; binding
->prefix
->name
[prefixLen
++];)
2563 tagNamePtr
->localPart
= localPart
;
2564 tagNamePtr
->uriLen
= binding
->uriLen
;
2565 tagNamePtr
->prefix
= binding
->prefix
->name
;
2566 tagNamePtr
->prefixLen
= prefixLen
;
2567 for (i
= 0; localPart
[i
++];)
2569 n
= i
+ binding
->uriLen
+ prefixLen
;
2570 if (n
> binding
->uriAlloc
) {
2572 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2574 return XML_ERROR_NO_MEMORY
;
2575 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2576 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2577 for (p
= tagStack
; p
; p
= p
->parent
)
2578 if (p
->name
.str
== binding
->uri
)
2583 uri
= binding
->uri
+ binding
->uriLen
;
2584 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2586 uri
= uri
+ (i
- 1);
2587 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2588 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2590 tagNamePtr
->str
= binding
->uri
;
2591 return XML_ERROR_NONE
;
2594 /* addBinding() overwrites the value of prefix->binding without checking.
2595 Therefore one must keep track of the old value outside of addBinding().
2597 static enum XML_Error
2598 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2599 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2604 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2605 if (*uri
== XML_T('\0') && prefix
->name
)
2606 return XML_ERROR_SYNTAX
;
2608 for (len
= 0; uri
[len
]; len
++)
2610 if (namespaceSeparator
)
2612 if (freeBindingList
) {
2613 b
= freeBindingList
;
2614 if (len
> b
->uriAlloc
) {
2615 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2616 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2618 return XML_ERROR_NO_MEMORY
;
2620 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2622 freeBindingList
= b
->nextTagBinding
;
2625 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2627 return XML_ERROR_NO_MEMORY
;
2628 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2631 return XML_ERROR_NO_MEMORY
;
2633 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2636 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2637 if (namespaceSeparator
)
2638 b
->uri
[len
- 1] = namespaceSeparator
;
2641 b
->prevPrefixBinding
= prefix
->binding
;
2642 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2643 prefix
->binding
= NULL
;
2645 prefix
->binding
= b
;
2646 b
->nextTagBinding
= *bindingsPtr
;
2648 if (startNamespaceDeclHandler
)
2649 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2650 prefix
->binding
? uri
: 0);
2651 return XML_ERROR_NONE
;
2654 /* The idea here is to avoid using stack for each CDATA section when
2655 the whole file is parsed with one call.
2657 static enum XML_Error PTRCALL
2658 cdataSectionProcessor(XML_Parser parser
,
2661 const char **endPtr
)
2663 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2666 if (parentParser
) { /* we are parsing an external entity */
2667 processor
= externalEntityContentProcessor
;
2668 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2671 processor
= contentProcessor
;
2672 return contentProcessor(parser
, start
, end
, endPtr
);
2678 /* startPtr gets set to non-null is the section is closed, and to null if
2679 the section is not yet closed.
2681 static enum XML_Error
2682 doCdataSection(XML_Parser parser
,
2683 const ENCODING
*enc
,
2684 const char **startPtr
,
2686 const char **nextPtr
)
2688 const char *s
= *startPtr
;
2689 const char **eventPP
;
2690 const char **eventEndPP
;
2691 if (enc
== encoding
) {
2692 eventPP
= &eventPtr
;
2694 eventEndPP
= &eventEndPtr
;
2697 eventPP
= &(openInternalEntities
->internalEventPtr
);
2698 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2704 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2707 case XML_TOK_CDATA_SECT_CLOSE
:
2708 if (endCdataSectionHandler
)
2709 endCdataSectionHandler(handlerArg
);
2711 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2712 else if (characterDataHandler
)
2713 characterDataHandler(handlerArg
, dataBuf
, 0);
2715 else if (defaultHandler
)
2716 reportDefault(parser
, enc
, s
, next
);
2718 return XML_ERROR_NONE
;
2719 case XML_TOK_DATA_NEWLINE
:
2720 if (characterDataHandler
) {
2722 characterDataHandler(handlerArg
, &c
, 1);
2724 else if (defaultHandler
)
2725 reportDefault(parser
, enc
, s
, next
);
2727 case XML_TOK_DATA_CHARS
:
2728 if (characterDataHandler
) {
2729 if (MUST_CONVERT(enc
, s
)) {
2731 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2732 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2734 characterDataHandler(handlerArg
, dataBuf
,
2735 dataPtr
- (ICHAR
*)dataBuf
);
2742 characterDataHandler(handlerArg
,
2744 (XML_Char
*)next
- (XML_Char
*)s
);
2746 else if (defaultHandler
)
2747 reportDefault(parser
, enc
, s
, next
);
2749 case XML_TOK_INVALID
:
2751 return XML_ERROR_INVALID_TOKEN
;
2752 case XML_TOK_PARTIAL_CHAR
:
2755 return XML_ERROR_NONE
;
2757 return XML_ERROR_PARTIAL_CHAR
;
2758 case XML_TOK_PARTIAL
:
2762 return XML_ERROR_NONE
;
2764 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2767 return XML_ERROR_UNEXPECTED_STATE
;
2769 *eventPP
= s
= next
;
2776 /* The idea here is to avoid using stack for each IGNORE section when
2777 the whole file is parsed with one call.
2779 static enum XML_Error PTRCALL
2780 ignoreSectionProcessor(XML_Parser parser
,
2783 const char **endPtr
)
2785 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2788 processor
= prologProcessor
;
2789 return prologProcessor(parser
, start
, end
, endPtr
);
2794 /* startPtr gets set to non-null is the section is closed, and to null
2795 if the section is not yet closed.
2797 static enum XML_Error
2798 doIgnoreSection(XML_Parser parser
,
2799 const ENCODING
*enc
,
2800 const char **startPtr
,
2802 const char **nextPtr
)
2806 const char *s
= *startPtr
;
2807 const char **eventPP
;
2808 const char **eventEndPP
;
2809 if (enc
== encoding
) {
2810 eventPP
= &eventPtr
;
2812 eventEndPP
= &eventEndPtr
;
2815 eventPP
= &(openInternalEntities
->internalEventPtr
);
2816 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2820 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2823 case XML_TOK_IGNORE_SECT
:
2825 reportDefault(parser
, enc
, s
, next
);
2827 return XML_ERROR_NONE
;
2828 case XML_TOK_INVALID
:
2830 return XML_ERROR_INVALID_TOKEN
;
2831 case XML_TOK_PARTIAL_CHAR
:
2834 return XML_ERROR_NONE
;
2836 return XML_ERROR_PARTIAL_CHAR
;
2837 case XML_TOK_PARTIAL
:
2841 return XML_ERROR_NONE
;
2843 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2846 return XML_ERROR_UNEXPECTED_STATE
;
2851 #endif /* XML_DTD */
2853 static enum XML_Error
2854 initializeEncoding(XML_Parser parser
)
2858 char encodingBuf
[128];
2859 if (!protocolEncodingName
)
2863 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2864 if (i
== sizeof(encodingBuf
) - 1
2865 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2866 encodingBuf
[0] = '\0';
2869 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2871 encodingBuf
[i
] = '\0';
2875 s
= protocolEncodingName
;
2877 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2878 return XML_ERROR_NONE
;
2879 return handleUnknownEncoding(parser
, protocolEncodingName
);
2882 static enum XML_Error
2883 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2884 const char *s
, const char *next
)
2886 const char *encodingName
= NULL
;
2887 const XML_Char
*storedEncName
= NULL
;
2888 const ENCODING
*newEncoding
= NULL
;
2889 const char *version
= NULL
;
2890 const char *versionend
;
2891 const XML_Char
*storedversion
= NULL
;
2892 int standalone
= -1;
2895 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2905 return XML_ERROR_SYNTAX
;
2906 if (!isGeneralTextEntity
&& standalone
== 1) {
2907 _dtd
->standalone
= XML_TRUE
;
2909 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2910 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2911 #endif /* XML_DTD */
2913 if (xmlDeclHandler
) {
2914 if (encodingName
!= NULL
) {
2915 storedEncName
= poolStoreString(&temp2Pool
,
2919 + XmlNameLength(encoding
, encodingName
));
2921 return XML_ERROR_NO_MEMORY
;
2922 poolFinish(&temp2Pool
);
2925 storedversion
= poolStoreString(&temp2Pool
,
2928 versionend
- encoding
->minBytesPerChar
);
2930 return XML_ERROR_NO_MEMORY
;
2932 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2934 else if (defaultHandler
)
2935 reportDefault(parser
, encoding
, s
, next
);
2936 if (protocolEncodingName
== NULL
) {
2938 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2939 eventPtr
= encodingName
;
2940 return XML_ERROR_INCORRECT_ENCODING
;
2942 encoding
= newEncoding
;
2944 else if (encodingName
) {
2945 enum XML_Error result
;
2946 if (!storedEncName
) {
2947 storedEncName
= poolStoreString(
2948 &temp2Pool
, encoding
, encodingName
,
2949 encodingName
+ XmlNameLength(encoding
, encodingName
));
2951 return XML_ERROR_NO_MEMORY
;
2953 result
= handleUnknownEncoding(parser
, storedEncName
);
2954 poolClear(&temp2Pool
);
2955 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2956 eventPtr
= encodingName
;
2961 if (storedEncName
|| storedversion
)
2962 poolClear(&temp2Pool
);
2964 return XML_ERROR_NONE
;
2967 static enum XML_Error
2968 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2970 if (unknownEncodingHandler
) {
2973 for (i
= 0; i
< 256; i
++)
2975 info
.convert
= NULL
;
2977 info
.release
= NULL
;
2978 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2981 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2982 if (!unknownEncodingMem
) {
2984 info
.release(info
.data
);
2985 return XML_ERROR_NO_MEMORY
;
2988 ? XmlInitUnknownEncodingNS
2989 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
2994 unknownEncodingData
= info
.data
;
2995 unknownEncodingRelease
= info
.release
;
2997 return XML_ERROR_NONE
;
3000 if (info
.release
!= NULL
)
3001 info
.release(info
.data
);
3003 return XML_ERROR_UNKNOWN_ENCODING
;
3006 static enum XML_Error PTRCALL
3007 prologInitProcessor(XML_Parser parser
,
3010 const char **nextPtr
)
3012 enum XML_Error result
= initializeEncoding(parser
);
3013 if (result
!= XML_ERROR_NONE
)
3015 processor
= prologProcessor
;
3016 return prologProcessor(parser
, s
, end
, nextPtr
);
3021 static enum XML_Error PTRCALL
3022 externalParEntInitProcessor(XML_Parser parser
,
3025 const char **nextPtr
)
3027 enum XML_Error result
= initializeEncoding(parser
);
3028 if (result
!= XML_ERROR_NONE
)
3031 /* we know now that XML_Parse(Buffer) has been called,
3032 so we consider the external parameter entity read */
3033 _dtd
->paramEntityRead
= XML_TRUE
;
3035 if (prologState
.inEntityValue
) {
3036 processor
= entityValueInitProcessor
;
3037 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3040 processor
= externalParEntProcessor
;
3041 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3045 static enum XML_Error PTRCALL
3046 entityValueInitProcessor(XML_Parser parser
,
3049 const char **nextPtr
)
3051 const char *start
= s
;
3052 const char *next
= s
;
3056 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3058 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3060 return XML_ERROR_NONE
;
3063 case XML_TOK_INVALID
:
3064 return XML_ERROR_INVALID_TOKEN
;
3065 case XML_TOK_PARTIAL
:
3066 return XML_ERROR_UNCLOSED_TOKEN
;
3067 case XML_TOK_PARTIAL_CHAR
:
3068 return XML_ERROR_PARTIAL_CHAR
;
3069 case XML_TOK_NONE
: /* start == end */
3073 return storeEntityValue(parser
, encoding
, s
, end
);
3075 else if (tok
== XML_TOK_XML_DECL
) {
3076 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
3077 if (result
!= XML_ERROR_NONE
)
3079 if (nextPtr
) *nextPtr
= next
;
3080 /* stop scanning for text declaration - we found one */
3081 processor
= entityValueProcessor
;
3082 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3084 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3085 return XML_TOK_NONE on the next call, which would then cause the
3086 function to exit with *nextPtr set to s - that is what we want for other
3087 tokens, but not for the BOM - we would rather like to skip it;
3088 then, when this routine is entered the next time, XmlPrologTok will
3089 return XML_TOK_INVALID, since the BOM is still in the buffer
3091 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3093 return XML_ERROR_NONE
;
3099 static enum XML_Error PTRCALL
3100 externalParEntProcessor(XML_Parser parser
,
3103 const char **nextPtr
)
3105 const char *start
= s
;
3106 const char *next
= s
;
3109 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3111 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3113 return XML_ERROR_NONE
;
3116 case XML_TOK_INVALID
:
3117 return XML_ERROR_INVALID_TOKEN
;
3118 case XML_TOK_PARTIAL
:
3119 return XML_ERROR_UNCLOSED_TOKEN
;
3120 case XML_TOK_PARTIAL_CHAR
:
3121 return XML_ERROR_PARTIAL_CHAR
;
3122 case XML_TOK_NONE
: /* start == end */
3127 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3128 However, when parsing an external subset, doProlog will not accept a BOM
3129 as valid, and report a syntax error, so we have to skip the BOM
3131 else if (tok
== XML_TOK_BOM
) {
3133 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3136 processor
= prologProcessor
;
3137 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3140 static enum XML_Error PTRCALL
3141 entityValueProcessor(XML_Parser parser
,
3144 const char **nextPtr
)
3146 const char *start
= s
;
3147 const char *next
= s
;
3148 const ENCODING
*enc
= encoding
;
3152 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3154 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3156 return XML_ERROR_NONE
;
3159 case XML_TOK_INVALID
:
3160 return XML_ERROR_INVALID_TOKEN
;
3161 case XML_TOK_PARTIAL
:
3162 return XML_ERROR_UNCLOSED_TOKEN
;
3163 case XML_TOK_PARTIAL_CHAR
:
3164 return XML_ERROR_PARTIAL_CHAR
;
3165 case XML_TOK_NONE
: /* start == end */
3169 return storeEntityValue(parser
, enc
, s
, end
);
3175 #endif /* XML_DTD */
3177 static enum XML_Error PTRCALL
3178 prologProcessor(XML_Parser parser
,
3181 const char **nextPtr
)
3183 const char *next
= s
;
3184 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3185 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3188 static enum XML_Error
3189 doProlog(XML_Parser parser
,
3190 const ENCODING
*enc
,
3195 const char **nextPtr
)
3198 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3199 #endif /* XML_DTD */
3200 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3201 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3202 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3203 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3204 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3205 static const XML_Char atypeENTITIES
[] =
3206 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3207 static const XML_Char atypeNMTOKEN
[] = {
3208 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3209 static const XML_Char atypeNMTOKENS
[] = {
3210 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3211 static const XML_Char notationPrefix
[] = {
3212 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3213 static const XML_Char enumValueSep
[] = { '|', '\0' };
3214 static const XML_Char enumValueStart
[] = { '(', '\0' };
3216 DTD
* const dtd
= _dtd
; /* save one level of indirection */
3218 const char **eventPP
;
3219 const char **eventEndPP
;
3220 enum XML_Content_Quant quant
;
3222 if (enc
== encoding
) {
3223 eventPP
= &eventPtr
;
3224 eventEndPP
= &eventEndPtr
;
3227 eventPP
= &(openInternalEntities
->internalEventPtr
);
3228 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3232 XML_Bool handleDefault
= XML_TRUE
;
3236 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3238 return XML_ERROR_NONE
;
3241 case XML_TOK_INVALID
:
3243 return XML_ERROR_INVALID_TOKEN
;
3244 case XML_TOK_PARTIAL
:
3245 return XML_ERROR_UNCLOSED_TOKEN
;
3246 case XML_TOK_PARTIAL_CHAR
:
3247 return XML_ERROR_PARTIAL_CHAR
;
3250 if (enc
!= encoding
)
3251 return XML_ERROR_NONE
;
3252 if (isParamEntity
) {
3253 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3255 return XML_ERROR_SYNTAX
;
3256 return XML_ERROR_NONE
;
3258 #endif /* XML_DTD */
3259 return XML_ERROR_NO_ELEMENTS
;
3266 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3268 case XML_ROLE_XML_DECL
:
3270 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3271 if (result
!= XML_ERROR_NONE
)
3274 handleDefault
= XML_FALSE
;
3277 case XML_ROLE_DOCTYPE_NAME
:
3278 if (startDoctypeDeclHandler
) {
3279 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3281 return XML_ERROR_NO_MEMORY
;
3282 poolFinish(&tempPool
);
3283 doctypePubid
= NULL
;
3284 handleDefault
= XML_FALSE
;
3286 doctypeSysid
= NULL
; /* always initialize to NULL */
3288 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3289 if (startDoctypeDeclHandler
) {
3290 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3293 poolClear(&tempPool
);
3294 handleDefault
= XML_FALSE
;
3298 case XML_ROLE_TEXT_DECL
:
3300 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3301 if (result
!= XML_ERROR_NONE
)
3304 handleDefault
= XML_FALSE
;
3307 #endif /* XML_DTD */
3308 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3310 useForeignDTD
= XML_FALSE
;
3311 #endif /* XML_DTD */
3312 dtd
->hasParamEntityRefs
= XML_TRUE
;
3313 if (startDoctypeDeclHandler
) {
3314 doctypePubid
= poolStoreString(&tempPool
, enc
,
3315 s
+ enc
->minBytesPerChar
,
3316 next
- enc
->minBytesPerChar
);
3318 return XML_ERROR_NO_MEMORY
;
3319 poolFinish(&tempPool
);
3320 handleDefault
= XML_FALSE
;
3323 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3327 return XML_ERROR_NO_MEMORY
;
3328 #endif /* XML_DTD */
3330 case XML_ROLE_ENTITY_PUBLIC_ID
:
3331 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3332 return XML_ERROR_SYNTAX
;
3333 if (dtd
->keepProcessing
&& declEntity
) {
3334 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3336 s
+ enc
->minBytesPerChar
,
3337 next
- enc
->minBytesPerChar
);
3339 return XML_ERROR_NO_MEMORY
;
3340 normalizePublicId(tem
);
3341 declEntity
->publicId
= tem
;
3342 poolFinish(&dtd
->pool
);
3343 if (entityDeclHandler
)
3344 handleDefault
= XML_FALSE
;
3347 case XML_ROLE_DOCTYPE_CLOSE
:
3349 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3350 doctypeSysid
, doctypePubid
, 0);
3351 poolClear(&tempPool
);
3352 handleDefault
= XML_FALSE
;
3354 /* doctypeSysid will be non-NULL in the case of a previous
3355 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3356 was not set, indicating an external subset
3359 if (doctypeSysid
|| useForeignDTD
) {
3360 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3361 if (paramEntityParsing
&& externalEntityRefHandler
) {
3362 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3366 return XML_ERROR_NO_MEMORY
;
3368 entity
->base
= curBase
;
3369 dtd
->paramEntityRead
= XML_FALSE
;
3370 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3375 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3376 if (dtd
->paramEntityRead
&&
3378 notStandaloneHandler
&&
3379 !notStandaloneHandler(handlerArg
))
3380 return XML_ERROR_NOT_STANDALONE
;
3381 /* end of DTD - no need to update dtd->keepProcessing */
3383 useForeignDTD
= XML_FALSE
;
3385 #endif /* XML_DTD */
3386 if (endDoctypeDeclHandler
) {
3387 endDoctypeDeclHandler(handlerArg
);
3388 handleDefault
= XML_FALSE
;
3391 case XML_ROLE_INSTANCE_START
:
3393 /* if there is no DOCTYPE declaration then now is the
3394 last chance to read the foreign DTD
3396 if (useForeignDTD
) {
3397 dtd
->hasParamEntityRefs
= XML_TRUE
;
3398 if (paramEntityParsing
&& externalEntityRefHandler
) {
3399 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3403 return XML_ERROR_NO_MEMORY
;
3404 entity
->base
= curBase
;
3405 dtd
->paramEntityRead
= XML_FALSE
;
3406 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3411 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3412 if (dtd
->paramEntityRead
&&
3414 notStandaloneHandler
&&
3415 !notStandaloneHandler(handlerArg
))
3416 return XML_ERROR_NOT_STANDALONE
;
3417 /* end of DTD - no need to update dtd->keepProcessing */
3420 #endif /* XML_DTD */
3421 processor
= contentProcessor
;
3422 return contentProcessor(parser
, s
, end
, nextPtr
);
3423 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3424 declElementType
= getElementType(parser
, enc
, s
, next
);
3425 if (!declElementType
)
3426 return XML_ERROR_NO_MEMORY
;
3427 goto checkAttListDeclHandler
;
3428 case XML_ROLE_ATTRIBUTE_NAME
:
3429 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3430 if (!declAttributeId
)
3431 return XML_ERROR_NO_MEMORY
;
3432 declAttributeIsCdata
= XML_FALSE
;
3433 declAttributeType
= NULL
;
3434 declAttributeIsId
= XML_FALSE
;
3435 goto checkAttListDeclHandler
;
3436 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3437 declAttributeIsCdata
= XML_TRUE
;
3438 declAttributeType
= atypeCDATA
;
3439 goto checkAttListDeclHandler
;
3440 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3441 declAttributeIsId
= XML_TRUE
;
3442 declAttributeType
= atypeID
;
3443 goto checkAttListDeclHandler
;
3444 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3445 declAttributeType
= atypeIDREF
;
3446 goto checkAttListDeclHandler
;
3447 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3448 declAttributeType
= atypeIDREFS
;
3449 goto checkAttListDeclHandler
;
3450 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3451 declAttributeType
= atypeENTITY
;
3452 goto checkAttListDeclHandler
;
3453 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3454 declAttributeType
= atypeENTITIES
;
3455 goto checkAttListDeclHandler
;
3456 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3457 declAttributeType
= atypeNMTOKEN
;
3458 goto checkAttListDeclHandler
;
3459 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3460 declAttributeType
= atypeNMTOKENS
;
3461 checkAttListDeclHandler
:
3462 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3463 handleDefault
= XML_FALSE
;
3465 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3466 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3467 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3468 const XML_Char
*prefix
;
3469 if (declAttributeType
) {
3470 prefix
= enumValueSep
;
3473 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3477 if (!poolAppendString(&tempPool
, prefix
))
3478 return XML_ERROR_NO_MEMORY
;
3479 if (!poolAppend(&tempPool
, enc
, s
, next
))
3480 return XML_ERROR_NO_MEMORY
;
3481 declAttributeType
= tempPool
.start
;
3482 handleDefault
= XML_FALSE
;
3485 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3486 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3487 if (dtd
->keepProcessing
) {
3488 if (!defineAttribute(declElementType
, declAttributeId
,
3489 declAttributeIsCdata
, declAttributeIsId
, 0,
3491 return XML_ERROR_NO_MEMORY
;
3492 if (attlistDeclHandler
&& declAttributeType
) {
3493 if (*declAttributeType
== XML_T('(')
3494 || (*declAttributeType
== XML_T('N')
3495 && declAttributeType
[1] == XML_T('O'))) {
3496 /* Enumerated or Notation type */
3497 if (!poolAppendChar(&tempPool
, XML_T(')'))
3498 || !poolAppendChar(&tempPool
, XML_T('\0')))
3499 return XML_ERROR_NO_MEMORY
;
3500 declAttributeType
= tempPool
.start
;
3501 poolFinish(&tempPool
);
3504 attlistDeclHandler(handlerArg
, declElementType
->name
,
3505 declAttributeId
->name
, declAttributeType
,
3506 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3507 poolClear(&tempPool
);
3508 handleDefault
= XML_FALSE
;
3512 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3513 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3514 if (dtd
->keepProcessing
) {
3515 const XML_Char
*attVal
;
3516 enum XML_Error result
3517 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3518 s
+ enc
->minBytesPerChar
,
3519 next
- enc
->minBytesPerChar
,
3523 attVal
= poolStart(&dtd
->pool
);
3524 poolFinish(&dtd
->pool
);
3525 /* ID attributes aren't allowed to have a default */
3526 if (!defineAttribute(declElementType
, declAttributeId
,
3527 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3528 return XML_ERROR_NO_MEMORY
;
3529 if (attlistDeclHandler
&& declAttributeType
) {
3530 if (*declAttributeType
== XML_T('(')
3531 || (*declAttributeType
== XML_T('N')
3532 && declAttributeType
[1] == XML_T('O'))) {
3533 /* Enumerated or Notation type */
3534 if (!poolAppendChar(&tempPool
, XML_T(')'))
3535 || !poolAppendChar(&tempPool
, XML_T('\0')))
3536 return XML_ERROR_NO_MEMORY
;
3537 declAttributeType
= tempPool
.start
;
3538 poolFinish(&tempPool
);
3541 attlistDeclHandler(handlerArg
, declElementType
->name
,
3542 declAttributeId
->name
, declAttributeType
,
3544 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3545 poolClear(&tempPool
);
3546 handleDefault
= XML_FALSE
;
3550 case XML_ROLE_ENTITY_VALUE
:
3551 if (dtd
->keepProcessing
) {
3552 enum XML_Error result
= storeEntityValue(parser
, enc
,
3553 s
+ enc
->minBytesPerChar
,
3554 next
- enc
->minBytesPerChar
);
3556 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3557 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3558 poolFinish(&dtd
->entityValuePool
);
3559 if (entityDeclHandler
) {
3561 entityDeclHandler(handlerArg
,
3563 declEntity
->is_param
,
3564 declEntity
->textPtr
,
3565 declEntity
->textLen
,
3567 handleDefault
= XML_FALSE
;
3571 poolDiscard(&dtd
->entityValuePool
);
3572 if (result
!= XML_ERROR_NONE
)
3576 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3578 useForeignDTD
= XML_FALSE
;
3579 #endif /* XML_DTD */
3580 dtd
->hasParamEntityRefs
= XML_TRUE
;
3581 if (startDoctypeDeclHandler
) {
3582 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3583 s
+ enc
->minBytesPerChar
,
3584 next
- enc
->minBytesPerChar
);
3585 if (doctypeSysid
== NULL
)
3586 return XML_ERROR_NO_MEMORY
;
3587 poolFinish(&tempPool
);
3588 handleDefault
= XML_FALSE
;
3592 /* use externalSubsetName to make doctypeSysid non-NULL
3593 for the case where no startDoctypeDeclHandler is set */
3594 doctypeSysid
= externalSubsetName
;
3595 #endif /* XML_DTD */
3596 if (!dtd
->standalone
3598 && !paramEntityParsing
3599 #endif /* XML_DTD */
3600 && notStandaloneHandler
3601 && !notStandaloneHandler(handlerArg
))
3602 return XML_ERROR_NOT_STANDALONE
;
3607 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3611 return XML_ERROR_NO_MEMORY
;
3612 declEntity
->publicId
= NULL
;
3615 #endif /* XML_DTD */
3616 case XML_ROLE_ENTITY_SYSTEM_ID
:
3617 if (dtd
->keepProcessing
&& declEntity
) {
3618 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
3619 s
+ enc
->minBytesPerChar
,
3620 next
- enc
->minBytesPerChar
);
3621 if (!declEntity
->systemId
)
3622 return XML_ERROR_NO_MEMORY
;
3623 declEntity
->base
= curBase
;
3624 poolFinish(&dtd
->pool
);
3625 if (entityDeclHandler
)
3626 handleDefault
= XML_FALSE
;
3629 case XML_ROLE_ENTITY_COMPLETE
:
3630 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
3632 entityDeclHandler(handlerArg
,
3634 declEntity
->is_param
,
3637 declEntity
->systemId
,
3638 declEntity
->publicId
,
3640 handleDefault
= XML_FALSE
;
3643 case XML_ROLE_ENTITY_NOTATION_NAME
:
3644 if (dtd
->keepProcessing
&& declEntity
) {
3645 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3646 if (!declEntity
->notation
)
3647 return XML_ERROR_NO_MEMORY
;
3648 poolFinish(&dtd
->pool
);
3649 if (unparsedEntityDeclHandler
) {
3651 unparsedEntityDeclHandler(handlerArg
,
3654 declEntity
->systemId
,
3655 declEntity
->publicId
,
3656 declEntity
->notation
);
3657 handleDefault
= XML_FALSE
;
3659 else if (entityDeclHandler
) {
3661 entityDeclHandler(handlerArg
,
3665 declEntity
->systemId
,
3666 declEntity
->publicId
,
3667 declEntity
->notation
);
3668 handleDefault
= XML_FALSE
;
3672 case XML_ROLE_GENERAL_ENTITY_NAME
:
3674 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3678 if (dtd
->keepProcessing
) {
3679 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3681 return XML_ERROR_NO_MEMORY
;
3682 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
3685 return XML_ERROR_NO_MEMORY
;
3686 if (declEntity
->name
!= name
) {
3687 poolDiscard(&dtd
->pool
);
3691 poolFinish(&dtd
->pool
);
3692 declEntity
->publicId
= NULL
;
3693 declEntity
->is_param
= XML_FALSE
;
3694 /* if we have a parent parser or are reading an internal parameter
3695 entity, then the entity declaration is not considered "internal"
3697 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3698 if (entityDeclHandler
)
3699 handleDefault
= XML_FALSE
;
3703 poolDiscard(&dtd
->pool
);
3708 case XML_ROLE_PARAM_ENTITY_NAME
:
3710 if (dtd
->keepProcessing
) {
3711 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
3713 return XML_ERROR_NO_MEMORY
;
3714 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3715 name
, sizeof(ENTITY
));
3717 return XML_ERROR_NO_MEMORY
;
3718 if (declEntity
->name
!= name
) {
3719 poolDiscard(&dtd
->pool
);
3723 poolFinish(&dtd
->pool
);
3724 declEntity
->publicId
= NULL
;
3725 declEntity
->is_param
= XML_TRUE
;
3726 /* if we have a parent parser or are reading an internal parameter
3727 entity, then the entity declaration is not considered "internal"
3729 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3730 if (entityDeclHandler
)
3731 handleDefault
= XML_FALSE
;
3735 poolDiscard(&dtd
->pool
);
3738 #else /* not XML_DTD */
3740 #endif /* XML_DTD */
3742 case XML_ROLE_NOTATION_NAME
:
3743 declNotationPublicId
= NULL
;
3744 declNotationName
= NULL
;
3745 if (notationDeclHandler
) {
3746 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3747 if (!declNotationName
)
3748 return XML_ERROR_NO_MEMORY
;
3749 poolFinish(&tempPool
);
3750 handleDefault
= XML_FALSE
;
3753 case XML_ROLE_NOTATION_PUBLIC_ID
:
3754 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3755 return XML_ERROR_SYNTAX
;
3756 if (declNotationName
) { /* means notationDeclHandler != NULL */
3757 XML_Char
*tem
= poolStoreString(&tempPool
,
3759 s
+ enc
->minBytesPerChar
,
3760 next
- enc
->minBytesPerChar
);
3762 return XML_ERROR_NO_MEMORY
;
3763 normalizePublicId(tem
);
3764 declNotationPublicId
= tem
;
3765 poolFinish(&tempPool
);
3766 handleDefault
= XML_FALSE
;
3769 case XML_ROLE_NOTATION_SYSTEM_ID
:
3770 if (declNotationName
&& notationDeclHandler
) {
3771 const XML_Char
*systemId
3772 = poolStoreString(&tempPool
, enc
,
3773 s
+ enc
->minBytesPerChar
,
3774 next
- enc
->minBytesPerChar
);
3776 return XML_ERROR_NO_MEMORY
;
3778 notationDeclHandler(handlerArg
,
3782 declNotationPublicId
);
3783 handleDefault
= XML_FALSE
;
3785 poolClear(&tempPool
);
3787 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3788 if (declNotationPublicId
&& notationDeclHandler
) {
3790 notationDeclHandler(handlerArg
,
3794 declNotationPublicId
);
3795 handleDefault
= XML_FALSE
;
3797 poolClear(&tempPool
);
3799 case XML_ROLE_ERROR
:
3801 case XML_TOK_PARAM_ENTITY_REF
:
3802 return XML_ERROR_PARAM_ENTITY_REF
;
3803 case XML_TOK_XML_DECL
:
3804 return XML_ERROR_MISPLACED_XML_PI
;
3806 return XML_ERROR_SYNTAX
;
3809 case XML_ROLE_IGNORE_SECT
:
3811 enum XML_Error result
;
3813 reportDefault(parser
, enc
, s
, next
);
3814 handleDefault
= XML_FALSE
;
3815 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3817 processor
= ignoreSectionProcessor
;
3822 #endif /* XML_DTD */
3823 case XML_ROLE_GROUP_OPEN
:
3824 if (prologState
.level
>= groupSize
) {
3826 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
3828 return XML_ERROR_NO_MEMORY
;
3829 groupConnector
= temp
;
3830 if (dtd
->scaffIndex
) {
3831 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
3832 groupSize
* sizeof(int));
3834 return XML_ERROR_NO_MEMORY
;
3835 dtd
->scaffIndex
= temp
;
3839 groupConnector
= (char *)MALLOC(groupSize
= 32);
3840 if (!groupConnector
)
3841 return XML_ERROR_NO_MEMORY
;
3844 groupConnector
[prologState
.level
] = 0;
3845 if (dtd
->in_eldecl
) {
3846 int myindex
= nextScaffoldPart(parser
);
3848 return XML_ERROR_NO_MEMORY
;
3849 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
3851 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3852 if (elementDeclHandler
)
3853 handleDefault
= XML_FALSE
;
3856 case XML_ROLE_GROUP_SEQUENCE
:
3857 if (groupConnector
[prologState
.level
] == '|')
3858 return XML_ERROR_SYNTAX
;
3859 groupConnector
[prologState
.level
] = ',';
3860 if (dtd
->in_eldecl
&& elementDeclHandler
)
3861 handleDefault
= XML_FALSE
;
3863 case XML_ROLE_GROUP_CHOICE
:
3864 if (groupConnector
[prologState
.level
] == ',')
3865 return XML_ERROR_SYNTAX
;
3867 && !groupConnector
[prologState
.level
]
3868 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3871 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
3873 if (elementDeclHandler
)
3874 handleDefault
= XML_FALSE
;
3876 groupConnector
[prologState
.level
] = '|';
3878 case XML_ROLE_PARAM_ENTITY_REF
:
3880 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3881 /* PE references in internal subset are
3882 not allowed within declarations */
3883 if (prologState
.documentEntity
&&
3884 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3885 return XML_ERROR_PARAM_ENTITY_REF
;
3886 dtd
->hasParamEntityRefs
= XML_TRUE
;
3887 if (!paramEntityParsing
)
3888 dtd
->keepProcessing
= dtd
->standalone
;
3890 const XML_Char
*name
;
3892 name
= poolStoreString(&dtd
->pool
, enc
,
3893 s
+ enc
->minBytesPerChar
,
3894 next
- enc
->minBytesPerChar
);
3896 return XML_ERROR_NO_MEMORY
;
3897 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
3898 poolDiscard(&dtd
->pool
);
3899 /* first, determine if a check for an existing declaration is needed;
3900 if yes, check that the entity exists, and that it is internal,
3901 otherwise call the skipped entity handler
3903 if (prologState
.documentEntity
&&
3905 ? !openInternalEntities
3906 : !dtd
->hasParamEntityRefs
)) {
3908 return XML_ERROR_UNDEFINED_ENTITY
;
3909 else if (!entity
->is_internal
)
3910 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3913 dtd
->keepProcessing
= dtd
->standalone
;
3914 /* cannot report skipped entities in declarations */
3915 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3916 skippedEntityHandler(handlerArg
, name
, 1);
3917 handleDefault
= XML_FALSE
;
3922 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3923 if (entity
->textPtr
) {
3924 enum XML_Error result
;
3925 result
= processInternalParamEntity(parser
, entity
);
3926 if (result
!= XML_ERROR_NONE
)
3928 handleDefault
= XML_FALSE
;
3931 if (externalEntityRefHandler
) {
3932 dtd
->paramEntityRead
= XML_FALSE
;
3933 entity
->open
= XML_TRUE
;
3934 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3938 entity
->publicId
)) {
3939 entity
->open
= XML_FALSE
;
3940 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3942 entity
->open
= XML_FALSE
;
3943 handleDefault
= XML_FALSE
;
3944 if (!dtd
->paramEntityRead
) {
3945 dtd
->keepProcessing
= dtd
->standalone
;
3950 dtd
->keepProcessing
= dtd
->standalone
;
3954 #endif /* XML_DTD */
3955 if (!dtd
->standalone
&&
3956 notStandaloneHandler
&&
3957 !notStandaloneHandler(handlerArg
))
3958 return XML_ERROR_NOT_STANDALONE
;
3961 /* Element declaration stuff */
3963 case XML_ROLE_ELEMENT_NAME
:
3964 if (elementDeclHandler
) {
3965 declElementType
= getElementType(parser
, enc
, s
, next
);
3966 if (!declElementType
)
3967 return XML_ERROR_NO_MEMORY
;
3968 dtd
->scaffLevel
= 0;
3969 dtd
->scaffCount
= 0;
3970 dtd
->in_eldecl
= XML_TRUE
;
3971 handleDefault
= XML_FALSE
;
3975 case XML_ROLE_CONTENT_ANY
:
3976 case XML_ROLE_CONTENT_EMPTY
:
3977 if (dtd
->in_eldecl
) {
3978 if (elementDeclHandler
) {
3979 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3981 return XML_ERROR_NO_MEMORY
;
3982 content
->quant
= XML_CQUANT_NONE
;
3983 content
->name
= NULL
;
3984 content
->numchildren
= 0;
3985 content
->children
= NULL
;
3986 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
3990 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
3991 handleDefault
= XML_FALSE
;
3993 dtd
->in_eldecl
= XML_FALSE
;
3997 case XML_ROLE_CONTENT_PCDATA
:
3998 if (dtd
->in_eldecl
) {
3999 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4001 if (elementDeclHandler
)
4002 handleDefault
= XML_FALSE
;
4006 case XML_ROLE_CONTENT_ELEMENT
:
4007 quant
= XML_CQUANT_NONE
;
4008 goto elementContent
;
4009 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4010 quant
= XML_CQUANT_OPT
;
4011 goto elementContent
;
4012 case XML_ROLE_CONTENT_ELEMENT_REP
:
4013 quant
= XML_CQUANT_REP
;
4014 goto elementContent
;
4015 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4016 quant
= XML_CQUANT_PLUS
;
4018 if (dtd
->in_eldecl
) {
4020 const XML_Char
*name
;
4022 const char *nxt
= (quant
== XML_CQUANT_NONE
4024 : next
- enc
->minBytesPerChar
);
4025 int myindex
= nextScaffoldPart(parser
);
4027 return XML_ERROR_NO_MEMORY
;
4028 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4029 dtd
->scaffold
[myindex
].quant
= quant
;
4030 el
= getElementType(parser
, enc
, s
, nxt
);
4032 return XML_ERROR_NO_MEMORY
;
4034 dtd
->scaffold
[myindex
].name
= name
;
4036 for (; name
[nameLen
++]; );
4037 dtd
->contentStringLen
+= nameLen
;
4038 if (elementDeclHandler
)
4039 handleDefault
= XML_FALSE
;
4043 case XML_ROLE_GROUP_CLOSE
:
4044 quant
= XML_CQUANT_NONE
;
4046 case XML_ROLE_GROUP_CLOSE_OPT
:
4047 quant
= XML_CQUANT_OPT
;
4049 case XML_ROLE_GROUP_CLOSE_REP
:
4050 quant
= XML_CQUANT_REP
;
4052 case XML_ROLE_GROUP_CLOSE_PLUS
:
4053 quant
= XML_CQUANT_PLUS
;
4055 if (dtd
->in_eldecl
) {
4056 if (elementDeclHandler
)
4057 handleDefault
= XML_FALSE
;
4059 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4060 if (dtd
->scaffLevel
== 0) {
4061 if (!handleDefault
) {
4062 XML_Content
*model
= build_model(parser
);
4064 return XML_ERROR_NO_MEMORY
;
4066 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4068 dtd
->in_eldecl
= XML_FALSE
;
4069 dtd
->contentStringLen
= 0;
4073 /* End element declaration stuff */
4076 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4077 return XML_ERROR_NO_MEMORY
;
4078 handleDefault
= XML_FALSE
;
4080 case XML_ROLE_COMMENT
:
4081 if (!reportComment(parser
, enc
, s
, next
))
4082 return XML_ERROR_NO_MEMORY
;
4083 handleDefault
= XML_FALSE
;
4088 handleDefault
= XML_FALSE
;
4092 case XML_ROLE_DOCTYPE_NONE
:
4093 if (startDoctypeDeclHandler
)
4094 handleDefault
= XML_FALSE
;
4096 case XML_ROLE_ENTITY_NONE
:
4097 if (dtd
->keepProcessing
&& entityDeclHandler
)
4098 handleDefault
= XML_FALSE
;
4100 case XML_ROLE_NOTATION_NONE
:
4101 if (notationDeclHandler
)
4102 handleDefault
= XML_FALSE
;
4104 case XML_ROLE_ATTLIST_NONE
:
4105 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4106 handleDefault
= XML_FALSE
;
4108 case XML_ROLE_ELEMENT_NONE
:
4109 if (elementDeclHandler
)
4110 handleDefault
= XML_FALSE
;
4112 } /* end of big switch */
4114 if (handleDefault
&& defaultHandler
)
4115 reportDefault(parser
, enc
, s
, next
);
4118 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4123 static enum XML_Error PTRCALL
4124 epilogProcessor(XML_Parser parser
,
4127 const char **nextPtr
)
4129 processor
= epilogProcessor
;
4132 const char *next
= NULL
;
4133 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4136 /* report partial linebreak - it might be the last token */
4137 case -XML_TOK_PROLOG_S
:
4138 if (defaultHandler
) {
4140 reportDefault(parser
, encoding
, s
, next
);
4144 return XML_ERROR_NONE
;
4148 return XML_ERROR_NONE
;
4149 case XML_TOK_PROLOG_S
:
4151 reportDefault(parser
, encoding
, s
, next
);
4154 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4155 return XML_ERROR_NO_MEMORY
;
4157 case XML_TOK_COMMENT
:
4158 if (!reportComment(parser
, encoding
, s
, next
))
4159 return XML_ERROR_NO_MEMORY
;
4161 case XML_TOK_INVALID
:
4163 return XML_ERROR_INVALID_TOKEN
;
4164 case XML_TOK_PARTIAL
:
4167 return XML_ERROR_NONE
;
4169 return XML_ERROR_UNCLOSED_TOKEN
;
4170 case XML_TOK_PARTIAL_CHAR
:
4173 return XML_ERROR_NONE
;
4175 return XML_ERROR_PARTIAL_CHAR
;
4177 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4179 eventPtr
= s
= next
;
4185 static enum XML_Error
4186 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4188 const char *s
, *end
, *next
;
4190 enum XML_Error result
;
4191 OPEN_INTERNAL_ENTITY openEntity
;
4192 entity
->open
= XML_TRUE
;
4193 openEntity
.next
= openInternalEntities
;
4194 openInternalEntities
= &openEntity
;
4195 openEntity
.entity
= entity
;
4196 openEntity
.internalEventPtr
= NULL
;
4197 openEntity
.internalEventEndPtr
= NULL
;
4198 s
= (char *)entity
->textPtr
;
4199 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4200 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4201 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4202 entity
->open
= XML_FALSE
;
4203 openInternalEntities
= openEntity
.next
;
4207 #endif /* XML_DTD */
4209 static enum XML_Error PTRCALL
4210 errorProcessor(XML_Parser parser
,
4213 const char **nextPtr
)
4218 static enum XML_Error
4219 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4220 const char *ptr
, const char *end
,
4223 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4227 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4229 if (!poolAppendChar(pool
, XML_T('\0')))
4230 return XML_ERROR_NO_MEMORY
;
4231 return XML_ERROR_NONE
;
4234 static enum XML_Error
4235 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4236 const char *ptr
, const char *end
,
4239 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4242 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4245 return XML_ERROR_NONE
;
4246 case XML_TOK_INVALID
:
4247 if (enc
== encoding
)
4249 return XML_ERROR_INVALID_TOKEN
;
4250 case XML_TOK_PARTIAL
:
4251 if (enc
== encoding
)
4253 return XML_ERROR_INVALID_TOKEN
;
4254 case XML_TOK_CHAR_REF
:
4256 XML_Char buf
[XML_ENCODE_MAX
];
4258 int n
= XmlCharRefNumber(enc
, ptr
);
4260 if (enc
== encoding
)
4262 return XML_ERROR_BAD_CHAR_REF
;
4265 && n
== 0x20 /* space */
4266 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4268 n
= XmlEncode(n
, (ICHAR
*)buf
);
4270 if (enc
== encoding
)
4272 return XML_ERROR_BAD_CHAR_REF
;
4274 for (i
= 0; i
< n
; i
++) {
4275 if (!poolAppendChar(pool
, buf
[i
]))
4276 return XML_ERROR_NO_MEMORY
;
4280 case XML_TOK_DATA_CHARS
:
4281 if (!poolAppend(pool
, enc
, ptr
, next
))
4282 return XML_ERROR_NO_MEMORY
;
4284 case XML_TOK_TRAILING_CR
:
4285 next
= ptr
+ enc
->minBytesPerChar
;
4287 case XML_TOK_ATTRIBUTE_VALUE_S
:
4288 case XML_TOK_DATA_NEWLINE
:
4289 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4291 if (!poolAppendChar(pool
, 0x20))
4292 return XML_ERROR_NO_MEMORY
;
4294 case XML_TOK_ENTITY_REF
:
4296 const XML_Char
*name
;
4298 char checkEntityDecl
;
4299 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4300 ptr
+ enc
->minBytesPerChar
,
4301 next
- enc
->minBytesPerChar
);
4303 if (!poolAppendChar(pool
, ch
))
4304 return XML_ERROR_NO_MEMORY
;
4307 name
= poolStoreString(&temp2Pool
, enc
,
4308 ptr
+ enc
->minBytesPerChar
,
4309 next
- enc
->minBytesPerChar
);
4311 return XML_ERROR_NO_MEMORY
;
4312 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4313 poolDiscard(&temp2Pool
);
4314 /* first, determine if a check for an existing declaration is needed;
4315 if yes, check that the entity exists, and that it is internal,
4316 otherwise call the default handler (if called from content)
4318 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4321 prologState
.documentEntity
&&
4322 #endif /* XML_DTD */
4324 ? !openInternalEntities
4325 : !dtd
->hasParamEntityRefs
);
4326 else /* if (pool == &tempPool): we are called from content */
4327 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4328 if (checkEntityDecl
) {
4330 return XML_ERROR_UNDEFINED_ENTITY
;
4331 else if (!entity
->is_internal
)
4332 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4335 /* cannot report skipped entity here - see comments on
4336 skippedEntityHandler
4337 if (skippedEntityHandler)
4338 skippedEntityHandler(handlerArg, name, 0);
4340 if ((pool
== &tempPool
) && defaultHandler
)
4341 reportDefault(parser
, enc
, ptr
, next
);
4345 if (enc
== encoding
)
4347 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4349 if (entity
->notation
) {
4350 if (enc
== encoding
)
4352 return XML_ERROR_BINARY_ENTITY_REF
;
4354 if (!entity
->textPtr
) {
4355 if (enc
== encoding
)
4357 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4360 enum XML_Error result
;
4361 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4362 entity
->open
= XML_TRUE
;
4363 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4364 (char *)entity
->textPtr
,
4365 (char *)textEnd
, pool
);
4366 entity
->open
= XML_FALSE
;
4373 if (enc
== encoding
)
4375 return XML_ERROR_UNEXPECTED_STATE
;
4382 static enum XML_Error
4383 storeEntityValue(XML_Parser parser
,
4384 const ENCODING
*enc
,
4385 const char *entityTextPtr
,
4386 const char *entityTextEnd
)
4388 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4389 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4390 enum XML_Error result
= XML_ERROR_NONE
;
4392 int oldInEntityValue
= prologState
.inEntityValue
;
4393 prologState
.inEntityValue
= 1;
4394 #endif /* XML_DTD */
4395 /* never return Null for the value argument in EntityDeclHandler,
4396 since this would indicate an external entity; therefore we
4397 have to make sure that entityValuePool.start is not null */
4398 if (!pool
->blocks
) {
4399 if (!poolGrow(pool
))
4400 return XML_ERROR_NO_MEMORY
;
4405 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4407 case XML_TOK_PARAM_ENTITY_REF
:
4409 if (isParamEntity
|| enc
!= encoding
) {
4410 const XML_Char
*name
;
4412 name
= poolStoreString(&tempPool
, enc
,
4413 entityTextPtr
+ enc
->minBytesPerChar
,
4414 next
- enc
->minBytesPerChar
);
4416 result
= XML_ERROR_NO_MEMORY
;
4417 goto endEntityValue
;
4419 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4420 poolDiscard(&tempPool
);
4422 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4423 /* cannot report skipped entity here - see comments on
4424 skippedEntityHandler
4425 if (skippedEntityHandler)
4426 skippedEntityHandler(handlerArg, name, 0);
4428 dtd
->keepProcessing
= dtd
->standalone
;
4429 goto endEntityValue
;
4432 if (enc
== encoding
)
4433 eventPtr
= entityTextPtr
;
4434 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4435 goto endEntityValue
;
4437 if (entity
->systemId
) {
4438 if (externalEntityRefHandler
) {
4439 dtd
->paramEntityRead
= XML_FALSE
;
4440 entity
->open
= XML_TRUE
;
4441 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4445 entity
->publicId
)) {
4446 entity
->open
= XML_FALSE
;
4447 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4448 goto endEntityValue
;
4450 entity
->open
= XML_FALSE
;
4451 if (!dtd
->paramEntityRead
)
4452 dtd
->keepProcessing
= dtd
->standalone
;
4455 dtd
->keepProcessing
= dtd
->standalone
;
4458 entity
->open
= XML_TRUE
;
4459 result
= storeEntityValue(parser
,
4461 (char *)entity
->textPtr
,
4462 (char *)(entity
->textPtr
4463 + entity
->textLen
));
4464 entity
->open
= XML_FALSE
;
4466 goto endEntityValue
;
4470 #endif /* XML_DTD */
4471 /* in the internal subset, PE references are not legal
4472 within markup declarations, e.g entity values in this case */
4473 eventPtr
= entityTextPtr
;
4474 result
= XML_ERROR_PARAM_ENTITY_REF
;
4475 goto endEntityValue
;
4477 result
= XML_ERROR_NONE
;
4478 goto endEntityValue
;
4479 case XML_TOK_ENTITY_REF
:
4480 case XML_TOK_DATA_CHARS
:
4481 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4482 result
= XML_ERROR_NO_MEMORY
;
4483 goto endEntityValue
;
4486 case XML_TOK_TRAILING_CR
:
4487 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4489 case XML_TOK_DATA_NEWLINE
:
4490 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4491 result
= XML_ERROR_NO_MEMORY
;
4492 goto endEntityValue
;
4494 *(pool
->ptr
)++ = 0xA;
4496 case XML_TOK_CHAR_REF
:
4498 XML_Char buf
[XML_ENCODE_MAX
];
4500 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4502 if (enc
== encoding
)
4503 eventPtr
= entityTextPtr
;
4504 result
= XML_ERROR_BAD_CHAR_REF
;
4505 goto endEntityValue
;
4507 n
= XmlEncode(n
, (ICHAR
*)buf
);
4509 if (enc
== encoding
)
4510 eventPtr
= entityTextPtr
;
4511 result
= XML_ERROR_BAD_CHAR_REF
;
4512 goto endEntityValue
;
4514 for (i
= 0; i
< n
; i
++) {
4515 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4516 result
= XML_ERROR_NO_MEMORY
;
4517 goto endEntityValue
;
4519 *(pool
->ptr
)++ = buf
[i
];
4523 case XML_TOK_PARTIAL
:
4524 if (enc
== encoding
)
4525 eventPtr
= entityTextPtr
;
4526 result
= XML_ERROR_INVALID_TOKEN
;
4527 goto endEntityValue
;
4528 case XML_TOK_INVALID
:
4529 if (enc
== encoding
)
4531 result
= XML_ERROR_INVALID_TOKEN
;
4532 goto endEntityValue
;
4534 if (enc
== encoding
)
4535 eventPtr
= entityTextPtr
;
4536 result
= XML_ERROR_UNEXPECTED_STATE
;
4537 goto endEntityValue
;
4539 entityTextPtr
= next
;
4543 prologState
.inEntityValue
= oldInEntityValue
;
4544 #endif /* XML_DTD */
4548 static void FASTCALL
4549 normalizeLines(XML_Char
*s
)
4553 if (*s
== XML_T('\0'))
4572 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4573 const char *start
, const char *end
)
4575 const XML_Char
*target
;
4578 if (!processingInstructionHandler
) {
4580 reportDefault(parser
, enc
, start
, end
);
4583 start
+= enc
->minBytesPerChar
* 2;
4584 tem
= start
+ XmlNameLength(enc
, start
);
4585 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4588 poolFinish(&tempPool
);
4589 data
= poolStoreString(&tempPool
, enc
,
4591 end
- enc
->minBytesPerChar
*2);
4594 normalizeLines(data
);
4595 processingInstructionHandler(handlerArg
, target
, data
);
4596 poolClear(&tempPool
);
4601 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4602 const char *start
, const char *end
)
4605 if (!commentHandler
) {
4607 reportDefault(parser
, enc
, start
, end
);
4610 data
= poolStoreString(&tempPool
,
4612 start
+ enc
->minBytesPerChar
* 4,
4613 end
- enc
->minBytesPerChar
* 3);
4616 normalizeLines(data
);
4617 commentHandler(handlerArg
, data
);
4618 poolClear(&tempPool
);
4623 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4624 const char *s
, const char *end
)
4626 if (MUST_CONVERT(enc
, s
)) {
4627 const char **eventPP
;
4628 const char **eventEndPP
;
4629 if (enc
== encoding
) {
4630 eventPP
= &eventPtr
;
4631 eventEndPP
= &eventEndPtr
;
4634 eventPP
= &(openInternalEntities
->internalEventPtr
);
4635 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4638 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4639 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4641 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4646 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4651 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4652 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4654 DEFAULT_ATTRIBUTE
*att
;
4655 if (value
|| isId
) {
4656 /* The handling of default attributes gets messed up if we have
4657 a default which duplicates a non-default. */
4659 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4660 if (attId
== type
->defaultAtts
[i
].id
)
4662 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4663 type
->idAtt
= attId
;
4665 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4666 if (type
->allocDefaultAtts
== 0) {
4667 type
->allocDefaultAtts
= 8;
4668 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
4669 * sizeof(DEFAULT_ATTRIBUTE
));
4670 if (!type
->defaultAtts
)
4674 DEFAULT_ATTRIBUTE
*temp
;
4675 int count
= type
->allocDefaultAtts
* 2;
4676 temp
= (DEFAULT_ATTRIBUTE
*)
4677 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4680 type
->allocDefaultAtts
= count
;
4681 type
->defaultAtts
= temp
;
4684 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4687 att
->isCdata
= isCdata
;
4689 attId
->maybeTokenized
= XML_TRUE
;
4690 type
->nDefaultAtts
+= 1;
4695 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4697 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4698 const XML_Char
*name
;
4699 for (name
= elementType
->name
; *name
; name
++) {
4700 if (*name
== XML_T(':')) {
4703 for (s
= elementType
->name
; s
!= name
; s
++) {
4704 if (!poolAppendChar(&dtd
->pool
, *s
))
4707 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4709 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4713 if (prefix
->name
== poolStart(&dtd
->pool
))
4714 poolFinish(&dtd
->pool
);
4716 poolDiscard(&dtd
->pool
);
4717 elementType
->prefix
= prefix
;
4724 static ATTRIBUTE_ID
*
4725 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4726 const char *start
, const char *end
)
4728 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4730 const XML_Char
*name
;
4731 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4733 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
4737 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4740 if (id
->name
!= name
)
4741 poolDiscard(&dtd
->pool
);
4743 poolFinish(&dtd
->pool
);
4746 else if (name
[0] == XML_T('x')
4747 && name
[1] == XML_T('m')
4748 && name
[2] == XML_T('l')
4749 && name
[3] == XML_T('n')
4750 && name
[4] == XML_T('s')
4751 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4752 if (name
[5] == XML_T('\0'))
4753 id
->prefix
= &dtd
->defaultPrefix
;
4755 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
4756 id
->xmlns
= XML_TRUE
;
4760 for (i
= 0; name
[i
]; i
++) {
4761 if (name
[i
] == XML_T(':')) {
4763 for (j
= 0; j
< i
; j
++) {
4764 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
4767 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
4769 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
4771 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
4772 poolFinish(&dtd
->pool
);
4774 poolDiscard(&dtd
->pool
);
4783 #define CONTEXT_SEP XML_T('\f')
4785 static const XML_Char
*
4786 getContext(XML_Parser parser
)
4788 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4789 HASH_TABLE_ITER iter
;
4790 XML_Bool needSep
= XML_FALSE
;
4792 if (dtd
->defaultPrefix
.binding
) {
4795 if (!poolAppendChar(&tempPool
, XML_T('=')))
4797 len
= dtd
->defaultPrefix
.binding
->uriLen
;
4798 if (namespaceSeparator
!= XML_T('\0'))
4800 for (i
= 0; i
< len
; i
++)
4801 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
4806 hashTableIterInit(&iter
, &(dtd
->prefixes
));
4811 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4814 if (!prefix
->binding
)
4816 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4818 for (s
= prefix
->name
; *s
; s
++)
4819 if (!poolAppendChar(&tempPool
, *s
))
4821 if (!poolAppendChar(&tempPool
, XML_T('=')))
4823 len
= prefix
->binding
->uriLen
;
4824 if (namespaceSeparator
!= XML_T('\0'))
4826 for (i
= 0; i
< len
; i
++)
4827 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4833 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
4836 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4841 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4843 for (s
= e
->name
; *s
; s
++)
4844 if (!poolAppendChar(&tempPool
, *s
))
4849 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4851 return tempPool
.start
;
4855 setContext(XML_Parser parser
, const XML_Char
*context
)
4857 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4858 const XML_Char
*s
= context
;
4860 while (*context
!= XML_T('\0')) {
4861 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4863 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4865 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
4868 if (*s
!= XML_T('\0'))
4871 poolDiscard(&tempPool
);
4873 else if (*s
== XML_T('=')) {
4875 if (poolLength(&tempPool
) == 0)
4876 prefix
= &dtd
->defaultPrefix
;
4878 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4880 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
4884 if (prefix
->name
== poolStart(&tempPool
)) {
4885 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
4889 poolDiscard(&tempPool
);
4891 for (context
= s
+ 1;
4892 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4894 if (!poolAppendChar(&tempPool
, *context
))
4896 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4898 if (addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4899 &inheritedBindings
) != XML_ERROR_NONE
)
4901 poolDiscard(&tempPool
);
4902 if (*context
!= XML_T('\0'))
4907 if (!poolAppendChar(&tempPool
, *s
))
4915 static void FASTCALL
4916 normalizePublicId(XML_Char
*publicId
)
4918 XML_Char
*p
= publicId
;
4920 for (s
= publicId
; *s
; s
++) {
4925 if (p
!= publicId
&& p
[-1] != 0x20)
4932 if (p
!= publicId
&& p
[-1] == 0x20)
4938 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
4940 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
4943 poolInit(&(p
->pool
), ms
);
4945 poolInit(&(p
->entityValuePool
), ms
);
4946 #endif /* XML_DTD */
4947 hashTableInit(&(p
->generalEntities
), ms
);
4948 hashTableInit(&(p
->elementTypes
), ms
);
4949 hashTableInit(&(p
->attributeIds
), ms
);
4950 hashTableInit(&(p
->prefixes
), ms
);
4952 p
->paramEntityRead
= XML_FALSE
;
4953 hashTableInit(&(p
->paramEntities
), ms
);
4954 #endif /* XML_DTD */
4955 p
->defaultPrefix
.name
= NULL
;
4956 p
->defaultPrefix
.binding
= NULL
;
4958 p
->in_eldecl
= XML_FALSE
;
4959 p
->scaffIndex
= NULL
;
4964 p
->contentStringLen
= 0;
4966 p
->keepProcessing
= XML_TRUE
;
4967 p
->hasParamEntityRefs
= XML_FALSE
;
4968 p
->standalone
= XML_FALSE
;
4973 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
4975 HASH_TABLE_ITER iter
;
4976 hashTableIterInit(&iter
, &(p
->elementTypes
));
4978 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4981 if (e
->allocDefaultAtts
!= 0)
4982 ms
->free_fcn(e
->defaultAtts
);
4984 hashTableClear(&(p
->generalEntities
));
4986 p
->paramEntityRead
= XML_FALSE
;
4987 hashTableClear(&(p
->paramEntities
));
4988 #endif /* XML_DTD */
4989 hashTableClear(&(p
->elementTypes
));
4990 hashTableClear(&(p
->attributeIds
));
4991 hashTableClear(&(p
->prefixes
));
4992 poolClear(&(p
->pool
));
4994 poolClear(&(p
->entityValuePool
));
4995 #endif /* XML_DTD */
4996 p
->defaultPrefix
.name
= NULL
;
4997 p
->defaultPrefix
.binding
= NULL
;
4999 p
->in_eldecl
= XML_FALSE
;
5000 if (p
->scaffIndex
) {
5001 ms
->free_fcn(p
->scaffIndex
);
5002 p
->scaffIndex
= NULL
;
5005 ms
->free_fcn(p
->scaffold
);
5011 p
->contentStringLen
= 0;
5013 p
->keepProcessing
= XML_TRUE
;
5014 p
->hasParamEntityRefs
= XML_FALSE
;
5015 p
->standalone
= XML_FALSE
;
5019 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5021 HASH_TABLE_ITER iter
;
5022 hashTableIterInit(&iter
, &(p
->elementTypes
));
5024 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5027 if (e
->allocDefaultAtts
!= 0)
5028 ms
->free_fcn(e
->defaultAtts
);
5030 hashTableDestroy(&(p
->generalEntities
));
5032 hashTableDestroy(&(p
->paramEntities
));
5033 #endif /* XML_DTD */
5034 hashTableDestroy(&(p
->elementTypes
));
5035 hashTableDestroy(&(p
->attributeIds
));
5036 hashTableDestroy(&(p
->prefixes
));
5037 poolDestroy(&(p
->pool
));
5039 poolDestroy(&(p
->entityValuePool
));
5040 #endif /* XML_DTD */
5043 ms
->free_fcn(p
->scaffIndex
);
5045 ms
->free_fcn(p
->scaffold
);
5050 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5051 The new DTD has already been initialized.
5054 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5056 HASH_TABLE_ITER iter
;
5058 /* Copy the prefix table. */
5060 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5062 const XML_Char
*name
;
5063 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5066 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5069 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5073 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5075 /* Copy the attribute id table. */
5079 const XML_Char
*name
;
5080 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5084 /* Remember to allocate the scratch byte before the name. */
5085 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5087 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5091 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5092 sizeof(ATTRIBUTE_ID
));
5095 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5097 newA
->xmlns
= oldA
->xmlns
;
5098 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5099 newA
->prefix
= &newDtd
->defaultPrefix
;
5101 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5102 oldA
->prefix
->name
, 0);
5106 /* Copy the element type table. */
5108 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5113 const XML_Char
*name
;
5114 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5117 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5120 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5121 sizeof(ELEMENT_TYPE
));
5124 if (oldE
->nDefaultAtts
) {
5125 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5126 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5127 if (!newE
->defaultAtts
) {
5133 newE
->idAtt
= (ATTRIBUTE_ID
*)
5134 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5135 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5137 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5138 oldE
->prefix
->name
, 0);
5139 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5140 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5141 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5142 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5143 if (oldE
->defaultAtts
[i
].value
) {
5144 newE
->defaultAtts
[i
].value
5145 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5146 if (!newE
->defaultAtts
[i
].value
)
5150 newE
->defaultAtts
[i
].value
= NULL
;
5154 /* Copy the entity tables. */
5155 if (!copyEntityTable(&(newDtd
->generalEntities
),
5157 &(oldDtd
->generalEntities
)))
5161 if (!copyEntityTable(&(newDtd
->paramEntities
),
5163 &(oldDtd
->paramEntities
)))
5165 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5166 #endif /* XML_DTD */
5168 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5169 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5170 newDtd
->standalone
= oldDtd
->standalone
;
5172 /* Don't want deep copying for scaffolding */
5173 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5174 newDtd
->scaffold
= oldDtd
->scaffold
;
5175 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5176 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5177 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5178 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5184 copyEntityTable(HASH_TABLE
*newTable
,
5185 STRING_POOL
*newPool
,
5186 const HASH_TABLE
*oldTable
)
5188 HASH_TABLE_ITER iter
;
5189 const XML_Char
*cachedOldBase
= NULL
;
5190 const XML_Char
*cachedNewBase
= NULL
;
5192 hashTableIterInit(&iter
, oldTable
);
5196 const XML_Char
*name
;
5197 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5200 name
= poolCopyString(newPool
, oldE
->name
);
5203 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5206 if (oldE
->systemId
) {
5207 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5210 newE
->systemId
= tem
;
5212 if (oldE
->base
== cachedOldBase
)
5213 newE
->base
= cachedNewBase
;
5215 cachedOldBase
= oldE
->base
;
5216 tem
= poolCopyString(newPool
, cachedOldBase
);
5219 cachedNewBase
= newE
->base
= tem
;
5222 if (oldE
->publicId
) {
5223 tem
= poolCopyString(newPool
, oldE
->publicId
);
5226 newE
->publicId
= tem
;
5230 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5234 newE
->textPtr
= tem
;
5235 newE
->textLen
= oldE
->textLen
;
5237 if (oldE
->notation
) {
5238 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5241 newE
->notation
= tem
;
5243 newE
->is_param
= oldE
->is_param
;
5244 newE
->is_internal
= oldE
->is_internal
;
5249 #define INIT_SIZE 64
5252 keyeq(KEY s1
, KEY s2
)
5254 for (; *s1
== *s2
; s1
++, s2
++)
5260 static unsigned long FASTCALL
5263 unsigned long h
= 0;
5265 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5270 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5273 if (table
->size
== 0) {
5278 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5279 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5282 memset(table
->v
, 0, tsize
);
5283 table
->size
= INIT_SIZE
;
5284 table
->usedLim
= INIT_SIZE
/ 2;
5285 i
= hash(name
) & (table
->size
- 1);
5288 unsigned long h
= hash(name
);
5289 for (i
= h
& (table
->size
- 1);
5291 i
== 0 ? i
= table
->size
- 1 : --i
) {
5292 if (keyeq(name
, table
->v
[i
]->name
))
5297 if (table
->used
== table
->usedLim
) {
5298 /* check for overflow */
5299 size_t newSize
= table
->size
* 2;
5300 size_t tsize
= newSize
* sizeof(NAMED
*);
5301 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5304 memset(newV
, 0, tsize
);
5305 for (i
= 0; i
< table
->size
; i
++)
5308 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5310 j
== 0 ? j
= newSize
- 1 : --j
)
5312 newV
[j
] = table
->v
[i
];
5314 table
->mem
->free_fcn(table
->v
);
5316 table
->size
= newSize
;
5317 table
->usedLim
= newSize
/2;
5318 for (i
= h
& (table
->size
- 1);
5320 i
== 0 ? i
= table
->size
- 1 : --i
)
5324 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5327 memset(table
->v
[i
], 0, createSize
);
5328 table
->v
[i
]->name
= name
;
5333 static void FASTCALL
5334 hashTableClear(HASH_TABLE
*table
)
5337 for (i
= 0; i
< table
->size
; i
++) {
5338 NAMED
*p
= table
->v
[i
];
5340 table
->mem
->free_fcn(p
);
5344 table
->usedLim
= table
->size
/ 2;
5348 static void FASTCALL
5349 hashTableDestroy(HASH_TABLE
*table
)
5352 for (i
= 0; i
< table
->size
; i
++) {
5353 NAMED
*p
= table
->v
[i
];
5355 table
->mem
->free_fcn(p
);
5358 table
->mem
->free_fcn(table
->v
);
5361 static void FASTCALL
5362 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5371 static void FASTCALL
5372 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5375 iter
->end
= iter
->p
+ table
->size
;
5378 static NAMED
* FASTCALL
5379 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5381 while (iter
->p
!= iter
->end
) {
5382 NAMED
*tem
= *(iter
->p
)++;
5389 static void FASTCALL
5390 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5392 pool
->blocks
= NULL
;
5393 pool
->freeBlocks
= NULL
;
5400 static void FASTCALL
5401 poolClear(STRING_POOL
*pool
)
5403 if (!pool
->freeBlocks
)
5404 pool
->freeBlocks
= pool
->blocks
;
5406 BLOCK
*p
= pool
->blocks
;
5408 BLOCK
*tem
= p
->next
;
5409 p
->next
= pool
->freeBlocks
;
5410 pool
->freeBlocks
= p
;
5414 pool
->blocks
= NULL
;
5420 static void FASTCALL
5421 poolDestroy(STRING_POOL
*pool
)
5423 BLOCK
*p
= pool
->blocks
;
5425 BLOCK
*tem
= p
->next
;
5426 pool
->mem
->free_fcn(p
);
5429 p
= pool
->freeBlocks
;
5431 BLOCK
*tem
= p
->next
;
5432 pool
->mem
->free_fcn(p
);
5438 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5439 const char *ptr
, const char *end
)
5441 if (!pool
->ptr
&& !poolGrow(pool
))
5444 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5447 if (!poolGrow(pool
))
5453 static const XML_Char
* FASTCALL
5454 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5457 if (!poolAppendChar(pool
, *s
))
5465 static const XML_Char
*
5466 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5468 if (!pool
->ptr
&& !poolGrow(pool
))
5470 for (; n
> 0; --n
, s
++) {
5471 if (!poolAppendChar(pool
, *s
))
5479 static const XML_Char
* FASTCALL
5480 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5483 if (!poolAppendChar(pool
, *s
))
5491 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5492 const char *ptr
, const char *end
)
5494 if (!poolAppend(pool
, enc
, ptr
, end
))
5496 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5502 static XML_Bool FASTCALL
5503 poolGrow(STRING_POOL
*pool
)
5505 if (pool
->freeBlocks
) {
5506 if (pool
->start
== 0) {
5507 pool
->blocks
= pool
->freeBlocks
;
5508 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5509 pool
->blocks
->next
= NULL
;
5510 pool
->start
= pool
->blocks
->s
;
5511 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5512 pool
->ptr
= pool
->start
;
5515 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
5516 BLOCK
*tem
= pool
->freeBlocks
->next
;
5517 pool
->freeBlocks
->next
= pool
->blocks
;
5518 pool
->blocks
= pool
->freeBlocks
;
5519 pool
->freeBlocks
= tem
;
5520 memcpy(pool
->blocks
->s
, pool
->start
,
5521 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
5522 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5523 pool
->start
= pool
->blocks
->s
;
5524 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5528 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5529 int blockSize
= (pool
->end
- pool
->start
)*2;
5530 pool
->blocks
= (BLOCK
*)
5531 pool
->mem
->realloc_fcn(pool
->blocks
,
5533 + blockSize
* sizeof(XML_Char
)));
5534 if (pool
->blocks
== NULL
)
5536 pool
->blocks
->size
= blockSize
;
5537 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5538 pool
->start
= pool
->blocks
->s
;
5539 pool
->end
= pool
->start
+ blockSize
;
5543 int blockSize
= pool
->end
- pool
->start
;
5544 if (blockSize
< INIT_BLOCK_SIZE
)
5545 blockSize
= INIT_BLOCK_SIZE
;
5548 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5549 + blockSize
* sizeof(XML_Char
));
5552 tem
->size
= blockSize
;
5553 tem
->next
= pool
->blocks
;
5555 if (pool
->ptr
!= pool
->start
)
5556 memcpy(tem
->s
, pool
->start
,
5557 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5558 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5559 pool
->start
= tem
->s
;
5560 pool
->end
= tem
->s
+ blockSize
;
5566 nextScaffoldPart(XML_Parser parser
)
5568 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5569 CONTENT_SCAFFOLD
* me
;
5572 if (!dtd
->scaffIndex
) {
5573 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
5574 if (!dtd
->scaffIndex
)
5576 dtd
->scaffIndex
[0] = 0;
5579 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
5580 CONTENT_SCAFFOLD
*temp
;
5581 if (dtd
->scaffold
) {
5582 temp
= (CONTENT_SCAFFOLD
*)
5583 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5586 dtd
->scaffSize
*= 2;
5589 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
5590 * sizeof(CONTENT_SCAFFOLD
));
5593 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5595 dtd
->scaffold
= temp
;
5597 next
= dtd
->scaffCount
++;
5598 me
= &dtd
->scaffold
[next
];
5599 if (dtd
->scaffLevel
) {
5600 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
5601 if (parent
->lastchild
) {
5602 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
5604 if (!parent
->childcnt
)
5605 parent
->firstchild
= next
;
5606 parent
->lastchild
= next
;
5609 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5614 build_node(XML_Parser parser
,
5617 XML_Content
**contpos
,
5620 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5621 dest
->type
= dtd
->scaffold
[src_node
].type
;
5622 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
5623 if (dest
->type
== XML_CTYPE_NAME
) {
5624 const XML_Char
*src
;
5625 dest
->name
= *strpos
;
5626 src
= dtd
->scaffold
[src_node
].name
;
5628 *(*strpos
)++ = *src
;
5633 dest
->numchildren
= 0;
5634 dest
->children
= NULL
;
5639 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
5640 dest
->children
= *contpos
;
5641 *contpos
+= dest
->numchildren
;
5642 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
5643 i
< dest
->numchildren
;
5644 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
5645 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5651 static XML_Content
*
5652 build_model (XML_Parser parser
)
5654 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5658 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
5659 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
5661 ret
= (XML_Content
*)MALLOC(allocsize
);
5665 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
5668 build_node(parser
, 0, ret
, &cpos
, &str
);
5672 static ELEMENT_TYPE
*
5673 getElementType(XML_Parser parser
,
5674 const ENCODING
*enc
,
5678 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5679 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
5684 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5687 if (ret
->name
!= name
)
5688 poolDiscard(&dtd
->pool
);
5690 poolFinish(&dtd
->pool
);
5691 if (!setElementTypePrefix(parser
, ret
))