1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
9 #define XML_BUILDING_EXPAT 1
11 #ifdef COMPILED_FROM_DSP
12 #include "winconfig.h"
13 #elif defined(MACOS_CLASSIC)
14 #include "macconfig.h"
15 #elif defined(__amigaos4__)
16 #include "amigaconfig.h"
17 #elif defined(__WATCOMC__)
18 #include "watcomconfig.h"
19 #elif defined(HAVE_EXPAT_CONFIG_H)
20 #include <expat_config.h>
21 #endif /* ndef COMPILED_FROM_DSP */
26 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
27 #define XmlConvert XmlUtf16Convert
28 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
29 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
30 #define XmlEncode XmlUtf16Encode
31 /* Using pointer subtraction to convert to integer type. */
32 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
33 typedef unsigned short ICHAR
;
35 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
36 #define XmlConvert XmlUtf8Convert
37 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
38 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
39 #define XmlEncode XmlUtf8Encode
40 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
47 #define XmlInitEncodingNS XmlInitEncoding
48 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
49 #undef XmlGetInternalEncodingNS
50 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
51 #define XmlParseXmlDeclNS XmlParseXmlDecl
57 #ifdef XML_UNICODE_WCHAR_T
58 #define XML_T(x) (const wchar_t)x
59 #define XML_L(x) L ## x
61 #define XML_T(x) (const unsigned short)x
72 /* Round up n to be a multiple of sz, where sz is a power of 2. */
73 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
75 /* Handle the case where memmove() doesn't exist. */
78 #define memmove(d,s,l) bcopy((s),(d),(l))
80 #error memmove does not exist on this platform, nor is a substitute available
81 #endif /* HAVE_BCOPY */
82 #endif /* HAVE_MEMMOVE */
88 typedef const XML_Char
*KEY
;
99 const XML_Memory_Handling_Suite
*mem
;
102 /* Basic character hash algorithm, taken from Python's string hash:
103 h = h * 1000003 ^ character, the constant being a prime number.
107 #define CHAR_HASH(h, c) \
108 (((h) * 0xF4243) ^ (unsigned short)(c))
110 #define CHAR_HASH(h, c) \
111 (((h) * 0xF4243) ^ (unsigned char)(c))
114 /* For probing (after a collision) we need a step size relative prime
115 to the hash table size, which is a power of 2. We use double-hashing,
116 since we can calculate a second hash value cheaply by taking those bits
117 of the first hash value that were discarded (masked out) when the table
118 index was calculated: index = hash & mask, where mask = table->size - 1.
119 We limit the maximum step size to table->size / 4 (mask >> 2) and make
120 it odd, since odd numbers are always relative prime to a power of 2.
122 #define SECOND_HASH(hash, mask, power) \
123 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
124 #define PROBE_STEP(hash, mask, power) \
125 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
132 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
133 #define INIT_DATA_BUF_SIZE 1024
134 #define INIT_ATTS_SIZE 16
135 #define INIT_ATTS_VERSION 0xFFFFFFFF
136 #define INIT_BLOCK_SIZE 1024
137 #define INIT_BUFFER_SIZE 1024
139 #define EXPAND_SPARE 24
141 typedef struct binding
{
142 struct prefix
*prefix
;
143 struct binding
*nextTagBinding
;
144 struct binding
*prevPrefixBinding
;
145 const struct attribute_id
*attId
;
151 typedef struct prefix
{
152 const XML_Char
*name
;
158 const XML_Char
*localPart
;
159 const XML_Char
*prefix
;
165 /* TAG represents an open element.
166 The name of the element is stored in both the document and API
167 encodings. The memory buffer 'buf' is a separately-allocated
168 memory area which stores the name. During the XML_Parse()/
169 XMLParseBuffer() when the element is open, the memory for the 'raw'
170 version of the name (in the document encoding) is shared with the
171 document buffer. If the element is open across calls to
172 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
173 contain the 'raw' name as well.
175 A parser re-uses these structures, maintaining a list of allocated
176 TAG objects in a free list.
179 struct tag
*parent
; /* parent of this element */
180 const char *rawName
; /* tagName in the original encoding */
182 TAG_NAME name
; /* tagName in the API encoding */
183 char *buf
; /* buffer for name components */
184 char *bufEnd
; /* end of the buffer */
189 const XML_Char
*name
;
190 const XML_Char
*textPtr
;
191 int textLen
; /* length in XML_Chars */
192 int processed
; /* # of processed bytes - when suspended */
193 const XML_Char
*systemId
;
194 const XML_Char
*base
;
195 const XML_Char
*publicId
;
196 const XML_Char
*notation
;
199 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
203 enum XML_Content_Type type
;
204 enum XML_Content_Quant quant
;
205 const XML_Char
* name
;
212 #define INIT_SCAFFOLD_ELEMENTS 32
214 typedef struct block
{
226 const XML_Memory_Handling_Suite
*mem
;
229 /* The XML_Char before the name is used to determine whether
230 an attribute has been specified. */
231 typedef struct attribute_id
{
234 XML_Bool maybeTokenized
;
239 const ATTRIBUTE_ID
*id
;
241 const XML_Char
*value
;
245 unsigned long version
;
247 const XML_Char
*uriName
;
251 const XML_Char
*name
;
253 const ATTRIBUTE_ID
*idAtt
;
255 int allocDefaultAtts
;
256 DEFAULT_ATTRIBUTE
*defaultAtts
;
260 HASH_TABLE generalEntities
;
261 HASH_TABLE elementTypes
;
262 HASH_TABLE attributeIds
;
265 STRING_POOL entityValuePool
;
266 /* false once a parameter entity reference has been skipped */
267 XML_Bool keepProcessing
;
268 /* true once an internal or external PE reference has been encountered;
269 this includes the reference to an external subset */
270 XML_Bool hasParamEntityRefs
;
273 /* indicates if external PE has been read */
274 XML_Bool paramEntityRead
;
275 HASH_TABLE paramEntities
;
277 PREFIX defaultPrefix
;
278 /* === scaffolding for building content model === */
280 CONTENT_SCAFFOLD
*scaffold
;
281 unsigned contentStringLen
;
288 typedef struct open_internal_entity
{
289 const char *internalEventPtr
;
290 const char *internalEventEndPtr
;
291 struct open_internal_entity
*next
;
294 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
295 } OPEN_INTERNAL_ENTITY
;
297 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
300 const char **endPtr
);
302 static Processor prologProcessor
;
303 static Processor prologInitProcessor
;
304 static Processor contentProcessor
;
305 static Processor cdataSectionProcessor
;
307 static Processor ignoreSectionProcessor
;
308 static Processor externalParEntProcessor
;
309 static Processor externalParEntInitProcessor
;
310 static Processor entityValueProcessor
;
311 static Processor entityValueInitProcessor
;
313 static Processor epilogProcessor
;
314 static Processor errorProcessor
;
315 static Processor externalEntityInitProcessor
;
316 static Processor externalEntityInitProcessor2
;
317 static Processor externalEntityInitProcessor3
;
318 static Processor externalEntityContentProcessor
;
319 static Processor internalEntityProcessor
;
321 static enum XML_Error
322 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
323 static enum XML_Error
324 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
325 const char *s
, const char *next
);
326 static enum XML_Error
327 initializeEncoding(XML_Parser parser
);
328 static enum XML_Error
329 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
330 const char *end
, int tok
, const char *next
, const char **nextPtr
,
332 static enum XML_Error
333 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
334 XML_Bool betweenDecl
);
335 static enum XML_Error
336 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
337 const char *start
, const char *end
, const char **endPtr
,
339 static enum XML_Error
340 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
341 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
343 static enum XML_Error
344 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
345 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
348 static enum XML_Error
349 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
350 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
351 static enum XML_Error
352 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
353 const XML_Char
*uri
, BINDING
**bindingsPtr
);
355 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
356 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
357 static enum XML_Error
358 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
359 const char *, const char *, STRING_POOL
*);
360 static enum XML_Error
361 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
362 const char *, const char *, STRING_POOL
*);
363 static ATTRIBUTE_ID
*
364 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
367 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
368 static enum XML_Error
369 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
372 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
373 const char *start
, const char *end
);
375 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
378 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
381 static const XML_Char
* getContext(XML_Parser parser
);
383 setContext(XML_Parser parser
, const XML_Char
*context
);
385 static void FASTCALL
normalizePublicId(XML_Char
*s
);
387 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
388 /* do not call if parentParser != NULL */
389 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
391 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
393 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
395 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
398 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
400 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
401 static void FASTCALL
hashTableClear(HASH_TABLE
*);
402 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
404 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
405 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
408 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
409 static void FASTCALL
poolClear(STRING_POOL
*);
410 static void FASTCALL
poolDestroy(STRING_POOL
*);
412 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
413 const char *ptr
, const char *end
);
415 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
416 const char *ptr
, const char *end
);
417 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
418 static const XML_Char
* FASTCALL
419 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
420 static const XML_Char
*
421 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
422 static const XML_Char
* FASTCALL
423 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
425 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
426 static XML_Content
* build_model(XML_Parser parser
);
427 static ELEMENT_TYPE
*
428 getElementType(XML_Parser parser
, const ENCODING
*enc
,
429 const char *ptr
, const char *end
);
432 parserCreate(const XML_Char
*encodingName
,
433 const XML_Memory_Handling_Suite
*memsuite
,
434 const XML_Char
*nameSep
,
437 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
439 #define poolStart(pool) ((pool)->start)
440 #define poolEnd(pool) ((pool)->ptr)
441 #define poolLength(pool) ((pool)->ptr - (pool)->start)
442 #define poolChop(pool) ((void)--(pool->ptr))
443 #define poolLastChar(pool) (((pool)->ptr)[-1])
444 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
445 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
446 #define poolAppendChar(pool, c) \
447 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
449 : ((*((pool)->ptr)++ = c), 1))
451 struct XML_ParserStruct
{
452 /* The first member must be userData so that the XML_GetUserData
457 const XML_Memory_Handling_Suite m_mem
;
458 /* first character to be parsed */
459 const char *m_bufferPtr
;
460 /* past last character to be parsed */
462 /* allocated end of buffer */
463 const char *m_bufferLim
;
464 XML_Index m_parseEndByteIndex
;
465 const char *m_parseEndPtr
;
467 XML_Char
*m_dataBufEnd
;
468 XML_StartElementHandler m_startElementHandler
;
469 XML_EndElementHandler m_endElementHandler
;
470 XML_CharacterDataHandler m_characterDataHandler
;
471 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
472 XML_CommentHandler m_commentHandler
;
473 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
474 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
475 XML_DefaultHandler m_defaultHandler
;
476 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
477 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
478 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
479 XML_NotationDeclHandler m_notationDeclHandler
;
480 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
481 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
482 XML_NotStandaloneHandler m_notStandaloneHandler
;
483 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
484 XML_Parser m_externalEntityRefHandlerArg
;
485 XML_SkippedEntityHandler m_skippedEntityHandler
;
486 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
487 XML_ElementDeclHandler m_elementDeclHandler
;
488 XML_AttlistDeclHandler m_attlistDeclHandler
;
489 XML_EntityDeclHandler m_entityDeclHandler
;
490 XML_XmlDeclHandler m_xmlDeclHandler
;
491 const ENCODING
*m_encoding
;
492 INIT_ENCODING m_initEncoding
;
493 const ENCODING
*m_internalEncoding
;
494 const XML_Char
*m_protocolEncodingName
;
496 XML_Bool m_ns_triplets
;
497 void *m_unknownEncodingMem
;
498 void *m_unknownEncodingData
;
499 void *m_unknownEncodingHandlerData
;
500 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
501 PROLOG_STATE m_prologState
;
502 Processor
*m_processor
;
503 enum XML_Error m_errorCode
;
504 const char *m_eventPtr
;
505 const char *m_eventEndPtr
;
506 const char *m_positionPtr
;
507 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
508 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
509 XML_Bool m_defaultExpandInternalEntities
;
511 ENTITY
*m_declEntity
;
512 const XML_Char
*m_doctypeName
;
513 const XML_Char
*m_doctypeSysid
;
514 const XML_Char
*m_doctypePubid
;
515 const XML_Char
*m_declAttributeType
;
516 const XML_Char
*m_declNotationName
;
517 const XML_Char
*m_declNotationPublicId
;
518 ELEMENT_TYPE
*m_declElementType
;
519 ATTRIBUTE_ID
*m_declAttributeId
;
520 XML_Bool m_declAttributeIsCdata
;
521 XML_Bool m_declAttributeIsId
;
523 const XML_Char
*m_curBase
;
526 BINDING
*m_inheritedBindings
;
527 BINDING
*m_freeBindingList
;
529 int m_nSpecifiedAtts
;
533 unsigned long m_nsAttsVersion
;
534 unsigned char m_nsAttsPower
;
536 STRING_POOL m_tempPool
;
537 STRING_POOL m_temp2Pool
;
538 char *m_groupConnector
;
539 unsigned int m_groupSize
;
540 XML_Char m_namespaceSeparator
;
541 XML_Parser m_parentParser
;
542 XML_ParsingStatus m_parsingStatus
;
544 XML_Bool m_isParamEntity
;
545 XML_Bool m_useForeignDTD
;
546 enum XML_ParamEntityParsing m_paramEntityParsing
;
550 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
551 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
552 #define FREE(p) (parser->m_mem.free_fcn((p)))
554 #define userData (parser->m_userData)
555 #define handlerArg (parser->m_handlerArg)
556 #define startElementHandler (parser->m_startElementHandler)
557 #define endElementHandler (parser->m_endElementHandler)
558 #define characterDataHandler (parser->m_characterDataHandler)
559 #define processingInstructionHandler \
560 (parser->m_processingInstructionHandler)
561 #define commentHandler (parser->m_commentHandler)
562 #define startCdataSectionHandler \
563 (parser->m_startCdataSectionHandler)
564 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
565 #define defaultHandler (parser->m_defaultHandler)
566 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
567 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
568 #define unparsedEntityDeclHandler \
569 (parser->m_unparsedEntityDeclHandler)
570 #define notationDeclHandler (parser->m_notationDeclHandler)
571 #define startNamespaceDeclHandler \
572 (parser->m_startNamespaceDeclHandler)
573 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
574 #define notStandaloneHandler (parser->m_notStandaloneHandler)
575 #define externalEntityRefHandler \
576 (parser->m_externalEntityRefHandler)
577 #define externalEntityRefHandlerArg \
578 (parser->m_externalEntityRefHandlerArg)
579 #define internalEntityRefHandler \
580 (parser->m_internalEntityRefHandler)
581 #define skippedEntityHandler (parser->m_skippedEntityHandler)
582 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
583 #define elementDeclHandler (parser->m_elementDeclHandler)
584 #define attlistDeclHandler (parser->m_attlistDeclHandler)
585 #define entityDeclHandler (parser->m_entityDeclHandler)
586 #define xmlDeclHandler (parser->m_xmlDeclHandler)
587 #define encoding (parser->m_encoding)
588 #define initEncoding (parser->m_initEncoding)
589 #define internalEncoding (parser->m_internalEncoding)
590 #define unknownEncodingMem (parser->m_unknownEncodingMem)
591 #define unknownEncodingData (parser->m_unknownEncodingData)
592 #define unknownEncodingHandlerData \
593 (parser->m_unknownEncodingHandlerData)
594 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
595 #define protocolEncodingName (parser->m_protocolEncodingName)
596 #define ns (parser->m_ns)
597 #define ns_triplets (parser->m_ns_triplets)
598 #define prologState (parser->m_prologState)
599 #define processor (parser->m_processor)
600 #define errorCode (parser->m_errorCode)
601 #define eventPtr (parser->m_eventPtr)
602 #define eventEndPtr (parser->m_eventEndPtr)
603 #define positionPtr (parser->m_positionPtr)
604 #define position (parser->m_position)
605 #define openInternalEntities (parser->m_openInternalEntities)
606 #define freeInternalEntities (parser->m_freeInternalEntities)
607 #define defaultExpandInternalEntities \
608 (parser->m_defaultExpandInternalEntities)
609 #define tagLevel (parser->m_tagLevel)
610 #define buffer (parser->m_buffer)
611 #define bufferPtr (parser->m_bufferPtr)
612 #define bufferEnd (parser->m_bufferEnd)
613 #define parseEndByteIndex (parser->m_parseEndByteIndex)
614 #define parseEndPtr (parser->m_parseEndPtr)
615 #define bufferLim (parser->m_bufferLim)
616 #define dataBuf (parser->m_dataBuf)
617 #define dataBufEnd (parser->m_dataBufEnd)
618 #define _dtd (parser->m_dtd)
619 #define curBase (parser->m_curBase)
620 #define declEntity (parser->m_declEntity)
621 #define doctypeName (parser->m_doctypeName)
622 #define doctypeSysid (parser->m_doctypeSysid)
623 #define doctypePubid (parser->m_doctypePubid)
624 #define declAttributeType (parser->m_declAttributeType)
625 #define declNotationName (parser->m_declNotationName)
626 #define declNotationPublicId (parser->m_declNotationPublicId)
627 #define declElementType (parser->m_declElementType)
628 #define declAttributeId (parser->m_declAttributeId)
629 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
630 #define declAttributeIsId (parser->m_declAttributeIsId)
631 #define freeTagList (parser->m_freeTagList)
632 #define freeBindingList (parser->m_freeBindingList)
633 #define inheritedBindings (parser->m_inheritedBindings)
634 #define tagStack (parser->m_tagStack)
635 #define atts (parser->m_atts)
636 #define attsSize (parser->m_attsSize)
637 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
638 #define idAttIndex (parser->m_idAttIndex)
639 #define nsAtts (parser->m_nsAtts)
640 #define nsAttsVersion (parser->m_nsAttsVersion)
641 #define nsAttsPower (parser->m_nsAttsPower)
642 #define tempPool (parser->m_tempPool)
643 #define temp2Pool (parser->m_temp2Pool)
644 #define groupConnector (parser->m_groupConnector)
645 #define groupSize (parser->m_groupSize)
646 #define namespaceSeparator (parser->m_namespaceSeparator)
647 #define parentParser (parser->m_parentParser)
648 #define ps_parsing (parser->m_parsingStatus.parsing)
649 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
651 #define isParamEntity (parser->m_isParamEntity)
652 #define useForeignDTD (parser->m_useForeignDTD)
653 #define paramEntityParsing (parser->m_paramEntityParsing)
657 XML_ParserCreate(const XML_Char
*encodingName
)
659 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
663 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
667 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
670 static const XML_Char implicitContext
[] = {
671 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
672 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
673 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
674 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
678 XML_ParserCreate_MM(const XML_Char
*encodingName
,
679 const XML_Memory_Handling_Suite
*memsuite
,
680 const XML_Char
*nameSep
)
682 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
683 if (parser
!= NULL
&& ns
) {
684 /* implicit context only set for root parser, since child
685 parsers (i.e. external entity parsers) will inherit it
687 if (!setContext(parser
, implicitContext
)) {
688 XML_ParserFree(parser
);
696 parserCreate(const XML_Char
*encodingName
,
697 const XML_Memory_Handling_Suite
*memsuite
,
698 const XML_Char
*nameSep
,
704 XML_Memory_Handling_Suite
*mtemp
;
705 parser
= (XML_Parser
)
706 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
707 if (parser
!= NULL
) {
708 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
709 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
710 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
711 mtemp
->free_fcn
= memsuite
->free_fcn
;
715 XML_Memory_Handling_Suite
*mtemp
;
716 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
717 if (parser
!= NULL
) {
718 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
719 mtemp
->malloc_fcn
= malloc
;
720 mtemp
->realloc_fcn
= realloc
;
721 mtemp
->free_fcn
= free
;
731 attsSize
= INIT_ATTS_SIZE
;
732 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
737 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
738 if (dataBuf
== NULL
) {
743 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
748 _dtd
= dtdCreate(&parser
->m_mem
);
757 freeBindingList
= NULL
;
759 freeInternalEntities
= NULL
;
762 groupConnector
= NULL
;
764 unknownEncodingHandler
= NULL
;
765 unknownEncodingHandlerData
= NULL
;
767 namespaceSeparator
= '!';
769 ns_triplets
= XML_FALSE
;
775 poolInit(&tempPool
, &(parser
->m_mem
));
776 poolInit(&temp2Pool
, &(parser
->m_mem
));
777 parserInit(parser
, encodingName
);
779 if (encodingName
&& !protocolEncodingName
) {
780 XML_ParserFree(parser
);
786 internalEncoding
= XmlGetInternalEncodingNS();
787 namespaceSeparator
= *nameSep
;
790 internalEncoding
= XmlGetInternalEncoding();
797 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
799 processor
= prologInitProcessor
;
800 XmlPrologStateInit(&prologState
);
801 protocolEncodingName
= (encodingName
!= NULL
802 ? poolCopyString(&tempPool
, encodingName
)
805 XmlInitEncoding(&initEncoding
, &encoding
, 0);
808 startElementHandler
= NULL
;
809 endElementHandler
= NULL
;
810 characterDataHandler
= NULL
;
811 processingInstructionHandler
= NULL
;
812 commentHandler
= NULL
;
813 startCdataSectionHandler
= NULL
;
814 endCdataSectionHandler
= NULL
;
815 defaultHandler
= NULL
;
816 startDoctypeDeclHandler
= NULL
;
817 endDoctypeDeclHandler
= NULL
;
818 unparsedEntityDeclHandler
= NULL
;
819 notationDeclHandler
= NULL
;
820 startNamespaceDeclHandler
= NULL
;
821 endNamespaceDeclHandler
= NULL
;
822 notStandaloneHandler
= NULL
;
823 externalEntityRefHandler
= NULL
;
824 externalEntityRefHandlerArg
= parser
;
825 skippedEntityHandler
= NULL
;
826 elementDeclHandler
= NULL
;
827 attlistDeclHandler
= NULL
;
828 entityDeclHandler
= NULL
;
829 xmlDeclHandler
= NULL
;
832 parseEndByteIndex
= 0;
834 declElementType
= NULL
;
835 declAttributeId
= NULL
;
840 declAttributeType
= NULL
;
841 declNotationName
= NULL
;
842 declNotationPublicId
= NULL
;
843 declAttributeIsCdata
= XML_FALSE
;
844 declAttributeIsId
= XML_FALSE
;
845 memset(&position
, 0, sizeof(POSITION
));
846 errorCode
= XML_ERROR_NONE
;
850 openInternalEntities
= NULL
;
851 defaultExpandInternalEntities
= XML_TRUE
;
854 inheritedBindings
= NULL
;
856 unknownEncodingMem
= NULL
;
857 unknownEncodingRelease
= NULL
;
858 unknownEncodingData
= NULL
;
860 ps_parsing
= XML_INITIALIZED
;
862 isParamEntity
= XML_FALSE
;
863 useForeignDTD
= XML_FALSE
;
864 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
868 /* moves list of bindings to freeBindingList */
870 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
873 BINDING
*b
= bindings
;
874 bindings
= bindings
->nextTagBinding
;
875 b
->nextTagBinding
= freeBindingList
;
881 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
884 OPEN_INTERNAL_ENTITY
*openEntityList
;
887 /* move tagStack to freeTagList */
892 tag
->parent
= freeTagList
;
893 moveToFreeBindingList(parser
, tag
->bindings
);
894 tag
->bindings
= NULL
;
897 /* move openInternalEntities to freeInternalEntities */
898 openEntityList
= openInternalEntities
;
899 while (openEntityList
) {
900 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
901 openEntityList
= openEntity
->next
;
902 openEntity
->next
= freeInternalEntities
;
903 freeInternalEntities
= openEntity
;
905 moveToFreeBindingList(parser
, inheritedBindings
);
906 FREE(unknownEncodingMem
);
907 if (unknownEncodingRelease
)
908 unknownEncodingRelease(unknownEncodingData
);
909 poolClear(&tempPool
);
910 poolClear(&temp2Pool
);
911 parserInit(parser
, encodingName
);
912 dtdReset(_dtd
, &parser
->m_mem
);
913 return setContext(parser
, implicitContext
);
916 enum XML_Status XMLCALL
917 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
919 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
920 XXX There's no way for the caller to determine which of the
921 XXX possible error cases caused the XML_STATUS_ERROR return.
923 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
924 return XML_STATUS_ERROR
;
925 if (encodingName
== NULL
)
926 protocolEncodingName
= NULL
;
928 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
929 if (!protocolEncodingName
)
930 return XML_STATUS_ERROR
;
932 return XML_STATUS_OK
;
936 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
937 const XML_Char
*context
,
938 const XML_Char
*encodingName
)
940 XML_Parser parser
= oldParser
;
943 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
944 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
945 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
946 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
947 = processingInstructionHandler
;
948 XML_CommentHandler oldCommentHandler
= commentHandler
;
949 XML_StartCdataSectionHandler oldStartCdataSectionHandler
950 = startCdataSectionHandler
;
951 XML_EndCdataSectionHandler oldEndCdataSectionHandler
952 = endCdataSectionHandler
;
953 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
954 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
955 = unparsedEntityDeclHandler
;
956 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
957 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
958 = startNamespaceDeclHandler
;
959 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
960 = endNamespaceDeclHandler
;
961 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
962 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
963 = externalEntityRefHandler
;
964 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
965 XML_UnknownEncodingHandler oldUnknownEncodingHandler
966 = unknownEncodingHandler
;
967 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
968 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
969 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
970 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
971 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
973 void *oldUserData
= userData
;
974 void *oldHandlerArg
= handlerArg
;
975 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
976 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
978 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
979 int oldInEntityValue
= prologState
.inEntityValue
;
981 XML_Bool oldns_triplets
= ns_triplets
;
988 /* Note that the magical uses of the pre-processor to make field
989 access look more like C++ require that `parser' be overwritten
990 here. This makes this function more painful to follow than it
995 *tmp
= namespaceSeparator
;
996 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
999 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1005 startElementHandler
= oldStartElementHandler
;
1006 endElementHandler
= oldEndElementHandler
;
1007 characterDataHandler
= oldCharacterDataHandler
;
1008 processingInstructionHandler
= oldProcessingInstructionHandler
;
1009 commentHandler
= oldCommentHandler
;
1010 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1011 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1012 defaultHandler
= oldDefaultHandler
;
1013 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1014 notationDeclHandler
= oldNotationDeclHandler
;
1015 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1016 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1017 notStandaloneHandler
= oldNotStandaloneHandler
;
1018 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1019 skippedEntityHandler
= oldSkippedEntityHandler
;
1020 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1021 elementDeclHandler
= oldElementDeclHandler
;
1022 attlistDeclHandler
= oldAttlistDeclHandler
;
1023 entityDeclHandler
= oldEntityDeclHandler
;
1024 xmlDeclHandler
= oldXmlDeclHandler
;
1025 declElementType
= oldDeclElementType
;
1026 userData
= oldUserData
;
1027 if (oldUserData
== oldHandlerArg
)
1028 handlerArg
= userData
;
1030 handlerArg
= parser
;
1031 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1032 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1033 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1034 ns_triplets
= oldns_triplets
;
1035 parentParser
= oldParser
;
1037 paramEntityParsing
= oldParamEntityParsing
;
1038 prologState
.inEntityValue
= oldInEntityValue
;
1040 #endif /* XML_DTD */
1041 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1042 || !setContext(parser
, context
)) {
1043 XML_ParserFree(parser
);
1046 processor
= externalEntityInitProcessor
;
1050 /* The DTD instance referenced by _dtd is shared between the document's
1051 root parser and external PE parsers, therefore one does not need to
1052 call setContext. In addition, one also *must* not call setContext,
1053 because this would overwrite existing prefix->binding pointers in
1054 _dtd with ones that get destroyed with the external PE parser.
1055 This would leave those prefixes with dangling pointers.
1057 isParamEntity
= XML_TRUE
;
1058 XmlPrologStateInitExternalEntity(&prologState
);
1059 processor
= externalParEntInitProcessor
;
1061 #endif /* XML_DTD */
1065 static void FASTCALL
1066 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1069 BINDING
*b
= bindings
;
1072 bindings
= b
->nextTagBinding
;
1079 XML_ParserFree(XML_Parser parser
)
1082 OPEN_INTERNAL_ENTITY
*entityList
;
1085 /* free tagStack and freeTagList */
1089 if (tagList
== NULL
) {
1090 if (freeTagList
== NULL
)
1092 tagList
= freeTagList
;
1096 tagList
= tagList
->parent
;
1098 destroyBindings(p
->bindings
, parser
);
1101 /* free openInternalEntities and freeInternalEntities */
1102 entityList
= openInternalEntities
;
1104 OPEN_INTERNAL_ENTITY
*openEntity
;
1105 if (entityList
== NULL
) {
1106 if (freeInternalEntities
== NULL
)
1108 entityList
= freeInternalEntities
;
1109 freeInternalEntities
= NULL
;
1111 openEntity
= entityList
;
1112 entityList
= entityList
->next
;
1116 destroyBindings(freeBindingList
, parser
);
1117 destroyBindings(inheritedBindings
, parser
);
1118 poolDestroy(&tempPool
);
1119 poolDestroy(&temp2Pool
);
1121 /* external parameter entity parsers share the DTD structure
1122 parser->m_dtd with the root parser, so we must not destroy it
1124 if (!isParamEntity
&& _dtd
)
1127 #endif /* XML_DTD */
1128 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1130 FREE(groupConnector
);
1134 FREE(unknownEncodingMem
);
1135 if (unknownEncodingRelease
)
1136 unknownEncodingRelease(unknownEncodingData
);
1141 XML_UseParserAsHandlerArg(XML_Parser parser
)
1143 handlerArg
= parser
;
1146 enum XML_Error XMLCALL
1147 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1150 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1151 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1152 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1153 useForeignDTD
= useDTD
;
1154 return XML_ERROR_NONE
;
1156 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1161 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1163 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1164 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1166 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1170 XML_SetUserData(XML_Parser parser
, void *p
)
1172 if (handlerArg
== userData
)
1173 handlerArg
= userData
= p
;
1178 enum XML_Status XMLCALL
1179 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1182 p
= poolCopyString(&_dtd
->pool
, p
);
1184 return XML_STATUS_ERROR
;
1189 return XML_STATUS_OK
;
1192 const XML_Char
* XMLCALL
1193 XML_GetBase(XML_Parser parser
)
1199 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1201 return nSpecifiedAtts
;
1205 XML_GetIdAttributeIndex(XML_Parser parser
)
1211 XML_SetElementHandler(XML_Parser parser
,
1212 XML_StartElementHandler start
,
1213 XML_EndElementHandler end
)
1215 startElementHandler
= start
;
1216 endElementHandler
= end
;
1220 XML_SetStartElementHandler(XML_Parser parser
,
1221 XML_StartElementHandler start
) {
1222 startElementHandler
= start
;
1226 XML_SetEndElementHandler(XML_Parser parser
,
1227 XML_EndElementHandler end
) {
1228 endElementHandler
= end
;
1232 XML_SetCharacterDataHandler(XML_Parser parser
,
1233 XML_CharacterDataHandler handler
)
1235 characterDataHandler
= handler
;
1239 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1240 XML_ProcessingInstructionHandler handler
)
1242 processingInstructionHandler
= handler
;
1246 XML_SetCommentHandler(XML_Parser parser
,
1247 XML_CommentHandler handler
)
1249 commentHandler
= handler
;
1253 XML_SetCdataSectionHandler(XML_Parser parser
,
1254 XML_StartCdataSectionHandler start
,
1255 XML_EndCdataSectionHandler end
)
1257 startCdataSectionHandler
= start
;
1258 endCdataSectionHandler
= end
;
1262 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1263 XML_StartCdataSectionHandler start
) {
1264 startCdataSectionHandler
= start
;
1268 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1269 XML_EndCdataSectionHandler end
) {
1270 endCdataSectionHandler
= end
;
1274 XML_SetDefaultHandler(XML_Parser parser
,
1275 XML_DefaultHandler handler
)
1277 defaultHandler
= handler
;
1278 defaultExpandInternalEntities
= XML_FALSE
;
1282 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1283 XML_DefaultHandler handler
)
1285 defaultHandler
= handler
;
1286 defaultExpandInternalEntities
= XML_TRUE
;
1290 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1291 XML_StartDoctypeDeclHandler start
,
1292 XML_EndDoctypeDeclHandler end
)
1294 startDoctypeDeclHandler
= start
;
1295 endDoctypeDeclHandler
= end
;
1299 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1300 XML_StartDoctypeDeclHandler start
) {
1301 startDoctypeDeclHandler
= start
;
1305 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1306 XML_EndDoctypeDeclHandler end
) {
1307 endDoctypeDeclHandler
= end
;
1311 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1312 XML_UnparsedEntityDeclHandler handler
)
1314 unparsedEntityDeclHandler
= handler
;
1318 XML_SetNotationDeclHandler(XML_Parser parser
,
1319 XML_NotationDeclHandler handler
)
1321 notationDeclHandler
= handler
;
1325 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1326 XML_StartNamespaceDeclHandler start
,
1327 XML_EndNamespaceDeclHandler end
)
1329 startNamespaceDeclHandler
= start
;
1330 endNamespaceDeclHandler
= end
;
1334 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1335 XML_StartNamespaceDeclHandler start
) {
1336 startNamespaceDeclHandler
= start
;
1340 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1341 XML_EndNamespaceDeclHandler end
) {
1342 endNamespaceDeclHandler
= end
;
1346 XML_SetNotStandaloneHandler(XML_Parser parser
,
1347 XML_NotStandaloneHandler handler
)
1349 notStandaloneHandler
= handler
;
1353 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1354 XML_ExternalEntityRefHandler handler
)
1356 externalEntityRefHandler
= handler
;
1360 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1363 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1365 externalEntityRefHandlerArg
= parser
;
1369 XML_SetSkippedEntityHandler(XML_Parser parser
,
1370 XML_SkippedEntityHandler handler
)
1372 skippedEntityHandler
= handler
;
1376 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1377 XML_UnknownEncodingHandler handler
,
1380 unknownEncodingHandler
= handler
;
1381 unknownEncodingHandlerData
= data
;
1385 XML_SetElementDeclHandler(XML_Parser parser
,
1386 XML_ElementDeclHandler eldecl
)
1388 elementDeclHandler
= eldecl
;
1392 XML_SetAttlistDeclHandler(XML_Parser parser
,
1393 XML_AttlistDeclHandler attdecl
)
1395 attlistDeclHandler
= attdecl
;
1399 XML_SetEntityDeclHandler(XML_Parser parser
,
1400 XML_EntityDeclHandler handler
)
1402 entityDeclHandler
= handler
;
1406 XML_SetXmlDeclHandler(XML_Parser parser
,
1407 XML_XmlDeclHandler handler
) {
1408 xmlDeclHandler
= handler
;
1412 XML_SetParamEntityParsing(XML_Parser parser
,
1413 enum XML_ParamEntityParsing peParsing
)
1415 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1416 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1419 paramEntityParsing
= peParsing
;
1422 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1426 enum XML_Status XMLCALL
1427 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1429 switch (ps_parsing
) {
1431 errorCode
= XML_ERROR_SUSPENDED
;
1432 return XML_STATUS_ERROR
;
1434 errorCode
= XML_ERROR_FINISHED
;
1435 return XML_STATUS_ERROR
;
1437 ps_parsing
= XML_PARSING
;
1441 ps_finalBuffer
= (XML_Bool
)isFinal
;
1443 return XML_STATUS_OK
;
1444 positionPtr
= bufferPtr
;
1445 parseEndPtr
= bufferEnd
;
1447 /* If data are left over from last buffer, and we now know that these
1448 data are the final chunk of input, then we have to check them again
1449 to detect errors based on that fact.
1451 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1453 if (errorCode
== XML_ERROR_NONE
) {
1454 switch (ps_parsing
) {
1456 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1457 positionPtr
= bufferPtr
;
1458 return XML_STATUS_SUSPENDED
;
1459 case XML_INITIALIZED
:
1461 ps_parsing
= XML_FINISHED
;
1464 return XML_STATUS_OK
;
1467 eventEndPtr
= eventPtr
;
1468 processor
= errorProcessor
;
1469 return XML_STATUS_ERROR
;
1471 #ifndef XML_CONTEXT_BYTES
1472 else if (bufferPtr
== bufferEnd
) {
1475 enum XML_Error result
;
1476 parseEndByteIndex
+= len
;
1478 ps_finalBuffer
= (XML_Bool
)isFinal
;
1480 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1482 if (errorCode
!= XML_ERROR_NONE
) {
1483 eventEndPtr
= eventPtr
;
1484 processor
= errorProcessor
;
1485 return XML_STATUS_ERROR
;
1488 switch (ps_parsing
) {
1490 result
= XML_STATUS_SUSPENDED
;
1492 case XML_INITIALIZED
:
1494 result
= XML_STATUS_OK
;
1496 ps_parsing
= XML_FINISHED
;
1502 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1503 nLeftOver
= s
+ len
- end
;
1505 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1506 /* FIXME avoid integer overflow */
1508 temp
= (buffer
== NULL
1509 ? (char *)MALLOC(len
* 2)
1510 : (char *)REALLOC(buffer
, len
* 2));
1512 errorCode
= XML_ERROR_NO_MEMORY
;
1513 return XML_STATUS_ERROR
;
1517 errorCode
= XML_ERROR_NO_MEMORY
;
1518 eventPtr
= eventEndPtr
= NULL
;
1519 processor
= errorProcessor
;
1520 return XML_STATUS_ERROR
;
1522 bufferLim
= buffer
+ len
* 2;
1524 memcpy(buffer
, end
, nLeftOver
);
1527 bufferEnd
= buffer
+ nLeftOver
;
1528 positionPtr
= bufferPtr
;
1529 parseEndPtr
= bufferEnd
;
1530 eventPtr
= bufferPtr
;
1531 eventEndPtr
= bufferPtr
;
1534 #endif /* not defined XML_CONTEXT_BYTES */
1536 void *buff
= XML_GetBuffer(parser
, len
);
1538 return XML_STATUS_ERROR
;
1540 memcpy(buff
, s
, len
);
1541 return XML_ParseBuffer(parser
, len
, isFinal
);
1546 enum XML_Status XMLCALL
1547 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1550 enum XML_Status result
= XML_STATUS_OK
;
1552 switch (ps_parsing
) {
1554 errorCode
= XML_ERROR_SUSPENDED
;
1555 return XML_STATUS_ERROR
;
1557 errorCode
= XML_ERROR_FINISHED
;
1558 return XML_STATUS_ERROR
;
1560 ps_parsing
= XML_PARSING
;
1564 positionPtr
= start
;
1566 parseEndPtr
= bufferEnd
;
1567 parseEndByteIndex
+= len
;
1568 ps_finalBuffer
= (XML_Bool
)isFinal
;
1570 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1572 if (errorCode
!= XML_ERROR_NONE
) {
1573 eventEndPtr
= eventPtr
;
1574 processor
= errorProcessor
;
1575 return XML_STATUS_ERROR
;
1578 switch (ps_parsing
) {
1580 result
= XML_STATUS_SUSPENDED
;
1582 case XML_INITIALIZED
:
1585 ps_parsing
= XML_FINISHED
;
1588 default: ; /* should not happen */
1592 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1593 positionPtr
= bufferPtr
;
1598 XML_GetBuffer(XML_Parser parser
, int len
)
1600 switch (ps_parsing
) {
1602 errorCode
= XML_ERROR_SUSPENDED
;
1605 errorCode
= XML_ERROR_FINISHED
;
1610 if (len
> bufferLim
- bufferEnd
) {
1611 /* FIXME avoid integer overflow */
1612 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1613 #ifdef XML_CONTEXT_BYTES
1614 int keep
= (int)(bufferPtr
- buffer
);
1616 if (keep
> XML_CONTEXT_BYTES
)
1617 keep
= XML_CONTEXT_BYTES
;
1619 #endif /* defined XML_CONTEXT_BYTES */
1620 if (neededSize
<= bufferLim
- buffer
) {
1621 #ifdef XML_CONTEXT_BYTES
1622 if (keep
< bufferPtr
- buffer
) {
1623 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1624 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1625 bufferEnd
-= offset
;
1626 bufferPtr
-= offset
;
1629 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1630 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1632 #endif /* not defined XML_CONTEXT_BYTES */
1636 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1637 if (bufferSize
== 0)
1638 bufferSize
= INIT_BUFFER_SIZE
;
1641 } while (bufferSize
< neededSize
);
1642 newBuf
= (char *)MALLOC(bufferSize
);
1644 errorCode
= XML_ERROR_NO_MEMORY
;
1647 bufferLim
= newBuf
+ bufferSize
;
1648 #ifdef XML_CONTEXT_BYTES
1650 int keep
= (int)(bufferPtr
- buffer
);
1651 if (keep
> XML_CONTEXT_BYTES
)
1652 keep
= XML_CONTEXT_BYTES
;
1653 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1656 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1657 bufferPtr
= buffer
+ keep
;
1660 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1661 bufferPtr
= buffer
= newBuf
;
1665 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1668 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1669 bufferPtr
= buffer
= newBuf
;
1670 #endif /* not defined XML_CONTEXT_BYTES */
1676 enum XML_Status XMLCALL
1677 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1679 switch (ps_parsing
) {
1682 errorCode
= XML_ERROR_SUSPENDED
;
1683 return XML_STATUS_ERROR
;
1685 ps_parsing
= XML_FINISHED
;
1688 errorCode
= XML_ERROR_FINISHED
;
1689 return XML_STATUS_ERROR
;
1693 if (isParamEntity
) {
1694 errorCode
= XML_ERROR_SUSPEND_PE
;
1695 return XML_STATUS_ERROR
;
1698 ps_parsing
= XML_SUSPENDED
;
1701 ps_parsing
= XML_FINISHED
;
1703 return XML_STATUS_OK
;
1706 enum XML_Status XMLCALL
1707 XML_ResumeParser(XML_Parser parser
)
1709 enum XML_Status result
= XML_STATUS_OK
;
1711 if (ps_parsing
!= XML_SUSPENDED
) {
1712 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1713 return XML_STATUS_ERROR
;
1715 ps_parsing
= XML_PARSING
;
1717 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1719 if (errorCode
!= XML_ERROR_NONE
) {
1720 eventEndPtr
= eventPtr
;
1721 processor
= errorProcessor
;
1722 return XML_STATUS_ERROR
;
1725 switch (ps_parsing
) {
1727 result
= XML_STATUS_SUSPENDED
;
1729 case XML_INITIALIZED
:
1731 if (ps_finalBuffer
) {
1732 ps_parsing
= XML_FINISHED
;
1739 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1740 positionPtr
= bufferPtr
;
1745 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1747 assert(status
!= NULL
);
1748 *status
= parser
->m_parsingStatus
;
1751 enum XML_Error XMLCALL
1752 XML_GetErrorCode(XML_Parser parser
)
1758 XML_GetCurrentByteIndex(XML_Parser parser
)
1761 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1766 XML_GetCurrentByteCount(XML_Parser parser
)
1768 if (eventEndPtr
&& eventPtr
)
1769 return (int)(eventEndPtr
- eventPtr
);
1773 const char * XMLCALL
1774 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1776 #ifdef XML_CONTEXT_BYTES
1777 if (eventPtr
&& buffer
) {
1778 *offset
= (int)(eventPtr
- buffer
);
1779 *size
= (int)(bufferEnd
- buffer
);
1782 #endif /* defined XML_CONTEXT_BYTES */
1787 XML_GetCurrentLineNumber(XML_Parser parser
)
1789 if (eventPtr
&& eventPtr
>= positionPtr
) {
1790 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1791 positionPtr
= eventPtr
;
1793 return position
.lineNumber
+ 1;
1797 XML_GetCurrentColumnNumber(XML_Parser parser
)
1799 if (eventPtr
&& eventPtr
>= positionPtr
) {
1800 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1801 positionPtr
= eventPtr
;
1803 return position
.columnNumber
;
1807 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1813 XML_MemMalloc(XML_Parser parser
, size_t size
)
1815 return MALLOC(size
);
1819 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1821 return REALLOC(ptr
, size
);
1825 XML_MemFree(XML_Parser parser
, void *ptr
)
1831 XML_DefaultCurrent(XML_Parser parser
)
1833 if (defaultHandler
) {
1834 if (openInternalEntities
)
1835 reportDefault(parser
,
1837 openInternalEntities
->internalEventPtr
,
1838 openInternalEntities
->internalEventEndPtr
);
1840 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1844 const XML_LChar
* XMLCALL
1845 XML_ErrorString(enum XML_Error code
)
1847 static const XML_LChar
* const message
[] = {
1849 XML_L("out of memory"),
1850 XML_L("syntax error"),
1851 XML_L("no element found"),
1852 XML_L("not well-formed (invalid token)"),
1853 XML_L("unclosed token"),
1854 XML_L("partial character"),
1855 XML_L("mismatched tag"),
1856 XML_L("duplicate attribute"),
1857 XML_L("junk after document element"),
1858 XML_L("illegal parameter entity reference"),
1859 XML_L("undefined entity"),
1860 XML_L("recursive entity reference"),
1861 XML_L("asynchronous entity"),
1862 XML_L("reference to invalid character number"),
1863 XML_L("reference to binary entity"),
1864 XML_L("reference to external entity in attribute"),
1865 XML_L("XML or text declaration not at start of entity"),
1866 XML_L("unknown encoding"),
1867 XML_L("encoding specified in XML declaration is incorrect"),
1868 XML_L("unclosed CDATA section"),
1869 XML_L("error in processing external entity reference"),
1870 XML_L("document is not standalone"),
1871 XML_L("unexpected parser state - please send a bug report"),
1872 XML_L("entity declared in parameter entity"),
1873 XML_L("requested feature requires XML_DTD support in Expat"),
1874 XML_L("cannot change setting once parsing has begun"),
1875 XML_L("unbound prefix"),
1876 XML_L("must not undeclare prefix"),
1877 XML_L("incomplete markup in parameter entity"),
1878 XML_L("XML declaration not well-formed"),
1879 XML_L("text declaration not well-formed"),
1880 XML_L("illegal character(s) in public id"),
1881 XML_L("parser suspended"),
1882 XML_L("parser not suspended"),
1883 XML_L("parsing aborted"),
1884 XML_L("parsing finished"),
1885 XML_L("cannot suspend in external parameter entity"),
1886 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1887 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1888 XML_L("prefix must not be bound to one of the reserved namespace names")
1890 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1891 return message
[code
];
1895 const XML_LChar
* XMLCALL
1896 XML_ExpatVersion(void) {
1898 /* V1 is used to string-ize the version number. However, it would
1899 string-ize the actual version macro *names* unless we get them
1900 substituted before being passed to V1. CPP is defined to expand
1901 a macro, then rescan for more expansions. Thus, we use V2 to expand
1902 the version macros, then CPP will expand the resulting V1() macro
1903 with the correct numerals. */
1904 /* ### I'm assuming cpp is portable in this respect... */
1906 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1907 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1909 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1915 XML_Expat_Version XMLCALL
1916 XML_ExpatVersionInfo(void)
1918 XML_Expat_Version version
;
1920 version
.major
= XML_MAJOR_VERSION
;
1921 version
.minor
= XML_MINOR_VERSION
;
1922 version
.micro
= XML_MICRO_VERSION
;
1927 const XML_Feature
* XMLCALL
1928 XML_GetFeatureList(void)
1930 static const XML_Feature features
[] = {
1931 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1933 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1936 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1938 #ifdef XML_UNICODE_WCHAR_T
1939 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1942 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1944 #ifdef XML_CONTEXT_BYTES
1945 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1949 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1952 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1954 #ifdef XML_LARGE_SIZE
1955 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
1957 {XML_FEATURE_END
, NULL
, 0}
1963 /* Initially tag->rawName always points into the parse buffer;
1964 for those TAG instances opened while the current parse buffer was
1965 processed, and not yet closed, we need to store tag->rawName in a more
1966 permanent location, since the parse buffer is about to be discarded.
1969 storeRawNames(XML_Parser parser
)
1971 TAG
*tag
= tagStack
;
1974 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1975 char *rawNameBuf
= tag
->buf
+ nameLen
;
1976 /* Stop if already stored. Since tagStack is a stack, we can stop
1977 at the first entry that has already been copied; everything
1978 below it in the stack is already been accounted for in a
1979 previous call to this function.
1981 if (tag
->rawName
== rawNameBuf
)
1983 /* For re-use purposes we need to ensure that the
1984 size of tag->buf is a multiple of sizeof(XML_Char).
1986 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1987 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1988 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1991 /* if tag->name.str points to tag->buf (only when namespace
1992 processing is off) then we have to update it
1994 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1995 tag
->name
.str
= (XML_Char
*)temp
;
1996 /* if tag->name.localPart is set (when namespace processing is on)
1997 then update it as well, since it will always point into tag->buf
1999 if (tag
->name
.localPart
)
2000 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2001 (XML_Char
*)tag
->buf
);
2003 tag
->bufEnd
= temp
+ bufSize
;
2004 rawNameBuf
= temp
+ nameLen
;
2006 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2007 tag
->rawName
= rawNameBuf
;
2013 static enum XML_Error PTRCALL
2014 contentProcessor(XML_Parser parser
,
2017 const char **endPtr
)
2019 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2020 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2021 if (result
== XML_ERROR_NONE
) {
2022 if (!storeRawNames(parser
))
2023 return XML_ERROR_NO_MEMORY
;
2028 static enum XML_Error PTRCALL
2029 externalEntityInitProcessor(XML_Parser parser
,
2032 const char **endPtr
)
2034 enum XML_Error result
= initializeEncoding(parser
);
2035 if (result
!= XML_ERROR_NONE
)
2037 processor
= externalEntityInitProcessor2
;
2038 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2041 static enum XML_Error PTRCALL
2042 externalEntityInitProcessor2(XML_Parser parser
,
2045 const char **endPtr
)
2047 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2048 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2051 /* If we are at the end of the buffer, this would cause the next stage,
2052 i.e. externalEntityInitProcessor3, to pass control directly to
2053 doContent (by detecting XML_TOK_NONE) without processing any xml text
2054 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2056 if (next
== end
&& !ps_finalBuffer
) {
2058 return XML_ERROR_NONE
;
2062 case XML_TOK_PARTIAL
:
2063 if (!ps_finalBuffer
) {
2065 return XML_ERROR_NONE
;
2068 return XML_ERROR_UNCLOSED_TOKEN
;
2069 case XML_TOK_PARTIAL_CHAR
:
2070 if (!ps_finalBuffer
) {
2072 return XML_ERROR_NONE
;
2075 return XML_ERROR_PARTIAL_CHAR
;
2077 processor
= externalEntityInitProcessor3
;
2078 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2081 static enum XML_Error PTRCALL
2082 externalEntityInitProcessor3(XML_Parser parser
,
2085 const char **endPtr
)
2088 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2090 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2094 case XML_TOK_XML_DECL
:
2096 enum XML_Error result
;
2097 result
= processXmlDecl(parser
, 1, start
, next
);
2098 if (result
!= XML_ERROR_NONE
)
2100 switch (ps_parsing
) {
2103 return XML_ERROR_NONE
;
2105 return XML_ERROR_ABORTED
;
2111 case XML_TOK_PARTIAL
:
2112 if (!ps_finalBuffer
) {
2114 return XML_ERROR_NONE
;
2116 return XML_ERROR_UNCLOSED_TOKEN
;
2117 case XML_TOK_PARTIAL_CHAR
:
2118 if (!ps_finalBuffer
) {
2120 return XML_ERROR_NONE
;
2122 return XML_ERROR_PARTIAL_CHAR
;
2124 processor
= externalEntityContentProcessor
;
2126 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2129 static enum XML_Error PTRCALL
2130 externalEntityContentProcessor(XML_Parser parser
,
2133 const char **endPtr
)
2135 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2136 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2137 if (result
== XML_ERROR_NONE
) {
2138 if (!storeRawNames(parser
))
2139 return XML_ERROR_NO_MEMORY
;
2144 static enum XML_Error
2145 doContent(XML_Parser parser
,
2147 const ENCODING
*enc
,
2150 const char **nextPtr
,
2153 /* save one level of indirection */
2154 DTD
* const dtd
= _dtd
;
2156 const char **eventPP
;
2157 const char **eventEndPP
;
2158 if (enc
== encoding
) {
2159 eventPP
= &eventPtr
;
2160 eventEndPP
= &eventEndPtr
;
2163 eventPP
= &(openInternalEntities
->internalEventPtr
);
2164 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2169 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2170 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2173 case XML_TOK_TRAILING_CR
:
2176 return XML_ERROR_NONE
;
2179 if (characterDataHandler
) {
2181 characterDataHandler(handlerArg
, &c
, 1);
2183 else if (defaultHandler
)
2184 reportDefault(parser
, enc
, s
, end
);
2185 /* We are at the end of the final buffer, should we check for
2186 XML_SUSPENDED, XML_FINISHED?
2188 if (startTagLevel
== 0)
2189 return XML_ERROR_NO_ELEMENTS
;
2190 if (tagLevel
!= startTagLevel
)
2191 return XML_ERROR_ASYNC_ENTITY
;
2193 return XML_ERROR_NONE
;
2197 return XML_ERROR_NONE
;
2199 if (startTagLevel
> 0) {
2200 if (tagLevel
!= startTagLevel
)
2201 return XML_ERROR_ASYNC_ENTITY
;
2203 return XML_ERROR_NONE
;
2205 return XML_ERROR_NO_ELEMENTS
;
2206 case XML_TOK_INVALID
:
2208 return XML_ERROR_INVALID_TOKEN
;
2209 case XML_TOK_PARTIAL
:
2212 return XML_ERROR_NONE
;
2214 return XML_ERROR_UNCLOSED_TOKEN
;
2215 case XML_TOK_PARTIAL_CHAR
:
2218 return XML_ERROR_NONE
;
2220 return XML_ERROR_PARTIAL_CHAR
;
2221 case XML_TOK_ENTITY_REF
:
2223 const XML_Char
*name
;
2225 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2226 s
+ enc
->minBytesPerChar
,
2227 next
- enc
->minBytesPerChar
);
2229 if (characterDataHandler
)
2230 characterDataHandler(handlerArg
, &ch
, 1);
2231 else if (defaultHandler
)
2232 reportDefault(parser
, enc
, s
, next
);
2235 name
= poolStoreString(&dtd
->pool
, enc
,
2236 s
+ enc
->minBytesPerChar
,
2237 next
- enc
->minBytesPerChar
);
2239 return XML_ERROR_NO_MEMORY
;
2240 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2241 poolDiscard(&dtd
->pool
);
2242 /* First, determine if a check for an existing declaration is needed;
2243 if yes, check that the entity exists, and that it is internal,
2244 otherwise call the skipped entity or default handler.
2246 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2248 return XML_ERROR_UNDEFINED_ENTITY
;
2249 else if (!entity
->is_internal
)
2250 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2253 if (skippedEntityHandler
)
2254 skippedEntityHandler(handlerArg
, name
, 0);
2255 else if (defaultHandler
)
2256 reportDefault(parser
, enc
, s
, next
);
2260 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2261 if (entity
->notation
)
2262 return XML_ERROR_BINARY_ENTITY_REF
;
2263 if (entity
->textPtr
) {
2264 enum XML_Error result
;
2265 if (!defaultExpandInternalEntities
) {
2266 if (skippedEntityHandler
)
2267 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2268 else if (defaultHandler
)
2269 reportDefault(parser
, enc
, s
, next
);
2272 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2273 if (result
!= XML_ERROR_NONE
)
2276 else if (externalEntityRefHandler
) {
2277 const XML_Char
*context
;
2278 entity
->open
= XML_TRUE
;
2279 context
= getContext(parser
);
2280 entity
->open
= XML_FALSE
;
2282 return XML_ERROR_NO_MEMORY
;
2283 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2288 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2289 poolDiscard(&tempPool
);
2291 else if (defaultHandler
)
2292 reportDefault(parser
, enc
, s
, next
);
2295 case XML_TOK_START_TAG_NO_ATTS
:
2297 case XML_TOK_START_TAG_WITH_ATTS
:
2300 enum XML_Error result
;
2304 freeTagList
= freeTagList
->parent
;
2307 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2309 return XML_ERROR_NO_MEMORY
;
2310 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2313 return XML_ERROR_NO_MEMORY
;
2315 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2317 tag
->bindings
= NULL
;
2318 tag
->parent
= tagStack
;
2320 tag
->name
.localPart
= NULL
;
2321 tag
->name
.prefix
= NULL
;
2322 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2323 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2326 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2327 const char *fromPtr
= tag
->rawName
;
2328 toPtr
= (XML_Char
*)tag
->buf
;
2333 &fromPtr
, rawNameEnd
,
2334 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2335 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2336 if (fromPtr
== rawNameEnd
) {
2337 tag
->name
.strLen
= convLen
;
2340 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2342 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2344 return XML_ERROR_NO_MEMORY
;
2346 tag
->bufEnd
= temp
+ bufSize
;
2347 toPtr
= (XML_Char
*)temp
+ convLen
;
2351 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2352 *toPtr
= XML_T('\0');
2353 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2356 if (startElementHandler
)
2357 startElementHandler(handlerArg
, tag
->name
.str
,
2358 (const XML_Char
**)atts
);
2359 else if (defaultHandler
)
2360 reportDefault(parser
, enc
, s
, next
);
2361 poolClear(&tempPool
);
2364 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2366 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2368 const char *rawName
= s
+ enc
->minBytesPerChar
;
2369 enum XML_Error result
;
2370 BINDING
*bindings
= NULL
;
2371 XML_Bool noElmHandlers
= XML_TRUE
;
2373 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2374 rawName
+ XmlNameLength(enc
, rawName
));
2376 return XML_ERROR_NO_MEMORY
;
2377 poolFinish(&tempPool
);
2378 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2381 poolFinish(&tempPool
);
2382 if (startElementHandler
) {
2383 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2384 noElmHandlers
= XML_FALSE
;
2386 if (endElementHandler
) {
2387 if (startElementHandler
)
2388 *eventPP
= *eventEndPP
;
2389 endElementHandler(handlerArg
, name
.str
);
2390 noElmHandlers
= XML_FALSE
;
2392 if (noElmHandlers
&& defaultHandler
)
2393 reportDefault(parser
, enc
, s
, next
);
2394 poolClear(&tempPool
);
2396 BINDING
*b
= bindings
;
2397 if (endNamespaceDeclHandler
)
2398 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2399 bindings
= bindings
->nextTagBinding
;
2400 b
->nextTagBinding
= freeBindingList
;
2401 freeBindingList
= b
;
2402 b
->prefix
->binding
= b
->prevPrefixBinding
;
2406 return epilogProcessor(parser
, next
, end
, nextPtr
);
2408 case XML_TOK_END_TAG
:
2409 if (tagLevel
== startTagLevel
)
2410 return XML_ERROR_ASYNC_ENTITY
;
2413 const char *rawName
;
2414 TAG
*tag
= tagStack
;
2415 tagStack
= tag
->parent
;
2416 tag
->parent
= freeTagList
;
2418 rawName
= s
+ enc
->minBytesPerChar
*2;
2419 len
= XmlNameLength(enc
, rawName
);
2420 if (len
!= tag
->rawNameLength
2421 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2423 return XML_ERROR_TAG_MISMATCH
;
2426 if (endElementHandler
) {
2427 const XML_Char
*localPart
;
2428 const XML_Char
*prefix
;
2430 localPart
= tag
->name
.localPart
;
2431 if (ns
&& localPart
) {
2432 /* localPart and prefix may have been overwritten in
2433 tag->name.str, since this points to the binding->uri
2434 buffer which gets re-used; so we have to add them again
2436 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2437 /* don't need to check for space - already done in storeAtts() */
2438 while (*localPart
) *uri
++ = *localPart
++;
2439 prefix
= (XML_Char
*)tag
->name
.prefix
;
2440 if (ns_triplets
&& prefix
) {
2441 *uri
++ = namespaceSeparator
;
2442 while (*prefix
) *uri
++ = *prefix
++;
2446 endElementHandler(handlerArg
, tag
->name
.str
);
2448 else if (defaultHandler
)
2449 reportDefault(parser
, enc
, s
, next
);
2450 while (tag
->bindings
) {
2451 BINDING
*b
= tag
->bindings
;
2452 if (endNamespaceDeclHandler
)
2453 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2454 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2455 b
->nextTagBinding
= freeBindingList
;
2456 freeBindingList
= b
;
2457 b
->prefix
->binding
= b
->prevPrefixBinding
;
2460 return epilogProcessor(parser
, next
, end
, nextPtr
);
2463 case XML_TOK_CHAR_REF
:
2465 int n
= XmlCharRefNumber(enc
, s
);
2467 return XML_ERROR_BAD_CHAR_REF
;
2468 if (characterDataHandler
) {
2469 XML_Char buf
[XML_ENCODE_MAX
];
2470 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2472 else if (defaultHandler
)
2473 reportDefault(parser
, enc
, s
, next
);
2476 case XML_TOK_XML_DECL
:
2477 return XML_ERROR_MISPLACED_XML_PI
;
2478 case XML_TOK_DATA_NEWLINE
:
2479 if (characterDataHandler
) {
2481 characterDataHandler(handlerArg
, &c
, 1);
2483 else if (defaultHandler
)
2484 reportDefault(parser
, enc
, s
, next
);
2486 case XML_TOK_CDATA_SECT_OPEN
:
2488 enum XML_Error result
;
2489 if (startCdataSectionHandler
)
2490 startCdataSectionHandler(handlerArg
);
2492 /* Suppose you doing a transformation on a document that involves
2493 changing only the character data. You set up a defaultHandler
2494 and a characterDataHandler. The defaultHandler simply copies
2495 characters through. The characterDataHandler does the
2496 transformation and writes the characters out escaping them as
2497 necessary. This case will fail to work if we leave out the
2498 following two lines (because & and < inside CDATA sections will
2499 be incorrectly escaped).
2501 However, now we have a start/endCdataSectionHandler, so it seems
2502 easier to let the user deal with this.
2504 else if (characterDataHandler
)
2505 characterDataHandler(handlerArg
, dataBuf
, 0);
2507 else if (defaultHandler
)
2508 reportDefault(parser
, enc
, s
, next
);
2509 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2510 if (result
!= XML_ERROR_NONE
)
2513 processor
= cdataSectionProcessor
;
2518 case XML_TOK_TRAILING_RSQB
:
2521 return XML_ERROR_NONE
;
2523 if (characterDataHandler
) {
2524 if (MUST_CONVERT(enc
, s
)) {
2525 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2526 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2527 characterDataHandler(handlerArg
, dataBuf
,
2528 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2531 characterDataHandler(handlerArg
,
2533 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2535 else if (defaultHandler
)
2536 reportDefault(parser
, enc
, s
, end
);
2537 /* We are at the end of the final buffer, should we check for
2538 XML_SUSPENDED, XML_FINISHED?
2540 if (startTagLevel
== 0) {
2542 return XML_ERROR_NO_ELEMENTS
;
2544 if (tagLevel
!= startTagLevel
) {
2546 return XML_ERROR_ASYNC_ENTITY
;
2549 return XML_ERROR_NONE
;
2550 case XML_TOK_DATA_CHARS
:
2552 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2553 if (charDataHandler
) {
2554 if (MUST_CONVERT(enc
, s
)) {
2556 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2557 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2559 charDataHandler(handlerArg
, dataBuf
,
2560 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2567 charDataHandler(handlerArg
,
2569 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2571 else if (defaultHandler
)
2572 reportDefault(parser
, enc
, s
, next
);
2576 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2577 return XML_ERROR_NO_MEMORY
;
2579 case XML_TOK_COMMENT
:
2580 if (!reportComment(parser
, enc
, s
, next
))
2581 return XML_ERROR_NO_MEMORY
;
2585 reportDefault(parser
, enc
, s
, next
);
2588 *eventPP
= s
= next
;
2589 switch (ps_parsing
) {
2592 return XML_ERROR_NONE
;
2594 return XML_ERROR_ABORTED
;
2601 /* Precondition: all arguments must be non-NULL;
2603 - normalize attributes
2604 - check attributes for well-formedness
2605 - generate namespace aware attribute names (URI, prefix)
2606 - build list of attributes for startElementHandler
2607 - default attributes
2608 - process namespace declarations (check and report them)
2609 - generate namespace aware element name (URI, prefix)
2611 static enum XML_Error
2612 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2613 const char *attStr
, TAG_NAME
*tagNamePtr
,
2614 BINDING
**bindingsPtr
)
2616 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2617 ELEMENT_TYPE
*elementType
;
2619 const XML_Char
**appAtts
; /* the attribute list for the application */
2627 const XML_Char
*localPart
;
2629 /* lookup the element type name */
2630 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2632 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2634 return XML_ERROR_NO_MEMORY
;
2635 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2636 sizeof(ELEMENT_TYPE
));
2638 return XML_ERROR_NO_MEMORY
;
2639 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2640 return XML_ERROR_NO_MEMORY
;
2642 nDefaultAtts
= elementType
->nDefaultAtts
;
2644 /* get the attributes from the tokenizer */
2645 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2646 if (n
+ nDefaultAtts
> attsSize
) {
2647 int oldAttsSize
= attsSize
;
2649 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2650 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2652 return XML_ERROR_NO_MEMORY
;
2654 if (n
> oldAttsSize
)
2655 XmlGetAttributes(enc
, attStr
, n
, atts
);
2658 appAtts
= (const XML_Char
**)atts
;
2659 for (i
= 0; i
< n
; i
++) {
2660 /* add the name and value to the attribute list */
2661 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2663 + XmlNameLength(enc
, atts
[i
].name
));
2665 return XML_ERROR_NO_MEMORY
;
2666 /* Detect duplicate attributes by their QNames. This does not work when
2667 namespace processing is turned on and different prefixes for the same
2668 namespace are used. For this case we have a check further down.
2670 if ((attId
->name
)[-1]) {
2671 if (enc
== encoding
)
2672 eventPtr
= atts
[i
].name
;
2673 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2675 (attId
->name
)[-1] = 1;
2676 appAtts
[attIndex
++] = attId
->name
;
2677 if (!atts
[i
].normalized
) {
2678 enum XML_Error result
;
2679 XML_Bool isCdata
= XML_TRUE
;
2681 /* figure out whether declared as other than CDATA */
2682 if (attId
->maybeTokenized
) {
2684 for (j
= 0; j
< nDefaultAtts
; j
++) {
2685 if (attId
== elementType
->defaultAtts
[j
].id
) {
2686 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2692 /* normalize the attribute value */
2693 result
= storeAttributeValue(parser
, enc
, isCdata
,
2694 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2698 appAtts
[attIndex
] = poolStart(&tempPool
);
2699 poolFinish(&tempPool
);
2702 /* the value did not need normalizing */
2703 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2705 if (appAtts
[attIndex
] == 0)
2706 return XML_ERROR_NO_MEMORY
;
2707 poolFinish(&tempPool
);
2709 /* handle prefixed attribute names */
2710 if (attId
->prefix
) {
2712 /* deal with namespace declarations here */
2713 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2714 appAtts
[attIndex
], bindingsPtr
);
2720 /* deal with other prefixed names later */
2723 (attId
->name
)[-1] = 2;
2730 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2731 nSpecifiedAtts
= attIndex
;
2732 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2733 for (i
= 0; i
< attIndex
; i
+= 2)
2734 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2742 /* do attribute defaulting */
2743 for (i
= 0; i
< nDefaultAtts
; i
++) {
2744 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2745 if (!(da
->id
->name
)[-1] && da
->value
) {
2746 if (da
->id
->prefix
) {
2747 if (da
->id
->xmlns
) {
2748 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2749 da
->value
, bindingsPtr
);
2754 (da
->id
->name
)[-1] = 2;
2756 appAtts
[attIndex
++] = da
->id
->name
;
2757 appAtts
[attIndex
++] = da
->value
;
2761 (da
->id
->name
)[-1] = 1;
2762 appAtts
[attIndex
++] = da
->id
->name
;
2763 appAtts
[attIndex
++] = da
->value
;
2767 appAtts
[attIndex
] = 0;
2769 /* expand prefixed attribute names, check for duplicates,
2770 and clear flags that say whether attributes were specified */
2773 int j
; /* hash table index */
2774 unsigned long version
= nsAttsVersion
;
2775 int nsAttsSize
= (int)1 << nsAttsPower
;
2776 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2777 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2779 /* hash table size must also be a power of 2 and >= 8 */
2780 while (nPrefixes
>> nsAttsPower
++);
2781 if (nsAttsPower
< 3)
2783 nsAttsSize
= (int)1 << nsAttsPower
;
2784 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2786 return XML_ERROR_NO_MEMORY
;
2788 version
= 0; /* force re-initialization of nsAtts hash table */
2790 /* using a version flag saves us from initializing nsAtts every time */
2791 if (!version
) { /* initialize version flags when version wraps around */
2792 version
= INIT_ATTS_VERSION
;
2793 for (j
= nsAttsSize
; j
!= 0; )
2794 nsAtts
[--j
].version
= version
;
2796 nsAttsVersion
= --version
;
2798 /* expand prefixed names and check for duplicates */
2799 for (; i
< attIndex
; i
+= 2) {
2800 const XML_Char
*s
= appAtts
[i
];
2801 if (s
[-1] == 2) { /* prefixed */
2804 unsigned long uriHash
= 0;
2805 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2806 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2807 b
= id
->prefix
->binding
;
2809 return XML_ERROR_UNBOUND_PREFIX
;
2811 /* as we expand the name we also calculate its hash value */
2812 for (j
= 0; j
< b
->uriLen
; j
++) {
2813 const XML_Char c
= b
->uri
[j
];
2814 if (!poolAppendChar(&tempPool
, c
))
2815 return XML_ERROR_NO_MEMORY
;
2816 uriHash
= CHAR_HASH(uriHash
, c
);
2818 while (*s
++ != XML_T(':'))
2820 do { /* copies null terminator */
2821 const XML_Char c
= *s
;
2822 if (!poolAppendChar(&tempPool
, *s
))
2823 return XML_ERROR_NO_MEMORY
;
2824 uriHash
= CHAR_HASH(uriHash
, c
);
2827 { /* Check hash table for duplicate of expanded name (uriName).
2828 Derived from code in lookup(HASH_TABLE *table, ...).
2830 unsigned char step
= 0;
2831 unsigned long mask
= nsAttsSize
- 1;
2832 j
= uriHash
& mask
; /* index into hash table */
2833 while (nsAtts
[j
].version
== version
) {
2834 /* for speed we compare stored hash values first */
2835 if (uriHash
== nsAtts
[j
].hash
) {
2836 const XML_Char
*s1
= poolStart(&tempPool
);
2837 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2838 /* s1 is null terminated, but not s2 */
2839 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2841 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2844 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2845 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2849 if (ns_triplets
) { /* append namespace separator and prefix */
2850 tempPool
.ptr
[-1] = namespaceSeparator
;
2851 s
= b
->prefix
->name
;
2853 if (!poolAppendChar(&tempPool
, *s
))
2854 return XML_ERROR_NO_MEMORY
;
2858 /* store expanded name in attribute list */
2859 s
= poolStart(&tempPool
);
2860 poolFinish(&tempPool
);
2863 /* fill empty slot with new version, uriName and hash value */
2864 nsAtts
[j
].version
= version
;
2865 nsAtts
[j
].hash
= uriHash
;
2866 nsAtts
[j
].uriName
= s
;
2873 else /* not prefixed */
2874 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2877 /* clear flags for the remaining attributes */
2878 for (; i
< attIndex
; i
+= 2)
2879 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2880 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2881 binding
->attId
->name
[-1] = 0;
2884 return XML_ERROR_NONE
;
2886 /* expand the element type name */
2887 if (elementType
->prefix
) {
2888 binding
= elementType
->prefix
->binding
;
2890 return XML_ERROR_UNBOUND_PREFIX
;
2891 localPart
= tagNamePtr
->str
;
2892 while (*localPart
++ != XML_T(':'))
2895 else if (dtd
->defaultPrefix
.binding
) {
2896 binding
= dtd
->defaultPrefix
.binding
;
2897 localPart
= tagNamePtr
->str
;
2900 return XML_ERROR_NONE
;
2902 if (ns_triplets
&& binding
->prefix
->name
) {
2903 for (; binding
->prefix
->name
[prefixLen
++];)
2904 ; /* prefixLen includes null terminator */
2906 tagNamePtr
->localPart
= localPart
;
2907 tagNamePtr
->uriLen
= binding
->uriLen
;
2908 tagNamePtr
->prefix
= binding
->prefix
->name
;
2909 tagNamePtr
->prefixLen
= prefixLen
;
2910 for (i
= 0; localPart
[i
++];)
2911 ; /* i includes null terminator */
2912 n
= i
+ binding
->uriLen
+ prefixLen
;
2913 if (n
> binding
->uriAlloc
) {
2915 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2917 return XML_ERROR_NO_MEMORY
;
2918 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2919 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2920 for (p
= tagStack
; p
; p
= p
->parent
)
2921 if (p
->name
.str
== binding
->uri
)
2926 /* if namespaceSeparator != '\0' then uri includes it already */
2927 uri
= binding
->uri
+ binding
->uriLen
;
2928 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2929 /* we always have a namespace separator between localPart and prefix */
2932 *uri
= namespaceSeparator
; /* replace null terminator */
2933 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2935 tagNamePtr
->str
= binding
->uri
;
2936 return XML_ERROR_NONE
;
2939 /* addBinding() overwrites the value of prefix->binding without checking.
2940 Therefore one must keep track of the old value outside of addBinding().
2942 static enum XML_Error
2943 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2944 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2946 static const XML_Char xmlNamespace
[] = {
2947 'h', 't', 't', 'p', ':', '/', '/',
2948 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2949 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2950 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2952 static const int xmlLen
=
2953 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2954 static const XML_Char xmlnsNamespace
[] = {
2955 'h', 't', 't', 'p', ':', '/', '/',
2956 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2957 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
2959 static const int xmlnsLen
=
2960 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2962 XML_Bool mustBeXML
= XML_FALSE
;
2963 XML_Bool isXML
= XML_TRUE
;
2964 XML_Bool isXMLNS
= XML_TRUE
;
2969 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2970 if (*uri
== XML_T('\0') && prefix
->name
)
2971 return XML_ERROR_UNDECLARING_PREFIX
;
2974 && prefix
->name
[0] == XML_T('x')
2975 && prefix
->name
[1] == XML_T('m')
2976 && prefix
->name
[2] == XML_T('l')) {
2978 /* Not allowed to bind xmlns */
2979 if (prefix
->name
[3] == XML_T('n')
2980 && prefix
->name
[4] == XML_T('s')
2981 && prefix
->name
[5] == XML_T('\0'))
2982 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2984 if (prefix
->name
[3] == XML_T('\0'))
2985 mustBeXML
= XML_TRUE
;
2988 for (len
= 0; uri
[len
]; len
++) {
2989 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
2992 if (!mustBeXML
&& isXMLNS
2993 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
2994 isXMLNS
= XML_FALSE
;
2996 isXML
= isXML
&& len
== xmlLen
;
2997 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
2999 if (mustBeXML
!= isXML
)
3000 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3001 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3004 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3006 if (namespaceSeparator
)
3008 if (freeBindingList
) {
3009 b
= freeBindingList
;
3010 if (len
> b
->uriAlloc
) {
3011 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3012 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3014 return XML_ERROR_NO_MEMORY
;
3016 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3018 freeBindingList
= b
->nextTagBinding
;
3021 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3023 return XML_ERROR_NO_MEMORY
;
3024 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3027 return XML_ERROR_NO_MEMORY
;
3029 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3032 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3033 if (namespaceSeparator
)
3034 b
->uri
[len
- 1] = namespaceSeparator
;
3037 b
->prevPrefixBinding
= prefix
->binding
;
3038 /* NULL binding when default namespace undeclared */
3039 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3040 prefix
->binding
= NULL
;
3042 prefix
->binding
= b
;
3043 b
->nextTagBinding
= *bindingsPtr
;
3045 /* if attId == NULL then we are not starting a namespace scope */
3046 if (attId
&& startNamespaceDeclHandler
)
3047 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3048 prefix
->binding
? uri
: 0);
3049 return XML_ERROR_NONE
;
3052 /* The idea here is to avoid using stack for each CDATA section when
3053 the whole file is parsed with one call.
3055 static enum XML_Error PTRCALL
3056 cdataSectionProcessor(XML_Parser parser
,
3059 const char **endPtr
)
3061 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3062 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3063 if (result
!= XML_ERROR_NONE
)
3066 if (parentParser
) { /* we are parsing an external entity */
3067 processor
= externalEntityContentProcessor
;
3068 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3071 processor
= contentProcessor
;
3072 return contentProcessor(parser
, start
, end
, endPtr
);
3078 /* startPtr gets set to non-null if the section is closed, and to null if
3079 the section is not yet closed.
3081 static enum XML_Error
3082 doCdataSection(XML_Parser parser
,
3083 const ENCODING
*enc
,
3084 const char **startPtr
,
3086 const char **nextPtr
,
3089 const char *s
= *startPtr
;
3090 const char **eventPP
;
3091 const char **eventEndPP
;
3092 if (enc
== encoding
) {
3093 eventPP
= &eventPtr
;
3095 eventEndPP
= &eventEndPtr
;
3098 eventPP
= &(openInternalEntities
->internalEventPtr
);
3099 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3106 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3109 case XML_TOK_CDATA_SECT_CLOSE
:
3110 if (endCdataSectionHandler
)
3111 endCdataSectionHandler(handlerArg
);
3113 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3114 else if (characterDataHandler
)
3115 characterDataHandler(handlerArg
, dataBuf
, 0);
3117 else if (defaultHandler
)
3118 reportDefault(parser
, enc
, s
, next
);
3121 if (ps_parsing
== XML_FINISHED
)
3122 return XML_ERROR_ABORTED
;
3124 return XML_ERROR_NONE
;
3125 case XML_TOK_DATA_NEWLINE
:
3126 if (characterDataHandler
) {
3128 characterDataHandler(handlerArg
, &c
, 1);
3130 else if (defaultHandler
)
3131 reportDefault(parser
, enc
, s
, next
);
3133 case XML_TOK_DATA_CHARS
:
3135 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3136 if (charDataHandler
) {
3137 if (MUST_CONVERT(enc
, s
)) {
3139 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3140 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3142 charDataHandler(handlerArg
, dataBuf
,
3143 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3150 charDataHandler(handlerArg
,
3152 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3154 else if (defaultHandler
)
3155 reportDefault(parser
, enc
, s
, next
);
3158 case XML_TOK_INVALID
:
3160 return XML_ERROR_INVALID_TOKEN
;
3161 case XML_TOK_PARTIAL_CHAR
:
3164 return XML_ERROR_NONE
;
3166 return XML_ERROR_PARTIAL_CHAR
;
3167 case XML_TOK_PARTIAL
:
3171 return XML_ERROR_NONE
;
3173 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3176 return XML_ERROR_UNEXPECTED_STATE
;
3179 *eventPP
= s
= next
;
3180 switch (ps_parsing
) {
3183 return XML_ERROR_NONE
;
3185 return XML_ERROR_ABORTED
;
3194 /* The idea here is to avoid using stack for each IGNORE section when
3195 the whole file is parsed with one call.
3197 static enum XML_Error PTRCALL
3198 ignoreSectionProcessor(XML_Parser parser
,
3201 const char **endPtr
)
3203 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3204 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3205 if (result
!= XML_ERROR_NONE
)
3208 processor
= prologProcessor
;
3209 return prologProcessor(parser
, start
, end
, endPtr
);
3214 /* startPtr gets set to non-null is the section is closed, and to null
3215 if the section is not yet closed.
3217 static enum XML_Error
3218 doIgnoreSection(XML_Parser parser
,
3219 const ENCODING
*enc
,
3220 const char **startPtr
,
3222 const char **nextPtr
,
3227 const char *s
= *startPtr
;
3228 const char **eventPP
;
3229 const char **eventEndPP
;
3230 if (enc
== encoding
) {
3231 eventPP
= &eventPtr
;
3233 eventEndPP
= &eventEndPtr
;
3236 eventPP
= &(openInternalEntities
->internalEventPtr
);
3237 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3241 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3244 case XML_TOK_IGNORE_SECT
:
3246 reportDefault(parser
, enc
, s
, next
);
3249 if (ps_parsing
== XML_FINISHED
)
3250 return XML_ERROR_ABORTED
;
3252 return XML_ERROR_NONE
;
3253 case XML_TOK_INVALID
:
3255 return XML_ERROR_INVALID_TOKEN
;
3256 case XML_TOK_PARTIAL_CHAR
:
3259 return XML_ERROR_NONE
;
3261 return XML_ERROR_PARTIAL_CHAR
;
3262 case XML_TOK_PARTIAL
:
3266 return XML_ERROR_NONE
;
3268 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3271 return XML_ERROR_UNEXPECTED_STATE
;
3276 #endif /* XML_DTD */
3278 static enum XML_Error
3279 initializeEncoding(XML_Parser parser
)
3283 char encodingBuf
[128];
3284 if (!protocolEncodingName
)
3288 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3289 if (i
== sizeof(encodingBuf
) - 1
3290 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3291 encodingBuf
[0] = '\0';
3294 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3296 encodingBuf
[i
] = '\0';
3300 s
= protocolEncodingName
;
3302 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3303 return XML_ERROR_NONE
;
3304 return handleUnknownEncoding(parser
, protocolEncodingName
);
3307 static enum XML_Error
3308 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3309 const char *s
, const char *next
)
3311 const char *encodingName
= NULL
;
3312 const XML_Char
*storedEncName
= NULL
;
3313 const ENCODING
*newEncoding
= NULL
;
3314 const char *version
= NULL
;
3315 const char *versionend
;
3316 const XML_Char
*storedversion
= NULL
;
3317 int standalone
= -1;
3320 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3330 if (isGeneralTextEntity
)
3331 return XML_ERROR_TEXT_DECL
;
3333 return XML_ERROR_XML_DECL
;
3335 if (!isGeneralTextEntity
&& standalone
== 1) {
3336 _dtd
->standalone
= XML_TRUE
;
3338 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3339 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3340 #endif /* XML_DTD */
3342 if (xmlDeclHandler
) {
3343 if (encodingName
!= NULL
) {
3344 storedEncName
= poolStoreString(&temp2Pool
,
3348 + XmlNameLength(encoding
, encodingName
));
3350 return XML_ERROR_NO_MEMORY
;
3351 poolFinish(&temp2Pool
);
3354 storedversion
= poolStoreString(&temp2Pool
,
3357 versionend
- encoding
->minBytesPerChar
);
3359 return XML_ERROR_NO_MEMORY
;
3361 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3363 else if (defaultHandler
)
3364 reportDefault(parser
, encoding
, s
, next
);
3365 if (protocolEncodingName
== NULL
) {
3367 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3368 eventPtr
= encodingName
;
3369 return XML_ERROR_INCORRECT_ENCODING
;
3371 encoding
= newEncoding
;
3373 else if (encodingName
) {
3374 enum XML_Error result
;
3375 if (!storedEncName
) {
3376 storedEncName
= poolStoreString(
3377 &temp2Pool
, encoding
, encodingName
,
3378 encodingName
+ XmlNameLength(encoding
, encodingName
));
3380 return XML_ERROR_NO_MEMORY
;
3382 result
= handleUnknownEncoding(parser
, storedEncName
);
3383 poolClear(&temp2Pool
);
3384 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3385 eventPtr
= encodingName
;
3390 if (storedEncName
|| storedversion
)
3391 poolClear(&temp2Pool
);
3393 return XML_ERROR_NONE
;
3396 static enum XML_Error
3397 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3399 if (unknownEncodingHandler
) {
3402 for (i
= 0; i
< 256; i
++)
3404 info
.convert
= NULL
;
3406 info
.release
= NULL
;
3407 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3410 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3411 if (!unknownEncodingMem
) {
3413 info
.release(info
.data
);
3414 return XML_ERROR_NO_MEMORY
;
3417 ? XmlInitUnknownEncodingNS
3418 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3423 unknownEncodingData
= info
.data
;
3424 unknownEncodingRelease
= info
.release
;
3426 return XML_ERROR_NONE
;
3429 if (info
.release
!= NULL
)
3430 info
.release(info
.data
);
3432 return XML_ERROR_UNKNOWN_ENCODING
;
3435 static enum XML_Error PTRCALL
3436 prologInitProcessor(XML_Parser parser
,
3439 const char **nextPtr
)
3441 enum XML_Error result
= initializeEncoding(parser
);
3442 if (result
!= XML_ERROR_NONE
)
3444 processor
= prologProcessor
;
3445 return prologProcessor(parser
, s
, end
, nextPtr
);
3450 static enum XML_Error PTRCALL
3451 externalParEntInitProcessor(XML_Parser parser
,
3454 const char **nextPtr
)
3456 enum XML_Error result
= initializeEncoding(parser
);
3457 if (result
!= XML_ERROR_NONE
)
3460 /* we know now that XML_Parse(Buffer) has been called,
3461 so we consider the external parameter entity read */
3462 _dtd
->paramEntityRead
= XML_TRUE
;
3464 if (prologState
.inEntityValue
) {
3465 processor
= entityValueInitProcessor
;
3466 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3469 processor
= externalParEntProcessor
;
3470 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3474 static enum XML_Error PTRCALL
3475 entityValueInitProcessor(XML_Parser parser
,
3478 const char **nextPtr
)
3481 const char *start
= s
;
3482 const char *next
= start
;
3486 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3489 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3491 return XML_ERROR_NONE
;
3494 case XML_TOK_INVALID
:
3495 return XML_ERROR_INVALID_TOKEN
;
3496 case XML_TOK_PARTIAL
:
3497 return XML_ERROR_UNCLOSED_TOKEN
;
3498 case XML_TOK_PARTIAL_CHAR
:
3499 return XML_ERROR_PARTIAL_CHAR
;
3500 case XML_TOK_NONE
: /* start == end */
3504 /* found end of entity value - can store it now */
3505 return storeEntityValue(parser
, encoding
, s
, end
);
3507 else if (tok
== XML_TOK_XML_DECL
) {
3508 enum XML_Error result
;
3509 result
= processXmlDecl(parser
, 0, start
, next
);
3510 if (result
!= XML_ERROR_NONE
)
3512 switch (ps_parsing
) {
3515 return XML_ERROR_NONE
;
3517 return XML_ERROR_ABORTED
;
3521 /* stop scanning for text declaration - we found one */
3522 processor
= entityValueProcessor
;
3523 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3525 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3526 return XML_TOK_NONE on the next call, which would then cause the
3527 function to exit with *nextPtr set to s - that is what we want for other
3528 tokens, but not for the BOM - we would rather like to skip it;
3529 then, when this routine is entered the next time, XmlPrologTok will
3530 return XML_TOK_INVALID, since the BOM is still in the buffer
3532 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3534 return XML_ERROR_NONE
;
3541 static enum XML_Error PTRCALL
3542 externalParEntProcessor(XML_Parser parser
,
3545 const char **nextPtr
)
3547 const char *next
= s
;
3550 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3552 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3554 return XML_ERROR_NONE
;
3557 case XML_TOK_INVALID
:
3558 return XML_ERROR_INVALID_TOKEN
;
3559 case XML_TOK_PARTIAL
:
3560 return XML_ERROR_UNCLOSED_TOKEN
;
3561 case XML_TOK_PARTIAL_CHAR
:
3562 return XML_ERROR_PARTIAL_CHAR
;
3563 case XML_TOK_NONE
: /* start == end */
3568 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3569 However, when parsing an external subset, doProlog will not accept a BOM
3570 as valid, and report a syntax error, so we have to skip the BOM
3572 else if (tok
== XML_TOK_BOM
) {
3574 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3577 processor
= prologProcessor
;
3578 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3579 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3582 static enum XML_Error PTRCALL
3583 entityValueProcessor(XML_Parser parser
,
3586 const char **nextPtr
)
3588 const char *start
= s
;
3589 const char *next
= s
;
3590 const ENCODING
*enc
= encoding
;
3594 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3596 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3598 return XML_ERROR_NONE
;
3601 case XML_TOK_INVALID
:
3602 return XML_ERROR_INVALID_TOKEN
;
3603 case XML_TOK_PARTIAL
:
3604 return XML_ERROR_UNCLOSED_TOKEN
;
3605 case XML_TOK_PARTIAL_CHAR
:
3606 return XML_ERROR_PARTIAL_CHAR
;
3607 case XML_TOK_NONE
: /* start == end */
3611 /* found end of entity value - can store it now */
3612 return storeEntityValue(parser
, enc
, s
, end
);
3618 #endif /* XML_DTD */
3620 static enum XML_Error PTRCALL
3621 prologProcessor(XML_Parser parser
,
3624 const char **nextPtr
)
3626 const char *next
= s
;
3627 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3628 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3629 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3632 static enum XML_Error
3633 doProlog(XML_Parser parser
,
3634 const ENCODING
*enc
,
3639 const char **nextPtr
,
3643 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3644 #endif /* XML_DTD */
3645 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3646 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3647 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3648 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3649 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3650 static const XML_Char atypeENTITIES
[] =
3651 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3652 static const XML_Char atypeNMTOKEN
[] = {
3653 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3654 static const XML_Char atypeNMTOKENS
[] = {
3655 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3656 static const XML_Char notationPrefix
[] = {
3657 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3658 static const XML_Char enumValueSep
[] = { '|', '\0' };
3659 static const XML_Char enumValueStart
[] = { '(', '\0' };
3661 /* save one level of indirection */
3662 DTD
* const dtd
= _dtd
;
3664 const char **eventPP
;
3665 const char **eventEndPP
;
3666 enum XML_Content_Quant quant
;
3668 if (enc
== encoding
) {
3669 eventPP
= &eventPtr
;
3670 eventEndPP
= &eventEndPtr
;
3673 eventPP
= &(openInternalEntities
->internalEventPtr
);
3674 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3679 XML_Bool handleDefault
= XML_TRUE
;
3683 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3685 return XML_ERROR_NONE
;
3688 case XML_TOK_INVALID
:
3690 return XML_ERROR_INVALID_TOKEN
;
3691 case XML_TOK_PARTIAL
:
3692 return XML_ERROR_UNCLOSED_TOKEN
;
3693 case XML_TOK_PARTIAL_CHAR
:
3694 return XML_ERROR_PARTIAL_CHAR
;
3697 /* for internal PE NOT referenced between declarations */
3698 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3700 return XML_ERROR_NONE
;
3702 /* WFC: PE Between Declarations - must check that PE contains
3703 complete markup, not only for external PEs, but also for
3704 internal PEs if the reference occurs between declarations.
3706 if (isParamEntity
|| enc
!= encoding
) {
3707 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3709 return XML_ERROR_INCOMPLETE_PE
;
3711 return XML_ERROR_NONE
;
3713 #endif /* XML_DTD */
3714 return XML_ERROR_NO_ELEMENTS
;
3721 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3723 case XML_ROLE_XML_DECL
:
3725 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3726 if (result
!= XML_ERROR_NONE
)
3729 handleDefault
= XML_FALSE
;
3732 case XML_ROLE_DOCTYPE_NAME
:
3733 if (startDoctypeDeclHandler
) {
3734 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3736 return XML_ERROR_NO_MEMORY
;
3737 poolFinish(&tempPool
);
3738 doctypePubid
= NULL
;
3739 handleDefault
= XML_FALSE
;
3741 doctypeSysid
= NULL
; /* always initialize to NULL */
3743 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3744 if (startDoctypeDeclHandler
) {
3745 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3748 poolClear(&tempPool
);
3749 handleDefault
= XML_FALSE
;
3753 case XML_ROLE_TEXT_DECL
:
3755 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3756 if (result
!= XML_ERROR_NONE
)
3759 handleDefault
= XML_FALSE
;
3762 #endif /* XML_DTD */
3763 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3765 useForeignDTD
= XML_FALSE
;
3766 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3770 return XML_ERROR_NO_MEMORY
;
3771 #endif /* XML_DTD */
3772 dtd
->hasParamEntityRefs
= XML_TRUE
;
3773 if (startDoctypeDeclHandler
) {
3774 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3775 return XML_ERROR_PUBLICID
;
3776 doctypePubid
= poolStoreString(&tempPool
, enc
,
3777 s
+ enc
->minBytesPerChar
,
3778 next
- enc
->minBytesPerChar
);
3780 return XML_ERROR_NO_MEMORY
;
3781 normalizePublicId((XML_Char
*)doctypePubid
);
3782 poolFinish(&tempPool
);
3783 handleDefault
= XML_FALSE
;
3784 goto alreadyChecked
;
3787 case XML_ROLE_ENTITY_PUBLIC_ID
:
3788 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3789 return XML_ERROR_PUBLICID
;
3791 if (dtd
->keepProcessing
&& declEntity
) {
3792 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3794 s
+ enc
->minBytesPerChar
,
3795 next
- enc
->minBytesPerChar
);
3797 return XML_ERROR_NO_MEMORY
;
3798 normalizePublicId(tem
);
3799 declEntity
->publicId
= tem
;
3800 poolFinish(&dtd
->pool
);
3801 if (entityDeclHandler
)
3802 handleDefault
= XML_FALSE
;
3805 case XML_ROLE_DOCTYPE_CLOSE
:
3807 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3808 doctypeSysid
, doctypePubid
, 0);
3809 poolClear(&tempPool
);
3810 handleDefault
= XML_FALSE
;
3812 /* doctypeSysid will be non-NULL in the case of a previous
3813 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3814 was not set, indicating an external subset
3817 if (doctypeSysid
|| useForeignDTD
) {
3818 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3819 dtd
->hasParamEntityRefs
= XML_TRUE
;
3820 if (paramEntityParsing
&& externalEntityRefHandler
) {
3821 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3825 return XML_ERROR_NO_MEMORY
;
3827 entity
->base
= curBase
;
3828 dtd
->paramEntityRead
= XML_FALSE
;
3829 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3834 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3835 if (dtd
->paramEntityRead
) {
3836 if (!dtd
->standalone
&&
3837 notStandaloneHandler
&&
3838 !notStandaloneHandler(handlerArg
))
3839 return XML_ERROR_NOT_STANDALONE
;
3841 /* if we didn't read the foreign DTD then this means that there
3842 is no external subset and we must reset dtd->hasParamEntityRefs
3844 else if (!doctypeSysid
)
3845 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3846 /* end of DTD - no need to update dtd->keepProcessing */
3848 useForeignDTD
= XML_FALSE
;
3850 #endif /* XML_DTD */
3851 if (endDoctypeDeclHandler
) {
3852 endDoctypeDeclHandler(handlerArg
);
3853 handleDefault
= XML_FALSE
;
3856 case XML_ROLE_INSTANCE_START
:
3858 /* if there is no DOCTYPE declaration then now is the
3859 last chance to read the foreign DTD
3861 if (useForeignDTD
) {
3862 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3863 dtd
->hasParamEntityRefs
= XML_TRUE
;
3864 if (paramEntityParsing
&& externalEntityRefHandler
) {
3865 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3869 return XML_ERROR_NO_MEMORY
;
3870 entity
->base
= curBase
;
3871 dtd
->paramEntityRead
= XML_FALSE
;
3872 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3877 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3878 if (dtd
->paramEntityRead
) {
3879 if (!dtd
->standalone
&&
3880 notStandaloneHandler
&&
3881 !notStandaloneHandler(handlerArg
))
3882 return XML_ERROR_NOT_STANDALONE
;
3884 /* if we didn't read the foreign DTD then this means that there
3885 is no external subset and we must reset dtd->hasParamEntityRefs
3888 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3889 /* end of DTD - no need to update dtd->keepProcessing */
3892 #endif /* XML_DTD */
3893 processor
= contentProcessor
;
3894 return contentProcessor(parser
, s
, end
, nextPtr
);
3895 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3896 declElementType
= getElementType(parser
, enc
, s
, next
);
3897 if (!declElementType
)
3898 return XML_ERROR_NO_MEMORY
;
3899 goto checkAttListDeclHandler
;
3900 case XML_ROLE_ATTRIBUTE_NAME
:
3901 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3902 if (!declAttributeId
)
3903 return XML_ERROR_NO_MEMORY
;
3904 declAttributeIsCdata
= XML_FALSE
;
3905 declAttributeType
= NULL
;
3906 declAttributeIsId
= XML_FALSE
;
3907 goto checkAttListDeclHandler
;
3908 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3909 declAttributeIsCdata
= XML_TRUE
;
3910 declAttributeType
= atypeCDATA
;
3911 goto checkAttListDeclHandler
;
3912 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3913 declAttributeIsId
= XML_TRUE
;
3914 declAttributeType
= atypeID
;
3915 goto checkAttListDeclHandler
;
3916 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3917 declAttributeType
= atypeIDREF
;
3918 goto checkAttListDeclHandler
;
3919 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3920 declAttributeType
= atypeIDREFS
;
3921 goto checkAttListDeclHandler
;
3922 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3923 declAttributeType
= atypeENTITY
;
3924 goto checkAttListDeclHandler
;
3925 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3926 declAttributeType
= atypeENTITIES
;
3927 goto checkAttListDeclHandler
;
3928 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3929 declAttributeType
= atypeNMTOKEN
;
3930 goto checkAttListDeclHandler
;
3931 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3932 declAttributeType
= atypeNMTOKENS
;
3933 checkAttListDeclHandler
:
3934 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3935 handleDefault
= XML_FALSE
;
3937 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3938 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3939 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3940 const XML_Char
*prefix
;
3941 if (declAttributeType
) {
3942 prefix
= enumValueSep
;
3945 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3949 if (!poolAppendString(&tempPool
, prefix
))
3950 return XML_ERROR_NO_MEMORY
;
3951 if (!poolAppend(&tempPool
, enc
, s
, next
))
3952 return XML_ERROR_NO_MEMORY
;
3953 declAttributeType
= tempPool
.start
;
3954 handleDefault
= XML_FALSE
;
3957 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3958 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3959 if (dtd
->keepProcessing
) {
3960 if (!defineAttribute(declElementType
, declAttributeId
,
3961 declAttributeIsCdata
, declAttributeIsId
,
3963 return XML_ERROR_NO_MEMORY
;
3964 if (attlistDeclHandler
&& declAttributeType
) {
3965 if (*declAttributeType
== XML_T('(')
3966 || (*declAttributeType
== XML_T('N')
3967 && declAttributeType
[1] == XML_T('O'))) {
3968 /* Enumerated or Notation type */
3969 if (!poolAppendChar(&tempPool
, XML_T(')'))
3970 || !poolAppendChar(&tempPool
, XML_T('\0')))
3971 return XML_ERROR_NO_MEMORY
;
3972 declAttributeType
= tempPool
.start
;
3973 poolFinish(&tempPool
);
3976 attlistDeclHandler(handlerArg
, declElementType
->name
,
3977 declAttributeId
->name
, declAttributeType
,
3978 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3979 poolClear(&tempPool
);
3980 handleDefault
= XML_FALSE
;
3984 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3985 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3986 if (dtd
->keepProcessing
) {
3987 const XML_Char
*attVal
;
3988 enum XML_Error result
=
3989 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3990 s
+ enc
->minBytesPerChar
,
3991 next
- enc
->minBytesPerChar
,
3995 attVal
= poolStart(&dtd
->pool
);
3996 poolFinish(&dtd
->pool
);
3997 /* ID attributes aren't allowed to have a default */
3998 if (!defineAttribute(declElementType
, declAttributeId
,
3999 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4000 return XML_ERROR_NO_MEMORY
;
4001 if (attlistDeclHandler
&& declAttributeType
) {
4002 if (*declAttributeType
== XML_T('(')
4003 || (*declAttributeType
== XML_T('N')
4004 && declAttributeType
[1] == XML_T('O'))) {
4005 /* Enumerated or Notation type */
4006 if (!poolAppendChar(&tempPool
, XML_T(')'))
4007 || !poolAppendChar(&tempPool
, XML_T('\0')))
4008 return XML_ERROR_NO_MEMORY
;
4009 declAttributeType
= tempPool
.start
;
4010 poolFinish(&tempPool
);
4013 attlistDeclHandler(handlerArg
, declElementType
->name
,
4014 declAttributeId
->name
, declAttributeType
,
4016 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4017 poolClear(&tempPool
);
4018 handleDefault
= XML_FALSE
;
4022 case XML_ROLE_ENTITY_VALUE
:
4023 if (dtd
->keepProcessing
) {
4024 enum XML_Error result
= storeEntityValue(parser
, enc
,
4025 s
+ enc
->minBytesPerChar
,
4026 next
- enc
->minBytesPerChar
);
4028 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4029 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4030 poolFinish(&dtd
->entityValuePool
);
4031 if (entityDeclHandler
) {
4033 entityDeclHandler(handlerArg
,
4035 declEntity
->is_param
,
4036 declEntity
->textPtr
,
4037 declEntity
->textLen
,
4039 handleDefault
= XML_FALSE
;
4043 poolDiscard(&dtd
->entityValuePool
);
4044 if (result
!= XML_ERROR_NONE
)
4048 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4050 useForeignDTD
= XML_FALSE
;
4051 #endif /* XML_DTD */
4052 dtd
->hasParamEntityRefs
= XML_TRUE
;
4053 if (startDoctypeDeclHandler
) {
4054 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4055 s
+ enc
->minBytesPerChar
,
4056 next
- enc
->minBytesPerChar
);
4057 if (doctypeSysid
== NULL
)
4058 return XML_ERROR_NO_MEMORY
;
4059 poolFinish(&tempPool
);
4060 handleDefault
= XML_FALSE
;
4064 /* use externalSubsetName to make doctypeSysid non-NULL
4065 for the case where no startDoctypeDeclHandler is set */
4066 doctypeSysid
= externalSubsetName
;
4067 #endif /* XML_DTD */
4068 if (!dtd
->standalone
4070 && !paramEntityParsing
4071 #endif /* XML_DTD */
4072 && notStandaloneHandler
4073 && !notStandaloneHandler(handlerArg
))
4074 return XML_ERROR_NOT_STANDALONE
;
4079 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4083 return XML_ERROR_NO_MEMORY
;
4084 declEntity
->publicId
= NULL
;
4087 #endif /* XML_DTD */
4088 case XML_ROLE_ENTITY_SYSTEM_ID
:
4089 if (dtd
->keepProcessing
&& declEntity
) {
4090 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4091 s
+ enc
->minBytesPerChar
,
4092 next
- enc
->minBytesPerChar
);
4093 if (!declEntity
->systemId
)
4094 return XML_ERROR_NO_MEMORY
;
4095 declEntity
->base
= curBase
;
4096 poolFinish(&dtd
->pool
);
4097 if (entityDeclHandler
)
4098 handleDefault
= XML_FALSE
;
4101 case XML_ROLE_ENTITY_COMPLETE
:
4102 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4104 entityDeclHandler(handlerArg
,
4106 declEntity
->is_param
,
4109 declEntity
->systemId
,
4110 declEntity
->publicId
,
4112 handleDefault
= XML_FALSE
;
4115 case XML_ROLE_ENTITY_NOTATION_NAME
:
4116 if (dtd
->keepProcessing
&& declEntity
) {
4117 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4118 if (!declEntity
->notation
)
4119 return XML_ERROR_NO_MEMORY
;
4120 poolFinish(&dtd
->pool
);
4121 if (unparsedEntityDeclHandler
) {
4123 unparsedEntityDeclHandler(handlerArg
,
4126 declEntity
->systemId
,
4127 declEntity
->publicId
,
4128 declEntity
->notation
);
4129 handleDefault
= XML_FALSE
;
4131 else if (entityDeclHandler
) {
4133 entityDeclHandler(handlerArg
,
4137 declEntity
->systemId
,
4138 declEntity
->publicId
,
4139 declEntity
->notation
);
4140 handleDefault
= XML_FALSE
;
4144 case XML_ROLE_GENERAL_ENTITY_NAME
:
4146 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4150 if (dtd
->keepProcessing
) {
4151 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4153 return XML_ERROR_NO_MEMORY
;
4154 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4157 return XML_ERROR_NO_MEMORY
;
4158 if (declEntity
->name
!= name
) {
4159 poolDiscard(&dtd
->pool
);
4163 poolFinish(&dtd
->pool
);
4164 declEntity
->publicId
= NULL
;
4165 declEntity
->is_param
= XML_FALSE
;
4166 /* if we have a parent parser or are reading an internal parameter
4167 entity, then the entity declaration is not considered "internal"
4169 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4170 if (entityDeclHandler
)
4171 handleDefault
= XML_FALSE
;
4175 poolDiscard(&dtd
->pool
);
4180 case XML_ROLE_PARAM_ENTITY_NAME
:
4182 if (dtd
->keepProcessing
) {
4183 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4185 return XML_ERROR_NO_MEMORY
;
4186 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4187 name
, sizeof(ENTITY
));
4189 return XML_ERROR_NO_MEMORY
;
4190 if (declEntity
->name
!= name
) {
4191 poolDiscard(&dtd
->pool
);
4195 poolFinish(&dtd
->pool
);
4196 declEntity
->publicId
= NULL
;
4197 declEntity
->is_param
= XML_TRUE
;
4198 /* if we have a parent parser or are reading an internal parameter
4199 entity, then the entity declaration is not considered "internal"
4201 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4202 if (entityDeclHandler
)
4203 handleDefault
= XML_FALSE
;
4207 poolDiscard(&dtd
->pool
);
4210 #else /* not XML_DTD */
4212 #endif /* XML_DTD */
4214 case XML_ROLE_NOTATION_NAME
:
4215 declNotationPublicId
= NULL
;
4216 declNotationName
= NULL
;
4217 if (notationDeclHandler
) {
4218 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4219 if (!declNotationName
)
4220 return XML_ERROR_NO_MEMORY
;
4221 poolFinish(&tempPool
);
4222 handleDefault
= XML_FALSE
;
4225 case XML_ROLE_NOTATION_PUBLIC_ID
:
4226 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4227 return XML_ERROR_PUBLICID
;
4228 if (declNotationName
) { /* means notationDeclHandler != NULL */
4229 XML_Char
*tem
= poolStoreString(&tempPool
,
4231 s
+ enc
->minBytesPerChar
,
4232 next
- enc
->minBytesPerChar
);
4234 return XML_ERROR_NO_MEMORY
;
4235 normalizePublicId(tem
);
4236 declNotationPublicId
= tem
;
4237 poolFinish(&tempPool
);
4238 handleDefault
= XML_FALSE
;
4241 case XML_ROLE_NOTATION_SYSTEM_ID
:
4242 if (declNotationName
&& notationDeclHandler
) {
4243 const XML_Char
*systemId
4244 = poolStoreString(&tempPool
, enc
,
4245 s
+ enc
->minBytesPerChar
,
4246 next
- enc
->minBytesPerChar
);
4248 return XML_ERROR_NO_MEMORY
;
4250 notationDeclHandler(handlerArg
,
4254 declNotationPublicId
);
4255 handleDefault
= XML_FALSE
;
4257 poolClear(&tempPool
);
4259 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4260 if (declNotationPublicId
&& notationDeclHandler
) {
4262 notationDeclHandler(handlerArg
,
4266 declNotationPublicId
);
4267 handleDefault
= XML_FALSE
;
4269 poolClear(&tempPool
);
4271 case XML_ROLE_ERROR
:
4273 case XML_TOK_PARAM_ENTITY_REF
:
4274 /* PE references in internal subset are
4275 not allowed within declarations. */
4276 return XML_ERROR_PARAM_ENTITY_REF
;
4277 case XML_TOK_XML_DECL
:
4278 return XML_ERROR_MISPLACED_XML_PI
;
4280 return XML_ERROR_SYNTAX
;
4283 case XML_ROLE_IGNORE_SECT
:
4285 enum XML_Error result
;
4287 reportDefault(parser
, enc
, s
, next
);
4288 handleDefault
= XML_FALSE
;
4289 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4290 if (result
!= XML_ERROR_NONE
)
4293 processor
= ignoreSectionProcessor
;
4298 #endif /* XML_DTD */
4299 case XML_ROLE_GROUP_OPEN
:
4300 if (prologState
.level
>= groupSize
) {
4302 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4304 return XML_ERROR_NO_MEMORY
;
4305 groupConnector
= temp
;
4306 if (dtd
->scaffIndex
) {
4307 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4308 groupSize
* sizeof(int));
4310 return XML_ERROR_NO_MEMORY
;
4311 dtd
->scaffIndex
= temp
;
4315 groupConnector
= (char *)MALLOC(groupSize
= 32);
4316 if (!groupConnector
)
4317 return XML_ERROR_NO_MEMORY
;
4320 groupConnector
[prologState
.level
] = 0;
4321 if (dtd
->in_eldecl
) {
4322 int myindex
= nextScaffoldPart(parser
);
4324 return XML_ERROR_NO_MEMORY
;
4325 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4327 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4328 if (elementDeclHandler
)
4329 handleDefault
= XML_FALSE
;
4332 case XML_ROLE_GROUP_SEQUENCE
:
4333 if (groupConnector
[prologState
.level
] == '|')
4334 return XML_ERROR_SYNTAX
;
4335 groupConnector
[prologState
.level
] = ',';
4336 if (dtd
->in_eldecl
&& elementDeclHandler
)
4337 handleDefault
= XML_FALSE
;
4339 case XML_ROLE_GROUP_CHOICE
:
4340 if (groupConnector
[prologState
.level
] == ',')
4341 return XML_ERROR_SYNTAX
;
4343 && !groupConnector
[prologState
.level
]
4344 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4347 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4349 if (elementDeclHandler
)
4350 handleDefault
= XML_FALSE
;
4352 groupConnector
[prologState
.level
] = '|';
4354 case XML_ROLE_PARAM_ENTITY_REF
:
4356 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4357 dtd
->hasParamEntityRefs
= XML_TRUE
;
4358 if (!paramEntityParsing
)
4359 dtd
->keepProcessing
= dtd
->standalone
;
4361 const XML_Char
*name
;
4363 name
= poolStoreString(&dtd
->pool
, enc
,
4364 s
+ enc
->minBytesPerChar
,
4365 next
- enc
->minBytesPerChar
);
4367 return XML_ERROR_NO_MEMORY
;
4368 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4369 poolDiscard(&dtd
->pool
);
4370 /* first, determine if a check for an existing declaration is needed;
4371 if yes, check that the entity exists, and that it is internal,
4372 otherwise call the skipped entity handler
4374 if (prologState
.documentEntity
&&
4376 ? !openInternalEntities
4377 : !dtd
->hasParamEntityRefs
)) {
4379 return XML_ERROR_UNDEFINED_ENTITY
;
4380 else if (!entity
->is_internal
)
4381 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4384 dtd
->keepProcessing
= dtd
->standalone
;
4385 /* cannot report skipped entities in declarations */
4386 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4387 skippedEntityHandler(handlerArg
, name
, 1);
4388 handleDefault
= XML_FALSE
;
4393 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4394 if (entity
->textPtr
) {
4395 enum XML_Error result
;
4396 XML_Bool betweenDecl
=
4397 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4398 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4399 if (result
!= XML_ERROR_NONE
)
4401 handleDefault
= XML_FALSE
;
4404 if (externalEntityRefHandler
) {
4405 dtd
->paramEntityRead
= XML_FALSE
;
4406 entity
->open
= XML_TRUE
;
4407 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4411 entity
->publicId
)) {
4412 entity
->open
= XML_FALSE
;
4413 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4415 entity
->open
= XML_FALSE
;
4416 handleDefault
= XML_FALSE
;
4417 if (!dtd
->paramEntityRead
) {
4418 dtd
->keepProcessing
= dtd
->standalone
;
4423 dtd
->keepProcessing
= dtd
->standalone
;
4427 #endif /* XML_DTD */
4428 if (!dtd
->standalone
&&
4429 notStandaloneHandler
&&
4430 !notStandaloneHandler(handlerArg
))
4431 return XML_ERROR_NOT_STANDALONE
;
4434 /* Element declaration stuff */
4436 case XML_ROLE_ELEMENT_NAME
:
4437 if (elementDeclHandler
) {
4438 declElementType
= getElementType(parser
, enc
, s
, next
);
4439 if (!declElementType
)
4440 return XML_ERROR_NO_MEMORY
;
4441 dtd
->scaffLevel
= 0;
4442 dtd
->scaffCount
= 0;
4443 dtd
->in_eldecl
= XML_TRUE
;
4444 handleDefault
= XML_FALSE
;
4448 case XML_ROLE_CONTENT_ANY
:
4449 case XML_ROLE_CONTENT_EMPTY
:
4450 if (dtd
->in_eldecl
) {
4451 if (elementDeclHandler
) {
4452 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4454 return XML_ERROR_NO_MEMORY
;
4455 content
->quant
= XML_CQUANT_NONE
;
4456 content
->name
= NULL
;
4457 content
->numchildren
= 0;
4458 content
->children
= NULL
;
4459 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4463 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4464 handleDefault
= XML_FALSE
;
4466 dtd
->in_eldecl
= XML_FALSE
;
4470 case XML_ROLE_CONTENT_PCDATA
:
4471 if (dtd
->in_eldecl
) {
4472 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4474 if (elementDeclHandler
)
4475 handleDefault
= XML_FALSE
;
4479 case XML_ROLE_CONTENT_ELEMENT
:
4480 quant
= XML_CQUANT_NONE
;
4481 goto elementContent
;
4482 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4483 quant
= XML_CQUANT_OPT
;
4484 goto elementContent
;
4485 case XML_ROLE_CONTENT_ELEMENT_REP
:
4486 quant
= XML_CQUANT_REP
;
4487 goto elementContent
;
4488 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4489 quant
= XML_CQUANT_PLUS
;
4491 if (dtd
->in_eldecl
) {
4493 const XML_Char
*name
;
4495 const char *nxt
= (quant
== XML_CQUANT_NONE
4497 : next
- enc
->minBytesPerChar
);
4498 int myindex
= nextScaffoldPart(parser
);
4500 return XML_ERROR_NO_MEMORY
;
4501 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4502 dtd
->scaffold
[myindex
].quant
= quant
;
4503 el
= getElementType(parser
, enc
, s
, nxt
);
4505 return XML_ERROR_NO_MEMORY
;
4507 dtd
->scaffold
[myindex
].name
= name
;
4509 for (; name
[nameLen
++]; );
4510 dtd
->contentStringLen
+= nameLen
;
4511 if (elementDeclHandler
)
4512 handleDefault
= XML_FALSE
;
4516 case XML_ROLE_GROUP_CLOSE
:
4517 quant
= XML_CQUANT_NONE
;
4519 case XML_ROLE_GROUP_CLOSE_OPT
:
4520 quant
= XML_CQUANT_OPT
;
4522 case XML_ROLE_GROUP_CLOSE_REP
:
4523 quant
= XML_CQUANT_REP
;
4525 case XML_ROLE_GROUP_CLOSE_PLUS
:
4526 quant
= XML_CQUANT_PLUS
;
4528 if (dtd
->in_eldecl
) {
4529 if (elementDeclHandler
)
4530 handleDefault
= XML_FALSE
;
4532 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4533 if (dtd
->scaffLevel
== 0) {
4534 if (!handleDefault
) {
4535 XML_Content
*model
= build_model(parser
);
4537 return XML_ERROR_NO_MEMORY
;
4539 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4541 dtd
->in_eldecl
= XML_FALSE
;
4542 dtd
->contentStringLen
= 0;
4546 /* End element declaration stuff */
4549 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4550 return XML_ERROR_NO_MEMORY
;
4551 handleDefault
= XML_FALSE
;
4553 case XML_ROLE_COMMENT
:
4554 if (!reportComment(parser
, enc
, s
, next
))
4555 return XML_ERROR_NO_MEMORY
;
4556 handleDefault
= XML_FALSE
;
4561 handleDefault
= XML_FALSE
;
4565 case XML_ROLE_DOCTYPE_NONE
:
4566 if (startDoctypeDeclHandler
)
4567 handleDefault
= XML_FALSE
;
4569 case XML_ROLE_ENTITY_NONE
:
4570 if (dtd
->keepProcessing
&& entityDeclHandler
)
4571 handleDefault
= XML_FALSE
;
4573 case XML_ROLE_NOTATION_NONE
:
4574 if (notationDeclHandler
)
4575 handleDefault
= XML_FALSE
;
4577 case XML_ROLE_ATTLIST_NONE
:
4578 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4579 handleDefault
= XML_FALSE
;
4581 case XML_ROLE_ELEMENT_NONE
:
4582 if (elementDeclHandler
)
4583 handleDefault
= XML_FALSE
;
4585 } /* end of big switch */
4587 if (handleDefault
&& defaultHandler
)
4588 reportDefault(parser
, enc
, s
, next
);
4590 switch (ps_parsing
) {
4593 return XML_ERROR_NONE
;
4595 return XML_ERROR_ABORTED
;
4598 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4604 static enum XML_Error PTRCALL
4605 epilogProcessor(XML_Parser parser
,
4608 const char **nextPtr
)
4610 processor
= epilogProcessor
;
4613 const char *next
= NULL
;
4614 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4617 /* report partial linebreak - it might be the last token */
4618 case -XML_TOK_PROLOG_S
:
4619 if (defaultHandler
) {
4620 reportDefault(parser
, encoding
, s
, next
);
4621 if (ps_parsing
== XML_FINISHED
)
4622 return XML_ERROR_ABORTED
;
4625 return XML_ERROR_NONE
;
4628 return XML_ERROR_NONE
;
4629 case XML_TOK_PROLOG_S
:
4631 reportDefault(parser
, encoding
, s
, next
);
4634 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4635 return XML_ERROR_NO_MEMORY
;
4637 case XML_TOK_COMMENT
:
4638 if (!reportComment(parser
, encoding
, s
, next
))
4639 return XML_ERROR_NO_MEMORY
;
4641 case XML_TOK_INVALID
:
4643 return XML_ERROR_INVALID_TOKEN
;
4644 case XML_TOK_PARTIAL
:
4645 if (!ps_finalBuffer
) {
4647 return XML_ERROR_NONE
;
4649 return XML_ERROR_UNCLOSED_TOKEN
;
4650 case XML_TOK_PARTIAL_CHAR
:
4651 if (!ps_finalBuffer
) {
4653 return XML_ERROR_NONE
;
4655 return XML_ERROR_PARTIAL_CHAR
;
4657 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4659 eventPtr
= s
= next
;
4660 switch (ps_parsing
) {
4663 return XML_ERROR_NONE
;
4665 return XML_ERROR_ABORTED
;
4671 static enum XML_Error
4672 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4673 XML_Bool betweenDecl
)
4675 const char *textStart
, *textEnd
;
4677 enum XML_Error result
;
4678 OPEN_INTERNAL_ENTITY
*openEntity
;
4680 if (freeInternalEntities
) {
4681 openEntity
= freeInternalEntities
;
4682 freeInternalEntities
= openEntity
->next
;
4685 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4687 return XML_ERROR_NO_MEMORY
;
4689 entity
->open
= XML_TRUE
;
4690 entity
->processed
= 0;
4691 openEntity
->next
= openInternalEntities
;
4692 openInternalEntities
= openEntity
;
4693 openEntity
->entity
= entity
;
4694 openEntity
->startTagLevel
= tagLevel
;
4695 openEntity
->betweenDecl
= betweenDecl
;
4696 openEntity
->internalEventPtr
= NULL
;
4697 openEntity
->internalEventEndPtr
= NULL
;
4698 textStart
= (char *)entity
->textPtr
;
4699 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4702 if (entity
->is_param
) {
4703 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4704 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4705 next
, &next
, XML_FALSE
);
4708 #endif /* XML_DTD */
4709 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4710 textEnd
, &next
, XML_FALSE
);
4712 if (result
== XML_ERROR_NONE
) {
4713 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4714 entity
->processed
= (int)(next
- textStart
);
4715 processor
= internalEntityProcessor
;
4718 entity
->open
= XML_FALSE
;
4719 openInternalEntities
= openEntity
->next
;
4720 /* put openEntity back in list of free instances */
4721 openEntity
->next
= freeInternalEntities
;
4722 freeInternalEntities
= openEntity
;
4728 static enum XML_Error PTRCALL
4729 internalEntityProcessor(XML_Parser parser
,
4732 const char **nextPtr
)
4735 const char *textStart
, *textEnd
;
4737 enum XML_Error result
;
4738 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4740 return XML_ERROR_UNEXPECTED_STATE
;
4742 entity
= openEntity
->entity
;
4743 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4744 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4747 if (entity
->is_param
) {
4748 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4749 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4750 next
, &next
, XML_FALSE
);
4753 #endif /* XML_DTD */
4754 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4755 textStart
, textEnd
, &next
, XML_FALSE
);
4757 if (result
!= XML_ERROR_NONE
)
4759 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4760 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4764 entity
->open
= XML_FALSE
;
4765 openInternalEntities
= openEntity
->next
;
4766 /* put openEntity back in list of free instances */
4767 openEntity
->next
= freeInternalEntities
;
4768 freeInternalEntities
= openEntity
;
4772 if (entity
->is_param
) {
4774 processor
= prologProcessor
;
4775 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4776 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4777 (XML_Bool
)!ps_finalBuffer
);
4780 #endif /* XML_DTD */
4782 processor
= contentProcessor
;
4783 /* see externalEntityContentProcessor vs contentProcessor */
4784 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4785 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4789 static enum XML_Error PTRCALL
4790 errorProcessor(XML_Parser parser
,
4793 const char **nextPtr
)
4798 static enum XML_Error
4799 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4800 const char *ptr
, const char *end
,
4803 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4807 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4809 if (!poolAppendChar(pool
, XML_T('\0')))
4810 return XML_ERROR_NO_MEMORY
;
4811 return XML_ERROR_NONE
;
4814 static enum XML_Error
4815 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4816 const char *ptr
, const char *end
,
4819 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4822 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4825 return XML_ERROR_NONE
;
4826 case XML_TOK_INVALID
:
4827 if (enc
== encoding
)
4829 return XML_ERROR_INVALID_TOKEN
;
4830 case XML_TOK_PARTIAL
:
4831 if (enc
== encoding
)
4833 return XML_ERROR_INVALID_TOKEN
;
4834 case XML_TOK_CHAR_REF
:
4836 XML_Char buf
[XML_ENCODE_MAX
];
4838 int n
= XmlCharRefNumber(enc
, ptr
);
4840 if (enc
== encoding
)
4842 return XML_ERROR_BAD_CHAR_REF
;
4845 && n
== 0x20 /* space */
4846 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4848 n
= XmlEncode(n
, (ICHAR
*)buf
);
4850 if (enc
== encoding
)
4852 return XML_ERROR_BAD_CHAR_REF
;
4854 for (i
= 0; i
< n
; i
++) {
4855 if (!poolAppendChar(pool
, buf
[i
]))
4856 return XML_ERROR_NO_MEMORY
;
4860 case XML_TOK_DATA_CHARS
:
4861 if (!poolAppend(pool
, enc
, ptr
, next
))
4862 return XML_ERROR_NO_MEMORY
;
4864 case XML_TOK_TRAILING_CR
:
4865 next
= ptr
+ enc
->minBytesPerChar
;
4867 case XML_TOK_ATTRIBUTE_VALUE_S
:
4868 case XML_TOK_DATA_NEWLINE
:
4869 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4871 if (!poolAppendChar(pool
, 0x20))
4872 return XML_ERROR_NO_MEMORY
;
4874 case XML_TOK_ENTITY_REF
:
4876 const XML_Char
*name
;
4878 char checkEntityDecl
;
4879 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4880 ptr
+ enc
->minBytesPerChar
,
4881 next
- enc
->minBytesPerChar
);
4883 if (!poolAppendChar(pool
, ch
))
4884 return XML_ERROR_NO_MEMORY
;
4887 name
= poolStoreString(&temp2Pool
, enc
,
4888 ptr
+ enc
->minBytesPerChar
,
4889 next
- enc
->minBytesPerChar
);
4891 return XML_ERROR_NO_MEMORY
;
4892 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4893 poolDiscard(&temp2Pool
);
4894 /* First, determine if a check for an existing declaration is needed;
4895 if yes, check that the entity exists, and that it is internal.
4897 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4900 prologState
.documentEntity
&&
4901 #endif /* XML_DTD */
4903 ? !openInternalEntities
4904 : !dtd
->hasParamEntityRefs
);
4905 else /* if (pool == &tempPool): we are called from content */
4906 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4907 if (checkEntityDecl
) {
4909 return XML_ERROR_UNDEFINED_ENTITY
;
4910 else if (!entity
->is_internal
)
4911 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4914 /* Cannot report skipped entity here - see comments on
4915 skippedEntityHandler.
4916 if (skippedEntityHandler)
4917 skippedEntityHandler(handlerArg, name, 0);
4919 /* Cannot call the default handler because this would be
4920 out of sync with the call to the startElementHandler.
4921 if ((pool == &tempPool) && defaultHandler)
4922 reportDefault(parser, enc, ptr, next);
4927 if (enc
== encoding
)
4929 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4931 if (entity
->notation
) {
4932 if (enc
== encoding
)
4934 return XML_ERROR_BINARY_ENTITY_REF
;
4936 if (!entity
->textPtr
) {
4937 if (enc
== encoding
)
4939 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4942 enum XML_Error result
;
4943 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4944 entity
->open
= XML_TRUE
;
4945 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4946 (char *)entity
->textPtr
,
4947 (char *)textEnd
, pool
);
4948 entity
->open
= XML_FALSE
;
4955 if (enc
== encoding
)
4957 return XML_ERROR_UNEXPECTED_STATE
;
4964 static enum XML_Error
4965 storeEntityValue(XML_Parser parser
,
4966 const ENCODING
*enc
,
4967 const char *entityTextPtr
,
4968 const char *entityTextEnd
)
4970 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4971 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4972 enum XML_Error result
= XML_ERROR_NONE
;
4974 int oldInEntityValue
= prologState
.inEntityValue
;
4975 prologState
.inEntityValue
= 1;
4976 #endif /* XML_DTD */
4977 /* never return Null for the value argument in EntityDeclHandler,
4978 since this would indicate an external entity; therefore we
4979 have to make sure that entityValuePool.start is not null */
4980 if (!pool
->blocks
) {
4981 if (!poolGrow(pool
))
4982 return XML_ERROR_NO_MEMORY
;
4987 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4989 case XML_TOK_PARAM_ENTITY_REF
:
4991 if (isParamEntity
|| enc
!= encoding
) {
4992 const XML_Char
*name
;
4994 name
= poolStoreString(&tempPool
, enc
,
4995 entityTextPtr
+ enc
->minBytesPerChar
,
4996 next
- enc
->minBytesPerChar
);
4998 result
= XML_ERROR_NO_MEMORY
;
4999 goto endEntityValue
;
5001 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
5002 poolDiscard(&tempPool
);
5004 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5005 /* cannot report skipped entity here - see comments on
5006 skippedEntityHandler
5007 if (skippedEntityHandler)
5008 skippedEntityHandler(handlerArg, name, 0);
5010 dtd
->keepProcessing
= dtd
->standalone
;
5011 goto endEntityValue
;
5014 if (enc
== encoding
)
5015 eventPtr
= entityTextPtr
;
5016 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5017 goto endEntityValue
;
5019 if (entity
->systemId
) {
5020 if (externalEntityRefHandler
) {
5021 dtd
->paramEntityRead
= XML_FALSE
;
5022 entity
->open
= XML_TRUE
;
5023 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5027 entity
->publicId
)) {
5028 entity
->open
= XML_FALSE
;
5029 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5030 goto endEntityValue
;
5032 entity
->open
= XML_FALSE
;
5033 if (!dtd
->paramEntityRead
)
5034 dtd
->keepProcessing
= dtd
->standalone
;
5037 dtd
->keepProcessing
= dtd
->standalone
;
5040 entity
->open
= XML_TRUE
;
5041 result
= storeEntityValue(parser
,
5043 (char *)entity
->textPtr
,
5044 (char *)(entity
->textPtr
5045 + entity
->textLen
));
5046 entity
->open
= XML_FALSE
;
5048 goto endEntityValue
;
5052 #endif /* XML_DTD */
5053 /* In the internal subset, PE references are not legal
5054 within markup declarations, e.g entity values in this case. */
5055 eventPtr
= entityTextPtr
;
5056 result
= XML_ERROR_PARAM_ENTITY_REF
;
5057 goto endEntityValue
;
5059 result
= XML_ERROR_NONE
;
5060 goto endEntityValue
;
5061 case XML_TOK_ENTITY_REF
:
5062 case XML_TOK_DATA_CHARS
:
5063 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5064 result
= XML_ERROR_NO_MEMORY
;
5065 goto endEntityValue
;
5068 case XML_TOK_TRAILING_CR
:
5069 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5071 case XML_TOK_DATA_NEWLINE
:
5072 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5073 result
= XML_ERROR_NO_MEMORY
;
5074 goto endEntityValue
;
5076 *(pool
->ptr
)++ = 0xA;
5078 case XML_TOK_CHAR_REF
:
5080 XML_Char buf
[XML_ENCODE_MAX
];
5082 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5084 if (enc
== encoding
)
5085 eventPtr
= entityTextPtr
;
5086 result
= XML_ERROR_BAD_CHAR_REF
;
5087 goto endEntityValue
;
5089 n
= XmlEncode(n
, (ICHAR
*)buf
);
5091 if (enc
== encoding
)
5092 eventPtr
= entityTextPtr
;
5093 result
= XML_ERROR_BAD_CHAR_REF
;
5094 goto endEntityValue
;
5096 for (i
= 0; i
< n
; i
++) {
5097 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5098 result
= XML_ERROR_NO_MEMORY
;
5099 goto endEntityValue
;
5101 *(pool
->ptr
)++ = buf
[i
];
5105 case XML_TOK_PARTIAL
:
5106 if (enc
== encoding
)
5107 eventPtr
= entityTextPtr
;
5108 result
= XML_ERROR_INVALID_TOKEN
;
5109 goto endEntityValue
;
5110 case XML_TOK_INVALID
:
5111 if (enc
== encoding
)
5113 result
= XML_ERROR_INVALID_TOKEN
;
5114 goto endEntityValue
;
5116 if (enc
== encoding
)
5117 eventPtr
= entityTextPtr
;
5118 result
= XML_ERROR_UNEXPECTED_STATE
;
5119 goto endEntityValue
;
5121 entityTextPtr
= next
;
5125 prologState
.inEntityValue
= oldInEntityValue
;
5126 #endif /* XML_DTD */
5130 static void FASTCALL
5131 normalizeLines(XML_Char
*s
)
5135 if (*s
== XML_T('\0'))
5154 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5155 const char *start
, const char *end
)
5157 const XML_Char
*target
;
5160 if (!processingInstructionHandler
) {
5162 reportDefault(parser
, enc
, start
, end
);
5165 start
+= enc
->minBytesPerChar
* 2;
5166 tem
= start
+ XmlNameLength(enc
, start
);
5167 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5170 poolFinish(&tempPool
);
5171 data
= poolStoreString(&tempPool
, enc
,
5173 end
- enc
->minBytesPerChar
*2);
5176 normalizeLines(data
);
5177 processingInstructionHandler(handlerArg
, target
, data
);
5178 poolClear(&tempPool
);
5183 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5184 const char *start
, const char *end
)
5187 if (!commentHandler
) {
5189 reportDefault(parser
, enc
, start
, end
);
5192 data
= poolStoreString(&tempPool
,
5194 start
+ enc
->minBytesPerChar
* 4,
5195 end
- enc
->minBytesPerChar
* 3);
5198 normalizeLines(data
);
5199 commentHandler(handlerArg
, data
);
5200 poolClear(&tempPool
);
5205 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5206 const char *s
, const char *end
)
5208 if (MUST_CONVERT(enc
, s
)) {
5209 const char **eventPP
;
5210 const char **eventEndPP
;
5211 if (enc
== encoding
) {
5212 eventPP
= &eventPtr
;
5213 eventEndPP
= &eventEndPtr
;
5216 eventPP
= &(openInternalEntities
->internalEventPtr
);
5217 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5220 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5221 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5223 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5228 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5233 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5234 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5236 DEFAULT_ATTRIBUTE
*att
;
5237 if (value
|| isId
) {
5238 /* The handling of default attributes gets messed up if we have
5239 a default which duplicates a non-default. */
5241 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5242 if (attId
== type
->defaultAtts
[i
].id
)
5244 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5245 type
->idAtt
= attId
;
5247 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5248 if (type
->allocDefaultAtts
== 0) {
5249 type
->allocDefaultAtts
= 8;
5250 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5251 * sizeof(DEFAULT_ATTRIBUTE
));
5252 if (!type
->defaultAtts
)
5256 DEFAULT_ATTRIBUTE
*temp
;
5257 int count
= type
->allocDefaultAtts
* 2;
5258 temp
= (DEFAULT_ATTRIBUTE
*)
5259 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5262 type
->allocDefaultAtts
= count
;
5263 type
->defaultAtts
= temp
;
5266 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5269 att
->isCdata
= isCdata
;
5271 attId
->maybeTokenized
= XML_TRUE
;
5272 type
->nDefaultAtts
+= 1;
5277 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5279 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5280 const XML_Char
*name
;
5281 for (name
= elementType
->name
; *name
; name
++) {
5282 if (*name
== XML_T(':')) {
5285 for (s
= elementType
->name
; s
!= name
; s
++) {
5286 if (!poolAppendChar(&dtd
->pool
, *s
))
5289 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5291 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5295 if (prefix
->name
== poolStart(&dtd
->pool
))
5296 poolFinish(&dtd
->pool
);
5298 poolDiscard(&dtd
->pool
);
5299 elementType
->prefix
= prefix
;
5306 static ATTRIBUTE_ID
*
5307 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5308 const char *start
, const char *end
)
5310 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5312 const XML_Char
*name
;
5313 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5315 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5318 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5320 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5323 if (id
->name
!= name
)
5324 poolDiscard(&dtd
->pool
);
5326 poolFinish(&dtd
->pool
);
5329 else if (name
[0] == XML_T('x')
5330 && name
[1] == XML_T('m')
5331 && name
[2] == XML_T('l')
5332 && name
[3] == XML_T('n')
5333 && name
[4] == XML_T('s')
5334 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
5335 if (name
[5] == XML_T('\0'))
5336 id
->prefix
= &dtd
->defaultPrefix
;
5338 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5339 id
->xmlns
= XML_TRUE
;
5343 for (i
= 0; name
[i
]; i
++) {
5344 /* attributes without prefix are *not* in the default namespace */
5345 if (name
[i
] == XML_T(':')) {
5347 for (j
= 0; j
< i
; j
++) {
5348 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5351 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5353 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5355 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5356 poolFinish(&dtd
->pool
);
5358 poolDiscard(&dtd
->pool
);
5367 #define CONTEXT_SEP XML_T('\f')
5369 static const XML_Char
*
5370 getContext(XML_Parser parser
)
5372 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5373 HASH_TABLE_ITER iter
;
5374 XML_Bool needSep
= XML_FALSE
;
5376 if (dtd
->defaultPrefix
.binding
) {
5379 if (!poolAppendChar(&tempPool
, XML_T('=')))
5381 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5382 if (namespaceSeparator
)
5384 for (i
= 0; i
< len
; i
++)
5385 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5390 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5395 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5398 if (!prefix
->binding
)
5400 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5402 for (s
= prefix
->name
; *s
; s
++)
5403 if (!poolAppendChar(&tempPool
, *s
))
5405 if (!poolAppendChar(&tempPool
, XML_T('=')))
5407 len
= prefix
->binding
->uriLen
;
5408 if (namespaceSeparator
)
5410 for (i
= 0; i
< len
; i
++)
5411 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5417 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5420 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5425 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5427 for (s
= e
->name
; *s
; s
++)
5428 if (!poolAppendChar(&tempPool
, *s
))
5433 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5435 return tempPool
.start
;
5439 setContext(XML_Parser parser
, const XML_Char
*context
)
5441 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5442 const XML_Char
*s
= context
;
5444 while (*context
!= XML_T('\0')) {
5445 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5447 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5449 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5452 if (*s
!= XML_T('\0'))
5455 poolDiscard(&tempPool
);
5457 else if (*s
== XML_T('=')) {
5459 if (poolLength(&tempPool
) == 0)
5460 prefix
= &dtd
->defaultPrefix
;
5462 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5464 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5468 if (prefix
->name
== poolStart(&tempPool
)) {
5469 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5473 poolDiscard(&tempPool
);
5475 for (context
= s
+ 1;
5476 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5478 if (!poolAppendChar(&tempPool
, *context
))
5480 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5482 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5483 &inheritedBindings
) != XML_ERROR_NONE
)
5485 poolDiscard(&tempPool
);
5486 if (*context
!= XML_T('\0'))
5491 if (!poolAppendChar(&tempPool
, *s
))
5499 static void FASTCALL
5500 normalizePublicId(XML_Char
*publicId
)
5502 XML_Char
*p
= publicId
;
5504 for (s
= publicId
; *s
; s
++) {
5509 if (p
!= publicId
&& p
[-1] != 0x20)
5516 if (p
!= publicId
&& p
[-1] == 0x20)
5522 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5524 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5527 poolInit(&(p
->pool
), ms
);
5528 poolInit(&(p
->entityValuePool
), ms
);
5529 hashTableInit(&(p
->generalEntities
), ms
);
5530 hashTableInit(&(p
->elementTypes
), ms
);
5531 hashTableInit(&(p
->attributeIds
), ms
);
5532 hashTableInit(&(p
->prefixes
), ms
);
5534 p
->paramEntityRead
= XML_FALSE
;
5535 hashTableInit(&(p
->paramEntities
), ms
);
5536 #endif /* XML_DTD */
5537 p
->defaultPrefix
.name
= NULL
;
5538 p
->defaultPrefix
.binding
= NULL
;
5540 p
->in_eldecl
= XML_FALSE
;
5541 p
->scaffIndex
= NULL
;
5546 p
->contentStringLen
= 0;
5548 p
->keepProcessing
= XML_TRUE
;
5549 p
->hasParamEntityRefs
= XML_FALSE
;
5550 p
->standalone
= XML_FALSE
;
5555 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5557 HASH_TABLE_ITER iter
;
5558 hashTableIterInit(&iter
, &(p
->elementTypes
));
5560 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5563 if (e
->allocDefaultAtts
!= 0)
5564 ms
->free_fcn(e
->defaultAtts
);
5566 hashTableClear(&(p
->generalEntities
));
5568 p
->paramEntityRead
= XML_FALSE
;
5569 hashTableClear(&(p
->paramEntities
));
5570 #endif /* XML_DTD */
5571 hashTableClear(&(p
->elementTypes
));
5572 hashTableClear(&(p
->attributeIds
));
5573 hashTableClear(&(p
->prefixes
));
5574 poolClear(&(p
->pool
));
5575 poolClear(&(p
->entityValuePool
));
5576 p
->defaultPrefix
.name
= NULL
;
5577 p
->defaultPrefix
.binding
= NULL
;
5579 p
->in_eldecl
= XML_FALSE
;
5581 ms
->free_fcn(p
->scaffIndex
);
5582 p
->scaffIndex
= NULL
;
5583 ms
->free_fcn(p
->scaffold
);
5589 p
->contentStringLen
= 0;
5591 p
->keepProcessing
= XML_TRUE
;
5592 p
->hasParamEntityRefs
= XML_FALSE
;
5593 p
->standalone
= XML_FALSE
;
5597 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5599 HASH_TABLE_ITER iter
;
5600 hashTableIterInit(&iter
, &(p
->elementTypes
));
5602 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5605 if (e
->allocDefaultAtts
!= 0)
5606 ms
->free_fcn(e
->defaultAtts
);
5608 hashTableDestroy(&(p
->generalEntities
));
5610 hashTableDestroy(&(p
->paramEntities
));
5611 #endif /* XML_DTD */
5612 hashTableDestroy(&(p
->elementTypes
));
5613 hashTableDestroy(&(p
->attributeIds
));
5614 hashTableDestroy(&(p
->prefixes
));
5615 poolDestroy(&(p
->pool
));
5616 poolDestroy(&(p
->entityValuePool
));
5618 ms
->free_fcn(p
->scaffIndex
);
5619 ms
->free_fcn(p
->scaffold
);
5624 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5625 The new DTD has already been initialized.
5628 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5630 HASH_TABLE_ITER iter
;
5632 /* Copy the prefix table. */
5634 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5636 const XML_Char
*name
;
5637 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5640 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5643 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5647 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5649 /* Copy the attribute id table. */
5653 const XML_Char
*name
;
5654 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5658 /* Remember to allocate the scratch byte before the name. */
5659 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5661 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5665 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5666 sizeof(ATTRIBUTE_ID
));
5669 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5671 newA
->xmlns
= oldA
->xmlns
;
5672 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5673 newA
->prefix
= &newDtd
->defaultPrefix
;
5675 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5676 oldA
->prefix
->name
, 0);
5680 /* Copy the element type table. */
5682 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5687 const XML_Char
*name
;
5688 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5691 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5694 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5695 sizeof(ELEMENT_TYPE
));
5698 if (oldE
->nDefaultAtts
) {
5699 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5700 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5701 if (!newE
->defaultAtts
) {
5707 newE
->idAtt
= (ATTRIBUTE_ID
*)
5708 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5709 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5711 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5712 oldE
->prefix
->name
, 0);
5713 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5714 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5715 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5716 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5717 if (oldE
->defaultAtts
[i
].value
) {
5718 newE
->defaultAtts
[i
].value
5719 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5720 if (!newE
->defaultAtts
[i
].value
)
5724 newE
->defaultAtts
[i
].value
= NULL
;
5728 /* Copy the entity tables. */
5729 if (!copyEntityTable(&(newDtd
->generalEntities
),
5731 &(oldDtd
->generalEntities
)))
5735 if (!copyEntityTable(&(newDtd
->paramEntities
),
5737 &(oldDtd
->paramEntities
)))
5739 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5740 #endif /* XML_DTD */
5742 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5743 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5744 newDtd
->standalone
= oldDtd
->standalone
;
5746 /* Don't want deep copying for scaffolding */
5747 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5748 newDtd
->scaffold
= oldDtd
->scaffold
;
5749 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5750 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5751 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5752 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5758 copyEntityTable(HASH_TABLE
*newTable
,
5759 STRING_POOL
*newPool
,
5760 const HASH_TABLE
*oldTable
)
5762 HASH_TABLE_ITER iter
;
5763 const XML_Char
*cachedOldBase
= NULL
;
5764 const XML_Char
*cachedNewBase
= NULL
;
5766 hashTableIterInit(&iter
, oldTable
);
5770 const XML_Char
*name
;
5771 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5774 name
= poolCopyString(newPool
, oldE
->name
);
5777 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5780 if (oldE
->systemId
) {
5781 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5784 newE
->systemId
= tem
;
5786 if (oldE
->base
== cachedOldBase
)
5787 newE
->base
= cachedNewBase
;
5789 cachedOldBase
= oldE
->base
;
5790 tem
= poolCopyString(newPool
, cachedOldBase
);
5793 cachedNewBase
= newE
->base
= tem
;
5796 if (oldE
->publicId
) {
5797 tem
= poolCopyString(newPool
, oldE
->publicId
);
5800 newE
->publicId
= tem
;
5804 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5808 newE
->textPtr
= tem
;
5809 newE
->textLen
= oldE
->textLen
;
5811 if (oldE
->notation
) {
5812 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5815 newE
->notation
= tem
;
5817 newE
->is_param
= oldE
->is_param
;
5818 newE
->is_internal
= oldE
->is_internal
;
5823 #define INIT_POWER 6
5825 static XML_Bool FASTCALL
5826 keyeq(KEY s1
, KEY s2
)
5828 for (; *s1
== *s2
; s1
++, s2
++)
5834 static unsigned long FASTCALL
5837 unsigned long h
= 0;
5839 h
= CHAR_HASH(h
, *s
++);
5844 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5847 if (table
->size
== 0) {
5851 table
->power
= INIT_POWER
;
5852 /* table->size is a power of 2 */
5853 table
->size
= (size_t)1 << INIT_POWER
;
5854 tsize
= table
->size
* sizeof(NAMED
*);
5855 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5860 memset(table
->v
, 0, tsize
);
5861 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5864 unsigned long h
= hash(name
);
5865 unsigned long mask
= (unsigned long)table
->size
- 1;
5866 unsigned char step
= 0;
5868 while (table
->v
[i
]) {
5869 if (keyeq(name
, table
->v
[i
]->name
))
5872 step
= PROBE_STEP(h
, mask
, table
->power
);
5873 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5878 /* check for overflow (table is half full) */
5879 if (table
->used
>> (table
->power
- 1)) {
5880 unsigned char newPower
= table
->power
+ 1;
5881 size_t newSize
= (size_t)1 << newPower
;
5882 unsigned long newMask
= (unsigned long)newSize
- 1;
5883 size_t tsize
= newSize
* sizeof(NAMED
*);
5884 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5887 memset(newV
, 0, tsize
);
5888 for (i
= 0; i
< table
->size
; i
++)
5890 unsigned long newHash
= hash(table
->v
[i
]->name
);
5891 size_t j
= newHash
& newMask
;
5895 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5896 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5898 newV
[j
] = table
->v
[i
];
5900 table
->mem
->free_fcn(table
->v
);
5902 table
->power
= newPower
;
5903 table
->size
= newSize
;
5906 while (table
->v
[i
]) {
5908 step
= PROBE_STEP(h
, newMask
, newPower
);
5909 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5913 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5916 memset(table
->v
[i
], 0, createSize
);
5917 table
->v
[i
]->name
= name
;
5922 static void FASTCALL
5923 hashTableClear(HASH_TABLE
*table
)
5926 for (i
= 0; i
< table
->size
; i
++) {
5927 table
->mem
->free_fcn(table
->v
[i
]);
5933 static void FASTCALL
5934 hashTableDestroy(HASH_TABLE
*table
)
5937 for (i
= 0; i
< table
->size
; i
++)
5938 table
->mem
->free_fcn(table
->v
[i
]);
5939 table
->mem
->free_fcn(table
->v
);
5942 static void FASTCALL
5943 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5952 static void FASTCALL
5953 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5956 iter
->end
= iter
->p
+ table
->size
;
5959 static NAMED
* FASTCALL
5960 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5962 while (iter
->p
!= iter
->end
) {
5963 NAMED
*tem
= *(iter
->p
)++;
5970 static void FASTCALL
5971 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5973 pool
->blocks
= NULL
;
5974 pool
->freeBlocks
= NULL
;
5981 static void FASTCALL
5982 poolClear(STRING_POOL
*pool
)
5984 if (!pool
->freeBlocks
)
5985 pool
->freeBlocks
= pool
->blocks
;
5987 BLOCK
*p
= pool
->blocks
;
5989 BLOCK
*tem
= p
->next
;
5990 p
->next
= pool
->freeBlocks
;
5991 pool
->freeBlocks
= p
;
5995 pool
->blocks
= NULL
;
6001 static void FASTCALL
6002 poolDestroy(STRING_POOL
*pool
)
6004 BLOCK
*p
= pool
->blocks
;
6006 BLOCK
*tem
= p
->next
;
6007 pool
->mem
->free_fcn(p
);
6010 p
= pool
->freeBlocks
;
6012 BLOCK
*tem
= p
->next
;
6013 pool
->mem
->free_fcn(p
);
6019 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6020 const char *ptr
, const char *end
)
6022 if (!pool
->ptr
&& !poolGrow(pool
))
6025 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6028 if (!poolGrow(pool
))
6034 static const XML_Char
* FASTCALL
6035 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6038 if (!poolAppendChar(pool
, *s
))
6046 static const XML_Char
*
6047 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6049 if (!pool
->ptr
&& !poolGrow(pool
))
6051 for (; n
> 0; --n
, s
++) {
6052 if (!poolAppendChar(pool
, *s
))
6060 static const XML_Char
* FASTCALL
6061 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6064 if (!poolAppendChar(pool
, *s
))
6072 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6073 const char *ptr
, const char *end
)
6075 if (!poolAppend(pool
, enc
, ptr
, end
))
6077 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6083 static XML_Bool FASTCALL
6084 poolGrow(STRING_POOL
*pool
)
6086 if (pool
->freeBlocks
) {
6087 if (pool
->start
== 0) {
6088 pool
->blocks
= pool
->freeBlocks
;
6089 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6090 pool
->blocks
->next
= NULL
;
6091 pool
->start
= pool
->blocks
->s
;
6092 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6093 pool
->ptr
= pool
->start
;
6096 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6097 BLOCK
*tem
= pool
->freeBlocks
->next
;
6098 pool
->freeBlocks
->next
= pool
->blocks
;
6099 pool
->blocks
= pool
->freeBlocks
;
6100 pool
->freeBlocks
= tem
;
6101 memcpy(pool
->blocks
->s
, pool
->start
,
6102 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6103 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6104 pool
->start
= pool
->blocks
->s
;
6105 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6109 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6110 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6111 pool
->blocks
= (BLOCK
*)
6112 pool
->mem
->realloc_fcn(pool
->blocks
,
6114 + blockSize
* sizeof(XML_Char
)));
6115 if (pool
->blocks
== NULL
)
6117 pool
->blocks
->size
= blockSize
;
6118 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6119 pool
->start
= pool
->blocks
->s
;
6120 pool
->end
= pool
->start
+ blockSize
;
6124 int blockSize
= (int)(pool
->end
- pool
->start
);
6125 if (blockSize
< INIT_BLOCK_SIZE
)
6126 blockSize
= INIT_BLOCK_SIZE
;
6129 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6130 + blockSize
* sizeof(XML_Char
));
6133 tem
->size
= blockSize
;
6134 tem
->next
= pool
->blocks
;
6136 if (pool
->ptr
!= pool
->start
)
6137 memcpy(tem
->s
, pool
->start
,
6138 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6139 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6140 pool
->start
= tem
->s
;
6141 pool
->end
= tem
->s
+ blockSize
;
6147 nextScaffoldPart(XML_Parser parser
)
6149 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6150 CONTENT_SCAFFOLD
* me
;
6153 if (!dtd
->scaffIndex
) {
6154 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6155 if (!dtd
->scaffIndex
)
6157 dtd
->scaffIndex
[0] = 0;
6160 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6161 CONTENT_SCAFFOLD
*temp
;
6162 if (dtd
->scaffold
) {
6163 temp
= (CONTENT_SCAFFOLD
*)
6164 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6167 dtd
->scaffSize
*= 2;
6170 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6171 * sizeof(CONTENT_SCAFFOLD
));
6174 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6176 dtd
->scaffold
= temp
;
6178 next
= dtd
->scaffCount
++;
6179 me
= &dtd
->scaffold
[next
];
6180 if (dtd
->scaffLevel
) {
6181 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6182 if (parent
->lastchild
) {
6183 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6185 if (!parent
->childcnt
)
6186 parent
->firstchild
= next
;
6187 parent
->lastchild
= next
;
6190 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6195 build_node(XML_Parser parser
,
6198 XML_Content
**contpos
,
6201 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6202 dest
->type
= dtd
->scaffold
[src_node
].type
;
6203 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6204 if (dest
->type
== XML_CTYPE_NAME
) {
6205 const XML_Char
*src
;
6206 dest
->name
= *strpos
;
6207 src
= dtd
->scaffold
[src_node
].name
;
6209 *(*strpos
)++ = *src
;
6214 dest
->numchildren
= 0;
6215 dest
->children
= NULL
;
6220 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6221 dest
->children
= *contpos
;
6222 *contpos
+= dest
->numchildren
;
6223 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6224 i
< dest
->numchildren
;
6225 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6226 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6232 static XML_Content
*
6233 build_model (XML_Parser parser
)
6235 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6239 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6240 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6242 ret
= (XML_Content
*)MALLOC(allocsize
);
6246 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6249 build_node(parser
, 0, ret
, &cpos
, &str
);
6253 static ELEMENT_TYPE
*
6254 getElementType(XML_Parser parser
,
6255 const ENCODING
*enc
,
6259 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6260 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6265 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6268 if (ret
->name
!= name
)
6269 poolDiscard(&dtd
->pool
);
6271 poolFinish(&dtd
->pool
);
6272 if (!setElementTypePrefix(parser
, ret
))