1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
5 #define XML_BUILDING_EXPAT 1
7 #ifdef COMPILED_FROM_DSP
9 #elif defined(MACOS_CLASSIC)
10 #include "macconfig.h"
11 #elif defined(__amigaos4__)
12 #include "amigaconfig.h"
13 #elif defined(HAVE_EXPAT_CONFIG_H)
14 #include <expat_config.h>
15 #endif /* ndef COMPILED_FROM_DSP */
18 #include <string.h> /* memset(), memcpy() */
24 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
25 #define XmlConvert XmlUtf16Convert
26 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
27 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
28 #define XmlEncode XmlUtf16Encode
29 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
30 typedef unsigned short ICHAR
;
32 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
33 #define XmlConvert XmlUtf8Convert
34 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
35 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
36 #define XmlEncode XmlUtf8Encode
37 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
44 #define XmlInitEncodingNS XmlInitEncoding
45 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
46 #undef XmlGetInternalEncodingNS
47 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
48 #define XmlParseXmlDeclNS XmlParseXmlDecl
54 #ifdef XML_UNICODE_WCHAR_T
55 #define XML_T(x) (const wchar_t)x
56 #define XML_L(x) L ## x
58 #define XML_T(x) (const unsigned short)x
69 /* Round up n to be a multiple of sz, where sz is a power of 2. */
70 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
72 /* Handle the case where memmove() doesn't exist. */
75 #define memmove(d,s,l) bcopy((s),(d),(l))
77 #error memmove does not exist on this platform, nor is a substitute available
78 #endif /* HAVE_BCOPY */
79 #endif /* HAVE_MEMMOVE */
85 typedef const XML_Char
*KEY
;
96 const XML_Memory_Handling_Suite
*mem
;
99 /* Basic character hash algorithm, taken from Python's string hash:
100 h = h * 1000003 ^ character, the constant being a prime number.
104 #define CHAR_HASH(h, c) \
105 (((h) * 0xF4243) ^ (unsigned short)(c))
107 #define CHAR_HASH(h, c) \
108 (((h) * 0xF4243) ^ (unsigned char)(c))
111 /* For probing (after a collision) we need a step size relative prime
112 to the hash table size, which is a power of 2. We use double-hashing,
113 since we can calculate a second hash value cheaply by taking those bits
114 of the first hash value that were discarded (masked out) when the table
115 index was calculated: index = hash & mask, where mask = table->size - 1.
116 We limit the maximum step size to table->size / 4 (mask >> 2) and make
117 it odd, since odd numbers are always relative prime to a power of 2.
119 #define SECOND_HASH(hash, mask, power) \
120 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
121 #define PROBE_STEP(hash, mask, power) \
122 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
129 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
130 #define INIT_DATA_BUF_SIZE 1024
131 #define INIT_ATTS_SIZE 16
132 #define INIT_ATTS_VERSION 0xFFFFFFFF
133 #define INIT_BLOCK_SIZE 1024
134 #define INIT_BUFFER_SIZE 1024
136 #define EXPAND_SPARE 24
138 typedef struct binding
{
139 struct prefix
*prefix
;
140 struct binding
*nextTagBinding
;
141 struct binding
*prevPrefixBinding
;
142 const struct attribute_id
*attId
;
148 typedef struct prefix
{
149 const XML_Char
*name
;
155 const XML_Char
*localPart
;
156 const XML_Char
*prefix
;
162 /* TAG represents an open element.
163 The name of the element is stored in both the document and API
164 encodings. The memory buffer 'buf' is a separately-allocated
165 memory area which stores the name. During the XML_Parse()/
166 XMLParseBuffer() when the element is open, the memory for the 'raw'
167 version of the name (in the document encoding) is shared with the
168 document buffer. If the element is open across calls to
169 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
170 contain the 'raw' name as well.
172 A parser re-uses these structures, maintaining a list of allocated
173 TAG objects in a free list.
176 struct tag
*parent
; /* parent of this element */
177 const char *rawName
; /* tagName in the original encoding */
179 TAG_NAME name
; /* tagName in the API encoding */
180 char *buf
; /* buffer for name components */
181 char *bufEnd
; /* end of the buffer */
186 const XML_Char
*name
;
187 const XML_Char
*textPtr
;
188 int textLen
; /* length in XML_Chars */
189 int processed
; /* # of processed bytes - when suspended */
190 const XML_Char
*systemId
;
191 const XML_Char
*base
;
192 const XML_Char
*publicId
;
193 const XML_Char
*notation
;
196 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
200 enum XML_Content_Type type
;
201 enum XML_Content_Quant quant
;
202 const XML_Char
* name
;
209 #define INIT_SCAFFOLD_ELEMENTS 32
211 typedef struct block
{
223 const XML_Memory_Handling_Suite
*mem
;
226 /* The XML_Char before the name is used to determine whether
227 an attribute has been specified. */
228 typedef struct attribute_id
{
231 XML_Bool maybeTokenized
;
236 const ATTRIBUTE_ID
*id
;
238 const XML_Char
*value
;
242 unsigned long version
;
244 const XML_Char
*uriName
;
248 const XML_Char
*name
;
250 const ATTRIBUTE_ID
*idAtt
;
252 int allocDefaultAtts
;
253 DEFAULT_ATTRIBUTE
*defaultAtts
;
257 HASH_TABLE generalEntities
;
258 HASH_TABLE elementTypes
;
259 HASH_TABLE attributeIds
;
262 STRING_POOL entityValuePool
;
263 /* false once a parameter entity reference has been skipped */
264 XML_Bool keepProcessing
;
265 /* true once an internal or external PE reference has been encountered;
266 this includes the reference to an external subset */
267 XML_Bool hasParamEntityRefs
;
270 /* indicates if external PE has been read */
271 XML_Bool paramEntityRead
;
272 HASH_TABLE paramEntities
;
274 PREFIX defaultPrefix
;
275 /* === scaffolding for building content model === */
277 CONTENT_SCAFFOLD
*scaffold
;
278 unsigned contentStringLen
;
285 typedef struct open_internal_entity
{
286 const char *internalEventPtr
;
287 const char *internalEventEndPtr
;
288 struct open_internal_entity
*next
;
291 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
292 } OPEN_INTERNAL_ENTITY
;
294 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
297 const char **endPtr
);
299 static Processor prologProcessor
;
300 static Processor prologInitProcessor
;
301 static Processor contentProcessor
;
302 static Processor cdataSectionProcessor
;
304 static Processor ignoreSectionProcessor
;
305 static Processor externalParEntProcessor
;
306 static Processor externalParEntInitProcessor
;
307 static Processor entityValueProcessor
;
308 static Processor entityValueInitProcessor
;
310 static Processor epilogProcessor
;
311 static Processor errorProcessor
;
312 static Processor externalEntityInitProcessor
;
313 static Processor externalEntityInitProcessor2
;
314 static Processor externalEntityInitProcessor3
;
315 static Processor externalEntityContentProcessor
;
316 static Processor internalEntityProcessor
;
318 static enum XML_Error
319 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
320 static enum XML_Error
321 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
322 const char *s
, const char *next
);
323 static enum XML_Error
324 initializeEncoding(XML_Parser parser
);
325 static enum XML_Error
326 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
327 const char *end
, int tok
, const char *next
, const char **nextPtr
,
329 static enum XML_Error
330 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
331 XML_Bool betweenDecl
);
332 static enum XML_Error
333 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
334 const char *start
, const char *end
, const char **endPtr
,
336 static enum XML_Error
337 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
338 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
340 static enum XML_Error
341 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
342 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
345 static enum XML_Error
346 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
347 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
348 static enum XML_Error
349 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
350 const XML_Char
*uri
, BINDING
**bindingsPtr
);
352 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
353 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
354 static enum XML_Error
355 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
356 const char *, const char *, STRING_POOL
*);
357 static enum XML_Error
358 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
359 const char *, const char *, STRING_POOL
*);
360 static ATTRIBUTE_ID
*
361 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
364 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
365 static enum XML_Error
366 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
369 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
370 const char *start
, const char *end
);
372 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
375 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
378 static const XML_Char
* getContext(XML_Parser parser
);
380 setContext(XML_Parser parser
, const XML_Char
*context
);
382 static void FASTCALL
normalizePublicId(XML_Char
*s
);
384 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
385 /* do not call if parentParser != NULL */
386 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
388 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
390 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
392 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
395 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
397 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
398 static void FASTCALL
hashTableClear(HASH_TABLE
*);
399 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
401 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
402 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
405 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
406 static void FASTCALL
poolClear(STRING_POOL
*);
407 static void FASTCALL
poolDestroy(STRING_POOL
*);
409 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
410 const char *ptr
, const char *end
);
412 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
413 const char *ptr
, const char *end
);
414 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
415 static const XML_Char
* FASTCALL
416 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
417 static const XML_Char
*
418 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
419 static const XML_Char
* FASTCALL
420 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
422 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
423 static XML_Content
* build_model(XML_Parser parser
);
424 static ELEMENT_TYPE
*
425 getElementType(XML_Parser parser
, const ENCODING
*enc
,
426 const char *ptr
, const char *end
);
429 parserCreate(const XML_Char
*encodingName
,
430 const XML_Memory_Handling_Suite
*memsuite
,
431 const XML_Char
*nameSep
,
434 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
436 #define poolStart(pool) ((pool)->start)
437 #define poolEnd(pool) ((pool)->ptr)
438 #define poolLength(pool) ((pool)->ptr - (pool)->start)
439 #define poolChop(pool) ((void)--(pool->ptr))
440 #define poolLastChar(pool) (((pool)->ptr)[-1])
441 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
442 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
443 #define poolAppendChar(pool, c) \
444 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
446 : ((*((pool)->ptr)++ = c), 1))
448 struct XML_ParserStruct
{
449 /* The first member must be userData so that the XML_GetUserData
454 const XML_Memory_Handling_Suite m_mem
;
455 /* first character to be parsed */
456 const char *m_bufferPtr
;
457 /* past last character to be parsed */
459 /* allocated end of buffer */
460 const char *m_bufferLim
;
461 XML_Index m_parseEndByteIndex
;
462 const char *m_parseEndPtr
;
464 XML_Char
*m_dataBufEnd
;
465 XML_StartElementHandler m_startElementHandler
;
466 XML_EndElementHandler m_endElementHandler
;
467 XML_CharacterDataHandler m_characterDataHandler
;
468 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
469 XML_CommentHandler m_commentHandler
;
470 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
471 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
472 XML_DefaultHandler m_defaultHandler
;
473 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
474 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
475 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
476 XML_NotationDeclHandler m_notationDeclHandler
;
477 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
478 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
479 XML_NotStandaloneHandler m_notStandaloneHandler
;
480 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
481 XML_Parser m_externalEntityRefHandlerArg
;
482 XML_SkippedEntityHandler m_skippedEntityHandler
;
483 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
484 XML_ElementDeclHandler m_elementDeclHandler
;
485 XML_AttlistDeclHandler m_attlistDeclHandler
;
486 XML_EntityDeclHandler m_entityDeclHandler
;
487 XML_XmlDeclHandler m_xmlDeclHandler
;
488 const ENCODING
*m_encoding
;
489 INIT_ENCODING m_initEncoding
;
490 const ENCODING
*m_internalEncoding
;
491 const XML_Char
*m_protocolEncodingName
;
493 XML_Bool m_ns_triplets
;
494 void *m_unknownEncodingMem
;
495 void *m_unknownEncodingData
;
496 void *m_unknownEncodingHandlerData
;
497 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
498 PROLOG_STATE m_prologState
;
499 Processor
*m_processor
;
500 enum XML_Error m_errorCode
;
501 const char *m_eventPtr
;
502 const char *m_eventEndPtr
;
503 const char *m_positionPtr
;
504 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
505 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
506 XML_Bool m_defaultExpandInternalEntities
;
508 ENTITY
*m_declEntity
;
509 const XML_Char
*m_doctypeName
;
510 const XML_Char
*m_doctypeSysid
;
511 const XML_Char
*m_doctypePubid
;
512 const XML_Char
*m_declAttributeType
;
513 const XML_Char
*m_declNotationName
;
514 const XML_Char
*m_declNotationPublicId
;
515 ELEMENT_TYPE
*m_declElementType
;
516 ATTRIBUTE_ID
*m_declAttributeId
;
517 XML_Bool m_declAttributeIsCdata
;
518 XML_Bool m_declAttributeIsId
;
520 const XML_Char
*m_curBase
;
523 BINDING
*m_inheritedBindings
;
524 BINDING
*m_freeBindingList
;
526 int m_nSpecifiedAtts
;
530 unsigned long m_nsAttsVersion
;
531 unsigned char m_nsAttsPower
;
533 STRING_POOL m_tempPool
;
534 STRING_POOL m_temp2Pool
;
535 char *m_groupConnector
;
536 unsigned int m_groupSize
;
537 XML_Char m_namespaceSeparator
;
538 XML_Parser m_parentParser
;
539 XML_ParsingStatus m_parsingStatus
;
541 XML_Bool m_isParamEntity
;
542 XML_Bool m_useForeignDTD
;
543 enum XML_ParamEntityParsing m_paramEntityParsing
;
547 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
548 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
549 #define FREE(p) (parser->m_mem.free_fcn((p)))
551 #define userData (parser->m_userData)
552 #define handlerArg (parser->m_handlerArg)
553 #define startElementHandler (parser->m_startElementHandler)
554 #define endElementHandler (parser->m_endElementHandler)
555 #define characterDataHandler (parser->m_characterDataHandler)
556 #define processingInstructionHandler \
557 (parser->m_processingInstructionHandler)
558 #define commentHandler (parser->m_commentHandler)
559 #define startCdataSectionHandler \
560 (parser->m_startCdataSectionHandler)
561 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
562 #define defaultHandler (parser->m_defaultHandler)
563 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
564 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
565 #define unparsedEntityDeclHandler \
566 (parser->m_unparsedEntityDeclHandler)
567 #define notationDeclHandler (parser->m_notationDeclHandler)
568 #define startNamespaceDeclHandler \
569 (parser->m_startNamespaceDeclHandler)
570 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
571 #define notStandaloneHandler (parser->m_notStandaloneHandler)
572 #define externalEntityRefHandler \
573 (parser->m_externalEntityRefHandler)
574 #define externalEntityRefHandlerArg \
575 (parser->m_externalEntityRefHandlerArg)
576 #define internalEntityRefHandler \
577 (parser->m_internalEntityRefHandler)
578 #define skippedEntityHandler (parser->m_skippedEntityHandler)
579 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
580 #define elementDeclHandler (parser->m_elementDeclHandler)
581 #define attlistDeclHandler (parser->m_attlistDeclHandler)
582 #define entityDeclHandler (parser->m_entityDeclHandler)
583 #define xmlDeclHandler (parser->m_xmlDeclHandler)
584 #define encoding (parser->m_encoding)
585 #define initEncoding (parser->m_initEncoding)
586 #define internalEncoding (parser->m_internalEncoding)
587 #define unknownEncodingMem (parser->m_unknownEncodingMem)
588 #define unknownEncodingData (parser->m_unknownEncodingData)
589 #define unknownEncodingHandlerData \
590 (parser->m_unknownEncodingHandlerData)
591 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
592 #define protocolEncodingName (parser->m_protocolEncodingName)
593 #define ns (parser->m_ns)
594 #define ns_triplets (parser->m_ns_triplets)
595 #define prologState (parser->m_prologState)
596 #define processor (parser->m_processor)
597 #define errorCode (parser->m_errorCode)
598 #define eventPtr (parser->m_eventPtr)
599 #define eventEndPtr (parser->m_eventEndPtr)
600 #define positionPtr (parser->m_positionPtr)
601 #define position (parser->m_position)
602 #define openInternalEntities (parser->m_openInternalEntities)
603 #define freeInternalEntities (parser->m_freeInternalEntities)
604 #define defaultExpandInternalEntities \
605 (parser->m_defaultExpandInternalEntities)
606 #define tagLevel (parser->m_tagLevel)
607 #define buffer (parser->m_buffer)
608 #define bufferPtr (parser->m_bufferPtr)
609 #define bufferEnd (parser->m_bufferEnd)
610 #define parseEndByteIndex (parser->m_parseEndByteIndex)
611 #define parseEndPtr (parser->m_parseEndPtr)
612 #define bufferLim (parser->m_bufferLim)
613 #define dataBuf (parser->m_dataBuf)
614 #define dataBufEnd (parser->m_dataBufEnd)
615 #define _dtd (parser->m_dtd)
616 #define curBase (parser->m_curBase)
617 #define declEntity (parser->m_declEntity)
618 #define doctypeName (parser->m_doctypeName)
619 #define doctypeSysid (parser->m_doctypeSysid)
620 #define doctypePubid (parser->m_doctypePubid)
621 #define declAttributeType (parser->m_declAttributeType)
622 #define declNotationName (parser->m_declNotationName)
623 #define declNotationPublicId (parser->m_declNotationPublicId)
624 #define declElementType (parser->m_declElementType)
625 #define declAttributeId (parser->m_declAttributeId)
626 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
627 #define declAttributeIsId (parser->m_declAttributeIsId)
628 #define freeTagList (parser->m_freeTagList)
629 #define freeBindingList (parser->m_freeBindingList)
630 #define inheritedBindings (parser->m_inheritedBindings)
631 #define tagStack (parser->m_tagStack)
632 #define atts (parser->m_atts)
633 #define attsSize (parser->m_attsSize)
634 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
635 #define idAttIndex (parser->m_idAttIndex)
636 #define nsAtts (parser->m_nsAtts)
637 #define nsAttsVersion (parser->m_nsAttsVersion)
638 #define nsAttsPower (parser->m_nsAttsPower)
639 #define tempPool (parser->m_tempPool)
640 #define temp2Pool (parser->m_temp2Pool)
641 #define groupConnector (parser->m_groupConnector)
642 #define groupSize (parser->m_groupSize)
643 #define namespaceSeparator (parser->m_namespaceSeparator)
644 #define parentParser (parser->m_parentParser)
645 #define ps_parsing (parser->m_parsingStatus.parsing)
646 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
648 #define isParamEntity (parser->m_isParamEntity)
649 #define useForeignDTD (parser->m_useForeignDTD)
650 #define paramEntityParsing (parser->m_paramEntityParsing)
654 XML_ParserCreate(const XML_Char
*encodingName
)
656 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
660 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
664 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
667 static const XML_Char implicitContext
[] = {
668 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
669 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
670 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
671 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
675 XML_ParserCreate_MM(const XML_Char
*encodingName
,
676 const XML_Memory_Handling_Suite
*memsuite
,
677 const XML_Char
*nameSep
)
679 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
680 if (parser
!= NULL
&& ns
) {
681 /* implicit context only set for root parser, since child
682 parsers (i.e. external entity parsers) will inherit it
684 if (!setContext(parser
, implicitContext
)) {
685 XML_ParserFree(parser
);
693 parserCreate(const XML_Char
*encodingName
,
694 const XML_Memory_Handling_Suite
*memsuite
,
695 const XML_Char
*nameSep
,
701 XML_Memory_Handling_Suite
*mtemp
;
702 parser
= (XML_Parser
)
703 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
704 if (parser
!= NULL
) {
705 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
706 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
707 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
708 mtemp
->free_fcn
= memsuite
->free_fcn
;
712 XML_Memory_Handling_Suite
*mtemp
;
713 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
714 if (parser
!= NULL
) {
715 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
716 mtemp
->malloc_fcn
= malloc
;
717 mtemp
->realloc_fcn
= realloc
;
718 mtemp
->free_fcn
= free
;
728 attsSize
= INIT_ATTS_SIZE
;
729 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
734 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
735 if (dataBuf
== NULL
) {
740 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
745 _dtd
= dtdCreate(&parser
->m_mem
);
754 freeBindingList
= NULL
;
756 freeInternalEntities
= NULL
;
759 groupConnector
= NULL
;
761 unknownEncodingHandler
= NULL
;
762 unknownEncodingHandlerData
= NULL
;
764 namespaceSeparator
= '!';
766 ns_triplets
= XML_FALSE
;
772 poolInit(&tempPool
, &(parser
->m_mem
));
773 poolInit(&temp2Pool
, &(parser
->m_mem
));
774 parserInit(parser
, encodingName
);
776 if (encodingName
&& !protocolEncodingName
) {
777 XML_ParserFree(parser
);
783 internalEncoding
= XmlGetInternalEncodingNS();
784 namespaceSeparator
= *nameSep
;
787 internalEncoding
= XmlGetInternalEncoding();
794 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
796 processor
= prologInitProcessor
;
797 XmlPrologStateInit(&prologState
);
798 protocolEncodingName
= (encodingName
!= NULL
799 ? poolCopyString(&tempPool
, encodingName
)
802 XmlInitEncoding(&initEncoding
, &encoding
, 0);
805 startElementHandler
= NULL
;
806 endElementHandler
= NULL
;
807 characterDataHandler
= NULL
;
808 processingInstructionHandler
= NULL
;
809 commentHandler
= NULL
;
810 startCdataSectionHandler
= NULL
;
811 endCdataSectionHandler
= NULL
;
812 defaultHandler
= NULL
;
813 startDoctypeDeclHandler
= NULL
;
814 endDoctypeDeclHandler
= NULL
;
815 unparsedEntityDeclHandler
= NULL
;
816 notationDeclHandler
= NULL
;
817 startNamespaceDeclHandler
= NULL
;
818 endNamespaceDeclHandler
= NULL
;
819 notStandaloneHandler
= NULL
;
820 externalEntityRefHandler
= NULL
;
821 externalEntityRefHandlerArg
= parser
;
822 skippedEntityHandler
= NULL
;
823 elementDeclHandler
= NULL
;
824 attlistDeclHandler
= NULL
;
825 entityDeclHandler
= NULL
;
826 xmlDeclHandler
= NULL
;
829 parseEndByteIndex
= 0;
831 declElementType
= NULL
;
832 declAttributeId
= NULL
;
837 declAttributeType
= NULL
;
838 declNotationName
= NULL
;
839 declNotationPublicId
= NULL
;
840 declAttributeIsCdata
= XML_FALSE
;
841 declAttributeIsId
= XML_FALSE
;
842 memset(&position
, 0, sizeof(POSITION
));
843 errorCode
= XML_ERROR_NONE
;
847 openInternalEntities
= NULL
;
848 defaultExpandInternalEntities
= XML_TRUE
;
851 inheritedBindings
= NULL
;
853 unknownEncodingMem
= NULL
;
854 unknownEncodingRelease
= NULL
;
855 unknownEncodingData
= NULL
;
857 ps_parsing
= XML_INITIALIZED
;
859 isParamEntity
= XML_FALSE
;
860 useForeignDTD
= XML_FALSE
;
861 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
865 /* moves list of bindings to freeBindingList */
867 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
870 BINDING
*b
= bindings
;
871 bindings
= bindings
->nextTagBinding
;
872 b
->nextTagBinding
= freeBindingList
;
878 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
881 OPEN_INTERNAL_ENTITY
*openEntityList
;
884 /* move tagStack to freeTagList */
889 tag
->parent
= freeTagList
;
890 moveToFreeBindingList(parser
, tag
->bindings
);
891 tag
->bindings
= NULL
;
894 /* move openInternalEntities to freeInternalEntities */
895 openEntityList
= openInternalEntities
;
896 while (openEntityList
) {
897 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
898 openEntityList
= openEntity
->next
;
899 openEntity
->next
= freeInternalEntities
;
900 freeInternalEntities
= openEntity
;
902 moveToFreeBindingList(parser
, inheritedBindings
);
903 FREE(unknownEncodingMem
);
904 if (unknownEncodingRelease
)
905 unknownEncodingRelease(unknownEncodingData
);
906 poolClear(&tempPool
);
907 poolClear(&temp2Pool
);
908 parserInit(parser
, encodingName
);
909 dtdReset(_dtd
, &parser
->m_mem
);
910 return setContext(parser
, implicitContext
);
913 enum XML_Status XMLCALL
914 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
916 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
917 XXX There's no way for the caller to determine which of the
918 XXX possible error cases caused the XML_STATUS_ERROR return.
920 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
921 return XML_STATUS_ERROR
;
922 if (encodingName
== NULL
)
923 protocolEncodingName
= NULL
;
925 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
926 if (!protocolEncodingName
)
927 return XML_STATUS_ERROR
;
929 return XML_STATUS_OK
;
933 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
934 const XML_Char
*context
,
935 const XML_Char
*encodingName
)
937 XML_Parser parser
= oldParser
;
940 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
941 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
942 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
943 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
944 = processingInstructionHandler
;
945 XML_CommentHandler oldCommentHandler
= commentHandler
;
946 XML_StartCdataSectionHandler oldStartCdataSectionHandler
947 = startCdataSectionHandler
;
948 XML_EndCdataSectionHandler oldEndCdataSectionHandler
949 = endCdataSectionHandler
;
950 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
951 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
952 = unparsedEntityDeclHandler
;
953 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
954 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
955 = startNamespaceDeclHandler
;
956 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
957 = endNamespaceDeclHandler
;
958 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
959 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
960 = externalEntityRefHandler
;
961 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
962 XML_UnknownEncodingHandler oldUnknownEncodingHandler
963 = unknownEncodingHandler
;
964 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
965 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
966 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
967 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
968 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
970 void *oldUserData
= userData
;
971 void *oldHandlerArg
= handlerArg
;
972 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
973 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
975 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
976 int oldInEntityValue
= prologState
.inEntityValue
;
978 XML_Bool oldns_triplets
= ns_triplets
;
985 /* Note that the magical uses of the pre-processor to make field
986 access look more like C++ require that `parser' be overwritten
987 here. This makes this function more painful to follow than it
992 *tmp
= namespaceSeparator
;
993 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
996 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1002 startElementHandler
= oldStartElementHandler
;
1003 endElementHandler
= oldEndElementHandler
;
1004 characterDataHandler
= oldCharacterDataHandler
;
1005 processingInstructionHandler
= oldProcessingInstructionHandler
;
1006 commentHandler
= oldCommentHandler
;
1007 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1008 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1009 defaultHandler
= oldDefaultHandler
;
1010 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1011 notationDeclHandler
= oldNotationDeclHandler
;
1012 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1013 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1014 notStandaloneHandler
= oldNotStandaloneHandler
;
1015 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1016 skippedEntityHandler
= oldSkippedEntityHandler
;
1017 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1018 elementDeclHandler
= oldElementDeclHandler
;
1019 attlistDeclHandler
= oldAttlistDeclHandler
;
1020 entityDeclHandler
= oldEntityDeclHandler
;
1021 xmlDeclHandler
= oldXmlDeclHandler
;
1022 declElementType
= oldDeclElementType
;
1023 userData
= oldUserData
;
1024 if (oldUserData
== oldHandlerArg
)
1025 handlerArg
= userData
;
1027 handlerArg
= parser
;
1028 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1029 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1030 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1031 ns_triplets
= oldns_triplets
;
1032 parentParser
= oldParser
;
1034 paramEntityParsing
= oldParamEntityParsing
;
1035 prologState
.inEntityValue
= oldInEntityValue
;
1037 #endif /* XML_DTD */
1038 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1039 || !setContext(parser
, context
)) {
1040 XML_ParserFree(parser
);
1043 processor
= externalEntityInitProcessor
;
1047 /* The DTD instance referenced by _dtd is shared between the document's
1048 root parser and external PE parsers, therefore one does not need to
1049 call setContext. In addition, one also *must* not call setContext,
1050 because this would overwrite existing prefix->binding pointers in
1051 _dtd with ones that get destroyed with the external PE parser.
1052 This would leave those prefixes with dangling pointers.
1054 isParamEntity
= XML_TRUE
;
1055 XmlPrologStateInitExternalEntity(&prologState
);
1056 processor
= externalParEntInitProcessor
;
1058 #endif /* XML_DTD */
1062 static void FASTCALL
1063 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1066 BINDING
*b
= bindings
;
1069 bindings
= b
->nextTagBinding
;
1076 XML_ParserFree(XML_Parser parser
)
1079 OPEN_INTERNAL_ENTITY
*entityList
;
1082 /* free tagStack and freeTagList */
1086 if (tagList
== NULL
) {
1087 if (freeTagList
== NULL
)
1089 tagList
= freeTagList
;
1093 tagList
= tagList
->parent
;
1095 destroyBindings(p
->bindings
, parser
);
1098 /* free openInternalEntities and freeInternalEntities */
1099 entityList
= openInternalEntities
;
1101 OPEN_INTERNAL_ENTITY
*openEntity
;
1102 if (entityList
== NULL
) {
1103 if (freeInternalEntities
== NULL
)
1105 entityList
= freeInternalEntities
;
1106 freeInternalEntities
= NULL
;
1108 openEntity
= entityList
;
1109 entityList
= entityList
->next
;
1113 destroyBindings(freeBindingList
, parser
);
1114 destroyBindings(inheritedBindings
, parser
);
1115 poolDestroy(&tempPool
);
1116 poolDestroy(&temp2Pool
);
1118 /* external parameter entity parsers share the DTD structure
1119 parser->m_dtd with the root parser, so we must not destroy it
1121 if (!isParamEntity
&& _dtd
)
1124 #endif /* XML_DTD */
1125 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1127 FREE(groupConnector
);
1131 FREE(unknownEncodingMem
);
1132 if (unknownEncodingRelease
)
1133 unknownEncodingRelease(unknownEncodingData
);
1138 XML_UseParserAsHandlerArg(XML_Parser parser
)
1140 handlerArg
= parser
;
1143 enum XML_Error XMLCALL
1144 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1147 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1148 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1149 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1150 useForeignDTD
= useDTD
;
1151 return XML_ERROR_NONE
;
1153 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1158 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1160 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1161 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1163 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1167 XML_SetUserData(XML_Parser parser
, void *p
)
1169 if (handlerArg
== userData
)
1170 handlerArg
= userData
= p
;
1175 enum XML_Status XMLCALL
1176 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1179 p
= poolCopyString(&_dtd
->pool
, p
);
1181 return XML_STATUS_ERROR
;
1186 return XML_STATUS_OK
;
1189 const XML_Char
* XMLCALL
1190 XML_GetBase(XML_Parser parser
)
1196 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1198 return nSpecifiedAtts
;
1202 XML_GetIdAttributeIndex(XML_Parser parser
)
1208 XML_SetElementHandler(XML_Parser parser
,
1209 XML_StartElementHandler start
,
1210 XML_EndElementHandler end
)
1212 startElementHandler
= start
;
1213 endElementHandler
= end
;
1217 XML_SetStartElementHandler(XML_Parser parser
,
1218 XML_StartElementHandler start
) {
1219 startElementHandler
= start
;
1223 XML_SetEndElementHandler(XML_Parser parser
,
1224 XML_EndElementHandler end
) {
1225 endElementHandler
= end
;
1229 XML_SetCharacterDataHandler(XML_Parser parser
,
1230 XML_CharacterDataHandler handler
)
1232 characterDataHandler
= handler
;
1236 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1237 XML_ProcessingInstructionHandler handler
)
1239 processingInstructionHandler
= handler
;
1243 XML_SetCommentHandler(XML_Parser parser
,
1244 XML_CommentHandler handler
)
1246 commentHandler
= handler
;
1250 XML_SetCdataSectionHandler(XML_Parser parser
,
1251 XML_StartCdataSectionHandler start
,
1252 XML_EndCdataSectionHandler end
)
1254 startCdataSectionHandler
= start
;
1255 endCdataSectionHandler
= end
;
1259 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1260 XML_StartCdataSectionHandler start
) {
1261 startCdataSectionHandler
= start
;
1265 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1266 XML_EndCdataSectionHandler end
) {
1267 endCdataSectionHandler
= end
;
1271 XML_SetDefaultHandler(XML_Parser parser
,
1272 XML_DefaultHandler handler
)
1274 defaultHandler
= handler
;
1275 defaultExpandInternalEntities
= XML_FALSE
;
1279 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1280 XML_DefaultHandler handler
)
1282 defaultHandler
= handler
;
1283 defaultExpandInternalEntities
= XML_TRUE
;
1287 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1288 XML_StartDoctypeDeclHandler start
,
1289 XML_EndDoctypeDeclHandler end
)
1291 startDoctypeDeclHandler
= start
;
1292 endDoctypeDeclHandler
= end
;
1296 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1297 XML_StartDoctypeDeclHandler start
) {
1298 startDoctypeDeclHandler
= start
;
1302 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1303 XML_EndDoctypeDeclHandler end
) {
1304 endDoctypeDeclHandler
= end
;
1308 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1309 XML_UnparsedEntityDeclHandler handler
)
1311 unparsedEntityDeclHandler
= handler
;
1315 XML_SetNotationDeclHandler(XML_Parser parser
,
1316 XML_NotationDeclHandler handler
)
1318 notationDeclHandler
= handler
;
1322 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1323 XML_StartNamespaceDeclHandler start
,
1324 XML_EndNamespaceDeclHandler end
)
1326 startNamespaceDeclHandler
= start
;
1327 endNamespaceDeclHandler
= end
;
1331 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1332 XML_StartNamespaceDeclHandler start
) {
1333 startNamespaceDeclHandler
= start
;
1337 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1338 XML_EndNamespaceDeclHandler end
) {
1339 endNamespaceDeclHandler
= end
;
1343 XML_SetNotStandaloneHandler(XML_Parser parser
,
1344 XML_NotStandaloneHandler handler
)
1346 notStandaloneHandler
= handler
;
1350 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1351 XML_ExternalEntityRefHandler handler
)
1353 externalEntityRefHandler
= handler
;
1357 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1360 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1362 externalEntityRefHandlerArg
= parser
;
1366 XML_SetSkippedEntityHandler(XML_Parser parser
,
1367 XML_SkippedEntityHandler handler
)
1369 skippedEntityHandler
= handler
;
1373 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1374 XML_UnknownEncodingHandler handler
,
1377 unknownEncodingHandler
= handler
;
1378 unknownEncodingHandlerData
= data
;
1382 XML_SetElementDeclHandler(XML_Parser parser
,
1383 XML_ElementDeclHandler eldecl
)
1385 elementDeclHandler
= eldecl
;
1389 XML_SetAttlistDeclHandler(XML_Parser parser
,
1390 XML_AttlistDeclHandler attdecl
)
1392 attlistDeclHandler
= attdecl
;
1396 XML_SetEntityDeclHandler(XML_Parser parser
,
1397 XML_EntityDeclHandler handler
)
1399 entityDeclHandler
= handler
;
1403 XML_SetXmlDeclHandler(XML_Parser parser
,
1404 XML_XmlDeclHandler handler
) {
1405 xmlDeclHandler
= handler
;
1409 XML_SetParamEntityParsing(XML_Parser parser
,
1410 enum XML_ParamEntityParsing peParsing
)
1412 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1413 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1416 paramEntityParsing
= peParsing
;
1419 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1423 enum XML_Status XMLCALL
1424 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1426 switch (ps_parsing
) {
1428 errorCode
= XML_ERROR_SUSPENDED
;
1429 return XML_STATUS_ERROR
;
1431 errorCode
= XML_ERROR_FINISHED
;
1432 return XML_STATUS_ERROR
;
1434 ps_parsing
= XML_PARSING
;
1438 ps_finalBuffer
= (XML_Bool
)isFinal
;
1440 return XML_STATUS_OK
;
1441 positionPtr
= bufferPtr
;
1442 parseEndPtr
= bufferEnd
;
1444 /* If data are left over from last buffer, and we now know that these
1445 data are the final chunk of input, then we have to check them again
1446 to detect errors based on that fact.
1448 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1450 if (errorCode
== XML_ERROR_NONE
) {
1451 switch (ps_parsing
) {
1453 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1454 positionPtr
= bufferPtr
;
1455 return XML_STATUS_SUSPENDED
;
1456 case XML_INITIALIZED
:
1458 ps_parsing
= XML_FINISHED
;
1461 return XML_STATUS_OK
;
1464 eventEndPtr
= eventPtr
;
1465 processor
= errorProcessor
;
1466 return XML_STATUS_ERROR
;
1468 #ifndef XML_CONTEXT_BYTES
1469 else if (bufferPtr
== bufferEnd
) {
1472 enum XML_Error result
;
1473 parseEndByteIndex
+= len
;
1475 ps_finalBuffer
= (XML_Bool
)isFinal
;
1477 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1479 if (errorCode
!= XML_ERROR_NONE
) {
1480 eventEndPtr
= eventPtr
;
1481 processor
= errorProcessor
;
1482 return XML_STATUS_ERROR
;
1485 switch (ps_parsing
) {
1487 result
= XML_STATUS_SUSPENDED
;
1489 case XML_INITIALIZED
:
1491 result
= XML_STATUS_OK
;
1493 ps_parsing
= XML_FINISHED
;
1499 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1500 nLeftOver
= s
+ len
- end
;
1502 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1503 /* FIXME avoid integer overflow */
1505 temp
= (buffer
== NULL
1506 ? (char *)MALLOC(len
* 2)
1507 : (char *)REALLOC(buffer
, len
* 2));
1509 errorCode
= XML_ERROR_NO_MEMORY
;
1510 return XML_STATUS_ERROR
;
1514 errorCode
= XML_ERROR_NO_MEMORY
;
1515 eventPtr
= eventEndPtr
= NULL
;
1516 processor
= errorProcessor
;
1517 return XML_STATUS_ERROR
;
1519 bufferLim
= buffer
+ len
* 2;
1521 memcpy(buffer
, end
, nLeftOver
);
1524 bufferEnd
= buffer
+ nLeftOver
;
1525 positionPtr
= bufferPtr
;
1526 parseEndPtr
= bufferEnd
;
1527 eventPtr
= bufferPtr
;
1528 eventEndPtr
= bufferPtr
;
1531 #endif /* not defined XML_CONTEXT_BYTES */
1533 void *buff
= XML_GetBuffer(parser
, len
);
1535 return XML_STATUS_ERROR
;
1537 memcpy(buff
, s
, len
);
1538 return XML_ParseBuffer(parser
, len
, isFinal
);
1543 enum XML_Status XMLCALL
1544 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1547 enum XML_Status result
= XML_STATUS_OK
;
1549 switch (ps_parsing
) {
1551 errorCode
= XML_ERROR_SUSPENDED
;
1552 return XML_STATUS_ERROR
;
1554 errorCode
= XML_ERROR_FINISHED
;
1555 return XML_STATUS_ERROR
;
1557 ps_parsing
= XML_PARSING
;
1561 positionPtr
= start
;
1563 parseEndPtr
= bufferEnd
;
1564 parseEndByteIndex
+= len
;
1565 ps_finalBuffer
= (XML_Bool
)isFinal
;
1567 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1569 if (errorCode
!= XML_ERROR_NONE
) {
1570 eventEndPtr
= eventPtr
;
1571 processor
= errorProcessor
;
1572 return XML_STATUS_ERROR
;
1575 switch (ps_parsing
) {
1577 result
= XML_STATUS_SUSPENDED
;
1579 case XML_INITIALIZED
:
1582 ps_parsing
= XML_FINISHED
;
1585 default: ; /* should not happen */
1589 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1590 positionPtr
= bufferPtr
;
1595 XML_GetBuffer(XML_Parser parser
, int len
)
1597 switch (ps_parsing
) {
1599 errorCode
= XML_ERROR_SUSPENDED
;
1602 errorCode
= XML_ERROR_FINISHED
;
1607 if (len
> bufferLim
- bufferEnd
) {
1608 /* FIXME avoid integer overflow */
1609 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1610 #ifdef XML_CONTEXT_BYTES
1611 int keep
= (int)(bufferPtr
- buffer
);
1613 if (keep
> XML_CONTEXT_BYTES
)
1614 keep
= XML_CONTEXT_BYTES
;
1616 #endif /* defined XML_CONTEXT_BYTES */
1617 if (neededSize
<= bufferLim
- buffer
) {
1618 #ifdef XML_CONTEXT_BYTES
1619 if (keep
< bufferPtr
- buffer
) {
1620 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1621 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1622 bufferEnd
-= offset
;
1623 bufferPtr
-= offset
;
1626 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1627 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1629 #endif /* not defined XML_CONTEXT_BYTES */
1633 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1634 if (bufferSize
== 0)
1635 bufferSize
= INIT_BUFFER_SIZE
;
1638 } while (bufferSize
< neededSize
);
1639 newBuf
= (char *)MALLOC(bufferSize
);
1641 errorCode
= XML_ERROR_NO_MEMORY
;
1644 bufferLim
= newBuf
+ bufferSize
;
1645 #ifdef XML_CONTEXT_BYTES
1647 int keep
= (int)(bufferPtr
- buffer
);
1648 if (keep
> XML_CONTEXT_BYTES
)
1649 keep
= XML_CONTEXT_BYTES
;
1650 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1653 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1654 bufferPtr
= buffer
+ keep
;
1657 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1658 bufferPtr
= buffer
= newBuf
;
1662 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1665 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1666 bufferPtr
= buffer
= newBuf
;
1667 #endif /* not defined XML_CONTEXT_BYTES */
1673 enum XML_Status XMLCALL
1674 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1676 switch (ps_parsing
) {
1679 errorCode
= XML_ERROR_SUSPENDED
;
1680 return XML_STATUS_ERROR
;
1682 ps_parsing
= XML_FINISHED
;
1685 errorCode
= XML_ERROR_FINISHED
;
1686 return XML_STATUS_ERROR
;
1690 if (isParamEntity
) {
1691 errorCode
= XML_ERROR_SUSPEND_PE
;
1692 return XML_STATUS_ERROR
;
1695 ps_parsing
= XML_SUSPENDED
;
1698 ps_parsing
= XML_FINISHED
;
1700 return XML_STATUS_OK
;
1703 enum XML_Status XMLCALL
1704 XML_ResumeParser(XML_Parser parser
)
1706 enum XML_Status result
= XML_STATUS_OK
;
1708 if (ps_parsing
!= XML_SUSPENDED
) {
1709 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1710 return XML_STATUS_ERROR
;
1712 ps_parsing
= XML_PARSING
;
1714 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1716 if (errorCode
!= XML_ERROR_NONE
) {
1717 eventEndPtr
= eventPtr
;
1718 processor
= errorProcessor
;
1719 return XML_STATUS_ERROR
;
1722 switch (ps_parsing
) {
1724 result
= XML_STATUS_SUSPENDED
;
1726 case XML_INITIALIZED
:
1728 if (ps_finalBuffer
) {
1729 ps_parsing
= XML_FINISHED
;
1736 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1737 positionPtr
= bufferPtr
;
1742 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1744 assert(status
!= NULL
);
1745 *status
= parser
->m_parsingStatus
;
1748 enum XML_Error XMLCALL
1749 XML_GetErrorCode(XML_Parser parser
)
1755 XML_GetCurrentByteIndex(XML_Parser parser
)
1758 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1763 XML_GetCurrentByteCount(XML_Parser parser
)
1765 if (eventEndPtr
&& eventPtr
)
1766 return (int)(eventEndPtr
- eventPtr
);
1770 const char * XMLCALL
1771 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1773 #ifdef XML_CONTEXT_BYTES
1774 if (eventPtr
&& buffer
) {
1775 *offset
= (int)(eventPtr
- buffer
);
1776 *size
= (int)(bufferEnd
- buffer
);
1779 #endif /* defined XML_CONTEXT_BYTES */
1784 XML_GetCurrentLineNumber(XML_Parser parser
)
1786 if (eventPtr
&& eventPtr
>= positionPtr
) {
1787 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1788 positionPtr
= eventPtr
;
1790 return position
.lineNumber
+ 1;
1794 XML_GetCurrentColumnNumber(XML_Parser parser
)
1796 if (eventPtr
&& eventPtr
>= positionPtr
) {
1797 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1798 positionPtr
= eventPtr
;
1800 return position
.columnNumber
;
1804 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1810 XML_MemMalloc(XML_Parser parser
, size_t size
)
1812 return MALLOC(size
);
1816 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1818 return REALLOC(ptr
, size
);
1822 XML_MemFree(XML_Parser parser
, void *ptr
)
1828 XML_DefaultCurrent(XML_Parser parser
)
1830 if (defaultHandler
) {
1831 if (openInternalEntities
)
1832 reportDefault(parser
,
1834 openInternalEntities
->internalEventPtr
,
1835 openInternalEntities
->internalEventEndPtr
);
1837 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1841 const XML_LChar
* XMLCALL
1842 XML_ErrorString(enum XML_Error code
)
1844 static const XML_LChar
* const message
[] = {
1846 XML_L("out of memory"),
1847 XML_L("syntax error"),
1848 XML_L("no element found"),
1849 XML_L("not well-formed (invalid token)"),
1850 XML_L("unclosed token"),
1851 XML_L("partial character"),
1852 XML_L("mismatched tag"),
1853 XML_L("duplicate attribute"),
1854 XML_L("junk after document element"),
1855 XML_L("illegal parameter entity reference"),
1856 XML_L("undefined entity"),
1857 XML_L("recursive entity reference"),
1858 XML_L("asynchronous entity"),
1859 XML_L("reference to invalid character number"),
1860 XML_L("reference to binary entity"),
1861 XML_L("reference to external entity in attribute"),
1862 XML_L("XML or text declaration not at start of entity"),
1863 XML_L("unknown encoding"),
1864 XML_L("encoding specified in XML declaration is incorrect"),
1865 XML_L("unclosed CDATA section"),
1866 XML_L("error in processing external entity reference"),
1867 XML_L("document is not standalone"),
1868 XML_L("unexpected parser state - please send a bug report"),
1869 XML_L("entity declared in parameter entity"),
1870 XML_L("requested feature requires XML_DTD support in Expat"),
1871 XML_L("cannot change setting once parsing has begun"),
1872 XML_L("unbound prefix"),
1873 XML_L("must not undeclare prefix"),
1874 XML_L("incomplete markup in parameter entity"),
1875 XML_L("XML declaration not well-formed"),
1876 XML_L("text declaration not well-formed"),
1877 XML_L("illegal character(s) in public id"),
1878 XML_L("parser suspended"),
1879 XML_L("parser not suspended"),
1880 XML_L("parsing aborted"),
1881 XML_L("parsing finished"),
1882 XML_L("cannot suspend in external parameter entity"),
1883 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1884 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1885 XML_L("prefix must not be bound to one of the reserved namespace names")
1887 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1888 return message
[code
];
1892 const XML_LChar
* XMLCALL
1893 XML_ExpatVersion(void) {
1895 /* V1 is used to string-ize the version number. However, it would
1896 string-ize the actual version macro *names* unless we get them
1897 substituted before being passed to V1. CPP is defined to expand
1898 a macro, then rescan for more expansions. Thus, we use V2 to expand
1899 the version macros, then CPP will expand the resulting V1() macro
1900 with the correct numerals. */
1901 /* ### I'm assuming cpp is portable in this respect... */
1903 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1904 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1906 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1912 XML_Expat_Version XMLCALL
1913 XML_ExpatVersionInfo(void)
1915 XML_Expat_Version version
;
1917 version
.major
= XML_MAJOR_VERSION
;
1918 version
.minor
= XML_MINOR_VERSION
;
1919 version
.micro
= XML_MICRO_VERSION
;
1924 const XML_Feature
* XMLCALL
1925 XML_GetFeatureList(void)
1927 static const XML_Feature features
[] = {
1928 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1930 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1933 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1935 #ifdef XML_UNICODE_WCHAR_T
1936 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1939 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1941 #ifdef XML_CONTEXT_BYTES
1942 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1946 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1949 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1951 {XML_FEATURE_END
, NULL
, 0}
1957 /* Initially tag->rawName always points into the parse buffer;
1958 for those TAG instances opened while the current parse buffer was
1959 processed, and not yet closed, we need to store tag->rawName in a more
1960 permanent location, since the parse buffer is about to be discarded.
1963 storeRawNames(XML_Parser parser
)
1965 TAG
*tag
= tagStack
;
1968 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1969 char *rawNameBuf
= tag
->buf
+ nameLen
;
1970 /* Stop if already stored. Since tagStack is a stack, we can stop
1971 at the first entry that has already been copied; everything
1972 below it in the stack is already been accounted for in a
1973 previous call to this function.
1975 if (tag
->rawName
== rawNameBuf
)
1977 /* For re-use purposes we need to ensure that the
1978 size of tag->buf is a multiple of sizeof(XML_Char).
1980 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1981 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1982 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1985 /* if tag->name.str points to tag->buf (only when namespace
1986 processing is off) then we have to update it
1988 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1989 tag
->name
.str
= (XML_Char
*)temp
;
1990 /* if tag->name.localPart is set (when namespace processing is on)
1991 then update it as well, since it will always point into tag->buf
1993 if (tag
->name
.localPart
)
1994 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1995 (XML_Char
*)tag
->buf
);
1997 tag
->bufEnd
= temp
+ bufSize
;
1998 rawNameBuf
= temp
+ nameLen
;
2000 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2001 tag
->rawName
= rawNameBuf
;
2007 static enum XML_Error PTRCALL
2008 contentProcessor(XML_Parser parser
,
2011 const char **endPtr
)
2013 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2014 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2015 if (result
== XML_ERROR_NONE
) {
2016 if (!storeRawNames(parser
))
2017 return XML_ERROR_NO_MEMORY
;
2022 static enum XML_Error PTRCALL
2023 externalEntityInitProcessor(XML_Parser parser
,
2026 const char **endPtr
)
2028 enum XML_Error result
= initializeEncoding(parser
);
2029 if (result
!= XML_ERROR_NONE
)
2031 processor
= externalEntityInitProcessor2
;
2032 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2035 static enum XML_Error PTRCALL
2036 externalEntityInitProcessor2(XML_Parser parser
,
2039 const char **endPtr
)
2041 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2042 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2045 /* If we are at the end of the buffer, this would cause the next stage,
2046 i.e. externalEntityInitProcessor3, to pass control directly to
2047 doContent (by detecting XML_TOK_NONE) without processing any xml text
2048 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2050 if (next
== end
&& !ps_finalBuffer
) {
2052 return XML_ERROR_NONE
;
2056 case XML_TOK_PARTIAL
:
2057 if (!ps_finalBuffer
) {
2059 return XML_ERROR_NONE
;
2062 return XML_ERROR_UNCLOSED_TOKEN
;
2063 case XML_TOK_PARTIAL_CHAR
:
2064 if (!ps_finalBuffer
) {
2066 return XML_ERROR_NONE
;
2069 return XML_ERROR_PARTIAL_CHAR
;
2071 processor
= externalEntityInitProcessor3
;
2072 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2075 static enum XML_Error PTRCALL
2076 externalEntityInitProcessor3(XML_Parser parser
,
2079 const char **endPtr
)
2082 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2084 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2088 case XML_TOK_XML_DECL
:
2090 enum XML_Error result
;
2091 result
= processXmlDecl(parser
, 1, start
, next
);
2092 if (result
!= XML_ERROR_NONE
)
2094 switch (ps_parsing
) {
2097 return XML_ERROR_NONE
;
2099 return XML_ERROR_ABORTED
;
2105 case XML_TOK_PARTIAL
:
2106 if (!ps_finalBuffer
) {
2108 return XML_ERROR_NONE
;
2110 return XML_ERROR_UNCLOSED_TOKEN
;
2111 case XML_TOK_PARTIAL_CHAR
:
2112 if (!ps_finalBuffer
) {
2114 return XML_ERROR_NONE
;
2116 return XML_ERROR_PARTIAL_CHAR
;
2118 processor
= externalEntityContentProcessor
;
2120 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2123 static enum XML_Error PTRCALL
2124 externalEntityContentProcessor(XML_Parser parser
,
2127 const char **endPtr
)
2129 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2130 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2131 if (result
== XML_ERROR_NONE
) {
2132 if (!storeRawNames(parser
))
2133 return XML_ERROR_NO_MEMORY
;
2138 static enum XML_Error
2139 doContent(XML_Parser parser
,
2141 const ENCODING
*enc
,
2144 const char **nextPtr
,
2147 /* save one level of indirection */
2148 DTD
* const dtd
= _dtd
;
2150 const char **eventPP
;
2151 const char **eventEndPP
;
2152 if (enc
== encoding
) {
2153 eventPP
= &eventPtr
;
2154 eventEndPP
= &eventEndPtr
;
2157 eventPP
= &(openInternalEntities
->internalEventPtr
);
2158 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2163 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2164 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2167 case XML_TOK_TRAILING_CR
:
2170 return XML_ERROR_NONE
;
2173 if (characterDataHandler
) {
2175 characterDataHandler(handlerArg
, &c
, 1);
2177 else if (defaultHandler
)
2178 reportDefault(parser
, enc
, s
, end
);
2179 /* We are at the end of the final buffer, should we check for
2180 XML_SUSPENDED, XML_FINISHED?
2182 if (startTagLevel
== 0)
2183 return XML_ERROR_NO_ELEMENTS
;
2184 if (tagLevel
!= startTagLevel
)
2185 return XML_ERROR_ASYNC_ENTITY
;
2187 return XML_ERROR_NONE
;
2191 return XML_ERROR_NONE
;
2193 if (startTagLevel
> 0) {
2194 if (tagLevel
!= startTagLevel
)
2195 return XML_ERROR_ASYNC_ENTITY
;
2197 return XML_ERROR_NONE
;
2199 return XML_ERROR_NO_ELEMENTS
;
2200 case XML_TOK_INVALID
:
2202 return XML_ERROR_INVALID_TOKEN
;
2203 case XML_TOK_PARTIAL
:
2206 return XML_ERROR_NONE
;
2208 return XML_ERROR_UNCLOSED_TOKEN
;
2209 case XML_TOK_PARTIAL_CHAR
:
2212 return XML_ERROR_NONE
;
2214 return XML_ERROR_PARTIAL_CHAR
;
2215 case XML_TOK_ENTITY_REF
:
2217 const XML_Char
*name
;
2219 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2220 s
+ enc
->minBytesPerChar
,
2221 next
- enc
->minBytesPerChar
);
2223 if (characterDataHandler
)
2224 characterDataHandler(handlerArg
, &ch
, 1);
2225 else if (defaultHandler
)
2226 reportDefault(parser
, enc
, s
, next
);
2229 name
= poolStoreString(&dtd
->pool
, enc
,
2230 s
+ enc
->minBytesPerChar
,
2231 next
- enc
->minBytesPerChar
);
2233 return XML_ERROR_NO_MEMORY
;
2234 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2235 poolDiscard(&dtd
->pool
);
2236 /* First, determine if a check for an existing declaration is needed;
2237 if yes, check that the entity exists, and that it is internal,
2238 otherwise call the skipped entity or default handler.
2240 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2242 return XML_ERROR_UNDEFINED_ENTITY
;
2243 else if (!entity
->is_internal
)
2244 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2247 if (skippedEntityHandler
)
2248 skippedEntityHandler(handlerArg
, name
, 0);
2249 else if (defaultHandler
)
2250 reportDefault(parser
, enc
, s
, next
);
2254 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2255 if (entity
->notation
)
2256 return XML_ERROR_BINARY_ENTITY_REF
;
2257 if (entity
->textPtr
) {
2258 enum XML_Error result
;
2259 if (!defaultExpandInternalEntities
) {
2260 if (skippedEntityHandler
)
2261 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2262 else if (defaultHandler
)
2263 reportDefault(parser
, enc
, s
, next
);
2266 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2267 if (result
!= XML_ERROR_NONE
)
2270 else if (externalEntityRefHandler
) {
2271 const XML_Char
*context
;
2272 entity
->open
= XML_TRUE
;
2273 context
= getContext(parser
);
2274 entity
->open
= XML_FALSE
;
2276 return XML_ERROR_NO_MEMORY
;
2277 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2282 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2283 poolDiscard(&tempPool
);
2285 else if (defaultHandler
)
2286 reportDefault(parser
, enc
, s
, next
);
2289 case XML_TOK_START_TAG_NO_ATTS
:
2291 case XML_TOK_START_TAG_WITH_ATTS
:
2294 enum XML_Error result
;
2298 freeTagList
= freeTagList
->parent
;
2301 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2303 return XML_ERROR_NO_MEMORY
;
2304 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2307 return XML_ERROR_NO_MEMORY
;
2309 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2311 tag
->bindings
= NULL
;
2312 tag
->parent
= tagStack
;
2314 tag
->name
.localPart
= NULL
;
2315 tag
->name
.prefix
= NULL
;
2316 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2317 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2320 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2321 const char *fromPtr
= tag
->rawName
;
2322 toPtr
= (XML_Char
*)tag
->buf
;
2327 &fromPtr
, rawNameEnd
,
2328 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2329 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2330 if (fromPtr
== rawNameEnd
) {
2331 tag
->name
.strLen
= convLen
;
2334 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2336 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2338 return XML_ERROR_NO_MEMORY
;
2340 tag
->bufEnd
= temp
+ bufSize
;
2341 toPtr
= (XML_Char
*)temp
+ convLen
;
2345 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2346 *toPtr
= XML_T('\0');
2347 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2350 if (startElementHandler
)
2351 startElementHandler(handlerArg
, tag
->name
.str
,
2352 (const XML_Char
**)atts
);
2353 else if (defaultHandler
)
2354 reportDefault(parser
, enc
, s
, next
);
2355 poolClear(&tempPool
);
2358 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2360 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2362 const char *rawName
= s
+ enc
->minBytesPerChar
;
2363 enum XML_Error result
;
2364 BINDING
*bindings
= NULL
;
2365 XML_Bool noElmHandlers
= XML_TRUE
;
2367 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2368 rawName
+ XmlNameLength(enc
, rawName
));
2370 return XML_ERROR_NO_MEMORY
;
2371 poolFinish(&tempPool
);
2372 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2375 poolFinish(&tempPool
);
2376 if (startElementHandler
) {
2377 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2378 noElmHandlers
= XML_FALSE
;
2380 if (endElementHandler
) {
2381 if (startElementHandler
)
2382 *eventPP
= *eventEndPP
;
2383 endElementHandler(handlerArg
, name
.str
);
2384 noElmHandlers
= XML_FALSE
;
2386 if (noElmHandlers
&& defaultHandler
)
2387 reportDefault(parser
, enc
, s
, next
);
2388 poolClear(&tempPool
);
2390 BINDING
*b
= bindings
;
2391 if (endNamespaceDeclHandler
)
2392 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2393 bindings
= bindings
->nextTagBinding
;
2394 b
->nextTagBinding
= freeBindingList
;
2395 freeBindingList
= b
;
2396 b
->prefix
->binding
= b
->prevPrefixBinding
;
2400 return epilogProcessor(parser
, next
, end
, nextPtr
);
2402 case XML_TOK_END_TAG
:
2403 if (tagLevel
== startTagLevel
)
2404 return XML_ERROR_ASYNC_ENTITY
;
2407 const char *rawName
;
2408 TAG
*tag
= tagStack
;
2409 tagStack
= tag
->parent
;
2410 tag
->parent
= freeTagList
;
2412 rawName
= s
+ enc
->minBytesPerChar
*2;
2413 len
= XmlNameLength(enc
, rawName
);
2414 if (len
!= tag
->rawNameLength
2415 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2417 return XML_ERROR_TAG_MISMATCH
;
2420 if (endElementHandler
) {
2421 const XML_Char
*localPart
;
2422 const XML_Char
*prefix
;
2424 localPart
= tag
->name
.localPart
;
2425 if (ns
&& localPart
) {
2426 /* localPart and prefix may have been overwritten in
2427 tag->name.str, since this points to the binding->uri
2428 buffer which gets re-used; so we have to add them again
2430 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2431 /* don't need to check for space - already done in storeAtts() */
2432 while (*localPart
) *uri
++ = *localPart
++;
2433 prefix
= (XML_Char
*)tag
->name
.prefix
;
2434 if (ns_triplets
&& prefix
) {
2435 *uri
++ = namespaceSeparator
;
2436 while (*prefix
) *uri
++ = *prefix
++;
2440 endElementHandler(handlerArg
, tag
->name
.str
);
2442 else if (defaultHandler
)
2443 reportDefault(parser
, enc
, s
, next
);
2444 while (tag
->bindings
) {
2445 BINDING
*b
= tag
->bindings
;
2446 if (endNamespaceDeclHandler
)
2447 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2448 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2449 b
->nextTagBinding
= freeBindingList
;
2450 freeBindingList
= b
;
2451 b
->prefix
->binding
= b
->prevPrefixBinding
;
2454 return epilogProcessor(parser
, next
, end
, nextPtr
);
2457 case XML_TOK_CHAR_REF
:
2459 int n
= XmlCharRefNumber(enc
, s
);
2461 return XML_ERROR_BAD_CHAR_REF
;
2462 if (characterDataHandler
) {
2463 XML_Char buf
[XML_ENCODE_MAX
];
2464 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2466 else if (defaultHandler
)
2467 reportDefault(parser
, enc
, s
, next
);
2470 case XML_TOK_XML_DECL
:
2471 return XML_ERROR_MISPLACED_XML_PI
;
2472 case XML_TOK_DATA_NEWLINE
:
2473 if (characterDataHandler
) {
2475 characterDataHandler(handlerArg
, &c
, 1);
2477 else if (defaultHandler
)
2478 reportDefault(parser
, enc
, s
, next
);
2480 case XML_TOK_CDATA_SECT_OPEN
:
2482 enum XML_Error result
;
2483 if (startCdataSectionHandler
)
2484 startCdataSectionHandler(handlerArg
);
2486 /* Suppose you doing a transformation on a document that involves
2487 changing only the character data. You set up a defaultHandler
2488 and a characterDataHandler. The defaultHandler simply copies
2489 characters through. The characterDataHandler does the
2490 transformation and writes the characters out escaping them as
2491 necessary. This case will fail to work if we leave out the
2492 following two lines (because & and < inside CDATA sections will
2493 be incorrectly escaped).
2495 However, now we have a start/endCdataSectionHandler, so it seems
2496 easier to let the user deal with this.
2498 else if (characterDataHandler
)
2499 characterDataHandler(handlerArg
, dataBuf
, 0);
2501 else if (defaultHandler
)
2502 reportDefault(parser
, enc
, s
, next
);
2503 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2504 if (result
!= XML_ERROR_NONE
)
2507 processor
= cdataSectionProcessor
;
2512 case XML_TOK_TRAILING_RSQB
:
2515 return XML_ERROR_NONE
;
2517 if (characterDataHandler
) {
2518 if (MUST_CONVERT(enc
, s
)) {
2519 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2520 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2521 characterDataHandler(handlerArg
, dataBuf
,
2522 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2525 characterDataHandler(handlerArg
,
2527 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2529 else if (defaultHandler
)
2530 reportDefault(parser
, enc
, s
, end
);
2531 /* We are at the end of the final buffer, should we check for
2532 XML_SUSPENDED, XML_FINISHED?
2534 if (startTagLevel
== 0) {
2536 return XML_ERROR_NO_ELEMENTS
;
2538 if (tagLevel
!= startTagLevel
) {
2540 return XML_ERROR_ASYNC_ENTITY
;
2543 return XML_ERROR_NONE
;
2544 case XML_TOK_DATA_CHARS
:
2545 if (characterDataHandler
) {
2546 if (MUST_CONVERT(enc
, s
)) {
2548 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2549 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2551 characterDataHandler(handlerArg
, dataBuf
,
2552 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2559 characterDataHandler(handlerArg
,
2561 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2563 else if (defaultHandler
)
2564 reportDefault(parser
, enc
, s
, next
);
2567 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2568 return XML_ERROR_NO_MEMORY
;
2570 case XML_TOK_COMMENT
:
2571 if (!reportComment(parser
, enc
, s
, next
))
2572 return XML_ERROR_NO_MEMORY
;
2576 reportDefault(parser
, enc
, s
, next
);
2579 *eventPP
= s
= next
;
2580 switch (ps_parsing
) {
2583 return XML_ERROR_NONE
;
2585 return XML_ERROR_ABORTED
;
2592 /* Precondition: all arguments must be non-NULL;
2594 - normalize attributes
2595 - check attributes for well-formedness
2596 - generate namespace aware attribute names (URI, prefix)
2597 - build list of attributes for startElementHandler
2598 - default attributes
2599 - process namespace declarations (check and report them)
2600 - generate namespace aware element name (URI, prefix)
2602 static enum XML_Error
2603 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2604 const char *attStr
, TAG_NAME
*tagNamePtr
,
2605 BINDING
**bindingsPtr
)
2607 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2608 ELEMENT_TYPE
*elementType
;
2610 const XML_Char
**appAtts
; /* the attribute list for the application */
2618 const XML_Char
*localPart
;
2620 /* lookup the element type name */
2621 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2623 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2625 return XML_ERROR_NO_MEMORY
;
2626 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2627 sizeof(ELEMENT_TYPE
));
2629 return XML_ERROR_NO_MEMORY
;
2630 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2631 return XML_ERROR_NO_MEMORY
;
2633 nDefaultAtts
= elementType
->nDefaultAtts
;
2635 /* get the attributes from the tokenizer */
2636 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2637 if (n
+ nDefaultAtts
> attsSize
) {
2638 int oldAttsSize
= attsSize
;
2640 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2641 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2643 return XML_ERROR_NO_MEMORY
;
2645 if (n
> oldAttsSize
)
2646 XmlGetAttributes(enc
, attStr
, n
, atts
);
2649 appAtts
= (const XML_Char
**)atts
;
2650 for (i
= 0; i
< n
; i
++) {
2651 /* add the name and value to the attribute list */
2652 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2654 + XmlNameLength(enc
, atts
[i
].name
));
2656 return XML_ERROR_NO_MEMORY
;
2657 /* Detect duplicate attributes by their QNames. This does not work when
2658 namespace processing is turned on and different prefixes for the same
2659 namespace are used. For this case we have a check further down.
2661 if ((attId
->name
)[-1]) {
2662 if (enc
== encoding
)
2663 eventPtr
= atts
[i
].name
;
2664 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2666 (attId
->name
)[-1] = 1;
2667 appAtts
[attIndex
++] = attId
->name
;
2668 if (!atts
[i
].normalized
) {
2669 enum XML_Error result
;
2670 XML_Bool isCdata
= XML_TRUE
;
2672 /* figure out whether declared as other than CDATA */
2673 if (attId
->maybeTokenized
) {
2675 for (j
= 0; j
< nDefaultAtts
; j
++) {
2676 if (attId
== elementType
->defaultAtts
[j
].id
) {
2677 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2683 /* normalize the attribute value */
2684 result
= storeAttributeValue(parser
, enc
, isCdata
,
2685 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2689 appAtts
[attIndex
] = poolStart(&tempPool
);
2690 poolFinish(&tempPool
);
2693 /* the value did not need normalizing */
2694 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2696 if (appAtts
[attIndex
] == 0)
2697 return XML_ERROR_NO_MEMORY
;
2698 poolFinish(&tempPool
);
2700 /* handle prefixed attribute names */
2701 if (attId
->prefix
) {
2703 /* deal with namespace declarations here */
2704 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2705 appAtts
[attIndex
], bindingsPtr
);
2711 /* deal with other prefixed names later */
2714 (attId
->name
)[-1] = 2;
2721 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2722 nSpecifiedAtts
= attIndex
;
2723 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2724 for (i
= 0; i
< attIndex
; i
+= 2)
2725 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2733 /* do attribute defaulting */
2734 for (i
= 0; i
< nDefaultAtts
; i
++) {
2735 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2736 if (!(da
->id
->name
)[-1] && da
->value
) {
2737 if (da
->id
->prefix
) {
2738 if (da
->id
->xmlns
) {
2739 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2740 da
->value
, bindingsPtr
);
2745 (da
->id
->name
)[-1] = 2;
2747 appAtts
[attIndex
++] = da
->id
->name
;
2748 appAtts
[attIndex
++] = da
->value
;
2752 (da
->id
->name
)[-1] = 1;
2753 appAtts
[attIndex
++] = da
->id
->name
;
2754 appAtts
[attIndex
++] = da
->value
;
2758 appAtts
[attIndex
] = 0;
2760 /* expand prefixed attribute names, check for duplicates,
2761 and clear flags that say whether attributes were specified */
2764 int j
; /* hash table index */
2765 unsigned long version
= nsAttsVersion
;
2766 int nsAttsSize
= (int)1 << nsAttsPower
;
2767 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2768 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2770 /* hash table size must also be a power of 2 and >= 8 */
2771 while (nPrefixes
>> nsAttsPower
++);
2772 if (nsAttsPower
< 3)
2774 nsAttsSize
= (int)1 << nsAttsPower
;
2775 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2777 return XML_ERROR_NO_MEMORY
;
2779 version
= 0; /* force re-initialization of nsAtts hash table */
2781 /* using a version flag saves us from initializing nsAtts every time */
2782 if (!version
) { /* initialize version flags when version wraps around */
2783 version
= INIT_ATTS_VERSION
;
2784 for (j
= nsAttsSize
; j
!= 0; )
2785 nsAtts
[--j
].version
= version
;
2787 nsAttsVersion
= --version
;
2789 /* expand prefixed names and check for duplicates */
2790 for (; i
< attIndex
; i
+= 2) {
2791 const XML_Char
*s
= appAtts
[i
];
2792 if (s
[-1] == 2) { /* prefixed */
2795 unsigned long uriHash
= 0;
2796 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2797 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2799 return XML_ERROR_NO_MEMORY
;
2800 b
= id
->prefix
->binding
;
2802 return XML_ERROR_UNBOUND_PREFIX
;
2804 /* as we expand the name we also calculate its hash value */
2805 for (j
= 0; j
< b
->uriLen
; j
++) {
2806 const XML_Char c
= b
->uri
[j
];
2807 if (!poolAppendChar(&tempPool
, c
))
2808 return XML_ERROR_NO_MEMORY
;
2809 uriHash
= CHAR_HASH(uriHash
, c
);
2811 while (*s
++ != XML_T(':'))
2813 do { /* copies null terminator */
2814 const XML_Char c
= *s
;
2815 if (!poolAppendChar(&tempPool
, *s
))
2816 return XML_ERROR_NO_MEMORY
;
2817 uriHash
= CHAR_HASH(uriHash
, c
);
2820 { /* Check hash table for duplicate of expanded name (uriName).
2821 Derived from code in lookup(HASH_TABLE *table, ...).
2823 unsigned char step
= 0;
2824 unsigned long mask
= nsAttsSize
- 1;
2825 j
= uriHash
& mask
; /* index into hash table */
2826 while (nsAtts
[j
].version
== version
) {
2827 /* for speed we compare stored hash values first */
2828 if (uriHash
== nsAtts
[j
].hash
) {
2829 const XML_Char
*s1
= poolStart(&tempPool
);
2830 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2831 /* s1 is null terminated, but not s2 */
2832 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2834 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2837 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2838 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2842 if (ns_triplets
) { /* append namespace separator and prefix */
2843 tempPool
.ptr
[-1] = namespaceSeparator
;
2844 s
= b
->prefix
->name
;
2846 if (!poolAppendChar(&tempPool
, *s
))
2847 return XML_ERROR_NO_MEMORY
;
2851 /* store expanded name in attribute list */
2852 s
= poolStart(&tempPool
);
2853 poolFinish(&tempPool
);
2856 /* fill empty slot with new version, uriName and hash value */
2857 nsAtts
[j
].version
= version
;
2858 nsAtts
[j
].hash
= uriHash
;
2859 nsAtts
[j
].uriName
= s
;
2866 else /* not prefixed */
2867 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2870 /* clear flags for the remaining attributes */
2871 for (; i
< attIndex
; i
+= 2)
2872 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2873 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2874 binding
->attId
->name
[-1] = 0;
2877 return XML_ERROR_NONE
;
2879 /* expand the element type name */
2880 if (elementType
->prefix
) {
2881 binding
= elementType
->prefix
->binding
;
2883 return XML_ERROR_UNBOUND_PREFIX
;
2884 localPart
= tagNamePtr
->str
;
2885 while (*localPart
++ != XML_T(':'))
2888 else if (dtd
->defaultPrefix
.binding
) {
2889 binding
= dtd
->defaultPrefix
.binding
;
2890 localPart
= tagNamePtr
->str
;
2893 return XML_ERROR_NONE
;
2895 if (ns_triplets
&& binding
->prefix
->name
) {
2896 for (; binding
->prefix
->name
[prefixLen
++];)
2897 ; /* prefixLen includes null terminator */
2899 tagNamePtr
->localPart
= localPart
;
2900 tagNamePtr
->uriLen
= binding
->uriLen
;
2901 tagNamePtr
->prefix
= binding
->prefix
->name
;
2902 tagNamePtr
->prefixLen
= prefixLen
;
2903 for (i
= 0; localPart
[i
++];)
2904 ; /* i includes null terminator */
2905 n
= i
+ binding
->uriLen
+ prefixLen
;
2906 if (n
> binding
->uriAlloc
) {
2908 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2910 return XML_ERROR_NO_MEMORY
;
2911 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2912 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2913 for (p
= tagStack
; p
; p
= p
->parent
)
2914 if (p
->name
.str
== binding
->uri
)
2919 /* if namespaceSeparator != '\0' then uri includes it already */
2920 uri
= binding
->uri
+ binding
->uriLen
;
2921 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2922 /* we always have a namespace separator between localPart and prefix */
2925 *uri
= namespaceSeparator
; /* replace null terminator */
2926 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2928 tagNamePtr
->str
= binding
->uri
;
2929 return XML_ERROR_NONE
;
2932 /* addBinding() overwrites the value of prefix->binding without checking.
2933 Therefore one must keep track of the old value outside of addBinding().
2935 static enum XML_Error
2936 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2937 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2939 static const XML_Char xmlNamespace
[] = {
2940 'h', 't', 't', 'p', ':', '/', '/',
2941 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2942 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2943 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2945 static const int xmlLen
=
2946 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2947 static const XML_Char xmlnsNamespace
[] = {
2948 'h', 't', 't', 'p', ':', '/', '/',
2949 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2950 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
2952 static const int xmlnsLen
=
2953 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2955 XML_Bool mustBeXML
= XML_FALSE
;
2956 XML_Bool isXML
= XML_TRUE
;
2957 XML_Bool isXMLNS
= XML_TRUE
;
2962 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2963 if (*uri
== XML_T('\0') && prefix
->name
)
2964 return XML_ERROR_UNDECLARING_PREFIX
;
2967 && prefix
->name
[0] == XML_T('x')
2968 && prefix
->name
[1] == XML_T('m')
2969 && prefix
->name
[2] == XML_T('l')) {
2971 /* Not allowed to bind xmlns */
2972 if (prefix
->name
[3] == XML_T('n')
2973 && prefix
->name
[4] == XML_T('s')
2974 && prefix
->name
[5] == XML_T('\0'))
2975 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2977 if (prefix
->name
[3] == XML_T('\0'))
2978 mustBeXML
= XML_TRUE
;
2981 for (len
= 0; uri
[len
]; len
++) {
2982 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
2985 if (!mustBeXML
&& isXMLNS
2986 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
2987 isXMLNS
= XML_FALSE
;
2989 isXML
= isXML
&& len
== xmlLen
;
2990 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
2992 if (mustBeXML
!= isXML
)
2993 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
2994 : XML_ERROR_RESERVED_NAMESPACE_URI
;
2997 return XML_ERROR_RESERVED_NAMESPACE_URI
;
2999 if (namespaceSeparator
)
3001 if (freeBindingList
) {
3002 b
= freeBindingList
;
3003 if (len
> b
->uriAlloc
) {
3004 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3005 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3007 return XML_ERROR_NO_MEMORY
;
3009 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3011 freeBindingList
= b
->nextTagBinding
;
3014 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3016 return XML_ERROR_NO_MEMORY
;
3017 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3020 return XML_ERROR_NO_MEMORY
;
3022 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3025 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3026 if (namespaceSeparator
)
3027 b
->uri
[len
- 1] = namespaceSeparator
;
3030 b
->prevPrefixBinding
= prefix
->binding
;
3031 /* NULL binding when default namespace undeclared */
3032 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3033 prefix
->binding
= NULL
;
3035 prefix
->binding
= b
;
3036 b
->nextTagBinding
= *bindingsPtr
;
3038 /* if attId == NULL then we are not starting a namespace scope */
3039 if (attId
&& startNamespaceDeclHandler
)
3040 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3041 prefix
->binding
? uri
: 0);
3042 return XML_ERROR_NONE
;
3045 /* The idea here is to avoid using stack for each CDATA section when
3046 the whole file is parsed with one call.
3048 static enum XML_Error PTRCALL
3049 cdataSectionProcessor(XML_Parser parser
,
3052 const char **endPtr
)
3054 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3055 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3056 if (result
!= XML_ERROR_NONE
)
3059 if (parentParser
) { /* we are parsing an external entity */
3060 processor
= externalEntityContentProcessor
;
3061 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3064 processor
= contentProcessor
;
3065 return contentProcessor(parser
, start
, end
, endPtr
);
3071 /* startPtr gets set to non-null if the section is closed, and to null if
3072 the section is not yet closed.
3074 static enum XML_Error
3075 doCdataSection(XML_Parser parser
,
3076 const ENCODING
*enc
,
3077 const char **startPtr
,
3079 const char **nextPtr
,
3082 const char *s
= *startPtr
;
3083 const char **eventPP
;
3084 const char **eventEndPP
;
3085 if (enc
== encoding
) {
3086 eventPP
= &eventPtr
;
3088 eventEndPP
= &eventEndPtr
;
3091 eventPP
= &(openInternalEntities
->internalEventPtr
);
3092 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3099 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3102 case XML_TOK_CDATA_SECT_CLOSE
:
3103 if (endCdataSectionHandler
)
3104 endCdataSectionHandler(handlerArg
);
3106 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3107 else if (characterDataHandler
)
3108 characterDataHandler(handlerArg
, dataBuf
, 0);
3110 else if (defaultHandler
)
3111 reportDefault(parser
, enc
, s
, next
);
3114 if (ps_parsing
== XML_FINISHED
)
3115 return XML_ERROR_ABORTED
;
3117 return XML_ERROR_NONE
;
3118 case XML_TOK_DATA_NEWLINE
:
3119 if (characterDataHandler
) {
3121 characterDataHandler(handlerArg
, &c
, 1);
3123 else if (defaultHandler
)
3124 reportDefault(parser
, enc
, s
, next
);
3126 case XML_TOK_DATA_CHARS
:
3127 if (characterDataHandler
) {
3128 if (MUST_CONVERT(enc
, s
)) {
3130 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3131 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3133 characterDataHandler(handlerArg
, dataBuf
,
3134 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3141 characterDataHandler(handlerArg
,
3143 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3145 else if (defaultHandler
)
3146 reportDefault(parser
, enc
, s
, next
);
3148 case XML_TOK_INVALID
:
3150 return XML_ERROR_INVALID_TOKEN
;
3151 case XML_TOK_PARTIAL_CHAR
:
3154 return XML_ERROR_NONE
;
3156 return XML_ERROR_PARTIAL_CHAR
;
3157 case XML_TOK_PARTIAL
:
3161 return XML_ERROR_NONE
;
3163 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3166 return XML_ERROR_UNEXPECTED_STATE
;
3169 *eventPP
= s
= next
;
3170 switch (ps_parsing
) {
3173 return XML_ERROR_NONE
;
3175 return XML_ERROR_ABORTED
;
3184 /* The idea here is to avoid using stack for each IGNORE section when
3185 the whole file is parsed with one call.
3187 static enum XML_Error PTRCALL
3188 ignoreSectionProcessor(XML_Parser parser
,
3191 const char **endPtr
)
3193 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3194 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3195 if (result
!= XML_ERROR_NONE
)
3198 processor
= prologProcessor
;
3199 return prologProcessor(parser
, start
, end
, endPtr
);
3204 /* startPtr gets set to non-null is the section is closed, and to null
3205 if the section is not yet closed.
3207 static enum XML_Error
3208 doIgnoreSection(XML_Parser parser
,
3209 const ENCODING
*enc
,
3210 const char **startPtr
,
3212 const char **nextPtr
,
3217 const char *s
= *startPtr
;
3218 const char **eventPP
;
3219 const char **eventEndPP
;
3220 if (enc
== encoding
) {
3221 eventPP
= &eventPtr
;
3223 eventEndPP
= &eventEndPtr
;
3226 eventPP
= &(openInternalEntities
->internalEventPtr
);
3227 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3231 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3234 case XML_TOK_IGNORE_SECT
:
3236 reportDefault(parser
, enc
, s
, next
);
3239 if (ps_parsing
== XML_FINISHED
)
3240 return XML_ERROR_ABORTED
;
3242 return XML_ERROR_NONE
;
3243 case XML_TOK_INVALID
:
3245 return XML_ERROR_INVALID_TOKEN
;
3246 case XML_TOK_PARTIAL_CHAR
:
3249 return XML_ERROR_NONE
;
3251 return XML_ERROR_PARTIAL_CHAR
;
3252 case XML_TOK_PARTIAL
:
3256 return XML_ERROR_NONE
;
3258 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3261 return XML_ERROR_UNEXPECTED_STATE
;
3266 #endif /* XML_DTD */
3268 static enum XML_Error
3269 initializeEncoding(XML_Parser parser
)
3273 char encodingBuf
[128];
3274 if (!protocolEncodingName
)
3278 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3279 if (i
== sizeof(encodingBuf
) - 1
3280 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3281 encodingBuf
[0] = '\0';
3284 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3286 encodingBuf
[i
] = '\0';
3290 s
= protocolEncodingName
;
3292 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3293 return XML_ERROR_NONE
;
3294 return handleUnknownEncoding(parser
, protocolEncodingName
);
3297 static enum XML_Error
3298 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3299 const char *s
, const char *next
)
3301 const char *encodingName
= NULL
;
3302 const XML_Char
*storedEncName
= NULL
;
3303 const ENCODING
*newEncoding
= NULL
;
3304 const char *version
= NULL
;
3305 const char *versionend
;
3306 const XML_Char
*storedversion
= NULL
;
3307 int standalone
= -1;
3310 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3320 if (isGeneralTextEntity
)
3321 return XML_ERROR_TEXT_DECL
;
3323 return XML_ERROR_XML_DECL
;
3325 if (!isGeneralTextEntity
&& standalone
== 1) {
3326 _dtd
->standalone
= XML_TRUE
;
3328 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3329 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3330 #endif /* XML_DTD */
3332 if (xmlDeclHandler
) {
3333 if (encodingName
!= NULL
) {
3334 storedEncName
= poolStoreString(&temp2Pool
,
3338 + XmlNameLength(encoding
, encodingName
));
3340 return XML_ERROR_NO_MEMORY
;
3341 poolFinish(&temp2Pool
);
3344 storedversion
= poolStoreString(&temp2Pool
,
3347 versionend
- encoding
->minBytesPerChar
);
3349 return XML_ERROR_NO_MEMORY
;
3351 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3353 else if (defaultHandler
)
3354 reportDefault(parser
, encoding
, s
, next
);
3355 if (protocolEncodingName
== NULL
) {
3357 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3358 eventPtr
= encodingName
;
3359 return XML_ERROR_INCORRECT_ENCODING
;
3361 encoding
= newEncoding
;
3363 else if (encodingName
) {
3364 enum XML_Error result
;
3365 if (!storedEncName
) {
3366 storedEncName
= poolStoreString(
3367 &temp2Pool
, encoding
, encodingName
,
3368 encodingName
+ XmlNameLength(encoding
, encodingName
));
3370 return XML_ERROR_NO_MEMORY
;
3372 result
= handleUnknownEncoding(parser
, storedEncName
);
3373 poolClear(&temp2Pool
);
3374 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3375 eventPtr
= encodingName
;
3380 if (storedEncName
|| storedversion
)
3381 poolClear(&temp2Pool
);
3383 return XML_ERROR_NONE
;
3386 static enum XML_Error
3387 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3389 if (unknownEncodingHandler
) {
3392 for (i
= 0; i
< 256; i
++)
3394 info
.convert
= NULL
;
3396 info
.release
= NULL
;
3397 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3400 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3401 if (!unknownEncodingMem
) {
3403 info
.release(info
.data
);
3404 return XML_ERROR_NO_MEMORY
;
3407 ? XmlInitUnknownEncodingNS
3408 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3413 unknownEncodingData
= info
.data
;
3414 unknownEncodingRelease
= info
.release
;
3416 return XML_ERROR_NONE
;
3419 if (info
.release
!= NULL
)
3420 info
.release(info
.data
);
3422 return XML_ERROR_UNKNOWN_ENCODING
;
3425 static enum XML_Error PTRCALL
3426 prologInitProcessor(XML_Parser parser
,
3429 const char **nextPtr
)
3431 enum XML_Error result
= initializeEncoding(parser
);
3432 if (result
!= XML_ERROR_NONE
)
3434 processor
= prologProcessor
;
3435 return prologProcessor(parser
, s
, end
, nextPtr
);
3440 static enum XML_Error PTRCALL
3441 externalParEntInitProcessor(XML_Parser parser
,
3444 const char **nextPtr
)
3446 enum XML_Error result
= initializeEncoding(parser
);
3447 if (result
!= XML_ERROR_NONE
)
3450 /* we know now that XML_Parse(Buffer) has been called,
3451 so we consider the external parameter entity read */
3452 _dtd
->paramEntityRead
= XML_TRUE
;
3454 if (prologState
.inEntityValue
) {
3455 processor
= entityValueInitProcessor
;
3456 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3459 processor
= externalParEntProcessor
;
3460 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3464 static enum XML_Error PTRCALL
3465 entityValueInitProcessor(XML_Parser parser
,
3468 const char **nextPtr
)
3471 const char *start
= s
;
3472 const char *next
= start
;
3476 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3479 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3481 return XML_ERROR_NONE
;
3484 case XML_TOK_INVALID
:
3485 return XML_ERROR_INVALID_TOKEN
;
3486 case XML_TOK_PARTIAL
:
3487 return XML_ERROR_UNCLOSED_TOKEN
;
3488 case XML_TOK_PARTIAL_CHAR
:
3489 return XML_ERROR_PARTIAL_CHAR
;
3490 case XML_TOK_NONE
: /* start == end */
3494 /* found end of entity value - can store it now */
3495 return storeEntityValue(parser
, encoding
, s
, end
);
3497 else if (tok
== XML_TOK_XML_DECL
) {
3498 enum XML_Error result
;
3499 result
= processXmlDecl(parser
, 0, start
, next
);
3500 if (result
!= XML_ERROR_NONE
)
3502 switch (ps_parsing
) {
3505 return XML_ERROR_NONE
;
3507 return XML_ERROR_ABORTED
;
3511 /* stop scanning for text declaration - we found one */
3512 processor
= entityValueProcessor
;
3513 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3515 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3516 return XML_TOK_NONE on the next call, which would then cause the
3517 function to exit with *nextPtr set to s - that is what we want for other
3518 tokens, but not for the BOM - we would rather like to skip it;
3519 then, when this routine is entered the next time, XmlPrologTok will
3520 return XML_TOK_INVALID, since the BOM is still in the buffer
3522 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3524 return XML_ERROR_NONE
;
3531 static enum XML_Error PTRCALL
3532 externalParEntProcessor(XML_Parser parser
,
3535 const char **nextPtr
)
3537 const char *next
= s
;
3540 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3542 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3544 return XML_ERROR_NONE
;
3547 case XML_TOK_INVALID
:
3548 return XML_ERROR_INVALID_TOKEN
;
3549 case XML_TOK_PARTIAL
:
3550 return XML_ERROR_UNCLOSED_TOKEN
;
3551 case XML_TOK_PARTIAL_CHAR
:
3552 return XML_ERROR_PARTIAL_CHAR
;
3553 case XML_TOK_NONE
: /* start == end */
3558 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3559 However, when parsing an external subset, doProlog will not accept a BOM
3560 as valid, and report a syntax error, so we have to skip the BOM
3562 else if (tok
== XML_TOK_BOM
) {
3564 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3567 processor
= prologProcessor
;
3568 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3569 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3572 static enum XML_Error PTRCALL
3573 entityValueProcessor(XML_Parser parser
,
3576 const char **nextPtr
)
3578 const char *start
= s
;
3579 const char *next
= s
;
3580 const ENCODING
*enc
= encoding
;
3584 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3586 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3588 return XML_ERROR_NONE
;
3591 case XML_TOK_INVALID
:
3592 return XML_ERROR_INVALID_TOKEN
;
3593 case XML_TOK_PARTIAL
:
3594 return XML_ERROR_UNCLOSED_TOKEN
;
3595 case XML_TOK_PARTIAL_CHAR
:
3596 return XML_ERROR_PARTIAL_CHAR
;
3597 case XML_TOK_NONE
: /* start == end */
3601 /* found end of entity value - can store it now */
3602 return storeEntityValue(parser
, enc
, s
, end
);
3608 #endif /* XML_DTD */
3610 static enum XML_Error PTRCALL
3611 prologProcessor(XML_Parser parser
,
3614 const char **nextPtr
)
3616 const char *next
= s
;
3617 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3618 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3619 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3622 static enum XML_Error
3623 doProlog(XML_Parser parser
,
3624 const ENCODING
*enc
,
3629 const char **nextPtr
,
3633 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3634 #endif /* XML_DTD */
3635 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3636 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3637 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3638 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3639 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3640 static const XML_Char atypeENTITIES
[] =
3641 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3642 static const XML_Char atypeNMTOKEN
[] = {
3643 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3644 static const XML_Char atypeNMTOKENS
[] = {
3645 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3646 static const XML_Char notationPrefix
[] = {
3647 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3648 static const XML_Char enumValueSep
[] = { '|', '\0' };
3649 static const XML_Char enumValueStart
[] = { '(', '\0' };
3651 /* save one level of indirection */
3652 DTD
* const dtd
= _dtd
;
3654 const char **eventPP
;
3655 const char **eventEndPP
;
3656 enum XML_Content_Quant quant
;
3658 if (enc
== encoding
) {
3659 eventPP
= &eventPtr
;
3660 eventEndPP
= &eventEndPtr
;
3663 eventPP
= &(openInternalEntities
->internalEventPtr
);
3664 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3669 XML_Bool handleDefault
= XML_TRUE
;
3673 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3675 return XML_ERROR_NONE
;
3678 case XML_TOK_INVALID
:
3680 return XML_ERROR_INVALID_TOKEN
;
3681 case XML_TOK_PARTIAL
:
3682 return XML_ERROR_UNCLOSED_TOKEN
;
3683 case XML_TOK_PARTIAL_CHAR
:
3684 return XML_ERROR_PARTIAL_CHAR
;
3687 /* for internal PE NOT referenced between declarations */
3688 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3690 return XML_ERROR_NONE
;
3692 /* WFC: PE Between Declarations - must check that PE contains
3693 complete markup, not only for external PEs, but also for
3694 internal PEs if the reference occurs between declarations.
3696 if (isParamEntity
|| enc
!= encoding
) {
3697 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3699 return XML_ERROR_INCOMPLETE_PE
;
3701 return XML_ERROR_NONE
;
3703 #endif /* XML_DTD */
3704 return XML_ERROR_NO_ELEMENTS
;
3711 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3713 case XML_ROLE_XML_DECL
:
3715 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3716 if (result
!= XML_ERROR_NONE
)
3719 handleDefault
= XML_FALSE
;
3722 case XML_ROLE_DOCTYPE_NAME
:
3723 if (startDoctypeDeclHandler
) {
3724 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3726 return XML_ERROR_NO_MEMORY
;
3727 poolFinish(&tempPool
);
3728 doctypePubid
= NULL
;
3729 handleDefault
= XML_FALSE
;
3731 doctypeSysid
= NULL
; /* always initialize to NULL */
3733 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3734 if (startDoctypeDeclHandler
) {
3735 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3738 poolClear(&tempPool
);
3739 handleDefault
= XML_FALSE
;
3743 case XML_ROLE_TEXT_DECL
:
3745 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3746 if (result
!= XML_ERROR_NONE
)
3749 handleDefault
= XML_FALSE
;
3752 #endif /* XML_DTD */
3753 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3755 useForeignDTD
= XML_FALSE
;
3756 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3760 return XML_ERROR_NO_MEMORY
;
3761 #endif /* XML_DTD */
3762 dtd
->hasParamEntityRefs
= XML_TRUE
;
3763 if (startDoctypeDeclHandler
) {
3764 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3765 return XML_ERROR_PUBLICID
;
3766 doctypePubid
= poolStoreString(&tempPool
, enc
,
3767 s
+ enc
->minBytesPerChar
,
3768 next
- enc
->minBytesPerChar
);
3770 return XML_ERROR_NO_MEMORY
;
3771 normalizePublicId((XML_Char
*)doctypePubid
);
3772 poolFinish(&tempPool
);
3773 handleDefault
= XML_FALSE
;
3774 goto alreadyChecked
;
3777 case XML_ROLE_ENTITY_PUBLIC_ID
:
3778 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3779 return XML_ERROR_PUBLICID
;
3781 if (dtd
->keepProcessing
&& declEntity
) {
3782 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3784 s
+ enc
->minBytesPerChar
,
3785 next
- enc
->minBytesPerChar
);
3787 return XML_ERROR_NO_MEMORY
;
3788 normalizePublicId(tem
);
3789 declEntity
->publicId
= tem
;
3790 poolFinish(&dtd
->pool
);
3791 if (entityDeclHandler
)
3792 handleDefault
= XML_FALSE
;
3795 case XML_ROLE_DOCTYPE_CLOSE
:
3797 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3798 doctypeSysid
, doctypePubid
, 0);
3799 poolClear(&tempPool
);
3800 handleDefault
= XML_FALSE
;
3802 /* doctypeSysid will be non-NULL in the case of a previous
3803 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3804 was not set, indicating an external subset
3807 if (doctypeSysid
|| useForeignDTD
) {
3808 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3809 dtd
->hasParamEntityRefs
= XML_TRUE
;
3810 if (paramEntityParsing
&& externalEntityRefHandler
) {
3811 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3815 return XML_ERROR_NO_MEMORY
;
3817 entity
->base
= curBase
;
3818 dtd
->paramEntityRead
= XML_FALSE
;
3819 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3824 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3825 if (dtd
->paramEntityRead
) {
3826 if (!dtd
->standalone
&&
3827 notStandaloneHandler
&&
3828 !notStandaloneHandler(handlerArg
))
3829 return XML_ERROR_NOT_STANDALONE
;
3831 /* if we didn't read the foreign DTD then this means that there
3832 is no external subset and we must reset dtd->hasParamEntityRefs
3834 else if (!doctypeSysid
)
3835 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3836 /* end of DTD - no need to update dtd->keepProcessing */
3838 useForeignDTD
= XML_FALSE
;
3840 #endif /* XML_DTD */
3841 if (endDoctypeDeclHandler
) {
3842 endDoctypeDeclHandler(handlerArg
);
3843 handleDefault
= XML_FALSE
;
3846 case XML_ROLE_INSTANCE_START
:
3848 /* if there is no DOCTYPE declaration then now is the
3849 last chance to read the foreign DTD
3851 if (useForeignDTD
) {
3852 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3853 dtd
->hasParamEntityRefs
= XML_TRUE
;
3854 if (paramEntityParsing
&& externalEntityRefHandler
) {
3855 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3859 return XML_ERROR_NO_MEMORY
;
3860 entity
->base
= curBase
;
3861 dtd
->paramEntityRead
= XML_FALSE
;
3862 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3867 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3868 if (dtd
->paramEntityRead
) {
3869 if (!dtd
->standalone
&&
3870 notStandaloneHandler
&&
3871 !notStandaloneHandler(handlerArg
))
3872 return XML_ERROR_NOT_STANDALONE
;
3874 /* if we didn't read the foreign DTD then this means that there
3875 is no external subset and we must reset dtd->hasParamEntityRefs
3878 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3879 /* end of DTD - no need to update dtd->keepProcessing */
3882 #endif /* XML_DTD */
3883 processor
= contentProcessor
;
3884 return contentProcessor(parser
, s
, end
, nextPtr
);
3885 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3886 declElementType
= getElementType(parser
, enc
, s
, next
);
3887 if (!declElementType
)
3888 return XML_ERROR_NO_MEMORY
;
3889 goto checkAttListDeclHandler
;
3890 case XML_ROLE_ATTRIBUTE_NAME
:
3891 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3892 if (!declAttributeId
)
3893 return XML_ERROR_NO_MEMORY
;
3894 declAttributeIsCdata
= XML_FALSE
;
3895 declAttributeType
= NULL
;
3896 declAttributeIsId
= XML_FALSE
;
3897 goto checkAttListDeclHandler
;
3898 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3899 declAttributeIsCdata
= XML_TRUE
;
3900 declAttributeType
= atypeCDATA
;
3901 goto checkAttListDeclHandler
;
3902 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3903 declAttributeIsId
= XML_TRUE
;
3904 declAttributeType
= atypeID
;
3905 goto checkAttListDeclHandler
;
3906 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3907 declAttributeType
= atypeIDREF
;
3908 goto checkAttListDeclHandler
;
3909 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3910 declAttributeType
= atypeIDREFS
;
3911 goto checkAttListDeclHandler
;
3912 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3913 declAttributeType
= atypeENTITY
;
3914 goto checkAttListDeclHandler
;
3915 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3916 declAttributeType
= atypeENTITIES
;
3917 goto checkAttListDeclHandler
;
3918 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3919 declAttributeType
= atypeNMTOKEN
;
3920 goto checkAttListDeclHandler
;
3921 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3922 declAttributeType
= atypeNMTOKENS
;
3923 checkAttListDeclHandler
:
3924 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3925 handleDefault
= XML_FALSE
;
3927 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3928 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3929 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3930 const XML_Char
*prefix
;
3931 if (declAttributeType
) {
3932 prefix
= enumValueSep
;
3935 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3939 if (!poolAppendString(&tempPool
, prefix
))
3940 return XML_ERROR_NO_MEMORY
;
3941 if (!poolAppend(&tempPool
, enc
, s
, next
))
3942 return XML_ERROR_NO_MEMORY
;
3943 declAttributeType
= tempPool
.start
;
3944 handleDefault
= XML_FALSE
;
3947 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3948 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3949 if (dtd
->keepProcessing
) {
3950 if (!defineAttribute(declElementType
, declAttributeId
,
3951 declAttributeIsCdata
, declAttributeIsId
,
3953 return XML_ERROR_NO_MEMORY
;
3954 if (attlistDeclHandler
&& declAttributeType
) {
3955 if (*declAttributeType
== XML_T('(')
3956 || (*declAttributeType
== XML_T('N')
3957 && declAttributeType
[1] == XML_T('O'))) {
3958 /* Enumerated or Notation type */
3959 if (!poolAppendChar(&tempPool
, XML_T(')'))
3960 || !poolAppendChar(&tempPool
, XML_T('\0')))
3961 return XML_ERROR_NO_MEMORY
;
3962 declAttributeType
= tempPool
.start
;
3963 poolFinish(&tempPool
);
3966 attlistDeclHandler(handlerArg
, declElementType
->name
,
3967 declAttributeId
->name
, declAttributeType
,
3968 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3969 poolClear(&tempPool
);
3970 handleDefault
= XML_FALSE
;
3974 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3975 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3976 if (dtd
->keepProcessing
) {
3977 const XML_Char
*attVal
;
3978 enum XML_Error result
=
3979 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3980 s
+ enc
->minBytesPerChar
,
3981 next
- enc
->minBytesPerChar
,
3985 attVal
= poolStart(&dtd
->pool
);
3986 poolFinish(&dtd
->pool
);
3987 /* ID attributes aren't allowed to have a default */
3988 if (!defineAttribute(declElementType
, declAttributeId
,
3989 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3990 return XML_ERROR_NO_MEMORY
;
3991 if (attlistDeclHandler
&& declAttributeType
) {
3992 if (*declAttributeType
== XML_T('(')
3993 || (*declAttributeType
== XML_T('N')
3994 && declAttributeType
[1] == XML_T('O'))) {
3995 /* Enumerated or Notation type */
3996 if (!poolAppendChar(&tempPool
, XML_T(')'))
3997 || !poolAppendChar(&tempPool
, XML_T('\0')))
3998 return XML_ERROR_NO_MEMORY
;
3999 declAttributeType
= tempPool
.start
;
4000 poolFinish(&tempPool
);
4003 attlistDeclHandler(handlerArg
, declElementType
->name
,
4004 declAttributeId
->name
, declAttributeType
,
4006 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4007 poolClear(&tempPool
);
4008 handleDefault
= XML_FALSE
;
4012 case XML_ROLE_ENTITY_VALUE
:
4013 if (dtd
->keepProcessing
) {
4014 enum XML_Error result
= storeEntityValue(parser
, enc
,
4015 s
+ enc
->minBytesPerChar
,
4016 next
- enc
->minBytesPerChar
);
4018 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4019 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4020 poolFinish(&dtd
->entityValuePool
);
4021 if (entityDeclHandler
) {
4023 entityDeclHandler(handlerArg
,
4025 declEntity
->is_param
,
4026 declEntity
->textPtr
,
4027 declEntity
->textLen
,
4029 handleDefault
= XML_FALSE
;
4033 poolDiscard(&dtd
->entityValuePool
);
4034 if (result
!= XML_ERROR_NONE
)
4038 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4040 useForeignDTD
= XML_FALSE
;
4041 #endif /* XML_DTD */
4042 dtd
->hasParamEntityRefs
= XML_TRUE
;
4043 if (startDoctypeDeclHandler
) {
4044 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4045 s
+ enc
->minBytesPerChar
,
4046 next
- enc
->minBytesPerChar
);
4047 if (doctypeSysid
== NULL
)
4048 return XML_ERROR_NO_MEMORY
;
4049 poolFinish(&tempPool
);
4050 handleDefault
= XML_FALSE
;
4054 /* use externalSubsetName to make doctypeSysid non-NULL
4055 for the case where no startDoctypeDeclHandler is set */
4056 doctypeSysid
= externalSubsetName
;
4057 #endif /* XML_DTD */
4058 if (!dtd
->standalone
4060 && !paramEntityParsing
4061 #endif /* XML_DTD */
4062 && notStandaloneHandler
4063 && !notStandaloneHandler(handlerArg
))
4064 return XML_ERROR_NOT_STANDALONE
;
4069 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4073 return XML_ERROR_NO_MEMORY
;
4074 declEntity
->publicId
= NULL
;
4077 #endif /* XML_DTD */
4078 case XML_ROLE_ENTITY_SYSTEM_ID
:
4079 if (dtd
->keepProcessing
&& declEntity
) {
4080 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4081 s
+ enc
->minBytesPerChar
,
4082 next
- enc
->minBytesPerChar
);
4083 if (!declEntity
->systemId
)
4084 return XML_ERROR_NO_MEMORY
;
4085 declEntity
->base
= curBase
;
4086 poolFinish(&dtd
->pool
);
4087 if (entityDeclHandler
)
4088 handleDefault
= XML_FALSE
;
4091 case XML_ROLE_ENTITY_COMPLETE
:
4092 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4094 entityDeclHandler(handlerArg
,
4096 declEntity
->is_param
,
4099 declEntity
->systemId
,
4100 declEntity
->publicId
,
4102 handleDefault
= XML_FALSE
;
4105 case XML_ROLE_ENTITY_NOTATION_NAME
:
4106 if (dtd
->keepProcessing
&& declEntity
) {
4107 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4108 if (!declEntity
->notation
)
4109 return XML_ERROR_NO_MEMORY
;
4110 poolFinish(&dtd
->pool
);
4111 if (unparsedEntityDeclHandler
) {
4113 unparsedEntityDeclHandler(handlerArg
,
4116 declEntity
->systemId
,
4117 declEntity
->publicId
,
4118 declEntity
->notation
);
4119 handleDefault
= XML_FALSE
;
4121 else if (entityDeclHandler
) {
4123 entityDeclHandler(handlerArg
,
4127 declEntity
->systemId
,
4128 declEntity
->publicId
,
4129 declEntity
->notation
);
4130 handleDefault
= XML_FALSE
;
4134 case XML_ROLE_GENERAL_ENTITY_NAME
:
4136 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4140 if (dtd
->keepProcessing
) {
4141 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4143 return XML_ERROR_NO_MEMORY
;
4144 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4147 return XML_ERROR_NO_MEMORY
;
4148 if (declEntity
->name
!= name
) {
4149 poolDiscard(&dtd
->pool
);
4153 poolFinish(&dtd
->pool
);
4154 declEntity
->publicId
= NULL
;
4155 declEntity
->is_param
= XML_FALSE
;
4156 /* if we have a parent parser or are reading an internal parameter
4157 entity, then the entity declaration is not considered "internal"
4159 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4160 if (entityDeclHandler
)
4161 handleDefault
= XML_FALSE
;
4165 poolDiscard(&dtd
->pool
);
4170 case XML_ROLE_PARAM_ENTITY_NAME
:
4172 if (dtd
->keepProcessing
) {
4173 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4175 return XML_ERROR_NO_MEMORY
;
4176 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4177 name
, sizeof(ENTITY
));
4179 return XML_ERROR_NO_MEMORY
;
4180 if (declEntity
->name
!= name
) {
4181 poolDiscard(&dtd
->pool
);
4185 poolFinish(&dtd
->pool
);
4186 declEntity
->publicId
= NULL
;
4187 declEntity
->is_param
= XML_TRUE
;
4188 /* if we have a parent parser or are reading an internal parameter
4189 entity, then the entity declaration is not considered "internal"
4191 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4192 if (entityDeclHandler
)
4193 handleDefault
= XML_FALSE
;
4197 poolDiscard(&dtd
->pool
);
4200 #else /* not XML_DTD */
4202 #endif /* XML_DTD */
4204 case XML_ROLE_NOTATION_NAME
:
4205 declNotationPublicId
= NULL
;
4206 declNotationName
= NULL
;
4207 if (notationDeclHandler
) {
4208 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4209 if (!declNotationName
)
4210 return XML_ERROR_NO_MEMORY
;
4211 poolFinish(&tempPool
);
4212 handleDefault
= XML_FALSE
;
4215 case XML_ROLE_NOTATION_PUBLIC_ID
:
4216 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4217 return XML_ERROR_PUBLICID
;
4218 if (declNotationName
) { /* means notationDeclHandler != NULL */
4219 XML_Char
*tem
= poolStoreString(&tempPool
,
4221 s
+ enc
->minBytesPerChar
,
4222 next
- enc
->minBytesPerChar
);
4224 return XML_ERROR_NO_MEMORY
;
4225 normalizePublicId(tem
);
4226 declNotationPublicId
= tem
;
4227 poolFinish(&tempPool
);
4228 handleDefault
= XML_FALSE
;
4231 case XML_ROLE_NOTATION_SYSTEM_ID
:
4232 if (declNotationName
&& notationDeclHandler
) {
4233 const XML_Char
*systemId
4234 = poolStoreString(&tempPool
, enc
,
4235 s
+ enc
->minBytesPerChar
,
4236 next
- enc
->minBytesPerChar
);
4238 return XML_ERROR_NO_MEMORY
;
4240 notationDeclHandler(handlerArg
,
4244 declNotationPublicId
);
4245 handleDefault
= XML_FALSE
;
4247 poolClear(&tempPool
);
4249 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4250 if (declNotationPublicId
&& notationDeclHandler
) {
4252 notationDeclHandler(handlerArg
,
4256 declNotationPublicId
);
4257 handleDefault
= XML_FALSE
;
4259 poolClear(&tempPool
);
4261 case XML_ROLE_ERROR
:
4263 case XML_TOK_PARAM_ENTITY_REF
:
4264 /* PE references in internal subset are
4265 not allowed within declarations. */
4266 return XML_ERROR_PARAM_ENTITY_REF
;
4267 case XML_TOK_XML_DECL
:
4268 return XML_ERROR_MISPLACED_XML_PI
;
4270 return XML_ERROR_SYNTAX
;
4273 case XML_ROLE_IGNORE_SECT
:
4275 enum XML_Error result
;
4277 reportDefault(parser
, enc
, s
, next
);
4278 handleDefault
= XML_FALSE
;
4279 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4280 if (result
!= XML_ERROR_NONE
)
4283 processor
= ignoreSectionProcessor
;
4288 #endif /* XML_DTD */
4289 case XML_ROLE_GROUP_OPEN
:
4290 if (prologState
.level
>= groupSize
) {
4292 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4294 return XML_ERROR_NO_MEMORY
;
4295 groupConnector
= temp
;
4296 if (dtd
->scaffIndex
) {
4297 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4298 groupSize
* sizeof(int));
4300 return XML_ERROR_NO_MEMORY
;
4301 dtd
->scaffIndex
= temp
;
4305 groupConnector
= (char *)MALLOC(groupSize
= 32);
4306 if (!groupConnector
)
4307 return XML_ERROR_NO_MEMORY
;
4310 groupConnector
[prologState
.level
] = 0;
4311 if (dtd
->in_eldecl
) {
4312 int myindex
= nextScaffoldPart(parser
);
4314 return XML_ERROR_NO_MEMORY
;
4315 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4317 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4318 if (elementDeclHandler
)
4319 handleDefault
= XML_FALSE
;
4322 case XML_ROLE_GROUP_SEQUENCE
:
4323 if (groupConnector
[prologState
.level
] == '|')
4324 return XML_ERROR_SYNTAX
;
4325 groupConnector
[prologState
.level
] = ',';
4326 if (dtd
->in_eldecl
&& elementDeclHandler
)
4327 handleDefault
= XML_FALSE
;
4329 case XML_ROLE_GROUP_CHOICE
:
4330 if (groupConnector
[prologState
.level
] == ',')
4331 return XML_ERROR_SYNTAX
;
4333 && !groupConnector
[prologState
.level
]
4334 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4337 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4339 if (elementDeclHandler
)
4340 handleDefault
= XML_FALSE
;
4342 groupConnector
[prologState
.level
] = '|';
4344 case XML_ROLE_PARAM_ENTITY_REF
:
4346 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4347 dtd
->hasParamEntityRefs
= XML_TRUE
;
4348 if (!paramEntityParsing
)
4349 dtd
->keepProcessing
= dtd
->standalone
;
4351 const XML_Char
*name
;
4353 name
= poolStoreString(&dtd
->pool
, enc
,
4354 s
+ enc
->minBytesPerChar
,
4355 next
- enc
->minBytesPerChar
);
4357 return XML_ERROR_NO_MEMORY
;
4358 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4359 poolDiscard(&dtd
->pool
);
4360 /* first, determine if a check for an existing declaration is needed;
4361 if yes, check that the entity exists, and that it is internal,
4362 otherwise call the skipped entity handler
4364 if (prologState
.documentEntity
&&
4366 ? !openInternalEntities
4367 : !dtd
->hasParamEntityRefs
)) {
4369 return XML_ERROR_UNDEFINED_ENTITY
;
4370 else if (!entity
->is_internal
)
4371 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4374 dtd
->keepProcessing
= dtd
->standalone
;
4375 /* cannot report skipped entities in declarations */
4376 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4377 skippedEntityHandler(handlerArg
, name
, 1);
4378 handleDefault
= XML_FALSE
;
4383 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4384 if (entity
->textPtr
) {
4385 enum XML_Error result
;
4386 XML_Bool betweenDecl
=
4387 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4388 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4389 if (result
!= XML_ERROR_NONE
)
4391 handleDefault
= XML_FALSE
;
4394 if (externalEntityRefHandler
) {
4395 dtd
->paramEntityRead
= XML_FALSE
;
4396 entity
->open
= XML_TRUE
;
4397 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4401 entity
->publicId
)) {
4402 entity
->open
= XML_FALSE
;
4403 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4405 entity
->open
= XML_FALSE
;
4406 handleDefault
= XML_FALSE
;
4407 if (!dtd
->paramEntityRead
) {
4408 dtd
->keepProcessing
= dtd
->standalone
;
4413 dtd
->keepProcessing
= dtd
->standalone
;
4417 #endif /* XML_DTD */
4418 if (!dtd
->standalone
&&
4419 notStandaloneHandler
&&
4420 !notStandaloneHandler(handlerArg
))
4421 return XML_ERROR_NOT_STANDALONE
;
4424 /* Element declaration stuff */
4426 case XML_ROLE_ELEMENT_NAME
:
4427 if (elementDeclHandler
) {
4428 declElementType
= getElementType(parser
, enc
, s
, next
);
4429 if (!declElementType
)
4430 return XML_ERROR_NO_MEMORY
;
4431 dtd
->scaffLevel
= 0;
4432 dtd
->scaffCount
= 0;
4433 dtd
->in_eldecl
= XML_TRUE
;
4434 handleDefault
= XML_FALSE
;
4438 case XML_ROLE_CONTENT_ANY
:
4439 case XML_ROLE_CONTENT_EMPTY
:
4440 if (dtd
->in_eldecl
) {
4441 if (elementDeclHandler
) {
4442 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4444 return XML_ERROR_NO_MEMORY
;
4445 content
->quant
= XML_CQUANT_NONE
;
4446 content
->name
= NULL
;
4447 content
->numchildren
= 0;
4448 content
->children
= NULL
;
4449 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4453 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4454 handleDefault
= XML_FALSE
;
4456 dtd
->in_eldecl
= XML_FALSE
;
4460 case XML_ROLE_CONTENT_PCDATA
:
4461 if (dtd
->in_eldecl
) {
4462 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4464 if (elementDeclHandler
)
4465 handleDefault
= XML_FALSE
;
4469 case XML_ROLE_CONTENT_ELEMENT
:
4470 quant
= XML_CQUANT_NONE
;
4471 goto elementContent
;
4472 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4473 quant
= XML_CQUANT_OPT
;
4474 goto elementContent
;
4475 case XML_ROLE_CONTENT_ELEMENT_REP
:
4476 quant
= XML_CQUANT_REP
;
4477 goto elementContent
;
4478 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4479 quant
= XML_CQUANT_PLUS
;
4481 if (dtd
->in_eldecl
) {
4483 const XML_Char
*name
;
4485 const char *nxt
= (quant
== XML_CQUANT_NONE
4487 : next
- enc
->minBytesPerChar
);
4488 int myindex
= nextScaffoldPart(parser
);
4490 return XML_ERROR_NO_MEMORY
;
4491 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4492 dtd
->scaffold
[myindex
].quant
= quant
;
4493 el
= getElementType(parser
, enc
, s
, nxt
);
4495 return XML_ERROR_NO_MEMORY
;
4497 dtd
->scaffold
[myindex
].name
= name
;
4499 for (; name
[nameLen
++]; );
4500 dtd
->contentStringLen
+= nameLen
;
4501 if (elementDeclHandler
)
4502 handleDefault
= XML_FALSE
;
4506 case XML_ROLE_GROUP_CLOSE
:
4507 quant
= XML_CQUANT_NONE
;
4509 case XML_ROLE_GROUP_CLOSE_OPT
:
4510 quant
= XML_CQUANT_OPT
;
4512 case XML_ROLE_GROUP_CLOSE_REP
:
4513 quant
= XML_CQUANT_REP
;
4515 case XML_ROLE_GROUP_CLOSE_PLUS
:
4516 quant
= XML_CQUANT_PLUS
;
4518 if (dtd
->in_eldecl
) {
4519 if (elementDeclHandler
)
4520 handleDefault
= XML_FALSE
;
4522 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4523 if (dtd
->scaffLevel
== 0) {
4524 if (!handleDefault
) {
4525 XML_Content
*model
= build_model(parser
);
4527 return XML_ERROR_NO_MEMORY
;
4529 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4531 dtd
->in_eldecl
= XML_FALSE
;
4532 dtd
->contentStringLen
= 0;
4536 /* End element declaration stuff */
4539 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4540 return XML_ERROR_NO_MEMORY
;
4541 handleDefault
= XML_FALSE
;
4543 case XML_ROLE_COMMENT
:
4544 if (!reportComment(parser
, enc
, s
, next
))
4545 return XML_ERROR_NO_MEMORY
;
4546 handleDefault
= XML_FALSE
;
4551 handleDefault
= XML_FALSE
;
4555 case XML_ROLE_DOCTYPE_NONE
:
4556 if (startDoctypeDeclHandler
)
4557 handleDefault
= XML_FALSE
;
4559 case XML_ROLE_ENTITY_NONE
:
4560 if (dtd
->keepProcessing
&& entityDeclHandler
)
4561 handleDefault
= XML_FALSE
;
4563 case XML_ROLE_NOTATION_NONE
:
4564 if (notationDeclHandler
)
4565 handleDefault
= XML_FALSE
;
4567 case XML_ROLE_ATTLIST_NONE
:
4568 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4569 handleDefault
= XML_FALSE
;
4571 case XML_ROLE_ELEMENT_NONE
:
4572 if (elementDeclHandler
)
4573 handleDefault
= XML_FALSE
;
4575 } /* end of big switch */
4577 if (handleDefault
&& defaultHandler
)
4578 reportDefault(parser
, enc
, s
, next
);
4580 switch (ps_parsing
) {
4583 return XML_ERROR_NONE
;
4585 return XML_ERROR_ABORTED
;
4588 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4594 static enum XML_Error PTRCALL
4595 epilogProcessor(XML_Parser parser
,
4598 const char **nextPtr
)
4600 processor
= epilogProcessor
;
4603 const char *next
= NULL
;
4604 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4607 /* report partial linebreak - it might be the last token */
4608 case -XML_TOK_PROLOG_S
:
4609 if (defaultHandler
) {
4610 reportDefault(parser
, encoding
, s
, next
);
4611 if (ps_parsing
== XML_FINISHED
)
4612 return XML_ERROR_ABORTED
;
4615 return XML_ERROR_NONE
;
4618 return XML_ERROR_NONE
;
4619 case XML_TOK_PROLOG_S
:
4621 reportDefault(parser
, encoding
, s
, next
);
4624 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4625 return XML_ERROR_NO_MEMORY
;
4627 case XML_TOK_COMMENT
:
4628 if (!reportComment(parser
, encoding
, s
, next
))
4629 return XML_ERROR_NO_MEMORY
;
4631 case XML_TOK_INVALID
:
4633 return XML_ERROR_INVALID_TOKEN
;
4634 case XML_TOK_PARTIAL
:
4635 if (!ps_finalBuffer
) {
4637 return XML_ERROR_NONE
;
4639 return XML_ERROR_UNCLOSED_TOKEN
;
4640 case XML_TOK_PARTIAL_CHAR
:
4641 if (!ps_finalBuffer
) {
4643 return XML_ERROR_NONE
;
4645 return XML_ERROR_PARTIAL_CHAR
;
4647 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4649 eventPtr
= s
= next
;
4650 switch (ps_parsing
) {
4653 return XML_ERROR_NONE
;
4655 return XML_ERROR_ABORTED
;
4661 static enum XML_Error
4662 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4663 XML_Bool betweenDecl
)
4665 const char *textStart
, *textEnd
;
4667 enum XML_Error result
;
4668 OPEN_INTERNAL_ENTITY
*openEntity
;
4670 if (freeInternalEntities
) {
4671 openEntity
= freeInternalEntities
;
4672 freeInternalEntities
= openEntity
->next
;
4675 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4677 return XML_ERROR_NO_MEMORY
;
4679 entity
->open
= XML_TRUE
;
4680 entity
->processed
= 0;
4681 openEntity
->next
= openInternalEntities
;
4682 openInternalEntities
= openEntity
;
4683 openEntity
->entity
= entity
;
4684 openEntity
->startTagLevel
= tagLevel
;
4685 openEntity
->betweenDecl
= betweenDecl
;
4686 openEntity
->internalEventPtr
= NULL
;
4687 openEntity
->internalEventEndPtr
= NULL
;
4688 textStart
= (char *)entity
->textPtr
;
4689 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4692 if (entity
->is_param
) {
4693 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4694 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4695 next
, &next
, XML_FALSE
);
4698 #endif /* XML_DTD */
4699 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4700 textEnd
, &next
, XML_FALSE
);
4702 if (result
== XML_ERROR_NONE
) {
4703 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4704 entity
->processed
= (int)(next
- textStart
);
4705 processor
= internalEntityProcessor
;
4708 entity
->open
= XML_FALSE
;
4709 openInternalEntities
= openEntity
->next
;
4710 /* put openEntity back in list of free instances */
4711 openEntity
->next
= freeInternalEntities
;
4712 freeInternalEntities
= openEntity
;
4718 static enum XML_Error PTRCALL
4719 internalEntityProcessor(XML_Parser parser
,
4722 const char **nextPtr
)
4725 const char *textStart
, *textEnd
;
4727 enum XML_Error result
;
4728 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4730 return XML_ERROR_UNEXPECTED_STATE
;
4732 entity
= openEntity
->entity
;
4733 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4734 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4737 if (entity
->is_param
) {
4738 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4739 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4740 next
, &next
, XML_FALSE
);
4743 #endif /* XML_DTD */
4744 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4745 textStart
, textEnd
, &next
, XML_FALSE
);
4747 if (result
!= XML_ERROR_NONE
)
4749 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4750 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4754 entity
->open
= XML_FALSE
;
4755 openInternalEntities
= openEntity
->next
;
4756 /* put openEntity back in list of free instances */
4757 openEntity
->next
= freeInternalEntities
;
4758 freeInternalEntities
= openEntity
;
4762 if (entity
->is_param
) {
4764 processor
= prologProcessor
;
4765 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4766 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4767 (XML_Bool
)!ps_finalBuffer
);
4770 #endif /* XML_DTD */
4772 processor
= contentProcessor
;
4773 /* see externalEntityContentProcessor vs contentProcessor */
4774 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4775 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4779 static enum XML_Error PTRCALL
4780 errorProcessor(XML_Parser parser
,
4783 const char **nextPtr
)
4788 static enum XML_Error
4789 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4790 const char *ptr
, const char *end
,
4793 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4797 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4799 if (!poolAppendChar(pool
, XML_T('\0')))
4800 return XML_ERROR_NO_MEMORY
;
4801 return XML_ERROR_NONE
;
4804 static enum XML_Error
4805 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4806 const char *ptr
, const char *end
,
4809 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4812 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4815 return XML_ERROR_NONE
;
4816 case XML_TOK_INVALID
:
4817 if (enc
== encoding
)
4819 return XML_ERROR_INVALID_TOKEN
;
4820 case XML_TOK_PARTIAL
:
4821 if (enc
== encoding
)
4823 return XML_ERROR_INVALID_TOKEN
;
4824 case XML_TOK_CHAR_REF
:
4826 XML_Char buf
[XML_ENCODE_MAX
];
4828 int n
= XmlCharRefNumber(enc
, ptr
);
4830 if (enc
== encoding
)
4832 return XML_ERROR_BAD_CHAR_REF
;
4835 && n
== 0x20 /* space */
4836 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4838 n
= XmlEncode(n
, (ICHAR
*)buf
);
4840 if (enc
== encoding
)
4842 return XML_ERROR_BAD_CHAR_REF
;
4844 for (i
= 0; i
< n
; i
++) {
4845 if (!poolAppendChar(pool
, buf
[i
]))
4846 return XML_ERROR_NO_MEMORY
;
4850 case XML_TOK_DATA_CHARS
:
4851 if (!poolAppend(pool
, enc
, ptr
, next
))
4852 return XML_ERROR_NO_MEMORY
;
4854 case XML_TOK_TRAILING_CR
:
4855 next
= ptr
+ enc
->minBytesPerChar
;
4857 case XML_TOK_ATTRIBUTE_VALUE_S
:
4858 case XML_TOK_DATA_NEWLINE
:
4859 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4861 if (!poolAppendChar(pool
, 0x20))
4862 return XML_ERROR_NO_MEMORY
;
4864 case XML_TOK_ENTITY_REF
:
4866 const XML_Char
*name
;
4868 char checkEntityDecl
;
4869 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4870 ptr
+ enc
->minBytesPerChar
,
4871 next
- enc
->minBytesPerChar
);
4873 if (!poolAppendChar(pool
, ch
))
4874 return XML_ERROR_NO_MEMORY
;
4877 name
= poolStoreString(&temp2Pool
, enc
,
4878 ptr
+ enc
->minBytesPerChar
,
4879 next
- enc
->minBytesPerChar
);
4881 return XML_ERROR_NO_MEMORY
;
4882 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4883 poolDiscard(&temp2Pool
);
4884 /* First, determine if a check for an existing declaration is needed;
4885 if yes, check that the entity exists, and that it is internal.
4887 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4890 prologState
.documentEntity
&&
4891 #endif /* XML_DTD */
4893 ? !openInternalEntities
4894 : !dtd
->hasParamEntityRefs
);
4895 else /* if (pool == &tempPool): we are called from content */
4896 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4897 if (checkEntityDecl
) {
4899 return XML_ERROR_UNDEFINED_ENTITY
;
4900 else if (!entity
->is_internal
)
4901 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4904 /* Cannot report skipped entity here - see comments on
4905 skippedEntityHandler.
4906 if (skippedEntityHandler)
4907 skippedEntityHandler(handlerArg, name, 0);
4909 /* Cannot call the default handler because this would be
4910 out of sync with the call to the startElementHandler.
4911 if ((pool == &tempPool) && defaultHandler)
4912 reportDefault(parser, enc, ptr, next);
4917 if (enc
== encoding
)
4919 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4921 if (entity
->notation
) {
4922 if (enc
== encoding
)
4924 return XML_ERROR_BINARY_ENTITY_REF
;
4926 if (!entity
->textPtr
) {
4927 if (enc
== encoding
)
4929 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4932 enum XML_Error result
;
4933 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4934 entity
->open
= XML_TRUE
;
4935 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4936 (char *)entity
->textPtr
,
4937 (char *)textEnd
, pool
);
4938 entity
->open
= XML_FALSE
;
4945 if (enc
== encoding
)
4947 return XML_ERROR_UNEXPECTED_STATE
;
4954 static enum XML_Error
4955 storeEntityValue(XML_Parser parser
,
4956 const ENCODING
*enc
,
4957 const char *entityTextPtr
,
4958 const char *entityTextEnd
)
4960 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4961 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4962 enum XML_Error result
= XML_ERROR_NONE
;
4964 int oldInEntityValue
= prologState
.inEntityValue
;
4965 prologState
.inEntityValue
= 1;
4966 #endif /* XML_DTD */
4967 /* never return Null for the value argument in EntityDeclHandler,
4968 since this would indicate an external entity; therefore we
4969 have to make sure that entityValuePool.start is not null */
4970 if (!pool
->blocks
) {
4971 if (!poolGrow(pool
))
4972 return XML_ERROR_NO_MEMORY
;
4977 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4979 case XML_TOK_PARAM_ENTITY_REF
:
4981 if (isParamEntity
|| enc
!= encoding
) {
4982 const XML_Char
*name
;
4984 name
= poolStoreString(&tempPool
, enc
,
4985 entityTextPtr
+ enc
->minBytesPerChar
,
4986 next
- enc
->minBytesPerChar
);
4988 result
= XML_ERROR_NO_MEMORY
;
4989 goto endEntityValue
;
4991 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4992 poolDiscard(&tempPool
);
4994 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4995 /* cannot report skipped entity here - see comments on
4996 skippedEntityHandler
4997 if (skippedEntityHandler)
4998 skippedEntityHandler(handlerArg, name, 0);
5000 dtd
->keepProcessing
= dtd
->standalone
;
5001 goto endEntityValue
;
5004 if (enc
== encoding
)
5005 eventPtr
= entityTextPtr
;
5006 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5007 goto endEntityValue
;
5009 if (entity
->systemId
) {
5010 if (externalEntityRefHandler
) {
5011 dtd
->paramEntityRead
= XML_FALSE
;
5012 entity
->open
= XML_TRUE
;
5013 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5017 entity
->publicId
)) {
5018 entity
->open
= XML_FALSE
;
5019 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5020 goto endEntityValue
;
5022 entity
->open
= XML_FALSE
;
5023 if (!dtd
->paramEntityRead
)
5024 dtd
->keepProcessing
= dtd
->standalone
;
5027 dtd
->keepProcessing
= dtd
->standalone
;
5030 entity
->open
= XML_TRUE
;
5031 result
= storeEntityValue(parser
,
5033 (char *)entity
->textPtr
,
5034 (char *)(entity
->textPtr
5035 + entity
->textLen
));
5036 entity
->open
= XML_FALSE
;
5038 goto endEntityValue
;
5042 #endif /* XML_DTD */
5043 /* In the internal subset, PE references are not legal
5044 within markup declarations, e.g entity values in this case. */
5045 eventPtr
= entityTextPtr
;
5046 result
= XML_ERROR_PARAM_ENTITY_REF
;
5047 goto endEntityValue
;
5049 result
= XML_ERROR_NONE
;
5050 goto endEntityValue
;
5051 case XML_TOK_ENTITY_REF
:
5052 case XML_TOK_DATA_CHARS
:
5053 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5054 result
= XML_ERROR_NO_MEMORY
;
5055 goto endEntityValue
;
5058 case XML_TOK_TRAILING_CR
:
5059 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5061 case XML_TOK_DATA_NEWLINE
:
5062 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5063 result
= XML_ERROR_NO_MEMORY
;
5064 goto endEntityValue
;
5066 *(pool
->ptr
)++ = 0xA;
5068 case XML_TOK_CHAR_REF
:
5070 XML_Char buf
[XML_ENCODE_MAX
];
5072 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5074 if (enc
== encoding
)
5075 eventPtr
= entityTextPtr
;
5076 result
= XML_ERROR_BAD_CHAR_REF
;
5077 goto endEntityValue
;
5079 n
= XmlEncode(n
, (ICHAR
*)buf
);
5081 if (enc
== encoding
)
5082 eventPtr
= entityTextPtr
;
5083 result
= XML_ERROR_BAD_CHAR_REF
;
5084 goto endEntityValue
;
5086 for (i
= 0; i
< n
; i
++) {
5087 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5088 result
= XML_ERROR_NO_MEMORY
;
5089 goto endEntityValue
;
5091 *(pool
->ptr
)++ = buf
[i
];
5095 case XML_TOK_PARTIAL
:
5096 if (enc
== encoding
)
5097 eventPtr
= entityTextPtr
;
5098 result
= XML_ERROR_INVALID_TOKEN
;
5099 goto endEntityValue
;
5100 case XML_TOK_INVALID
:
5101 if (enc
== encoding
)
5103 result
= XML_ERROR_INVALID_TOKEN
;
5104 goto endEntityValue
;
5106 if (enc
== encoding
)
5107 eventPtr
= entityTextPtr
;
5108 result
= XML_ERROR_UNEXPECTED_STATE
;
5109 goto endEntityValue
;
5111 entityTextPtr
= next
;
5115 prologState
.inEntityValue
= oldInEntityValue
;
5116 #endif /* XML_DTD */
5120 static void FASTCALL
5121 normalizeLines(XML_Char
*s
)
5125 if (*s
== XML_T('\0'))
5144 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5145 const char *start
, const char *end
)
5147 const XML_Char
*target
;
5150 if (!processingInstructionHandler
) {
5152 reportDefault(parser
, enc
, start
, end
);
5155 start
+= enc
->minBytesPerChar
* 2;
5156 tem
= start
+ XmlNameLength(enc
, start
);
5157 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5160 poolFinish(&tempPool
);
5161 data
= poolStoreString(&tempPool
, enc
,
5163 end
- enc
->minBytesPerChar
*2);
5166 normalizeLines(data
);
5167 processingInstructionHandler(handlerArg
, target
, data
);
5168 poolClear(&tempPool
);
5173 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5174 const char *start
, const char *end
)
5177 if (!commentHandler
) {
5179 reportDefault(parser
, enc
, start
, end
);
5182 data
= poolStoreString(&tempPool
,
5184 start
+ enc
->minBytesPerChar
* 4,
5185 end
- enc
->minBytesPerChar
* 3);
5188 normalizeLines(data
);
5189 commentHandler(handlerArg
, data
);
5190 poolClear(&tempPool
);
5195 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5196 const char *s
, const char *end
)
5198 if (MUST_CONVERT(enc
, s
)) {
5199 const char **eventPP
;
5200 const char **eventEndPP
;
5201 if (enc
== encoding
) {
5202 eventPP
= &eventPtr
;
5203 eventEndPP
= &eventEndPtr
;
5206 eventPP
= &(openInternalEntities
->internalEventPtr
);
5207 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5210 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5211 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5213 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5218 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5223 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5224 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5226 DEFAULT_ATTRIBUTE
*att
;
5227 if (value
|| isId
) {
5228 /* The handling of default attributes gets messed up if we have
5229 a default which duplicates a non-default. */
5231 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5232 if (attId
== type
->defaultAtts
[i
].id
)
5234 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5235 type
->idAtt
= attId
;
5237 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5238 if (type
->allocDefaultAtts
== 0) {
5239 type
->allocDefaultAtts
= 8;
5240 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5241 * sizeof(DEFAULT_ATTRIBUTE
));
5242 if (!type
->defaultAtts
)
5246 DEFAULT_ATTRIBUTE
*temp
;
5247 int count
= type
->allocDefaultAtts
* 2;
5248 temp
= (DEFAULT_ATTRIBUTE
*)
5249 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5252 type
->allocDefaultAtts
= count
;
5253 type
->defaultAtts
= temp
;
5256 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5259 att
->isCdata
= isCdata
;
5261 attId
->maybeTokenized
= XML_TRUE
;
5262 type
->nDefaultAtts
+= 1;
5267 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5269 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5270 const XML_Char
*name
;
5271 for (name
= elementType
->name
; *name
; name
++) {
5272 if (*name
== XML_T(':')) {
5275 for (s
= elementType
->name
; s
!= name
; s
++) {
5276 if (!poolAppendChar(&dtd
->pool
, *s
))
5279 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5281 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5285 if (prefix
->name
== poolStart(&dtd
->pool
))
5286 poolFinish(&dtd
->pool
);
5288 poolDiscard(&dtd
->pool
);
5289 elementType
->prefix
= prefix
;
5296 static ATTRIBUTE_ID
*
5297 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5298 const char *start
, const char *end
)
5300 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5302 const XML_Char
*name
;
5303 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5305 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5308 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5310 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5313 if (id
->name
!= name
)
5314 poolDiscard(&dtd
->pool
);
5316 poolFinish(&dtd
->pool
);
5319 else if (name
[0] == XML_T('x')
5320 && name
[1] == XML_T('m')
5321 && name
[2] == XML_T('l')
5322 && name
[3] == XML_T('n')
5323 && name
[4] == XML_T('s')
5324 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
5325 if (name
[5] == XML_T('\0'))
5326 id
->prefix
= &dtd
->defaultPrefix
;
5328 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5329 id
->xmlns
= XML_TRUE
;
5333 for (i
= 0; name
[i
]; i
++) {
5334 /* attributes without prefix are *not* in the default namespace */
5335 if (name
[i
] == XML_T(':')) {
5337 for (j
= 0; j
< i
; j
++) {
5338 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5341 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5343 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5347 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5348 poolFinish(&dtd
->pool
);
5350 poolDiscard(&dtd
->pool
);
5359 #define CONTEXT_SEP XML_T('\f')
5361 static const XML_Char
*
5362 getContext(XML_Parser parser
)
5364 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5365 HASH_TABLE_ITER iter
;
5366 XML_Bool needSep
= XML_FALSE
;
5368 if (dtd
->defaultPrefix
.binding
) {
5371 if (!poolAppendChar(&tempPool
, XML_T('=')))
5373 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5374 if (namespaceSeparator
)
5376 for (i
= 0; i
< len
; i
++)
5377 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5382 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5387 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5390 if (!prefix
->binding
)
5392 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5394 for (s
= prefix
->name
; *s
; s
++)
5395 if (!poolAppendChar(&tempPool
, *s
))
5397 if (!poolAppendChar(&tempPool
, XML_T('=')))
5399 len
= prefix
->binding
->uriLen
;
5400 if (namespaceSeparator
)
5402 for (i
= 0; i
< len
; i
++)
5403 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5409 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5412 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5417 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5419 for (s
= e
->name
; *s
; s
++)
5420 if (!poolAppendChar(&tempPool
, *s
))
5425 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5427 return tempPool
.start
;
5431 setContext(XML_Parser parser
, const XML_Char
*context
)
5433 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5434 const XML_Char
*s
= context
;
5436 while (*context
!= XML_T('\0')) {
5437 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5439 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5441 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5444 if (*s
!= XML_T('\0'))
5447 poolDiscard(&tempPool
);
5449 else if (*s
== XML_T('=')) {
5451 if (poolLength(&tempPool
) == 0)
5452 prefix
= &dtd
->defaultPrefix
;
5454 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5456 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5460 if (prefix
->name
== poolStart(&tempPool
)) {
5461 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5465 poolDiscard(&tempPool
);
5467 for (context
= s
+ 1;
5468 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5470 if (!poolAppendChar(&tempPool
, *context
))
5472 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5474 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5475 &inheritedBindings
) != XML_ERROR_NONE
)
5477 poolDiscard(&tempPool
);
5478 if (*context
!= XML_T('\0'))
5483 if (!poolAppendChar(&tempPool
, *s
))
5491 static void FASTCALL
5492 normalizePublicId(XML_Char
*publicId
)
5494 XML_Char
*p
= publicId
;
5496 for (s
= publicId
; *s
; s
++) {
5501 if (p
!= publicId
&& p
[-1] != 0x20)
5508 if (p
!= publicId
&& p
[-1] == 0x20)
5514 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5516 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5519 poolInit(&(p
->pool
), ms
);
5520 poolInit(&(p
->entityValuePool
), ms
);
5521 hashTableInit(&(p
->generalEntities
), ms
);
5522 hashTableInit(&(p
->elementTypes
), ms
);
5523 hashTableInit(&(p
->attributeIds
), ms
);
5524 hashTableInit(&(p
->prefixes
), ms
);
5526 p
->paramEntityRead
= XML_FALSE
;
5527 hashTableInit(&(p
->paramEntities
), ms
);
5528 #endif /* XML_DTD */
5529 p
->defaultPrefix
.name
= NULL
;
5530 p
->defaultPrefix
.binding
= NULL
;
5532 p
->in_eldecl
= XML_FALSE
;
5533 p
->scaffIndex
= NULL
;
5538 p
->contentStringLen
= 0;
5540 p
->keepProcessing
= XML_TRUE
;
5541 p
->hasParamEntityRefs
= XML_FALSE
;
5542 p
->standalone
= XML_FALSE
;
5547 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5549 HASH_TABLE_ITER iter
;
5550 hashTableIterInit(&iter
, &(p
->elementTypes
));
5552 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5555 if (e
->allocDefaultAtts
!= 0)
5556 ms
->free_fcn(e
->defaultAtts
);
5558 hashTableClear(&(p
->generalEntities
));
5560 p
->paramEntityRead
= XML_FALSE
;
5561 hashTableClear(&(p
->paramEntities
));
5562 #endif /* XML_DTD */
5563 hashTableClear(&(p
->elementTypes
));
5564 hashTableClear(&(p
->attributeIds
));
5565 hashTableClear(&(p
->prefixes
));
5566 poolClear(&(p
->pool
));
5567 poolClear(&(p
->entityValuePool
));
5568 p
->defaultPrefix
.name
= NULL
;
5569 p
->defaultPrefix
.binding
= NULL
;
5571 p
->in_eldecl
= XML_FALSE
;
5573 ms
->free_fcn(p
->scaffIndex
);
5574 p
->scaffIndex
= NULL
;
5575 ms
->free_fcn(p
->scaffold
);
5581 p
->contentStringLen
= 0;
5583 p
->keepProcessing
= XML_TRUE
;
5584 p
->hasParamEntityRefs
= XML_FALSE
;
5585 p
->standalone
= XML_FALSE
;
5589 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5591 HASH_TABLE_ITER iter
;
5592 hashTableIterInit(&iter
, &(p
->elementTypes
));
5594 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5597 if (e
->allocDefaultAtts
!= 0)
5598 ms
->free_fcn(e
->defaultAtts
);
5600 hashTableDestroy(&(p
->generalEntities
));
5602 hashTableDestroy(&(p
->paramEntities
));
5603 #endif /* XML_DTD */
5604 hashTableDestroy(&(p
->elementTypes
));
5605 hashTableDestroy(&(p
->attributeIds
));
5606 hashTableDestroy(&(p
->prefixes
));
5607 poolDestroy(&(p
->pool
));
5608 poolDestroy(&(p
->entityValuePool
));
5610 ms
->free_fcn(p
->scaffIndex
);
5611 ms
->free_fcn(p
->scaffold
);
5616 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5617 The new DTD has already been initialized.
5620 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5622 HASH_TABLE_ITER iter
;
5624 /* Copy the prefix table. */
5626 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5628 const XML_Char
*name
;
5629 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5632 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5635 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5639 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5641 /* Copy the attribute id table. */
5645 const XML_Char
*name
;
5646 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5650 /* Remember to allocate the scratch byte before the name. */
5651 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5653 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5657 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5658 sizeof(ATTRIBUTE_ID
));
5661 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5663 newA
->xmlns
= oldA
->xmlns
;
5664 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5665 newA
->prefix
= &newDtd
->defaultPrefix
;
5667 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5668 oldA
->prefix
->name
, 0);
5672 /* Copy the element type table. */
5674 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5679 const XML_Char
*name
;
5680 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5683 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5686 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5687 sizeof(ELEMENT_TYPE
));
5690 if (oldE
->nDefaultAtts
) {
5691 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5692 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5693 if (!newE
->defaultAtts
) {
5699 newE
->idAtt
= (ATTRIBUTE_ID
*)
5700 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5701 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5703 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5704 oldE
->prefix
->name
, 0);
5705 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5706 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5707 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5708 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5709 if (oldE
->defaultAtts
[i
].value
) {
5710 newE
->defaultAtts
[i
].value
5711 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5712 if (!newE
->defaultAtts
[i
].value
)
5716 newE
->defaultAtts
[i
].value
= NULL
;
5720 /* Copy the entity tables. */
5721 if (!copyEntityTable(&(newDtd
->generalEntities
),
5723 &(oldDtd
->generalEntities
)))
5727 if (!copyEntityTable(&(newDtd
->paramEntities
),
5729 &(oldDtd
->paramEntities
)))
5731 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5732 #endif /* XML_DTD */
5734 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5735 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5736 newDtd
->standalone
= oldDtd
->standalone
;
5738 /* Don't want deep copying for scaffolding */
5739 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5740 newDtd
->scaffold
= oldDtd
->scaffold
;
5741 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5742 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5743 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5744 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5750 copyEntityTable(HASH_TABLE
*newTable
,
5751 STRING_POOL
*newPool
,
5752 const HASH_TABLE
*oldTable
)
5754 HASH_TABLE_ITER iter
;
5755 const XML_Char
*cachedOldBase
= NULL
;
5756 const XML_Char
*cachedNewBase
= NULL
;
5758 hashTableIterInit(&iter
, oldTable
);
5762 const XML_Char
*name
;
5763 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5766 name
= poolCopyString(newPool
, oldE
->name
);
5769 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5772 if (oldE
->systemId
) {
5773 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5776 newE
->systemId
= tem
;
5778 if (oldE
->base
== cachedOldBase
)
5779 newE
->base
= cachedNewBase
;
5781 cachedOldBase
= oldE
->base
;
5782 tem
= poolCopyString(newPool
, cachedOldBase
);
5785 cachedNewBase
= newE
->base
= tem
;
5788 if (oldE
->publicId
) {
5789 tem
= poolCopyString(newPool
, oldE
->publicId
);
5792 newE
->publicId
= tem
;
5796 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5800 newE
->textPtr
= tem
;
5801 newE
->textLen
= oldE
->textLen
;
5803 if (oldE
->notation
) {
5804 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5807 newE
->notation
= tem
;
5809 newE
->is_param
= oldE
->is_param
;
5810 newE
->is_internal
= oldE
->is_internal
;
5815 #define INIT_POWER 6
5817 static XML_Bool FASTCALL
5818 keyeq(KEY s1
, KEY s2
)
5820 for (; *s1
== *s2
; s1
++, s2
++)
5826 static unsigned long FASTCALL
5829 unsigned long h
= 0;
5831 h
= CHAR_HASH(h
, *s
++);
5836 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5839 if (table
->size
== 0) {
5843 table
->power
= INIT_POWER
;
5844 /* table->size is a power of 2 */
5845 table
->size
= (size_t)1 << INIT_POWER
;
5846 tsize
= table
->size
* sizeof(NAMED
*);
5847 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5852 memset(table
->v
, 0, tsize
);
5853 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5856 unsigned long h
= hash(name
);
5857 unsigned long mask
= (unsigned long)table
->size
- 1;
5858 unsigned char step
= 0;
5860 while (table
->v
[i
]) {
5861 if (keyeq(name
, table
->v
[i
]->name
))
5864 step
= PROBE_STEP(h
, mask
, table
->power
);
5865 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5870 /* check for overflow (table is half full) */
5871 if (table
->used
>> (table
->power
- 1)) {
5872 unsigned char newPower
= table
->power
+ 1;
5873 size_t newSize
= (size_t)1 << newPower
;
5874 unsigned long newMask
= (unsigned long)newSize
- 1;
5875 size_t tsize
= newSize
* sizeof(NAMED
*);
5876 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5879 memset(newV
, 0, tsize
);
5880 for (i
= 0; i
< table
->size
; i
++)
5882 unsigned long newHash
= hash(table
->v
[i
]->name
);
5883 size_t j
= newHash
& newMask
;
5887 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5888 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5890 newV
[j
] = table
->v
[i
];
5892 table
->mem
->free_fcn(table
->v
);
5894 table
->power
= newPower
;
5895 table
->size
= newSize
;
5898 while (table
->v
[i
]) {
5900 step
= PROBE_STEP(h
, newMask
, newPower
);
5901 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5905 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5908 memset(table
->v
[i
], 0, createSize
);
5909 table
->v
[i
]->name
= name
;
5914 static void FASTCALL
5915 hashTableClear(HASH_TABLE
*table
)
5918 for (i
= 0; i
< table
->size
; i
++) {
5919 table
->mem
->free_fcn(table
->v
[i
]);
5925 static void FASTCALL
5926 hashTableDestroy(HASH_TABLE
*table
)
5929 for (i
= 0; i
< table
->size
; i
++)
5930 table
->mem
->free_fcn(table
->v
[i
]);
5931 table
->mem
->free_fcn(table
->v
);
5934 static void FASTCALL
5935 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5944 static void FASTCALL
5945 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5948 iter
->end
= iter
->p
+ table
->size
;
5951 static NAMED
* FASTCALL
5952 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5954 while (iter
->p
!= iter
->end
) {
5955 NAMED
*tem
= *(iter
->p
)++;
5962 static void FASTCALL
5963 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5965 pool
->blocks
= NULL
;
5966 pool
->freeBlocks
= NULL
;
5973 static void FASTCALL
5974 poolClear(STRING_POOL
*pool
)
5976 if (!pool
->freeBlocks
)
5977 pool
->freeBlocks
= pool
->blocks
;
5979 BLOCK
*p
= pool
->blocks
;
5981 BLOCK
*tem
= p
->next
;
5982 p
->next
= pool
->freeBlocks
;
5983 pool
->freeBlocks
= p
;
5987 pool
->blocks
= NULL
;
5993 static void FASTCALL
5994 poolDestroy(STRING_POOL
*pool
)
5996 BLOCK
*p
= pool
->blocks
;
5998 BLOCK
*tem
= p
->next
;
5999 pool
->mem
->free_fcn(p
);
6002 p
= pool
->freeBlocks
;
6004 BLOCK
*tem
= p
->next
;
6005 pool
->mem
->free_fcn(p
);
6011 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6012 const char *ptr
, const char *end
)
6014 if (!pool
->ptr
&& !poolGrow(pool
))
6017 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6020 if (!poolGrow(pool
))
6026 static const XML_Char
* FASTCALL
6027 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6030 if (!poolAppendChar(pool
, *s
))
6038 static const XML_Char
*
6039 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6041 if (!pool
->ptr
&& !poolGrow(pool
))
6043 for (; n
> 0; --n
, s
++) {
6044 if (!poolAppendChar(pool
, *s
))
6052 static const XML_Char
* FASTCALL
6053 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6056 if (!poolAppendChar(pool
, *s
))
6064 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6065 const char *ptr
, const char *end
)
6067 if (!poolAppend(pool
, enc
, ptr
, end
))
6069 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6075 static XML_Bool FASTCALL
6076 poolGrow(STRING_POOL
*pool
)
6078 if (pool
->freeBlocks
) {
6079 if (pool
->start
== 0) {
6080 pool
->blocks
= pool
->freeBlocks
;
6081 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6082 pool
->blocks
->next
= NULL
;
6083 pool
->start
= pool
->blocks
->s
;
6084 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6085 pool
->ptr
= pool
->start
;
6088 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6089 BLOCK
*tem
= pool
->freeBlocks
->next
;
6090 pool
->freeBlocks
->next
= pool
->blocks
;
6091 pool
->blocks
= pool
->freeBlocks
;
6092 pool
->freeBlocks
= tem
;
6093 memcpy(pool
->blocks
->s
, pool
->start
,
6094 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6095 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6096 pool
->start
= pool
->blocks
->s
;
6097 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6101 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6102 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6103 pool
->blocks
= (BLOCK
*)
6104 pool
->mem
->realloc_fcn(pool
->blocks
,
6106 + blockSize
* sizeof(XML_Char
)));
6107 if (pool
->blocks
== NULL
)
6109 pool
->blocks
->size
= blockSize
;
6110 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6111 pool
->start
= pool
->blocks
->s
;
6112 pool
->end
= pool
->start
+ blockSize
;
6116 int blockSize
= (int)(pool
->end
- pool
->start
);
6117 if (blockSize
< INIT_BLOCK_SIZE
)
6118 blockSize
= INIT_BLOCK_SIZE
;
6121 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6122 + blockSize
* sizeof(XML_Char
));
6125 tem
->size
= blockSize
;
6126 tem
->next
= pool
->blocks
;
6128 if (pool
->ptr
!= pool
->start
)
6129 memcpy(tem
->s
, pool
->start
,
6130 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6131 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6132 pool
->start
= tem
->s
;
6133 pool
->end
= tem
->s
+ blockSize
;
6139 nextScaffoldPart(XML_Parser parser
)
6141 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6142 CONTENT_SCAFFOLD
* me
;
6145 if (!dtd
->scaffIndex
) {
6146 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6147 if (!dtd
->scaffIndex
)
6149 dtd
->scaffIndex
[0] = 0;
6152 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6153 CONTENT_SCAFFOLD
*temp
;
6154 if (dtd
->scaffold
) {
6155 temp
= (CONTENT_SCAFFOLD
*)
6156 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6159 dtd
->scaffSize
*= 2;
6162 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6163 * sizeof(CONTENT_SCAFFOLD
));
6166 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6168 dtd
->scaffold
= temp
;
6170 next
= dtd
->scaffCount
++;
6171 me
= &dtd
->scaffold
[next
];
6172 if (dtd
->scaffLevel
) {
6173 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6174 if (parent
->lastchild
) {
6175 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6177 if (!parent
->childcnt
)
6178 parent
->firstchild
= next
;
6179 parent
->lastchild
= next
;
6182 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6187 build_node(XML_Parser parser
,
6190 XML_Content
**contpos
,
6193 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6194 dest
->type
= dtd
->scaffold
[src_node
].type
;
6195 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6196 if (dest
->type
== XML_CTYPE_NAME
) {
6197 const XML_Char
*src
;
6198 dest
->name
= *strpos
;
6199 src
= dtd
->scaffold
[src_node
].name
;
6201 *(*strpos
)++ = *src
;
6206 dest
->numchildren
= 0;
6207 dest
->children
= NULL
;
6212 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6213 dest
->children
= *contpos
;
6214 *contpos
+= dest
->numchildren
;
6215 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6216 i
< dest
->numchildren
;
6217 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6218 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6224 static XML_Content
*
6225 build_model (XML_Parser parser
)
6227 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6231 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6232 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6234 ret
= (XML_Content
*)MALLOC(allocsize
);
6238 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6241 build_node(parser
, 0, ret
, &cpos
, &str
);
6245 static ELEMENT_TYPE
*
6246 getElementType(XML_Parser parser
,
6247 const ENCODING
*enc
,
6251 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6252 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6257 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6260 if (ret
->name
!= name
)
6261 poolDiscard(&dtd
->pool
);
6263 poolFinish(&dtd
->pool
);
6264 if (!setElementTypePrefix(parser
, ret
))