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 */
27 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
28 #define XmlConvert XmlUtf16Convert
29 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
30 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
31 #define XmlEncode XmlUtf16Encode
32 /* Using pointer subtraction to convert to integer type. */
33 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
34 typedef unsigned short ICHAR
;
36 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
37 #define XmlConvert XmlUtf8Convert
38 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
39 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
40 #define XmlEncode XmlUtf8Encode
41 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
48 #define XmlInitEncodingNS XmlInitEncoding
49 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
50 #undef XmlGetInternalEncodingNS
51 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
52 #define XmlParseXmlDeclNS XmlParseXmlDecl
58 #ifdef XML_UNICODE_WCHAR_T
59 #define XML_T(x) (const wchar_t)x
60 #define XML_L(x) L ## x
62 #define XML_T(x) (const unsigned short)x
73 /* Round up n to be a multiple of sz, where sz is a power of 2. */
74 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
76 /* Handle the case where memmove() doesn't exist. */
79 #define memmove(d,s,l) bcopy((s),(d),(l))
81 #error memmove does not exist on this platform, nor is a substitute available
82 #endif /* HAVE_BCOPY */
83 #endif /* HAVE_MEMMOVE */
89 typedef const XML_Char
*KEY
;
100 const XML_Memory_Handling_Suite
*mem
;
103 /* Basic character hash algorithm, taken from Python's string hash:
104 h = h * 1000003 ^ character, the constant being a prime number.
108 #define CHAR_HASH(h, c) \
109 (((h) * 0xF4243) ^ (unsigned short)(c))
111 #define CHAR_HASH(h, c) \
112 (((h) * 0xF4243) ^ (unsigned char)(c))
115 /* For probing (after a collision) we need a step size relative prime
116 to the hash table size, which is a power of 2. We use double-hashing,
117 since we can calculate a second hash value cheaply by taking those bits
118 of the first hash value that were discarded (masked out) when the table
119 index was calculated: index = hash & mask, where mask = table->size - 1.
120 We limit the maximum step size to table->size / 4 (mask >> 2) and make
121 it odd, since odd numbers are always relative prime to a power of 2.
123 #define SECOND_HASH(hash, mask, power) \
124 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
125 #define PROBE_STEP(hash, mask, power) \
126 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
133 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
134 #define INIT_DATA_BUF_SIZE 1024
135 #define INIT_ATTS_SIZE 16
136 #define INIT_ATTS_VERSION 0xFFFFFFFF
137 #define INIT_BLOCK_SIZE 1024
138 #define INIT_BUFFER_SIZE 1024
140 #define EXPAND_SPARE 24
142 typedef struct binding
{
143 struct prefix
*prefix
;
144 struct binding
*nextTagBinding
;
145 struct binding
*prevPrefixBinding
;
146 const struct attribute_id
*attId
;
152 typedef struct prefix
{
153 const XML_Char
*name
;
159 const XML_Char
*localPart
;
160 const XML_Char
*prefix
;
166 /* TAG represents an open element.
167 The name of the element is stored in both the document and API
168 encodings. The memory buffer 'buf' is a separately-allocated
169 memory area which stores the name. During the XML_Parse()/
170 XMLParseBuffer() when the element is open, the memory for the 'raw'
171 version of the name (in the document encoding) is shared with the
172 document buffer. If the element is open across calls to
173 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
174 contain the 'raw' name as well.
176 A parser re-uses these structures, maintaining a list of allocated
177 TAG objects in a free list.
180 struct tag
*parent
; /* parent of this element */
181 const char *rawName
; /* tagName in the original encoding */
183 TAG_NAME name
; /* tagName in the API encoding */
184 char *buf
; /* buffer for name components */
185 char *bufEnd
; /* end of the buffer */
190 const XML_Char
*name
;
191 const XML_Char
*textPtr
;
192 int textLen
; /* length in XML_Chars */
193 int processed
; /* # of processed bytes - when suspended */
194 const XML_Char
*systemId
;
195 const XML_Char
*base
;
196 const XML_Char
*publicId
;
197 const XML_Char
*notation
;
200 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
204 enum XML_Content_Type type
;
205 enum XML_Content_Quant quant
;
206 const XML_Char
* name
;
213 #define INIT_SCAFFOLD_ELEMENTS 32
215 typedef struct block
{
227 const XML_Memory_Handling_Suite
*mem
;
230 /* The XML_Char before the name is used to determine whether
231 an attribute has been specified. */
232 typedef struct attribute_id
{
235 XML_Bool maybeTokenized
;
240 const ATTRIBUTE_ID
*id
;
242 const XML_Char
*value
;
246 unsigned long version
;
248 const XML_Char
*uriName
;
252 const XML_Char
*name
;
254 const ATTRIBUTE_ID
*idAtt
;
256 int allocDefaultAtts
;
257 DEFAULT_ATTRIBUTE
*defaultAtts
;
261 HASH_TABLE generalEntities
;
262 HASH_TABLE elementTypes
;
263 HASH_TABLE attributeIds
;
266 STRING_POOL entityValuePool
;
267 /* false once a parameter entity reference has been skipped */
268 XML_Bool keepProcessing
;
269 /* true once an internal or external PE reference has been encountered;
270 this includes the reference to an external subset */
271 XML_Bool hasParamEntityRefs
;
274 /* indicates if external PE has been read */
275 XML_Bool paramEntityRead
;
276 HASH_TABLE paramEntities
;
278 PREFIX defaultPrefix
;
279 /* === scaffolding for building content model === */
281 CONTENT_SCAFFOLD
*scaffold
;
282 unsigned contentStringLen
;
289 typedef struct open_internal_entity
{
290 const char *internalEventPtr
;
291 const char *internalEventEndPtr
;
292 struct open_internal_entity
*next
;
295 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
296 } OPEN_INTERNAL_ENTITY
;
298 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
301 const char **endPtr
);
303 static Processor prologProcessor
;
304 static Processor prologInitProcessor
;
305 static Processor contentProcessor
;
306 static Processor cdataSectionProcessor
;
308 static Processor ignoreSectionProcessor
;
309 static Processor externalParEntProcessor
;
310 static Processor externalParEntInitProcessor
;
311 static Processor entityValueProcessor
;
312 static Processor entityValueInitProcessor
;
314 static Processor epilogProcessor
;
315 static Processor errorProcessor
;
316 static Processor externalEntityInitProcessor
;
317 static Processor externalEntityInitProcessor2
;
318 static Processor externalEntityInitProcessor3
;
319 static Processor externalEntityContentProcessor
;
320 static Processor internalEntityProcessor
;
322 static enum XML_Error
323 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
324 static enum XML_Error
325 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
326 const char *s
, const char *next
);
327 static enum XML_Error
328 initializeEncoding(XML_Parser parser
);
329 static enum XML_Error
330 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
331 const char *end
, int tok
, const char *next
, const char **nextPtr
,
333 static enum XML_Error
334 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
335 XML_Bool betweenDecl
);
336 static enum XML_Error
337 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
338 const char *start
, const char *end
, const char **endPtr
,
340 static enum XML_Error
341 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
342 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
344 static enum XML_Error
345 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
346 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
349 static enum XML_Error
350 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
351 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
352 static enum XML_Error
353 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
354 const XML_Char
*uri
, BINDING
**bindingsPtr
);
356 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
357 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
358 static enum XML_Error
359 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
360 const char *, const char *, STRING_POOL
*);
361 static enum XML_Error
362 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
363 const char *, const char *, STRING_POOL
*);
364 static ATTRIBUTE_ID
*
365 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
368 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
369 static enum XML_Error
370 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
373 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
374 const char *start
, const char *end
);
376 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
379 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
382 static const XML_Char
* getContext(XML_Parser parser
);
384 setContext(XML_Parser parser
, const XML_Char
*context
);
386 static void FASTCALL
normalizePublicId(XML_Char
*s
);
388 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
389 /* do not call if parentParser != NULL */
390 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
392 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
394 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
396 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
399 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
401 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
402 static void FASTCALL
hashTableClear(HASH_TABLE
*);
403 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
405 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
406 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
409 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
410 static void FASTCALL
poolClear(STRING_POOL
*);
411 static void FASTCALL
poolDestroy(STRING_POOL
*);
413 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
414 const char *ptr
, const char *end
);
416 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
417 const char *ptr
, const char *end
);
418 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
419 static const XML_Char
* FASTCALL
420 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
421 static const XML_Char
*
422 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
423 static const XML_Char
* FASTCALL
424 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
426 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
427 static XML_Content
* build_model(XML_Parser parser
);
428 static ELEMENT_TYPE
*
429 getElementType(XML_Parser parser
, const ENCODING
*enc
,
430 const char *ptr
, const char *end
);
433 parserCreate(const XML_Char
*encodingName
,
434 const XML_Memory_Handling_Suite
*memsuite
,
435 const XML_Char
*nameSep
,
438 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
440 #define poolStart(pool) ((pool)->start)
441 #define poolEnd(pool) ((pool)->ptr)
442 #define poolLength(pool) ((pool)->ptr - (pool)->start)
443 #define poolChop(pool) ((void)--(pool->ptr))
444 #define poolLastChar(pool) (((pool)->ptr)[-1])
445 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
446 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
447 #define poolAppendChar(pool, c) \
448 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
450 : ((*((pool)->ptr)++ = c), 1))
452 struct XML_ParserStruct
{
453 /* The first member must be userData so that the XML_GetUserData
458 const XML_Memory_Handling_Suite m_mem
;
459 /* first character to be parsed */
460 const char *m_bufferPtr
;
461 /* past last character to be parsed */
463 /* allocated end of buffer */
464 const char *m_bufferLim
;
465 XML_Index m_parseEndByteIndex
;
466 const char *m_parseEndPtr
;
468 XML_Char
*m_dataBufEnd
;
469 XML_StartElementHandler m_startElementHandler
;
470 XML_EndElementHandler m_endElementHandler
;
471 XML_CharacterDataHandler m_characterDataHandler
;
472 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
473 XML_CommentHandler m_commentHandler
;
474 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
475 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
476 XML_DefaultHandler m_defaultHandler
;
477 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
478 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
479 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
480 XML_NotationDeclHandler m_notationDeclHandler
;
481 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
482 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
483 XML_NotStandaloneHandler m_notStandaloneHandler
;
484 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
485 XML_Parser m_externalEntityRefHandlerArg
;
486 XML_SkippedEntityHandler m_skippedEntityHandler
;
487 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
488 XML_ElementDeclHandler m_elementDeclHandler
;
489 XML_AttlistDeclHandler m_attlistDeclHandler
;
490 XML_EntityDeclHandler m_entityDeclHandler
;
491 XML_XmlDeclHandler m_xmlDeclHandler
;
492 const ENCODING
*m_encoding
;
493 INIT_ENCODING m_initEncoding
;
494 const ENCODING
*m_internalEncoding
;
495 const XML_Char
*m_protocolEncodingName
;
497 XML_Bool m_ns_triplets
;
498 void *m_unknownEncodingMem
;
499 void *m_unknownEncodingData
;
500 void *m_unknownEncodingHandlerData
;
501 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
502 PROLOG_STATE m_prologState
;
503 Processor
*m_processor
;
504 enum XML_Error m_errorCode
;
505 const char *m_eventPtr
;
506 const char *m_eventEndPtr
;
507 const char *m_positionPtr
;
508 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
509 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
510 XML_Bool m_defaultExpandInternalEntities
;
512 ENTITY
*m_declEntity
;
513 const XML_Char
*m_doctypeName
;
514 const XML_Char
*m_doctypeSysid
;
515 const XML_Char
*m_doctypePubid
;
516 const XML_Char
*m_declAttributeType
;
517 const XML_Char
*m_declNotationName
;
518 const XML_Char
*m_declNotationPublicId
;
519 ELEMENT_TYPE
*m_declElementType
;
520 ATTRIBUTE_ID
*m_declAttributeId
;
521 XML_Bool m_declAttributeIsCdata
;
522 XML_Bool m_declAttributeIsId
;
524 const XML_Char
*m_curBase
;
527 BINDING
*m_inheritedBindings
;
528 BINDING
*m_freeBindingList
;
530 int m_nSpecifiedAtts
;
534 unsigned long m_nsAttsVersion
;
535 unsigned char m_nsAttsPower
;
537 STRING_POOL m_tempPool
;
538 STRING_POOL m_temp2Pool
;
539 char *m_groupConnector
;
540 unsigned int m_groupSize
;
541 XML_Char m_namespaceSeparator
;
542 XML_Parser m_parentParser
;
543 XML_ParsingStatus m_parsingStatus
;
545 XML_Bool m_isParamEntity
;
546 XML_Bool m_useForeignDTD
;
547 enum XML_ParamEntityParsing m_paramEntityParsing
;
551 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
552 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
553 #define FREE(p) (parser->m_mem.free_fcn((p)))
555 #define userData (parser->m_userData)
556 #define handlerArg (parser->m_handlerArg)
557 #define startElementHandler (parser->m_startElementHandler)
558 #define endElementHandler (parser->m_endElementHandler)
559 #define characterDataHandler (parser->m_characterDataHandler)
560 #define processingInstructionHandler \
561 (parser->m_processingInstructionHandler)
562 #define commentHandler (parser->m_commentHandler)
563 #define startCdataSectionHandler \
564 (parser->m_startCdataSectionHandler)
565 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
566 #define defaultHandler (parser->m_defaultHandler)
567 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
568 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
569 #define unparsedEntityDeclHandler \
570 (parser->m_unparsedEntityDeclHandler)
571 #define notationDeclHandler (parser->m_notationDeclHandler)
572 #define startNamespaceDeclHandler \
573 (parser->m_startNamespaceDeclHandler)
574 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
575 #define notStandaloneHandler (parser->m_notStandaloneHandler)
576 #define externalEntityRefHandler \
577 (parser->m_externalEntityRefHandler)
578 #define externalEntityRefHandlerArg \
579 (parser->m_externalEntityRefHandlerArg)
580 #define internalEntityRefHandler \
581 (parser->m_internalEntityRefHandler)
582 #define skippedEntityHandler (parser->m_skippedEntityHandler)
583 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
584 #define elementDeclHandler (parser->m_elementDeclHandler)
585 #define attlistDeclHandler (parser->m_attlistDeclHandler)
586 #define entityDeclHandler (parser->m_entityDeclHandler)
587 #define xmlDeclHandler (parser->m_xmlDeclHandler)
588 #define encoding (parser->m_encoding)
589 #define initEncoding (parser->m_initEncoding)
590 #define internalEncoding (parser->m_internalEncoding)
591 #define unknownEncodingMem (parser->m_unknownEncodingMem)
592 #define unknownEncodingData (parser->m_unknownEncodingData)
593 #define unknownEncodingHandlerData \
594 (parser->m_unknownEncodingHandlerData)
595 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
596 #define protocolEncodingName (parser->m_protocolEncodingName)
597 #define ns (parser->m_ns)
598 #define ns_triplets (parser->m_ns_triplets)
599 #define prologState (parser->m_prologState)
600 #define processor (parser->m_processor)
601 #define errorCode (parser->m_errorCode)
602 #define eventPtr (parser->m_eventPtr)
603 #define eventEndPtr (parser->m_eventEndPtr)
604 #define positionPtr (parser->m_positionPtr)
605 #define position (parser->m_position)
606 #define openInternalEntities (parser->m_openInternalEntities)
607 #define freeInternalEntities (parser->m_freeInternalEntities)
608 #define defaultExpandInternalEntities \
609 (parser->m_defaultExpandInternalEntities)
610 #define tagLevel (parser->m_tagLevel)
611 #define buffer (parser->m_buffer)
612 #define bufferPtr (parser->m_bufferPtr)
613 #define bufferEnd (parser->m_bufferEnd)
614 #define parseEndByteIndex (parser->m_parseEndByteIndex)
615 #define parseEndPtr (parser->m_parseEndPtr)
616 #define bufferLim (parser->m_bufferLim)
617 #define dataBuf (parser->m_dataBuf)
618 #define dataBufEnd (parser->m_dataBufEnd)
619 #define _dtd (parser->m_dtd)
620 #define curBase (parser->m_curBase)
621 #define declEntity (parser->m_declEntity)
622 #define doctypeName (parser->m_doctypeName)
623 #define doctypeSysid (parser->m_doctypeSysid)
624 #define doctypePubid (parser->m_doctypePubid)
625 #define declAttributeType (parser->m_declAttributeType)
626 #define declNotationName (parser->m_declNotationName)
627 #define declNotationPublicId (parser->m_declNotationPublicId)
628 #define declElementType (parser->m_declElementType)
629 #define declAttributeId (parser->m_declAttributeId)
630 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
631 #define declAttributeIsId (parser->m_declAttributeIsId)
632 #define freeTagList (parser->m_freeTagList)
633 #define freeBindingList (parser->m_freeBindingList)
634 #define inheritedBindings (parser->m_inheritedBindings)
635 #define tagStack (parser->m_tagStack)
636 #define atts (parser->m_atts)
637 #define attsSize (parser->m_attsSize)
638 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
639 #define idAttIndex (parser->m_idAttIndex)
640 #define nsAtts (parser->m_nsAtts)
641 #define nsAttsVersion (parser->m_nsAttsVersion)
642 #define nsAttsPower (parser->m_nsAttsPower)
643 #define tempPool (parser->m_tempPool)
644 #define temp2Pool (parser->m_temp2Pool)
645 #define groupConnector (parser->m_groupConnector)
646 #define groupSize (parser->m_groupSize)
647 #define namespaceSeparator (parser->m_namespaceSeparator)
648 #define parentParser (parser->m_parentParser)
649 #define ps_parsing (parser->m_parsingStatus.parsing)
650 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
652 #define isParamEntity (parser->m_isParamEntity)
653 #define useForeignDTD (parser->m_useForeignDTD)
654 #define paramEntityParsing (parser->m_paramEntityParsing)
658 XML_ParserCreate(const XML_Char
*encodingName
)
660 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
664 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
668 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
671 static const XML_Char implicitContext
[] = {
672 ASCII_x
, ASCII_m
, ASCII_l
, ASCII_EQUALS
, ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
,
673 ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, ASCII_w
, ASCII_w
, ASCII_w
,
674 ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, ASCII_o
, ASCII_r
, ASCII_g
,
675 ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, ASCII_SLASH
, ASCII_1
, ASCII_9
,
676 ASCII_9
, ASCII_8
, ASCII_SLASH
, ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
,
677 ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, ASCII_e
, '\0'
681 XML_ParserCreate_MM(const XML_Char
*encodingName
,
682 const XML_Memory_Handling_Suite
*memsuite
,
683 const XML_Char
*nameSep
)
685 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
686 if (parser
!= NULL
&& ns
) {
687 /* implicit context only set for root parser, since child
688 parsers (i.e. external entity parsers) will inherit it
690 if (!setContext(parser
, implicitContext
)) {
691 XML_ParserFree(parser
);
699 parserCreate(const XML_Char
*encodingName
,
700 const XML_Memory_Handling_Suite
*memsuite
,
701 const XML_Char
*nameSep
,
707 XML_Memory_Handling_Suite
*mtemp
;
708 parser
= (XML_Parser
)
709 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
710 if (parser
!= NULL
) {
711 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
712 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
713 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
714 mtemp
->free_fcn
= memsuite
->free_fcn
;
718 XML_Memory_Handling_Suite
*mtemp
;
719 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
720 if (parser
!= NULL
) {
721 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
722 mtemp
->malloc_fcn
= malloc
;
723 mtemp
->realloc_fcn
= realloc
;
724 mtemp
->free_fcn
= free
;
734 attsSize
= INIT_ATTS_SIZE
;
735 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
740 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
741 if (dataBuf
== NULL
) {
746 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
751 _dtd
= dtdCreate(&parser
->m_mem
);
760 freeBindingList
= NULL
;
762 freeInternalEntities
= NULL
;
765 groupConnector
= NULL
;
767 unknownEncodingHandler
= NULL
;
768 unknownEncodingHandlerData
= NULL
;
770 namespaceSeparator
= ASCII_EXCL
;
772 ns_triplets
= XML_FALSE
;
778 poolInit(&tempPool
, &(parser
->m_mem
));
779 poolInit(&temp2Pool
, &(parser
->m_mem
));
780 parserInit(parser
, encodingName
);
782 if (encodingName
&& !protocolEncodingName
) {
783 XML_ParserFree(parser
);
789 internalEncoding
= XmlGetInternalEncodingNS();
790 namespaceSeparator
= *nameSep
;
793 internalEncoding
= XmlGetInternalEncoding();
800 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
802 processor
= prologInitProcessor
;
803 XmlPrologStateInit(&prologState
);
804 protocolEncodingName
= (encodingName
!= NULL
805 ? poolCopyString(&tempPool
, encodingName
)
808 XmlInitEncoding(&initEncoding
, &encoding
, 0);
811 startElementHandler
= NULL
;
812 endElementHandler
= NULL
;
813 characterDataHandler
= NULL
;
814 processingInstructionHandler
= NULL
;
815 commentHandler
= NULL
;
816 startCdataSectionHandler
= NULL
;
817 endCdataSectionHandler
= NULL
;
818 defaultHandler
= NULL
;
819 startDoctypeDeclHandler
= NULL
;
820 endDoctypeDeclHandler
= NULL
;
821 unparsedEntityDeclHandler
= NULL
;
822 notationDeclHandler
= NULL
;
823 startNamespaceDeclHandler
= NULL
;
824 endNamespaceDeclHandler
= NULL
;
825 notStandaloneHandler
= NULL
;
826 externalEntityRefHandler
= NULL
;
827 externalEntityRefHandlerArg
= parser
;
828 skippedEntityHandler
= NULL
;
829 elementDeclHandler
= NULL
;
830 attlistDeclHandler
= NULL
;
831 entityDeclHandler
= NULL
;
832 xmlDeclHandler
= NULL
;
835 parseEndByteIndex
= 0;
837 declElementType
= NULL
;
838 declAttributeId
= NULL
;
843 declAttributeType
= NULL
;
844 declNotationName
= NULL
;
845 declNotationPublicId
= NULL
;
846 declAttributeIsCdata
= XML_FALSE
;
847 declAttributeIsId
= XML_FALSE
;
848 memset(&position
, 0, sizeof(POSITION
));
849 errorCode
= XML_ERROR_NONE
;
853 openInternalEntities
= NULL
;
854 defaultExpandInternalEntities
= XML_TRUE
;
857 inheritedBindings
= NULL
;
859 unknownEncodingMem
= NULL
;
860 unknownEncodingRelease
= NULL
;
861 unknownEncodingData
= NULL
;
863 ps_parsing
= XML_INITIALIZED
;
865 isParamEntity
= XML_FALSE
;
866 useForeignDTD
= XML_FALSE
;
867 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
871 /* moves list of bindings to freeBindingList */
873 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
876 BINDING
*b
= bindings
;
877 bindings
= bindings
->nextTagBinding
;
878 b
->nextTagBinding
= freeBindingList
;
884 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
887 OPEN_INTERNAL_ENTITY
*openEntityList
;
890 /* move tagStack to freeTagList */
895 tag
->parent
= freeTagList
;
896 moveToFreeBindingList(parser
, tag
->bindings
);
897 tag
->bindings
= NULL
;
900 /* move openInternalEntities to freeInternalEntities */
901 openEntityList
= openInternalEntities
;
902 while (openEntityList
) {
903 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
904 openEntityList
= openEntity
->next
;
905 openEntity
->next
= freeInternalEntities
;
906 freeInternalEntities
= openEntity
;
908 moveToFreeBindingList(parser
, inheritedBindings
);
909 FREE(unknownEncodingMem
);
910 if (unknownEncodingRelease
)
911 unknownEncodingRelease(unknownEncodingData
);
912 poolClear(&tempPool
);
913 poolClear(&temp2Pool
);
914 parserInit(parser
, encodingName
);
915 dtdReset(_dtd
, &parser
->m_mem
);
916 return setContext(parser
, implicitContext
);
919 enum XML_Status XMLCALL
920 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
922 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
923 XXX There's no way for the caller to determine which of the
924 XXX possible error cases caused the XML_STATUS_ERROR return.
926 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
927 return XML_STATUS_ERROR
;
928 if (encodingName
== NULL
)
929 protocolEncodingName
= NULL
;
931 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
932 if (!protocolEncodingName
)
933 return XML_STATUS_ERROR
;
935 return XML_STATUS_OK
;
939 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
940 const XML_Char
*context
,
941 const XML_Char
*encodingName
)
943 XML_Parser parser
= oldParser
;
946 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
947 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
948 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
949 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
950 = processingInstructionHandler
;
951 XML_CommentHandler oldCommentHandler
= commentHandler
;
952 XML_StartCdataSectionHandler oldStartCdataSectionHandler
953 = startCdataSectionHandler
;
954 XML_EndCdataSectionHandler oldEndCdataSectionHandler
955 = endCdataSectionHandler
;
956 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
957 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
958 = unparsedEntityDeclHandler
;
959 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
960 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
961 = startNamespaceDeclHandler
;
962 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
963 = endNamespaceDeclHandler
;
964 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
965 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
966 = externalEntityRefHandler
;
967 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
968 XML_UnknownEncodingHandler oldUnknownEncodingHandler
969 = unknownEncodingHandler
;
970 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
971 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
972 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
973 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
974 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
976 void *oldUserData
= userData
;
977 void *oldHandlerArg
= handlerArg
;
978 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
979 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
981 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
982 int oldInEntityValue
= prologState
.inEntityValue
;
984 XML_Bool oldns_triplets
= ns_triplets
;
991 /* Note that the magical uses of the pre-processor to make field
992 access look more like C++ require that `parser' be overwritten
993 here. This makes this function more painful to follow than it
998 *tmp
= namespaceSeparator
;
999 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
1002 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1008 startElementHandler
= oldStartElementHandler
;
1009 endElementHandler
= oldEndElementHandler
;
1010 characterDataHandler
= oldCharacterDataHandler
;
1011 processingInstructionHandler
= oldProcessingInstructionHandler
;
1012 commentHandler
= oldCommentHandler
;
1013 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1014 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1015 defaultHandler
= oldDefaultHandler
;
1016 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1017 notationDeclHandler
= oldNotationDeclHandler
;
1018 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1019 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1020 notStandaloneHandler
= oldNotStandaloneHandler
;
1021 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1022 skippedEntityHandler
= oldSkippedEntityHandler
;
1023 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1024 elementDeclHandler
= oldElementDeclHandler
;
1025 attlistDeclHandler
= oldAttlistDeclHandler
;
1026 entityDeclHandler
= oldEntityDeclHandler
;
1027 xmlDeclHandler
= oldXmlDeclHandler
;
1028 declElementType
= oldDeclElementType
;
1029 userData
= oldUserData
;
1030 if (oldUserData
== oldHandlerArg
)
1031 handlerArg
= userData
;
1033 handlerArg
= parser
;
1034 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1035 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1036 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1037 ns_triplets
= oldns_triplets
;
1038 parentParser
= oldParser
;
1040 paramEntityParsing
= oldParamEntityParsing
;
1041 prologState
.inEntityValue
= oldInEntityValue
;
1043 #endif /* XML_DTD */
1044 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1045 || !setContext(parser
, context
)) {
1046 XML_ParserFree(parser
);
1049 processor
= externalEntityInitProcessor
;
1053 /* The DTD instance referenced by _dtd is shared between the document's
1054 root parser and external PE parsers, therefore one does not need to
1055 call setContext. In addition, one also *must* not call setContext,
1056 because this would overwrite existing prefix->binding pointers in
1057 _dtd with ones that get destroyed with the external PE parser.
1058 This would leave those prefixes with dangling pointers.
1060 isParamEntity
= XML_TRUE
;
1061 XmlPrologStateInitExternalEntity(&prologState
);
1062 processor
= externalParEntInitProcessor
;
1064 #endif /* XML_DTD */
1068 static void FASTCALL
1069 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1072 BINDING
*b
= bindings
;
1075 bindings
= b
->nextTagBinding
;
1082 XML_ParserFree(XML_Parser parser
)
1085 OPEN_INTERNAL_ENTITY
*entityList
;
1088 /* free tagStack and freeTagList */
1092 if (tagList
== NULL
) {
1093 if (freeTagList
== NULL
)
1095 tagList
= freeTagList
;
1099 tagList
= tagList
->parent
;
1101 destroyBindings(p
->bindings
, parser
);
1104 /* free openInternalEntities and freeInternalEntities */
1105 entityList
= openInternalEntities
;
1107 OPEN_INTERNAL_ENTITY
*openEntity
;
1108 if (entityList
== NULL
) {
1109 if (freeInternalEntities
== NULL
)
1111 entityList
= freeInternalEntities
;
1112 freeInternalEntities
= NULL
;
1114 openEntity
= entityList
;
1115 entityList
= entityList
->next
;
1119 destroyBindings(freeBindingList
, parser
);
1120 destroyBindings(inheritedBindings
, parser
);
1121 poolDestroy(&tempPool
);
1122 poolDestroy(&temp2Pool
);
1124 /* external parameter entity parsers share the DTD structure
1125 parser->m_dtd with the root parser, so we must not destroy it
1127 if (!isParamEntity
&& _dtd
)
1130 #endif /* XML_DTD */
1131 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1133 FREE(groupConnector
);
1137 FREE(unknownEncodingMem
);
1138 if (unknownEncodingRelease
)
1139 unknownEncodingRelease(unknownEncodingData
);
1144 XML_UseParserAsHandlerArg(XML_Parser parser
)
1146 handlerArg
= parser
;
1149 enum XML_Error XMLCALL
1150 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1153 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1154 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1155 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1156 useForeignDTD
= useDTD
;
1157 return XML_ERROR_NONE
;
1159 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1164 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1166 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1167 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1169 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1173 XML_SetUserData(XML_Parser parser
, void *p
)
1175 if (handlerArg
== userData
)
1176 handlerArg
= userData
= p
;
1181 enum XML_Status XMLCALL
1182 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1185 p
= poolCopyString(&_dtd
->pool
, p
);
1187 return XML_STATUS_ERROR
;
1192 return XML_STATUS_OK
;
1195 const XML_Char
* XMLCALL
1196 XML_GetBase(XML_Parser parser
)
1202 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1204 return nSpecifiedAtts
;
1208 XML_GetIdAttributeIndex(XML_Parser parser
)
1214 XML_SetElementHandler(XML_Parser parser
,
1215 XML_StartElementHandler start
,
1216 XML_EndElementHandler end
)
1218 startElementHandler
= start
;
1219 endElementHandler
= end
;
1223 XML_SetStartElementHandler(XML_Parser parser
,
1224 XML_StartElementHandler start
) {
1225 startElementHandler
= start
;
1229 XML_SetEndElementHandler(XML_Parser parser
,
1230 XML_EndElementHandler end
) {
1231 endElementHandler
= end
;
1235 XML_SetCharacterDataHandler(XML_Parser parser
,
1236 XML_CharacterDataHandler handler
)
1238 characterDataHandler
= handler
;
1242 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1243 XML_ProcessingInstructionHandler handler
)
1245 processingInstructionHandler
= handler
;
1249 XML_SetCommentHandler(XML_Parser parser
,
1250 XML_CommentHandler handler
)
1252 commentHandler
= handler
;
1256 XML_SetCdataSectionHandler(XML_Parser parser
,
1257 XML_StartCdataSectionHandler start
,
1258 XML_EndCdataSectionHandler end
)
1260 startCdataSectionHandler
= start
;
1261 endCdataSectionHandler
= end
;
1265 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1266 XML_StartCdataSectionHandler start
) {
1267 startCdataSectionHandler
= start
;
1271 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1272 XML_EndCdataSectionHandler end
) {
1273 endCdataSectionHandler
= end
;
1277 XML_SetDefaultHandler(XML_Parser parser
,
1278 XML_DefaultHandler handler
)
1280 defaultHandler
= handler
;
1281 defaultExpandInternalEntities
= XML_FALSE
;
1285 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1286 XML_DefaultHandler handler
)
1288 defaultHandler
= handler
;
1289 defaultExpandInternalEntities
= XML_TRUE
;
1293 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1294 XML_StartDoctypeDeclHandler start
,
1295 XML_EndDoctypeDeclHandler end
)
1297 startDoctypeDeclHandler
= start
;
1298 endDoctypeDeclHandler
= end
;
1302 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1303 XML_StartDoctypeDeclHandler start
) {
1304 startDoctypeDeclHandler
= start
;
1308 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1309 XML_EndDoctypeDeclHandler end
) {
1310 endDoctypeDeclHandler
= end
;
1314 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1315 XML_UnparsedEntityDeclHandler handler
)
1317 unparsedEntityDeclHandler
= handler
;
1321 XML_SetNotationDeclHandler(XML_Parser parser
,
1322 XML_NotationDeclHandler handler
)
1324 notationDeclHandler
= handler
;
1328 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1329 XML_StartNamespaceDeclHandler start
,
1330 XML_EndNamespaceDeclHandler end
)
1332 startNamespaceDeclHandler
= start
;
1333 endNamespaceDeclHandler
= end
;
1337 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1338 XML_StartNamespaceDeclHandler start
) {
1339 startNamespaceDeclHandler
= start
;
1343 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1344 XML_EndNamespaceDeclHandler end
) {
1345 endNamespaceDeclHandler
= end
;
1349 XML_SetNotStandaloneHandler(XML_Parser parser
,
1350 XML_NotStandaloneHandler handler
)
1352 notStandaloneHandler
= handler
;
1356 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1357 XML_ExternalEntityRefHandler handler
)
1359 externalEntityRefHandler
= handler
;
1363 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1366 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1368 externalEntityRefHandlerArg
= parser
;
1372 XML_SetSkippedEntityHandler(XML_Parser parser
,
1373 XML_SkippedEntityHandler handler
)
1375 skippedEntityHandler
= handler
;
1379 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1380 XML_UnknownEncodingHandler handler
,
1383 unknownEncodingHandler
= handler
;
1384 unknownEncodingHandlerData
= data
;
1388 XML_SetElementDeclHandler(XML_Parser parser
,
1389 XML_ElementDeclHandler eldecl
)
1391 elementDeclHandler
= eldecl
;
1395 XML_SetAttlistDeclHandler(XML_Parser parser
,
1396 XML_AttlistDeclHandler attdecl
)
1398 attlistDeclHandler
= attdecl
;
1402 XML_SetEntityDeclHandler(XML_Parser parser
,
1403 XML_EntityDeclHandler handler
)
1405 entityDeclHandler
= handler
;
1409 XML_SetXmlDeclHandler(XML_Parser parser
,
1410 XML_XmlDeclHandler handler
) {
1411 xmlDeclHandler
= handler
;
1415 XML_SetParamEntityParsing(XML_Parser parser
,
1416 enum XML_ParamEntityParsing peParsing
)
1418 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1419 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1422 paramEntityParsing
= peParsing
;
1425 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1429 enum XML_Status XMLCALL
1430 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1432 switch (ps_parsing
) {
1434 errorCode
= XML_ERROR_SUSPENDED
;
1435 return XML_STATUS_ERROR
;
1437 errorCode
= XML_ERROR_FINISHED
;
1438 return XML_STATUS_ERROR
;
1440 ps_parsing
= XML_PARSING
;
1444 ps_finalBuffer
= (XML_Bool
)isFinal
;
1446 return XML_STATUS_OK
;
1447 positionPtr
= bufferPtr
;
1448 parseEndPtr
= bufferEnd
;
1450 /* If data are left over from last buffer, and we now know that these
1451 data are the final chunk of input, then we have to check them again
1452 to detect errors based on that fact.
1454 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1456 if (errorCode
== XML_ERROR_NONE
) {
1457 switch (ps_parsing
) {
1459 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1460 positionPtr
= bufferPtr
;
1461 return XML_STATUS_SUSPENDED
;
1462 case XML_INITIALIZED
:
1464 ps_parsing
= XML_FINISHED
;
1467 return XML_STATUS_OK
;
1470 eventEndPtr
= eventPtr
;
1471 processor
= errorProcessor
;
1472 return XML_STATUS_ERROR
;
1474 #ifndef XML_CONTEXT_BYTES
1475 else if (bufferPtr
== bufferEnd
) {
1478 enum XML_Error result
;
1479 parseEndByteIndex
+= len
;
1481 ps_finalBuffer
= (XML_Bool
)isFinal
;
1483 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1485 if (errorCode
!= XML_ERROR_NONE
) {
1486 eventEndPtr
= eventPtr
;
1487 processor
= errorProcessor
;
1488 return XML_STATUS_ERROR
;
1491 switch (ps_parsing
) {
1493 result
= XML_STATUS_SUSPENDED
;
1495 case XML_INITIALIZED
:
1497 result
= XML_STATUS_OK
;
1499 ps_parsing
= XML_FINISHED
;
1505 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1506 nLeftOver
= s
+ len
- end
;
1508 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1509 /* FIXME avoid integer overflow */
1511 temp
= (buffer
== NULL
1512 ? (char *)MALLOC(len
* 2)
1513 : (char *)REALLOC(buffer
, len
* 2));
1515 errorCode
= XML_ERROR_NO_MEMORY
;
1516 return XML_STATUS_ERROR
;
1520 errorCode
= XML_ERROR_NO_MEMORY
;
1521 eventPtr
= eventEndPtr
= NULL
;
1522 processor
= errorProcessor
;
1523 return XML_STATUS_ERROR
;
1525 bufferLim
= buffer
+ len
* 2;
1527 memcpy(buffer
, end
, nLeftOver
);
1530 bufferEnd
= buffer
+ nLeftOver
;
1531 positionPtr
= bufferPtr
;
1532 parseEndPtr
= bufferEnd
;
1533 eventPtr
= bufferPtr
;
1534 eventEndPtr
= bufferPtr
;
1537 #endif /* not defined XML_CONTEXT_BYTES */
1539 void *buff
= XML_GetBuffer(parser
, len
);
1541 return XML_STATUS_ERROR
;
1543 memcpy(buff
, s
, len
);
1544 return XML_ParseBuffer(parser
, len
, isFinal
);
1549 enum XML_Status XMLCALL
1550 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1553 enum XML_Status result
= XML_STATUS_OK
;
1555 switch (ps_parsing
) {
1557 errorCode
= XML_ERROR_SUSPENDED
;
1558 return XML_STATUS_ERROR
;
1560 errorCode
= XML_ERROR_FINISHED
;
1561 return XML_STATUS_ERROR
;
1563 ps_parsing
= XML_PARSING
;
1567 positionPtr
= start
;
1569 parseEndPtr
= bufferEnd
;
1570 parseEndByteIndex
+= len
;
1571 ps_finalBuffer
= (XML_Bool
)isFinal
;
1573 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1575 if (errorCode
!= XML_ERROR_NONE
) {
1576 eventEndPtr
= eventPtr
;
1577 processor
= errorProcessor
;
1578 return XML_STATUS_ERROR
;
1581 switch (ps_parsing
) {
1583 result
= XML_STATUS_SUSPENDED
;
1585 case XML_INITIALIZED
:
1588 ps_parsing
= XML_FINISHED
;
1591 default: ; /* should not happen */
1595 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1596 positionPtr
= bufferPtr
;
1601 XML_GetBuffer(XML_Parser parser
, int len
)
1603 switch (ps_parsing
) {
1605 errorCode
= XML_ERROR_SUSPENDED
;
1608 errorCode
= XML_ERROR_FINISHED
;
1613 if (len
> bufferLim
- bufferEnd
) {
1614 /* FIXME avoid integer overflow */
1615 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1616 #ifdef XML_CONTEXT_BYTES
1617 int keep
= (int)(bufferPtr
- buffer
);
1619 if (keep
> XML_CONTEXT_BYTES
)
1620 keep
= XML_CONTEXT_BYTES
;
1622 #endif /* defined XML_CONTEXT_BYTES */
1623 if (neededSize
<= bufferLim
- buffer
) {
1624 #ifdef XML_CONTEXT_BYTES
1625 if (keep
< bufferPtr
- buffer
) {
1626 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1627 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1628 bufferEnd
-= offset
;
1629 bufferPtr
-= offset
;
1632 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1633 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1635 #endif /* not defined XML_CONTEXT_BYTES */
1639 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1640 if (bufferSize
== 0)
1641 bufferSize
= INIT_BUFFER_SIZE
;
1644 } while (bufferSize
< neededSize
);
1645 newBuf
= (char *)MALLOC(bufferSize
);
1647 errorCode
= XML_ERROR_NO_MEMORY
;
1650 bufferLim
= newBuf
+ bufferSize
;
1651 #ifdef XML_CONTEXT_BYTES
1653 int keep
= (int)(bufferPtr
- buffer
);
1654 if (keep
> XML_CONTEXT_BYTES
)
1655 keep
= XML_CONTEXT_BYTES
;
1656 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1659 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1660 bufferPtr
= buffer
+ keep
;
1663 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1664 bufferPtr
= buffer
= newBuf
;
1668 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1671 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1672 bufferPtr
= buffer
= newBuf
;
1673 #endif /* not defined XML_CONTEXT_BYTES */
1679 enum XML_Status XMLCALL
1680 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1682 switch (ps_parsing
) {
1685 errorCode
= XML_ERROR_SUSPENDED
;
1686 return XML_STATUS_ERROR
;
1688 ps_parsing
= XML_FINISHED
;
1691 errorCode
= XML_ERROR_FINISHED
;
1692 return XML_STATUS_ERROR
;
1696 if (isParamEntity
) {
1697 errorCode
= XML_ERROR_SUSPEND_PE
;
1698 return XML_STATUS_ERROR
;
1701 ps_parsing
= XML_SUSPENDED
;
1704 ps_parsing
= XML_FINISHED
;
1706 return XML_STATUS_OK
;
1709 enum XML_Status XMLCALL
1710 XML_ResumeParser(XML_Parser parser
)
1712 enum XML_Status result
= XML_STATUS_OK
;
1714 if (ps_parsing
!= XML_SUSPENDED
) {
1715 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1716 return XML_STATUS_ERROR
;
1718 ps_parsing
= XML_PARSING
;
1720 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1722 if (errorCode
!= XML_ERROR_NONE
) {
1723 eventEndPtr
= eventPtr
;
1724 processor
= errorProcessor
;
1725 return XML_STATUS_ERROR
;
1728 switch (ps_parsing
) {
1730 result
= XML_STATUS_SUSPENDED
;
1732 case XML_INITIALIZED
:
1734 if (ps_finalBuffer
) {
1735 ps_parsing
= XML_FINISHED
;
1742 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1743 positionPtr
= bufferPtr
;
1748 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1750 assert(status
!= NULL
);
1751 *status
= parser
->m_parsingStatus
;
1754 enum XML_Error XMLCALL
1755 XML_GetErrorCode(XML_Parser parser
)
1761 XML_GetCurrentByteIndex(XML_Parser parser
)
1764 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1769 XML_GetCurrentByteCount(XML_Parser parser
)
1771 if (eventEndPtr
&& eventPtr
)
1772 return (int)(eventEndPtr
- eventPtr
);
1776 const char * XMLCALL
1777 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1779 #ifdef XML_CONTEXT_BYTES
1780 if (eventPtr
&& buffer
) {
1781 *offset
= (int)(eventPtr
- buffer
);
1782 *size
= (int)(bufferEnd
- buffer
);
1785 #endif /* defined XML_CONTEXT_BYTES */
1790 XML_GetCurrentLineNumber(XML_Parser parser
)
1792 if (eventPtr
&& eventPtr
>= positionPtr
) {
1793 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1794 positionPtr
= eventPtr
;
1796 return position
.lineNumber
+ 1;
1800 XML_GetCurrentColumnNumber(XML_Parser parser
)
1802 if (eventPtr
&& eventPtr
>= positionPtr
) {
1803 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1804 positionPtr
= eventPtr
;
1806 return position
.columnNumber
;
1810 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1816 XML_MemMalloc(XML_Parser parser
, size_t size
)
1818 return MALLOC(size
);
1822 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1824 return REALLOC(ptr
, size
);
1828 XML_MemFree(XML_Parser parser
, void *ptr
)
1834 XML_DefaultCurrent(XML_Parser parser
)
1836 if (defaultHandler
) {
1837 if (openInternalEntities
)
1838 reportDefault(parser
,
1840 openInternalEntities
->internalEventPtr
,
1841 openInternalEntities
->internalEventEndPtr
);
1843 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1847 const XML_LChar
* XMLCALL
1848 XML_ErrorString(enum XML_Error code
)
1850 static const XML_LChar
* const message
[] = {
1852 XML_L("out of memory"),
1853 XML_L("syntax error"),
1854 XML_L("no element found"),
1855 XML_L("not well-formed (invalid token)"),
1856 XML_L("unclosed token"),
1857 XML_L("partial character"),
1858 XML_L("mismatched tag"),
1859 XML_L("duplicate attribute"),
1860 XML_L("junk after document element"),
1861 XML_L("illegal parameter entity reference"),
1862 XML_L("undefined entity"),
1863 XML_L("recursive entity reference"),
1864 XML_L("asynchronous entity"),
1865 XML_L("reference to invalid character number"),
1866 XML_L("reference to binary entity"),
1867 XML_L("reference to external entity in attribute"),
1868 XML_L("XML or text declaration not at start of entity"),
1869 XML_L("unknown encoding"),
1870 XML_L("encoding specified in XML declaration is incorrect"),
1871 XML_L("unclosed CDATA section"),
1872 XML_L("error in processing external entity reference"),
1873 XML_L("document is not standalone"),
1874 XML_L("unexpected parser state - please send a bug report"),
1875 XML_L("entity declared in parameter entity"),
1876 XML_L("requested feature requires XML_DTD support in Expat"),
1877 XML_L("cannot change setting once parsing has begun"),
1878 XML_L("unbound prefix"),
1879 XML_L("must not undeclare prefix"),
1880 XML_L("incomplete markup in parameter entity"),
1881 XML_L("XML declaration not well-formed"),
1882 XML_L("text declaration not well-formed"),
1883 XML_L("illegal character(s) in public id"),
1884 XML_L("parser suspended"),
1885 XML_L("parser not suspended"),
1886 XML_L("parsing aborted"),
1887 XML_L("parsing finished"),
1888 XML_L("cannot suspend in external parameter entity"),
1889 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1890 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1891 XML_L("prefix must not be bound to one of the reserved namespace names")
1893 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1894 return message
[code
];
1898 const XML_LChar
* XMLCALL
1899 XML_ExpatVersion(void) {
1901 /* V1 is used to string-ize the version number. However, it would
1902 string-ize the actual version macro *names* unless we get them
1903 substituted before being passed to V1. CPP is defined to expand
1904 a macro, then rescan for more expansions. Thus, we use V2 to expand
1905 the version macros, then CPP will expand the resulting V1() macro
1906 with the correct numerals. */
1907 /* ### I'm assuming cpp is portable in this respect... */
1909 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1910 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1912 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1918 XML_Expat_Version XMLCALL
1919 XML_ExpatVersionInfo(void)
1921 XML_Expat_Version version
;
1923 version
.major
= XML_MAJOR_VERSION
;
1924 version
.minor
= XML_MINOR_VERSION
;
1925 version
.micro
= XML_MICRO_VERSION
;
1930 const XML_Feature
* XMLCALL
1931 XML_GetFeatureList(void)
1933 static const XML_Feature features
[] = {
1934 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1936 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1939 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1941 #ifdef XML_UNICODE_WCHAR_T
1942 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1945 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1947 #ifdef XML_CONTEXT_BYTES
1948 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1952 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1955 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1957 #ifdef XML_LARGE_SIZE
1958 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
1960 {XML_FEATURE_END
, NULL
, 0}
1966 /* Initially tag->rawName always points into the parse buffer;
1967 for those TAG instances opened while the current parse buffer was
1968 processed, and not yet closed, we need to store tag->rawName in a more
1969 permanent location, since the parse buffer is about to be discarded.
1972 storeRawNames(XML_Parser parser
)
1974 TAG
*tag
= tagStack
;
1977 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1978 char *rawNameBuf
= tag
->buf
+ nameLen
;
1979 /* Stop if already stored. Since tagStack is a stack, we can stop
1980 at the first entry that has already been copied; everything
1981 below it in the stack is already been accounted for in a
1982 previous call to this function.
1984 if (tag
->rawName
== rawNameBuf
)
1986 /* For re-use purposes we need to ensure that the
1987 size of tag->buf is a multiple of sizeof(XML_Char).
1989 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1990 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1991 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1994 /* if tag->name.str points to tag->buf (only when namespace
1995 processing is off) then we have to update it
1997 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1998 tag
->name
.str
= (XML_Char
*)temp
;
1999 /* if tag->name.localPart is set (when namespace processing is on)
2000 then update it as well, since it will always point into tag->buf
2002 if (tag
->name
.localPart
)
2003 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2004 (XML_Char
*)tag
->buf
);
2006 tag
->bufEnd
= temp
+ bufSize
;
2007 rawNameBuf
= temp
+ nameLen
;
2009 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2010 tag
->rawName
= rawNameBuf
;
2016 static enum XML_Error PTRCALL
2017 contentProcessor(XML_Parser parser
,
2020 const char **endPtr
)
2022 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2023 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2024 if (result
== XML_ERROR_NONE
) {
2025 if (!storeRawNames(parser
))
2026 return XML_ERROR_NO_MEMORY
;
2031 static enum XML_Error PTRCALL
2032 externalEntityInitProcessor(XML_Parser parser
,
2035 const char **endPtr
)
2037 enum XML_Error result
= initializeEncoding(parser
);
2038 if (result
!= XML_ERROR_NONE
)
2040 processor
= externalEntityInitProcessor2
;
2041 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2044 static enum XML_Error PTRCALL
2045 externalEntityInitProcessor2(XML_Parser parser
,
2048 const char **endPtr
)
2050 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2051 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2054 /* If we are at the end of the buffer, this would cause the next stage,
2055 i.e. externalEntityInitProcessor3, to pass control directly to
2056 doContent (by detecting XML_TOK_NONE) without processing any xml text
2057 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2059 if (next
== end
&& !ps_finalBuffer
) {
2061 return XML_ERROR_NONE
;
2065 case XML_TOK_PARTIAL
:
2066 if (!ps_finalBuffer
) {
2068 return XML_ERROR_NONE
;
2071 return XML_ERROR_UNCLOSED_TOKEN
;
2072 case XML_TOK_PARTIAL_CHAR
:
2073 if (!ps_finalBuffer
) {
2075 return XML_ERROR_NONE
;
2078 return XML_ERROR_PARTIAL_CHAR
;
2080 processor
= externalEntityInitProcessor3
;
2081 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2084 static enum XML_Error PTRCALL
2085 externalEntityInitProcessor3(XML_Parser parser
,
2088 const char **endPtr
)
2091 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2093 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2097 case XML_TOK_XML_DECL
:
2099 enum XML_Error result
;
2100 result
= processXmlDecl(parser
, 1, start
, next
);
2101 if (result
!= XML_ERROR_NONE
)
2103 switch (ps_parsing
) {
2106 return XML_ERROR_NONE
;
2108 return XML_ERROR_ABORTED
;
2114 case XML_TOK_PARTIAL
:
2115 if (!ps_finalBuffer
) {
2117 return XML_ERROR_NONE
;
2119 return XML_ERROR_UNCLOSED_TOKEN
;
2120 case XML_TOK_PARTIAL_CHAR
:
2121 if (!ps_finalBuffer
) {
2123 return XML_ERROR_NONE
;
2125 return XML_ERROR_PARTIAL_CHAR
;
2127 processor
= externalEntityContentProcessor
;
2129 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2132 static enum XML_Error PTRCALL
2133 externalEntityContentProcessor(XML_Parser parser
,
2136 const char **endPtr
)
2138 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2139 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2140 if (result
== XML_ERROR_NONE
) {
2141 if (!storeRawNames(parser
))
2142 return XML_ERROR_NO_MEMORY
;
2147 static enum XML_Error
2148 doContent(XML_Parser parser
,
2150 const ENCODING
*enc
,
2153 const char **nextPtr
,
2156 /* save one level of indirection */
2157 DTD
* const dtd
= _dtd
;
2159 const char **eventPP
;
2160 const char **eventEndPP
;
2161 if (enc
== encoding
) {
2162 eventPP
= &eventPtr
;
2163 eventEndPP
= &eventEndPtr
;
2166 eventPP
= &(openInternalEntities
->internalEventPtr
);
2167 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2172 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2173 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2176 case XML_TOK_TRAILING_CR
:
2179 return XML_ERROR_NONE
;
2182 if (characterDataHandler
) {
2184 characterDataHandler(handlerArg
, &c
, 1);
2186 else if (defaultHandler
)
2187 reportDefault(parser
, enc
, s
, end
);
2188 /* We are at the end of the final buffer, should we check for
2189 XML_SUSPENDED, XML_FINISHED?
2191 if (startTagLevel
== 0)
2192 return XML_ERROR_NO_ELEMENTS
;
2193 if (tagLevel
!= startTagLevel
)
2194 return XML_ERROR_ASYNC_ENTITY
;
2196 return XML_ERROR_NONE
;
2200 return XML_ERROR_NONE
;
2202 if (startTagLevel
> 0) {
2203 if (tagLevel
!= startTagLevel
)
2204 return XML_ERROR_ASYNC_ENTITY
;
2206 return XML_ERROR_NONE
;
2208 return XML_ERROR_NO_ELEMENTS
;
2209 case XML_TOK_INVALID
:
2211 return XML_ERROR_INVALID_TOKEN
;
2212 case XML_TOK_PARTIAL
:
2215 return XML_ERROR_NONE
;
2217 return XML_ERROR_UNCLOSED_TOKEN
;
2218 case XML_TOK_PARTIAL_CHAR
:
2221 return XML_ERROR_NONE
;
2223 return XML_ERROR_PARTIAL_CHAR
;
2224 case XML_TOK_ENTITY_REF
:
2226 const XML_Char
*name
;
2228 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2229 s
+ enc
->minBytesPerChar
,
2230 next
- enc
->minBytesPerChar
);
2232 if (characterDataHandler
)
2233 characterDataHandler(handlerArg
, &ch
, 1);
2234 else if (defaultHandler
)
2235 reportDefault(parser
, enc
, s
, next
);
2238 name
= poolStoreString(&dtd
->pool
, enc
,
2239 s
+ enc
->minBytesPerChar
,
2240 next
- enc
->minBytesPerChar
);
2242 return XML_ERROR_NO_MEMORY
;
2243 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2244 poolDiscard(&dtd
->pool
);
2245 /* First, determine if a check for an existing declaration is needed;
2246 if yes, check that the entity exists, and that it is internal,
2247 otherwise call the skipped entity or default handler.
2249 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2251 return XML_ERROR_UNDEFINED_ENTITY
;
2252 else if (!entity
->is_internal
)
2253 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2256 if (skippedEntityHandler
)
2257 skippedEntityHandler(handlerArg
, name
, 0);
2258 else if (defaultHandler
)
2259 reportDefault(parser
, enc
, s
, next
);
2263 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2264 if (entity
->notation
)
2265 return XML_ERROR_BINARY_ENTITY_REF
;
2266 if (entity
->textPtr
) {
2267 enum XML_Error result
;
2268 if (!defaultExpandInternalEntities
) {
2269 if (skippedEntityHandler
)
2270 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2271 else if (defaultHandler
)
2272 reportDefault(parser
, enc
, s
, next
);
2275 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2276 if (result
!= XML_ERROR_NONE
)
2279 else if (externalEntityRefHandler
) {
2280 const XML_Char
*context
;
2281 entity
->open
= XML_TRUE
;
2282 context
= getContext(parser
);
2283 entity
->open
= XML_FALSE
;
2285 return XML_ERROR_NO_MEMORY
;
2286 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2291 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2292 poolDiscard(&tempPool
);
2294 else if (defaultHandler
)
2295 reportDefault(parser
, enc
, s
, next
);
2298 case XML_TOK_START_TAG_NO_ATTS
:
2300 case XML_TOK_START_TAG_WITH_ATTS
:
2303 enum XML_Error result
;
2307 freeTagList
= freeTagList
->parent
;
2310 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2312 return XML_ERROR_NO_MEMORY
;
2313 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2316 return XML_ERROR_NO_MEMORY
;
2318 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2320 tag
->bindings
= NULL
;
2321 tag
->parent
= tagStack
;
2323 tag
->name
.localPart
= NULL
;
2324 tag
->name
.prefix
= NULL
;
2325 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2326 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2329 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2330 const char *fromPtr
= tag
->rawName
;
2331 toPtr
= (XML_Char
*)tag
->buf
;
2336 &fromPtr
, rawNameEnd
,
2337 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2338 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2339 if (fromPtr
== rawNameEnd
) {
2340 tag
->name
.strLen
= convLen
;
2343 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2345 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2347 return XML_ERROR_NO_MEMORY
;
2349 tag
->bufEnd
= temp
+ bufSize
;
2350 toPtr
= (XML_Char
*)temp
+ convLen
;
2354 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2355 *toPtr
= XML_T('\0');
2356 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2359 if (startElementHandler
)
2360 startElementHandler(handlerArg
, tag
->name
.str
,
2361 (const XML_Char
**)atts
);
2362 else if (defaultHandler
)
2363 reportDefault(parser
, enc
, s
, next
);
2364 poolClear(&tempPool
);
2367 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2369 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2371 const char *rawName
= s
+ enc
->minBytesPerChar
;
2372 enum XML_Error result
;
2373 BINDING
*bindings
= NULL
;
2374 XML_Bool noElmHandlers
= XML_TRUE
;
2376 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2377 rawName
+ XmlNameLength(enc
, rawName
));
2379 return XML_ERROR_NO_MEMORY
;
2380 poolFinish(&tempPool
);
2381 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2384 poolFinish(&tempPool
);
2385 if (startElementHandler
) {
2386 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2387 noElmHandlers
= XML_FALSE
;
2389 if (endElementHandler
) {
2390 if (startElementHandler
)
2391 *eventPP
= *eventEndPP
;
2392 endElementHandler(handlerArg
, name
.str
);
2393 noElmHandlers
= XML_FALSE
;
2395 if (noElmHandlers
&& defaultHandler
)
2396 reportDefault(parser
, enc
, s
, next
);
2397 poolClear(&tempPool
);
2399 BINDING
*b
= bindings
;
2400 if (endNamespaceDeclHandler
)
2401 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2402 bindings
= bindings
->nextTagBinding
;
2403 b
->nextTagBinding
= freeBindingList
;
2404 freeBindingList
= b
;
2405 b
->prefix
->binding
= b
->prevPrefixBinding
;
2409 return epilogProcessor(parser
, next
, end
, nextPtr
);
2411 case XML_TOK_END_TAG
:
2412 if (tagLevel
== startTagLevel
)
2413 return XML_ERROR_ASYNC_ENTITY
;
2416 const char *rawName
;
2417 TAG
*tag
= tagStack
;
2418 tagStack
= tag
->parent
;
2419 tag
->parent
= freeTagList
;
2421 rawName
= s
+ enc
->minBytesPerChar
*2;
2422 len
= XmlNameLength(enc
, rawName
);
2423 if (len
!= tag
->rawNameLength
2424 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2426 return XML_ERROR_TAG_MISMATCH
;
2429 if (endElementHandler
) {
2430 const XML_Char
*localPart
;
2431 const XML_Char
*prefix
;
2433 localPart
= tag
->name
.localPart
;
2434 if (ns
&& localPart
) {
2435 /* localPart and prefix may have been overwritten in
2436 tag->name.str, since this points to the binding->uri
2437 buffer which gets re-used; so we have to add them again
2439 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2440 /* don't need to check for space - already done in storeAtts() */
2441 while (*localPart
) *uri
++ = *localPart
++;
2442 prefix
= (XML_Char
*)tag
->name
.prefix
;
2443 if (ns_triplets
&& prefix
) {
2444 *uri
++ = namespaceSeparator
;
2445 while (*prefix
) *uri
++ = *prefix
++;
2449 endElementHandler(handlerArg
, tag
->name
.str
);
2451 else if (defaultHandler
)
2452 reportDefault(parser
, enc
, s
, next
);
2453 while (tag
->bindings
) {
2454 BINDING
*b
= tag
->bindings
;
2455 if (endNamespaceDeclHandler
)
2456 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2457 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2458 b
->nextTagBinding
= freeBindingList
;
2459 freeBindingList
= b
;
2460 b
->prefix
->binding
= b
->prevPrefixBinding
;
2463 return epilogProcessor(parser
, next
, end
, nextPtr
);
2466 case XML_TOK_CHAR_REF
:
2468 int n
= XmlCharRefNumber(enc
, s
);
2470 return XML_ERROR_BAD_CHAR_REF
;
2471 if (characterDataHandler
) {
2472 XML_Char buf
[XML_ENCODE_MAX
];
2473 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2475 else if (defaultHandler
)
2476 reportDefault(parser
, enc
, s
, next
);
2479 case XML_TOK_XML_DECL
:
2480 return XML_ERROR_MISPLACED_XML_PI
;
2481 case XML_TOK_DATA_NEWLINE
:
2482 if (characterDataHandler
) {
2484 characterDataHandler(handlerArg
, &c
, 1);
2486 else if (defaultHandler
)
2487 reportDefault(parser
, enc
, s
, next
);
2489 case XML_TOK_CDATA_SECT_OPEN
:
2491 enum XML_Error result
;
2492 if (startCdataSectionHandler
)
2493 startCdataSectionHandler(handlerArg
);
2495 /* Suppose you doing a transformation on a document that involves
2496 changing only the character data. You set up a defaultHandler
2497 and a characterDataHandler. The defaultHandler simply copies
2498 characters through. The characterDataHandler does the
2499 transformation and writes the characters out escaping them as
2500 necessary. This case will fail to work if we leave out the
2501 following two lines (because & and < inside CDATA sections will
2502 be incorrectly escaped).
2504 However, now we have a start/endCdataSectionHandler, so it seems
2505 easier to let the user deal with this.
2507 else if (characterDataHandler
)
2508 characterDataHandler(handlerArg
, dataBuf
, 0);
2510 else if (defaultHandler
)
2511 reportDefault(parser
, enc
, s
, next
);
2512 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2513 if (result
!= XML_ERROR_NONE
)
2516 processor
= cdataSectionProcessor
;
2521 case XML_TOK_TRAILING_RSQB
:
2524 return XML_ERROR_NONE
;
2526 if (characterDataHandler
) {
2527 if (MUST_CONVERT(enc
, s
)) {
2528 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2529 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2530 characterDataHandler(handlerArg
, dataBuf
,
2531 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2534 characterDataHandler(handlerArg
,
2536 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2538 else if (defaultHandler
)
2539 reportDefault(parser
, enc
, s
, end
);
2540 /* We are at the end of the final buffer, should we check for
2541 XML_SUSPENDED, XML_FINISHED?
2543 if (startTagLevel
== 0) {
2545 return XML_ERROR_NO_ELEMENTS
;
2547 if (tagLevel
!= startTagLevel
) {
2549 return XML_ERROR_ASYNC_ENTITY
;
2552 return XML_ERROR_NONE
;
2553 case XML_TOK_DATA_CHARS
:
2555 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2556 if (charDataHandler
) {
2557 if (MUST_CONVERT(enc
, s
)) {
2559 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2560 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2562 charDataHandler(handlerArg
, dataBuf
,
2563 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2570 charDataHandler(handlerArg
,
2572 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2574 else if (defaultHandler
)
2575 reportDefault(parser
, enc
, s
, next
);
2579 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2580 return XML_ERROR_NO_MEMORY
;
2582 case XML_TOK_COMMENT
:
2583 if (!reportComment(parser
, enc
, s
, next
))
2584 return XML_ERROR_NO_MEMORY
;
2588 reportDefault(parser
, enc
, s
, next
);
2591 *eventPP
= s
= next
;
2592 switch (ps_parsing
) {
2595 return XML_ERROR_NONE
;
2597 return XML_ERROR_ABORTED
;
2604 /* Precondition: all arguments must be non-NULL;
2606 - normalize attributes
2607 - check attributes for well-formedness
2608 - generate namespace aware attribute names (URI, prefix)
2609 - build list of attributes for startElementHandler
2610 - default attributes
2611 - process namespace declarations (check and report them)
2612 - generate namespace aware element name (URI, prefix)
2614 static enum XML_Error
2615 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2616 const char *attStr
, TAG_NAME
*tagNamePtr
,
2617 BINDING
**bindingsPtr
)
2619 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2620 ELEMENT_TYPE
*elementType
;
2622 const XML_Char
**appAtts
; /* the attribute list for the application */
2630 const XML_Char
*localPart
;
2632 /* lookup the element type name */
2633 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2635 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2637 return XML_ERROR_NO_MEMORY
;
2638 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2639 sizeof(ELEMENT_TYPE
));
2641 return XML_ERROR_NO_MEMORY
;
2642 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2643 return XML_ERROR_NO_MEMORY
;
2645 nDefaultAtts
= elementType
->nDefaultAtts
;
2647 /* get the attributes from the tokenizer */
2648 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2649 if (n
+ nDefaultAtts
> attsSize
) {
2650 int oldAttsSize
= attsSize
;
2652 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2653 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2655 return XML_ERROR_NO_MEMORY
;
2657 if (n
> oldAttsSize
)
2658 XmlGetAttributes(enc
, attStr
, n
, atts
);
2661 appAtts
= (const XML_Char
**)atts
;
2662 for (i
= 0; i
< n
; i
++) {
2663 /* add the name and value to the attribute list */
2664 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2666 + XmlNameLength(enc
, atts
[i
].name
));
2668 return XML_ERROR_NO_MEMORY
;
2669 /* Detect duplicate attributes by their QNames. This does not work when
2670 namespace processing is turned on and different prefixes for the same
2671 namespace are used. For this case we have a check further down.
2673 if ((attId
->name
)[-1]) {
2674 if (enc
== encoding
)
2675 eventPtr
= atts
[i
].name
;
2676 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2678 (attId
->name
)[-1] = 1;
2679 appAtts
[attIndex
++] = attId
->name
;
2680 if (!atts
[i
].normalized
) {
2681 enum XML_Error result
;
2682 XML_Bool isCdata
= XML_TRUE
;
2684 /* figure out whether declared as other than CDATA */
2685 if (attId
->maybeTokenized
) {
2687 for (j
= 0; j
< nDefaultAtts
; j
++) {
2688 if (attId
== elementType
->defaultAtts
[j
].id
) {
2689 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2695 /* normalize the attribute value */
2696 result
= storeAttributeValue(parser
, enc
, isCdata
,
2697 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2701 appAtts
[attIndex
] = poolStart(&tempPool
);
2702 poolFinish(&tempPool
);
2705 /* the value did not need normalizing */
2706 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2708 if (appAtts
[attIndex
] == 0)
2709 return XML_ERROR_NO_MEMORY
;
2710 poolFinish(&tempPool
);
2712 /* handle prefixed attribute names */
2713 if (attId
->prefix
) {
2715 /* deal with namespace declarations here */
2716 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2717 appAtts
[attIndex
], bindingsPtr
);
2723 /* deal with other prefixed names later */
2726 (attId
->name
)[-1] = 2;
2733 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2734 nSpecifiedAtts
= attIndex
;
2735 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2736 for (i
= 0; i
< attIndex
; i
+= 2)
2737 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2745 /* do attribute defaulting */
2746 for (i
= 0; i
< nDefaultAtts
; i
++) {
2747 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2748 if (!(da
->id
->name
)[-1] && da
->value
) {
2749 if (da
->id
->prefix
) {
2750 if (da
->id
->xmlns
) {
2751 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2752 da
->value
, bindingsPtr
);
2757 (da
->id
->name
)[-1] = 2;
2759 appAtts
[attIndex
++] = da
->id
->name
;
2760 appAtts
[attIndex
++] = da
->value
;
2764 (da
->id
->name
)[-1] = 1;
2765 appAtts
[attIndex
++] = da
->id
->name
;
2766 appAtts
[attIndex
++] = da
->value
;
2770 appAtts
[attIndex
] = 0;
2772 /* expand prefixed attribute names, check for duplicates,
2773 and clear flags that say whether attributes were specified */
2776 int j
; /* hash table index */
2777 unsigned long version
= nsAttsVersion
;
2778 int nsAttsSize
= (int)1 << nsAttsPower
;
2779 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2780 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2782 /* hash table size must also be a power of 2 and >= 8 */
2783 while (nPrefixes
>> nsAttsPower
++);
2784 if (nsAttsPower
< 3)
2786 nsAttsSize
= (int)1 << nsAttsPower
;
2787 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2789 return XML_ERROR_NO_MEMORY
;
2791 version
= 0; /* force re-initialization of nsAtts hash table */
2793 /* using a version flag saves us from initializing nsAtts every time */
2794 if (!version
) { /* initialize version flags when version wraps around */
2795 version
= INIT_ATTS_VERSION
;
2796 for (j
= nsAttsSize
; j
!= 0; )
2797 nsAtts
[--j
].version
= version
;
2799 nsAttsVersion
= --version
;
2801 /* expand prefixed names and check for duplicates */
2802 for (; i
< attIndex
; i
+= 2) {
2803 const XML_Char
*s
= appAtts
[i
];
2804 if (s
[-1] == 2) { /* prefixed */
2807 unsigned long uriHash
= 0;
2808 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2809 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2810 b
= id
->prefix
->binding
;
2812 return XML_ERROR_UNBOUND_PREFIX
;
2814 /* as we expand the name we also calculate its hash value */
2815 for (j
= 0; j
< b
->uriLen
; j
++) {
2816 const XML_Char c
= b
->uri
[j
];
2817 if (!poolAppendChar(&tempPool
, c
))
2818 return XML_ERROR_NO_MEMORY
;
2819 uriHash
= CHAR_HASH(uriHash
, c
);
2821 while (*s
++ != XML_T(ASCII_COLON
))
2823 do { /* copies null terminator */
2824 const XML_Char c
= *s
;
2825 if (!poolAppendChar(&tempPool
, *s
))
2826 return XML_ERROR_NO_MEMORY
;
2827 uriHash
= CHAR_HASH(uriHash
, c
);
2830 { /* Check hash table for duplicate of expanded name (uriName).
2831 Derived from code in lookup(HASH_TABLE *table, ...).
2833 unsigned char step
= 0;
2834 unsigned long mask
= nsAttsSize
- 1;
2835 j
= uriHash
& mask
; /* index into hash table */
2836 while (nsAtts
[j
].version
== version
) {
2837 /* for speed we compare stored hash values first */
2838 if (uriHash
== nsAtts
[j
].hash
) {
2839 const XML_Char
*s1
= poolStart(&tempPool
);
2840 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2841 /* s1 is null terminated, but not s2 */
2842 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2844 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2847 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2848 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2852 if (ns_triplets
) { /* append namespace separator and prefix */
2853 tempPool
.ptr
[-1] = namespaceSeparator
;
2854 s
= b
->prefix
->name
;
2856 if (!poolAppendChar(&tempPool
, *s
))
2857 return XML_ERROR_NO_MEMORY
;
2861 /* store expanded name in attribute list */
2862 s
= poolStart(&tempPool
);
2863 poolFinish(&tempPool
);
2866 /* fill empty slot with new version, uriName and hash value */
2867 nsAtts
[j
].version
= version
;
2868 nsAtts
[j
].hash
= uriHash
;
2869 nsAtts
[j
].uriName
= s
;
2876 else /* not prefixed */
2877 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2880 /* clear flags for the remaining attributes */
2881 for (; i
< attIndex
; i
+= 2)
2882 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2883 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2884 binding
->attId
->name
[-1] = 0;
2887 return XML_ERROR_NONE
;
2889 /* expand the element type name */
2890 if (elementType
->prefix
) {
2891 binding
= elementType
->prefix
->binding
;
2893 return XML_ERROR_UNBOUND_PREFIX
;
2894 localPart
= tagNamePtr
->str
;
2895 while (*localPart
++ != XML_T(ASCII_COLON
))
2898 else if (dtd
->defaultPrefix
.binding
) {
2899 binding
= dtd
->defaultPrefix
.binding
;
2900 localPart
= tagNamePtr
->str
;
2903 return XML_ERROR_NONE
;
2905 if (ns_triplets
&& binding
->prefix
->name
) {
2906 for (; binding
->prefix
->name
[prefixLen
++];)
2907 ; /* prefixLen includes null terminator */
2909 tagNamePtr
->localPart
= localPart
;
2910 tagNamePtr
->uriLen
= binding
->uriLen
;
2911 tagNamePtr
->prefix
= binding
->prefix
->name
;
2912 tagNamePtr
->prefixLen
= prefixLen
;
2913 for (i
= 0; localPart
[i
++];)
2914 ; /* i includes null terminator */
2915 n
= i
+ binding
->uriLen
+ prefixLen
;
2916 if (n
> binding
->uriAlloc
) {
2918 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2920 return XML_ERROR_NO_MEMORY
;
2921 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2922 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2923 for (p
= tagStack
; p
; p
= p
->parent
)
2924 if (p
->name
.str
== binding
->uri
)
2929 /* if namespaceSeparator != '\0' then uri includes it already */
2930 uri
= binding
->uri
+ binding
->uriLen
;
2931 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2932 /* we always have a namespace separator between localPart and prefix */
2935 *uri
= namespaceSeparator
; /* replace null terminator */
2936 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2938 tagNamePtr
->str
= binding
->uri
;
2939 return XML_ERROR_NONE
;
2942 /* addBinding() overwrites the value of prefix->binding without checking.
2943 Therefore one must keep track of the old value outside of addBinding().
2945 static enum XML_Error
2946 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2947 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2949 static const XML_Char xmlNamespace
[] = {
2950 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2951 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2952 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
2953 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
2954 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
2957 static const int xmlLen
=
2958 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2959 static const XML_Char xmlnsNamespace
[] = {
2960 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2961 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2962 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
2963 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
2966 static const int xmlnsLen
=
2967 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2969 XML_Bool mustBeXML
= XML_FALSE
;
2970 XML_Bool isXML
= XML_TRUE
;
2971 XML_Bool isXMLNS
= XML_TRUE
;
2976 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2977 if (*uri
== XML_T('\0') && prefix
->name
)
2978 return XML_ERROR_UNDECLARING_PREFIX
;
2981 && prefix
->name
[0] == XML_T(ASCII_x
)
2982 && prefix
->name
[1] == XML_T(ASCII_m
)
2983 && prefix
->name
[2] == XML_T(ASCII_l
)) {
2985 /* Not allowed to bind xmlns */
2986 if (prefix
->name
[3] == XML_T(ASCII_n
)
2987 && prefix
->name
[4] == XML_T(ASCII_s
)
2988 && prefix
->name
[5] == XML_T('\0'))
2989 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2991 if (prefix
->name
[3] == XML_T('\0'))
2992 mustBeXML
= XML_TRUE
;
2995 for (len
= 0; uri
[len
]; len
++) {
2996 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
2999 if (!mustBeXML
&& isXMLNS
3000 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
3001 isXMLNS
= XML_FALSE
;
3003 isXML
= isXML
&& len
== xmlLen
;
3004 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3006 if (mustBeXML
!= isXML
)
3007 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3008 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3011 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3013 if (namespaceSeparator
)
3015 if (freeBindingList
) {
3016 b
= freeBindingList
;
3017 if (len
> b
->uriAlloc
) {
3018 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3019 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3021 return XML_ERROR_NO_MEMORY
;
3023 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3025 freeBindingList
= b
->nextTagBinding
;
3028 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3030 return XML_ERROR_NO_MEMORY
;
3031 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3034 return XML_ERROR_NO_MEMORY
;
3036 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3039 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3040 if (namespaceSeparator
)
3041 b
->uri
[len
- 1] = namespaceSeparator
;
3044 b
->prevPrefixBinding
= prefix
->binding
;
3045 /* NULL binding when default namespace undeclared */
3046 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3047 prefix
->binding
= NULL
;
3049 prefix
->binding
= b
;
3050 b
->nextTagBinding
= *bindingsPtr
;
3052 /* if attId == NULL then we are not starting a namespace scope */
3053 if (attId
&& startNamespaceDeclHandler
)
3054 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3055 prefix
->binding
? uri
: 0);
3056 return XML_ERROR_NONE
;
3059 /* The idea here is to avoid using stack for each CDATA section when
3060 the whole file is parsed with one call.
3062 static enum XML_Error PTRCALL
3063 cdataSectionProcessor(XML_Parser parser
,
3066 const char **endPtr
)
3068 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3069 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3070 if (result
!= XML_ERROR_NONE
)
3073 if (parentParser
) { /* we are parsing an external entity */
3074 processor
= externalEntityContentProcessor
;
3075 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3078 processor
= contentProcessor
;
3079 return contentProcessor(parser
, start
, end
, endPtr
);
3085 /* startPtr gets set to non-null if the section is closed, and to null if
3086 the section is not yet closed.
3088 static enum XML_Error
3089 doCdataSection(XML_Parser parser
,
3090 const ENCODING
*enc
,
3091 const char **startPtr
,
3093 const char **nextPtr
,
3096 const char *s
= *startPtr
;
3097 const char **eventPP
;
3098 const char **eventEndPP
;
3099 if (enc
== encoding
) {
3100 eventPP
= &eventPtr
;
3102 eventEndPP
= &eventEndPtr
;
3105 eventPP
= &(openInternalEntities
->internalEventPtr
);
3106 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3113 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3116 case XML_TOK_CDATA_SECT_CLOSE
:
3117 if (endCdataSectionHandler
)
3118 endCdataSectionHandler(handlerArg
);
3120 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3121 else if (characterDataHandler
)
3122 characterDataHandler(handlerArg
, dataBuf
, 0);
3124 else if (defaultHandler
)
3125 reportDefault(parser
, enc
, s
, next
);
3128 if (ps_parsing
== XML_FINISHED
)
3129 return XML_ERROR_ABORTED
;
3131 return XML_ERROR_NONE
;
3132 case XML_TOK_DATA_NEWLINE
:
3133 if (characterDataHandler
) {
3135 characterDataHandler(handlerArg
, &c
, 1);
3137 else if (defaultHandler
)
3138 reportDefault(parser
, enc
, s
, next
);
3140 case XML_TOK_DATA_CHARS
:
3142 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3143 if (charDataHandler
) {
3144 if (MUST_CONVERT(enc
, s
)) {
3146 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3147 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3149 charDataHandler(handlerArg
, dataBuf
,
3150 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3157 charDataHandler(handlerArg
,
3159 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3161 else if (defaultHandler
)
3162 reportDefault(parser
, enc
, s
, next
);
3165 case XML_TOK_INVALID
:
3167 return XML_ERROR_INVALID_TOKEN
;
3168 case XML_TOK_PARTIAL_CHAR
:
3171 return XML_ERROR_NONE
;
3173 return XML_ERROR_PARTIAL_CHAR
;
3174 case XML_TOK_PARTIAL
:
3178 return XML_ERROR_NONE
;
3180 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3183 return XML_ERROR_UNEXPECTED_STATE
;
3186 *eventPP
= s
= next
;
3187 switch (ps_parsing
) {
3190 return XML_ERROR_NONE
;
3192 return XML_ERROR_ABORTED
;
3201 /* The idea here is to avoid using stack for each IGNORE section when
3202 the whole file is parsed with one call.
3204 static enum XML_Error PTRCALL
3205 ignoreSectionProcessor(XML_Parser parser
,
3208 const char **endPtr
)
3210 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3211 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3212 if (result
!= XML_ERROR_NONE
)
3215 processor
= prologProcessor
;
3216 return prologProcessor(parser
, start
, end
, endPtr
);
3221 /* startPtr gets set to non-null is the section is closed, and to null
3222 if the section is not yet closed.
3224 static enum XML_Error
3225 doIgnoreSection(XML_Parser parser
,
3226 const ENCODING
*enc
,
3227 const char **startPtr
,
3229 const char **nextPtr
,
3234 const char *s
= *startPtr
;
3235 const char **eventPP
;
3236 const char **eventEndPP
;
3237 if (enc
== encoding
) {
3238 eventPP
= &eventPtr
;
3240 eventEndPP
= &eventEndPtr
;
3243 eventPP
= &(openInternalEntities
->internalEventPtr
);
3244 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3248 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3251 case XML_TOK_IGNORE_SECT
:
3253 reportDefault(parser
, enc
, s
, next
);
3256 if (ps_parsing
== XML_FINISHED
)
3257 return XML_ERROR_ABORTED
;
3259 return XML_ERROR_NONE
;
3260 case XML_TOK_INVALID
:
3262 return XML_ERROR_INVALID_TOKEN
;
3263 case XML_TOK_PARTIAL_CHAR
:
3266 return XML_ERROR_NONE
;
3268 return XML_ERROR_PARTIAL_CHAR
;
3269 case XML_TOK_PARTIAL
:
3273 return XML_ERROR_NONE
;
3275 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3278 return XML_ERROR_UNEXPECTED_STATE
;
3283 #endif /* XML_DTD */
3285 static enum XML_Error
3286 initializeEncoding(XML_Parser parser
)
3290 char encodingBuf
[128];
3291 if (!protocolEncodingName
)
3295 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3296 if (i
== sizeof(encodingBuf
) - 1
3297 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3298 encodingBuf
[0] = '\0';
3301 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3303 encodingBuf
[i
] = '\0';
3307 s
= protocolEncodingName
;
3309 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3310 return XML_ERROR_NONE
;
3311 return handleUnknownEncoding(parser
, protocolEncodingName
);
3314 static enum XML_Error
3315 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3316 const char *s
, const char *next
)
3318 const char *encodingName
= NULL
;
3319 const XML_Char
*storedEncName
= NULL
;
3320 const ENCODING
*newEncoding
= NULL
;
3321 const char *version
= NULL
;
3322 const char *versionend
;
3323 const XML_Char
*storedversion
= NULL
;
3324 int standalone
= -1;
3327 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3337 if (isGeneralTextEntity
)
3338 return XML_ERROR_TEXT_DECL
;
3340 return XML_ERROR_XML_DECL
;
3342 if (!isGeneralTextEntity
&& standalone
== 1) {
3343 _dtd
->standalone
= XML_TRUE
;
3345 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3346 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3347 #endif /* XML_DTD */
3349 if (xmlDeclHandler
) {
3350 if (encodingName
!= NULL
) {
3351 storedEncName
= poolStoreString(&temp2Pool
,
3355 + XmlNameLength(encoding
, encodingName
));
3357 return XML_ERROR_NO_MEMORY
;
3358 poolFinish(&temp2Pool
);
3361 storedversion
= poolStoreString(&temp2Pool
,
3364 versionend
- encoding
->minBytesPerChar
);
3366 return XML_ERROR_NO_MEMORY
;
3368 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3370 else if (defaultHandler
)
3371 reportDefault(parser
, encoding
, s
, next
);
3372 if (protocolEncodingName
== NULL
) {
3374 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3375 eventPtr
= encodingName
;
3376 return XML_ERROR_INCORRECT_ENCODING
;
3378 encoding
= newEncoding
;
3380 else if (encodingName
) {
3381 enum XML_Error result
;
3382 if (!storedEncName
) {
3383 storedEncName
= poolStoreString(
3384 &temp2Pool
, encoding
, encodingName
,
3385 encodingName
+ XmlNameLength(encoding
, encodingName
));
3387 return XML_ERROR_NO_MEMORY
;
3389 result
= handleUnknownEncoding(parser
, storedEncName
);
3390 poolClear(&temp2Pool
);
3391 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3392 eventPtr
= encodingName
;
3397 if (storedEncName
|| storedversion
)
3398 poolClear(&temp2Pool
);
3400 return XML_ERROR_NONE
;
3403 static enum XML_Error
3404 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3406 if (unknownEncodingHandler
) {
3409 for (i
= 0; i
< 256; i
++)
3411 info
.convert
= NULL
;
3413 info
.release
= NULL
;
3414 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3417 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3418 if (!unknownEncodingMem
) {
3420 info
.release(info
.data
);
3421 return XML_ERROR_NO_MEMORY
;
3424 ? XmlInitUnknownEncodingNS
3425 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3430 unknownEncodingData
= info
.data
;
3431 unknownEncodingRelease
= info
.release
;
3433 return XML_ERROR_NONE
;
3436 if (info
.release
!= NULL
)
3437 info
.release(info
.data
);
3439 return XML_ERROR_UNKNOWN_ENCODING
;
3442 static enum XML_Error PTRCALL
3443 prologInitProcessor(XML_Parser parser
,
3446 const char **nextPtr
)
3448 enum XML_Error result
= initializeEncoding(parser
);
3449 if (result
!= XML_ERROR_NONE
)
3451 processor
= prologProcessor
;
3452 return prologProcessor(parser
, s
, end
, nextPtr
);
3457 static enum XML_Error PTRCALL
3458 externalParEntInitProcessor(XML_Parser parser
,
3461 const char **nextPtr
)
3463 enum XML_Error result
= initializeEncoding(parser
);
3464 if (result
!= XML_ERROR_NONE
)
3467 /* we know now that XML_Parse(Buffer) has been called,
3468 so we consider the external parameter entity read */
3469 _dtd
->paramEntityRead
= XML_TRUE
;
3471 if (prologState
.inEntityValue
) {
3472 processor
= entityValueInitProcessor
;
3473 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3476 processor
= externalParEntProcessor
;
3477 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3481 static enum XML_Error PTRCALL
3482 entityValueInitProcessor(XML_Parser parser
,
3485 const char **nextPtr
)
3488 const char *start
= s
;
3489 const char *next
= start
;
3493 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3496 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3498 return XML_ERROR_NONE
;
3501 case XML_TOK_INVALID
:
3502 return XML_ERROR_INVALID_TOKEN
;
3503 case XML_TOK_PARTIAL
:
3504 return XML_ERROR_UNCLOSED_TOKEN
;
3505 case XML_TOK_PARTIAL_CHAR
:
3506 return XML_ERROR_PARTIAL_CHAR
;
3507 case XML_TOK_NONE
: /* start == end */
3511 /* found end of entity value - can store it now */
3512 return storeEntityValue(parser
, encoding
, s
, end
);
3514 else if (tok
== XML_TOK_XML_DECL
) {
3515 enum XML_Error result
;
3516 result
= processXmlDecl(parser
, 0, start
, next
);
3517 if (result
!= XML_ERROR_NONE
)
3519 switch (ps_parsing
) {
3522 return XML_ERROR_NONE
;
3524 return XML_ERROR_ABORTED
;
3528 /* stop scanning for text declaration - we found one */
3529 processor
= entityValueProcessor
;
3530 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3532 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3533 return XML_TOK_NONE on the next call, which would then cause the
3534 function to exit with *nextPtr set to s - that is what we want for other
3535 tokens, but not for the BOM - we would rather like to skip it;
3536 then, when this routine is entered the next time, XmlPrologTok will
3537 return XML_TOK_INVALID, since the BOM is still in the buffer
3539 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3541 return XML_ERROR_NONE
;
3548 static enum XML_Error PTRCALL
3549 externalParEntProcessor(XML_Parser parser
,
3552 const char **nextPtr
)
3554 const char *next
= s
;
3557 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3559 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3561 return XML_ERROR_NONE
;
3564 case XML_TOK_INVALID
:
3565 return XML_ERROR_INVALID_TOKEN
;
3566 case XML_TOK_PARTIAL
:
3567 return XML_ERROR_UNCLOSED_TOKEN
;
3568 case XML_TOK_PARTIAL_CHAR
:
3569 return XML_ERROR_PARTIAL_CHAR
;
3570 case XML_TOK_NONE
: /* start == end */
3575 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3576 However, when parsing an external subset, doProlog will not accept a BOM
3577 as valid, and report a syntax error, so we have to skip the BOM
3579 else if (tok
== XML_TOK_BOM
) {
3581 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3584 processor
= prologProcessor
;
3585 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3586 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3589 static enum XML_Error PTRCALL
3590 entityValueProcessor(XML_Parser parser
,
3593 const char **nextPtr
)
3595 const char *start
= s
;
3596 const char *next
= s
;
3597 const ENCODING
*enc
= encoding
;
3601 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3603 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3605 return XML_ERROR_NONE
;
3608 case XML_TOK_INVALID
:
3609 return XML_ERROR_INVALID_TOKEN
;
3610 case XML_TOK_PARTIAL
:
3611 return XML_ERROR_UNCLOSED_TOKEN
;
3612 case XML_TOK_PARTIAL_CHAR
:
3613 return XML_ERROR_PARTIAL_CHAR
;
3614 case XML_TOK_NONE
: /* start == end */
3618 /* found end of entity value - can store it now */
3619 return storeEntityValue(parser
, enc
, s
, end
);
3625 #endif /* XML_DTD */
3627 static enum XML_Error PTRCALL
3628 prologProcessor(XML_Parser parser
,
3631 const char **nextPtr
)
3633 const char *next
= s
;
3634 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3635 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3636 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3639 static enum XML_Error
3640 doProlog(XML_Parser parser
,
3641 const ENCODING
*enc
,
3646 const char **nextPtr
,
3650 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3651 #endif /* XML_DTD */
3652 static const XML_Char atypeCDATA
[] =
3653 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3654 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3655 static const XML_Char atypeIDREF
[] =
3656 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3657 static const XML_Char atypeIDREFS
[] =
3658 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3659 static const XML_Char atypeENTITY
[] =
3660 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3661 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3662 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3663 static const XML_Char atypeNMTOKEN
[] = {
3664 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3665 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3666 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3667 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3668 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3669 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3670 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3672 /* save one level of indirection */
3673 DTD
* const dtd
= _dtd
;
3675 const char **eventPP
;
3676 const char **eventEndPP
;
3677 enum XML_Content_Quant quant
;
3679 if (enc
== encoding
) {
3680 eventPP
= &eventPtr
;
3681 eventEndPP
= &eventEndPtr
;
3684 eventPP
= &(openInternalEntities
->internalEventPtr
);
3685 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3690 XML_Bool handleDefault
= XML_TRUE
;
3694 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3696 return XML_ERROR_NONE
;
3699 case XML_TOK_INVALID
:
3701 return XML_ERROR_INVALID_TOKEN
;
3702 case XML_TOK_PARTIAL
:
3703 return XML_ERROR_UNCLOSED_TOKEN
;
3704 case XML_TOK_PARTIAL_CHAR
:
3705 return XML_ERROR_PARTIAL_CHAR
;
3708 /* for internal PE NOT referenced between declarations */
3709 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3711 return XML_ERROR_NONE
;
3713 /* WFC: PE Between Declarations - must check that PE contains
3714 complete markup, not only for external PEs, but also for
3715 internal PEs if the reference occurs between declarations.
3717 if (isParamEntity
|| enc
!= encoding
) {
3718 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3720 return XML_ERROR_INCOMPLETE_PE
;
3722 return XML_ERROR_NONE
;
3724 #endif /* XML_DTD */
3725 return XML_ERROR_NO_ELEMENTS
;
3732 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3734 case XML_ROLE_XML_DECL
:
3736 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3737 if (result
!= XML_ERROR_NONE
)
3740 handleDefault
= XML_FALSE
;
3743 case XML_ROLE_DOCTYPE_NAME
:
3744 if (startDoctypeDeclHandler
) {
3745 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3747 return XML_ERROR_NO_MEMORY
;
3748 poolFinish(&tempPool
);
3749 doctypePubid
= NULL
;
3750 handleDefault
= XML_FALSE
;
3752 doctypeSysid
= NULL
; /* always initialize to NULL */
3754 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3755 if (startDoctypeDeclHandler
) {
3756 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3759 poolClear(&tempPool
);
3760 handleDefault
= XML_FALSE
;
3764 case XML_ROLE_TEXT_DECL
:
3766 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3767 if (result
!= XML_ERROR_NONE
)
3770 handleDefault
= XML_FALSE
;
3773 #endif /* XML_DTD */
3774 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3776 useForeignDTD
= XML_FALSE
;
3777 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3781 return XML_ERROR_NO_MEMORY
;
3782 #endif /* XML_DTD */
3783 dtd
->hasParamEntityRefs
= XML_TRUE
;
3784 if (startDoctypeDeclHandler
) {
3786 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3787 return XML_ERROR_PUBLICID
;
3788 pubId
= poolStoreString(&tempPool
, enc
,
3789 s
+ enc
->minBytesPerChar
,
3790 next
- enc
->minBytesPerChar
);
3792 return XML_ERROR_NO_MEMORY
;
3793 normalizePublicId(pubId
);
3794 poolFinish(&tempPool
);
3795 doctypePubid
= pubId
;
3796 handleDefault
= XML_FALSE
;
3797 goto alreadyChecked
;
3800 case XML_ROLE_ENTITY_PUBLIC_ID
:
3801 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3802 return XML_ERROR_PUBLICID
;
3804 if (dtd
->keepProcessing
&& declEntity
) {
3805 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3807 s
+ enc
->minBytesPerChar
,
3808 next
- enc
->minBytesPerChar
);
3810 return XML_ERROR_NO_MEMORY
;
3811 normalizePublicId(tem
);
3812 declEntity
->publicId
= tem
;
3813 poolFinish(&dtd
->pool
);
3814 if (entityDeclHandler
)
3815 handleDefault
= XML_FALSE
;
3818 case XML_ROLE_DOCTYPE_CLOSE
:
3820 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3821 doctypeSysid
, doctypePubid
, 0);
3822 poolClear(&tempPool
);
3823 handleDefault
= XML_FALSE
;
3825 /* doctypeSysid will be non-NULL in the case of a previous
3826 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3827 was not set, indicating an external subset
3830 if (doctypeSysid
|| useForeignDTD
) {
3831 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3832 dtd
->hasParamEntityRefs
= XML_TRUE
;
3833 if (paramEntityParsing
&& externalEntityRefHandler
) {
3834 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3838 return XML_ERROR_NO_MEMORY
;
3840 entity
->base
= curBase
;
3841 dtd
->paramEntityRead
= XML_FALSE
;
3842 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3847 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3848 if (dtd
->paramEntityRead
) {
3849 if (!dtd
->standalone
&&
3850 notStandaloneHandler
&&
3851 !notStandaloneHandler(handlerArg
))
3852 return XML_ERROR_NOT_STANDALONE
;
3854 /* if we didn't read the foreign DTD then this means that there
3855 is no external subset and we must reset dtd->hasParamEntityRefs
3857 else if (!doctypeSysid
)
3858 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3859 /* end of DTD - no need to update dtd->keepProcessing */
3861 useForeignDTD
= XML_FALSE
;
3863 #endif /* XML_DTD */
3864 if (endDoctypeDeclHandler
) {
3865 endDoctypeDeclHandler(handlerArg
);
3866 handleDefault
= XML_FALSE
;
3869 case XML_ROLE_INSTANCE_START
:
3871 /* if there is no DOCTYPE declaration then now is the
3872 last chance to read the foreign DTD
3874 if (useForeignDTD
) {
3875 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3876 dtd
->hasParamEntityRefs
= XML_TRUE
;
3877 if (paramEntityParsing
&& externalEntityRefHandler
) {
3878 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3882 return XML_ERROR_NO_MEMORY
;
3883 entity
->base
= curBase
;
3884 dtd
->paramEntityRead
= XML_FALSE
;
3885 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3890 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3891 if (dtd
->paramEntityRead
) {
3892 if (!dtd
->standalone
&&
3893 notStandaloneHandler
&&
3894 !notStandaloneHandler(handlerArg
))
3895 return XML_ERROR_NOT_STANDALONE
;
3897 /* if we didn't read the foreign DTD then this means that there
3898 is no external subset and we must reset dtd->hasParamEntityRefs
3901 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3902 /* end of DTD - no need to update dtd->keepProcessing */
3905 #endif /* XML_DTD */
3906 processor
= contentProcessor
;
3907 return contentProcessor(parser
, s
, end
, nextPtr
);
3908 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3909 declElementType
= getElementType(parser
, enc
, s
, next
);
3910 if (!declElementType
)
3911 return XML_ERROR_NO_MEMORY
;
3912 goto checkAttListDeclHandler
;
3913 case XML_ROLE_ATTRIBUTE_NAME
:
3914 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3915 if (!declAttributeId
)
3916 return XML_ERROR_NO_MEMORY
;
3917 declAttributeIsCdata
= XML_FALSE
;
3918 declAttributeType
= NULL
;
3919 declAttributeIsId
= XML_FALSE
;
3920 goto checkAttListDeclHandler
;
3921 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3922 declAttributeIsCdata
= XML_TRUE
;
3923 declAttributeType
= atypeCDATA
;
3924 goto checkAttListDeclHandler
;
3925 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3926 declAttributeIsId
= XML_TRUE
;
3927 declAttributeType
= atypeID
;
3928 goto checkAttListDeclHandler
;
3929 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3930 declAttributeType
= atypeIDREF
;
3931 goto checkAttListDeclHandler
;
3932 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3933 declAttributeType
= atypeIDREFS
;
3934 goto checkAttListDeclHandler
;
3935 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3936 declAttributeType
= atypeENTITY
;
3937 goto checkAttListDeclHandler
;
3938 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3939 declAttributeType
= atypeENTITIES
;
3940 goto checkAttListDeclHandler
;
3941 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3942 declAttributeType
= atypeNMTOKEN
;
3943 goto checkAttListDeclHandler
;
3944 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3945 declAttributeType
= atypeNMTOKENS
;
3946 checkAttListDeclHandler
:
3947 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3948 handleDefault
= XML_FALSE
;
3950 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3951 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3952 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3953 const XML_Char
*prefix
;
3954 if (declAttributeType
) {
3955 prefix
= enumValueSep
;
3958 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3962 if (!poolAppendString(&tempPool
, prefix
))
3963 return XML_ERROR_NO_MEMORY
;
3964 if (!poolAppend(&tempPool
, enc
, s
, next
))
3965 return XML_ERROR_NO_MEMORY
;
3966 declAttributeType
= tempPool
.start
;
3967 handleDefault
= XML_FALSE
;
3970 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3971 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3972 if (dtd
->keepProcessing
) {
3973 if (!defineAttribute(declElementType
, declAttributeId
,
3974 declAttributeIsCdata
, declAttributeIsId
,
3976 return XML_ERROR_NO_MEMORY
;
3977 if (attlistDeclHandler
&& declAttributeType
) {
3978 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
3979 || (*declAttributeType
== XML_T(ASCII_N
)
3980 && declAttributeType
[1] == XML_T(ASCII_O
))) {
3981 /* Enumerated or Notation type */
3982 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
3983 || !poolAppendChar(&tempPool
, XML_T('\0')))
3984 return XML_ERROR_NO_MEMORY
;
3985 declAttributeType
= tempPool
.start
;
3986 poolFinish(&tempPool
);
3989 attlistDeclHandler(handlerArg
, declElementType
->name
,
3990 declAttributeId
->name
, declAttributeType
,
3991 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3992 poolClear(&tempPool
);
3993 handleDefault
= XML_FALSE
;
3997 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3998 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3999 if (dtd
->keepProcessing
) {
4000 const XML_Char
*attVal
;
4001 enum XML_Error result
=
4002 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4003 s
+ enc
->minBytesPerChar
,
4004 next
- enc
->minBytesPerChar
,
4008 attVal
= poolStart(&dtd
->pool
);
4009 poolFinish(&dtd
->pool
);
4010 /* ID attributes aren't allowed to have a default */
4011 if (!defineAttribute(declElementType
, declAttributeId
,
4012 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4013 return XML_ERROR_NO_MEMORY
;
4014 if (attlistDeclHandler
&& declAttributeType
) {
4015 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4016 || (*declAttributeType
== XML_T(ASCII_N
)
4017 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4018 /* Enumerated or Notation type */
4019 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4020 || !poolAppendChar(&tempPool
, XML_T('\0')))
4021 return XML_ERROR_NO_MEMORY
;
4022 declAttributeType
= tempPool
.start
;
4023 poolFinish(&tempPool
);
4026 attlistDeclHandler(handlerArg
, declElementType
->name
,
4027 declAttributeId
->name
, declAttributeType
,
4029 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4030 poolClear(&tempPool
);
4031 handleDefault
= XML_FALSE
;
4035 case XML_ROLE_ENTITY_VALUE
:
4036 if (dtd
->keepProcessing
) {
4037 enum XML_Error result
= storeEntityValue(parser
, enc
,
4038 s
+ enc
->minBytesPerChar
,
4039 next
- enc
->minBytesPerChar
);
4041 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4042 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4043 poolFinish(&dtd
->entityValuePool
);
4044 if (entityDeclHandler
) {
4046 entityDeclHandler(handlerArg
,
4048 declEntity
->is_param
,
4049 declEntity
->textPtr
,
4050 declEntity
->textLen
,
4052 handleDefault
= XML_FALSE
;
4056 poolDiscard(&dtd
->entityValuePool
);
4057 if (result
!= XML_ERROR_NONE
)
4061 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4063 useForeignDTD
= XML_FALSE
;
4064 #endif /* XML_DTD */
4065 dtd
->hasParamEntityRefs
= XML_TRUE
;
4066 if (startDoctypeDeclHandler
) {
4067 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4068 s
+ enc
->minBytesPerChar
,
4069 next
- enc
->minBytesPerChar
);
4070 if (doctypeSysid
== NULL
)
4071 return XML_ERROR_NO_MEMORY
;
4072 poolFinish(&tempPool
);
4073 handleDefault
= XML_FALSE
;
4077 /* use externalSubsetName to make doctypeSysid non-NULL
4078 for the case where no startDoctypeDeclHandler is set */
4079 doctypeSysid
= externalSubsetName
;
4080 #endif /* XML_DTD */
4081 if (!dtd
->standalone
4083 && !paramEntityParsing
4084 #endif /* XML_DTD */
4085 && notStandaloneHandler
4086 && !notStandaloneHandler(handlerArg
))
4087 return XML_ERROR_NOT_STANDALONE
;
4092 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4096 return XML_ERROR_NO_MEMORY
;
4097 declEntity
->publicId
= NULL
;
4100 #endif /* XML_DTD */
4101 case XML_ROLE_ENTITY_SYSTEM_ID
:
4102 if (dtd
->keepProcessing
&& declEntity
) {
4103 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4104 s
+ enc
->minBytesPerChar
,
4105 next
- enc
->minBytesPerChar
);
4106 if (!declEntity
->systemId
)
4107 return XML_ERROR_NO_MEMORY
;
4108 declEntity
->base
= curBase
;
4109 poolFinish(&dtd
->pool
);
4110 if (entityDeclHandler
)
4111 handleDefault
= XML_FALSE
;
4114 case XML_ROLE_ENTITY_COMPLETE
:
4115 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4117 entityDeclHandler(handlerArg
,
4119 declEntity
->is_param
,
4122 declEntity
->systemId
,
4123 declEntity
->publicId
,
4125 handleDefault
= XML_FALSE
;
4128 case XML_ROLE_ENTITY_NOTATION_NAME
:
4129 if (dtd
->keepProcessing
&& declEntity
) {
4130 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4131 if (!declEntity
->notation
)
4132 return XML_ERROR_NO_MEMORY
;
4133 poolFinish(&dtd
->pool
);
4134 if (unparsedEntityDeclHandler
) {
4136 unparsedEntityDeclHandler(handlerArg
,
4139 declEntity
->systemId
,
4140 declEntity
->publicId
,
4141 declEntity
->notation
);
4142 handleDefault
= XML_FALSE
;
4144 else if (entityDeclHandler
) {
4146 entityDeclHandler(handlerArg
,
4150 declEntity
->systemId
,
4151 declEntity
->publicId
,
4152 declEntity
->notation
);
4153 handleDefault
= XML_FALSE
;
4157 case XML_ROLE_GENERAL_ENTITY_NAME
:
4159 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4163 if (dtd
->keepProcessing
) {
4164 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4166 return XML_ERROR_NO_MEMORY
;
4167 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4170 return XML_ERROR_NO_MEMORY
;
4171 if (declEntity
->name
!= name
) {
4172 poolDiscard(&dtd
->pool
);
4176 poolFinish(&dtd
->pool
);
4177 declEntity
->publicId
= NULL
;
4178 declEntity
->is_param
= XML_FALSE
;
4179 /* if we have a parent parser or are reading an internal parameter
4180 entity, then the entity declaration is not considered "internal"
4182 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4183 if (entityDeclHandler
)
4184 handleDefault
= XML_FALSE
;
4188 poolDiscard(&dtd
->pool
);
4193 case XML_ROLE_PARAM_ENTITY_NAME
:
4195 if (dtd
->keepProcessing
) {
4196 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4198 return XML_ERROR_NO_MEMORY
;
4199 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4200 name
, sizeof(ENTITY
));
4202 return XML_ERROR_NO_MEMORY
;
4203 if (declEntity
->name
!= name
) {
4204 poolDiscard(&dtd
->pool
);
4208 poolFinish(&dtd
->pool
);
4209 declEntity
->publicId
= NULL
;
4210 declEntity
->is_param
= XML_TRUE
;
4211 /* if we have a parent parser or are reading an internal parameter
4212 entity, then the entity declaration is not considered "internal"
4214 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4215 if (entityDeclHandler
)
4216 handleDefault
= XML_FALSE
;
4220 poolDiscard(&dtd
->pool
);
4223 #else /* not XML_DTD */
4225 #endif /* XML_DTD */
4227 case XML_ROLE_NOTATION_NAME
:
4228 declNotationPublicId
= NULL
;
4229 declNotationName
= NULL
;
4230 if (notationDeclHandler
) {
4231 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4232 if (!declNotationName
)
4233 return XML_ERROR_NO_MEMORY
;
4234 poolFinish(&tempPool
);
4235 handleDefault
= XML_FALSE
;
4238 case XML_ROLE_NOTATION_PUBLIC_ID
:
4239 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4240 return XML_ERROR_PUBLICID
;
4241 if (declNotationName
) { /* means notationDeclHandler != NULL */
4242 XML_Char
*tem
= poolStoreString(&tempPool
,
4244 s
+ enc
->minBytesPerChar
,
4245 next
- enc
->minBytesPerChar
);
4247 return XML_ERROR_NO_MEMORY
;
4248 normalizePublicId(tem
);
4249 declNotationPublicId
= tem
;
4250 poolFinish(&tempPool
);
4251 handleDefault
= XML_FALSE
;
4254 case XML_ROLE_NOTATION_SYSTEM_ID
:
4255 if (declNotationName
&& notationDeclHandler
) {
4256 const XML_Char
*systemId
4257 = poolStoreString(&tempPool
, enc
,
4258 s
+ enc
->minBytesPerChar
,
4259 next
- enc
->minBytesPerChar
);
4261 return XML_ERROR_NO_MEMORY
;
4263 notationDeclHandler(handlerArg
,
4267 declNotationPublicId
);
4268 handleDefault
= XML_FALSE
;
4270 poolClear(&tempPool
);
4272 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4273 if (declNotationPublicId
&& notationDeclHandler
) {
4275 notationDeclHandler(handlerArg
,
4279 declNotationPublicId
);
4280 handleDefault
= XML_FALSE
;
4282 poolClear(&tempPool
);
4284 case XML_ROLE_ERROR
:
4286 case XML_TOK_PARAM_ENTITY_REF
:
4287 /* PE references in internal subset are
4288 not allowed within declarations. */
4289 return XML_ERROR_PARAM_ENTITY_REF
;
4290 case XML_TOK_XML_DECL
:
4291 return XML_ERROR_MISPLACED_XML_PI
;
4293 return XML_ERROR_SYNTAX
;
4296 case XML_ROLE_IGNORE_SECT
:
4298 enum XML_Error result
;
4300 reportDefault(parser
, enc
, s
, next
);
4301 handleDefault
= XML_FALSE
;
4302 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4303 if (result
!= XML_ERROR_NONE
)
4306 processor
= ignoreSectionProcessor
;
4311 #endif /* XML_DTD */
4312 case XML_ROLE_GROUP_OPEN
:
4313 if (prologState
.level
>= groupSize
) {
4315 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4317 return XML_ERROR_NO_MEMORY
;
4318 groupConnector
= temp
;
4319 if (dtd
->scaffIndex
) {
4320 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4321 groupSize
* sizeof(int));
4323 return XML_ERROR_NO_MEMORY
;
4324 dtd
->scaffIndex
= temp
;
4328 groupConnector
= (char *)MALLOC(groupSize
= 32);
4329 if (!groupConnector
)
4330 return XML_ERROR_NO_MEMORY
;
4333 groupConnector
[prologState
.level
] = 0;
4334 if (dtd
->in_eldecl
) {
4335 int myindex
= nextScaffoldPart(parser
);
4337 return XML_ERROR_NO_MEMORY
;
4338 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4340 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4341 if (elementDeclHandler
)
4342 handleDefault
= XML_FALSE
;
4345 case XML_ROLE_GROUP_SEQUENCE
:
4346 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4347 return XML_ERROR_SYNTAX
;
4348 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4349 if (dtd
->in_eldecl
&& elementDeclHandler
)
4350 handleDefault
= XML_FALSE
;
4352 case XML_ROLE_GROUP_CHOICE
:
4353 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4354 return XML_ERROR_SYNTAX
;
4356 && !groupConnector
[prologState
.level
]
4357 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4360 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4362 if (elementDeclHandler
)
4363 handleDefault
= XML_FALSE
;
4365 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4367 case XML_ROLE_PARAM_ENTITY_REF
:
4369 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4370 dtd
->hasParamEntityRefs
= XML_TRUE
;
4371 if (!paramEntityParsing
)
4372 dtd
->keepProcessing
= dtd
->standalone
;
4374 const XML_Char
*name
;
4376 name
= poolStoreString(&dtd
->pool
, enc
,
4377 s
+ enc
->minBytesPerChar
,
4378 next
- enc
->minBytesPerChar
);
4380 return XML_ERROR_NO_MEMORY
;
4381 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4382 poolDiscard(&dtd
->pool
);
4383 /* first, determine if a check for an existing declaration is needed;
4384 if yes, check that the entity exists, and that it is internal,
4385 otherwise call the skipped entity handler
4387 if (prologState
.documentEntity
&&
4389 ? !openInternalEntities
4390 : !dtd
->hasParamEntityRefs
)) {
4392 return XML_ERROR_UNDEFINED_ENTITY
;
4393 else if (!entity
->is_internal
)
4394 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4397 dtd
->keepProcessing
= dtd
->standalone
;
4398 /* cannot report skipped entities in declarations */
4399 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4400 skippedEntityHandler(handlerArg
, name
, 1);
4401 handleDefault
= XML_FALSE
;
4406 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4407 if (entity
->textPtr
) {
4408 enum XML_Error result
;
4409 XML_Bool betweenDecl
=
4410 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4411 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4412 if (result
!= XML_ERROR_NONE
)
4414 handleDefault
= XML_FALSE
;
4417 if (externalEntityRefHandler
) {
4418 dtd
->paramEntityRead
= XML_FALSE
;
4419 entity
->open
= XML_TRUE
;
4420 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4424 entity
->publicId
)) {
4425 entity
->open
= XML_FALSE
;
4426 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4428 entity
->open
= XML_FALSE
;
4429 handleDefault
= XML_FALSE
;
4430 if (!dtd
->paramEntityRead
) {
4431 dtd
->keepProcessing
= dtd
->standalone
;
4436 dtd
->keepProcessing
= dtd
->standalone
;
4440 #endif /* XML_DTD */
4441 if (!dtd
->standalone
&&
4442 notStandaloneHandler
&&
4443 !notStandaloneHandler(handlerArg
))
4444 return XML_ERROR_NOT_STANDALONE
;
4447 /* Element declaration stuff */
4449 case XML_ROLE_ELEMENT_NAME
:
4450 if (elementDeclHandler
) {
4451 declElementType
= getElementType(parser
, enc
, s
, next
);
4452 if (!declElementType
)
4453 return XML_ERROR_NO_MEMORY
;
4454 dtd
->scaffLevel
= 0;
4455 dtd
->scaffCount
= 0;
4456 dtd
->in_eldecl
= XML_TRUE
;
4457 handleDefault
= XML_FALSE
;
4461 case XML_ROLE_CONTENT_ANY
:
4462 case XML_ROLE_CONTENT_EMPTY
:
4463 if (dtd
->in_eldecl
) {
4464 if (elementDeclHandler
) {
4465 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4467 return XML_ERROR_NO_MEMORY
;
4468 content
->quant
= XML_CQUANT_NONE
;
4469 content
->name
= NULL
;
4470 content
->numchildren
= 0;
4471 content
->children
= NULL
;
4472 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4476 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4477 handleDefault
= XML_FALSE
;
4479 dtd
->in_eldecl
= XML_FALSE
;
4483 case XML_ROLE_CONTENT_PCDATA
:
4484 if (dtd
->in_eldecl
) {
4485 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4487 if (elementDeclHandler
)
4488 handleDefault
= XML_FALSE
;
4492 case XML_ROLE_CONTENT_ELEMENT
:
4493 quant
= XML_CQUANT_NONE
;
4494 goto elementContent
;
4495 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4496 quant
= XML_CQUANT_OPT
;
4497 goto elementContent
;
4498 case XML_ROLE_CONTENT_ELEMENT_REP
:
4499 quant
= XML_CQUANT_REP
;
4500 goto elementContent
;
4501 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4502 quant
= XML_CQUANT_PLUS
;
4504 if (dtd
->in_eldecl
) {
4506 const XML_Char
*name
;
4508 const char *nxt
= (quant
== XML_CQUANT_NONE
4510 : next
- enc
->minBytesPerChar
);
4511 int myindex
= nextScaffoldPart(parser
);
4513 return XML_ERROR_NO_MEMORY
;
4514 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4515 dtd
->scaffold
[myindex
].quant
= quant
;
4516 el
= getElementType(parser
, enc
, s
, nxt
);
4518 return XML_ERROR_NO_MEMORY
;
4520 dtd
->scaffold
[myindex
].name
= name
;
4522 for (; name
[nameLen
++]; );
4523 dtd
->contentStringLen
+= nameLen
;
4524 if (elementDeclHandler
)
4525 handleDefault
= XML_FALSE
;
4529 case XML_ROLE_GROUP_CLOSE
:
4530 quant
= XML_CQUANT_NONE
;
4532 case XML_ROLE_GROUP_CLOSE_OPT
:
4533 quant
= XML_CQUANT_OPT
;
4535 case XML_ROLE_GROUP_CLOSE_REP
:
4536 quant
= XML_CQUANT_REP
;
4538 case XML_ROLE_GROUP_CLOSE_PLUS
:
4539 quant
= XML_CQUANT_PLUS
;
4541 if (dtd
->in_eldecl
) {
4542 if (elementDeclHandler
)
4543 handleDefault
= XML_FALSE
;
4545 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4546 if (dtd
->scaffLevel
== 0) {
4547 if (!handleDefault
) {
4548 XML_Content
*model
= build_model(parser
);
4550 return XML_ERROR_NO_MEMORY
;
4552 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4554 dtd
->in_eldecl
= XML_FALSE
;
4555 dtd
->contentStringLen
= 0;
4559 /* End element declaration stuff */
4562 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4563 return XML_ERROR_NO_MEMORY
;
4564 handleDefault
= XML_FALSE
;
4566 case XML_ROLE_COMMENT
:
4567 if (!reportComment(parser
, enc
, s
, next
))
4568 return XML_ERROR_NO_MEMORY
;
4569 handleDefault
= XML_FALSE
;
4574 handleDefault
= XML_FALSE
;
4578 case XML_ROLE_DOCTYPE_NONE
:
4579 if (startDoctypeDeclHandler
)
4580 handleDefault
= XML_FALSE
;
4582 case XML_ROLE_ENTITY_NONE
:
4583 if (dtd
->keepProcessing
&& entityDeclHandler
)
4584 handleDefault
= XML_FALSE
;
4586 case XML_ROLE_NOTATION_NONE
:
4587 if (notationDeclHandler
)
4588 handleDefault
= XML_FALSE
;
4590 case XML_ROLE_ATTLIST_NONE
:
4591 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4592 handleDefault
= XML_FALSE
;
4594 case XML_ROLE_ELEMENT_NONE
:
4595 if (elementDeclHandler
)
4596 handleDefault
= XML_FALSE
;
4598 } /* end of big switch */
4600 if (handleDefault
&& defaultHandler
)
4601 reportDefault(parser
, enc
, s
, next
);
4603 switch (ps_parsing
) {
4606 return XML_ERROR_NONE
;
4608 return XML_ERROR_ABORTED
;
4611 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4617 static enum XML_Error PTRCALL
4618 epilogProcessor(XML_Parser parser
,
4621 const char **nextPtr
)
4623 processor
= epilogProcessor
;
4626 const char *next
= NULL
;
4627 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4630 /* report partial linebreak - it might be the last token */
4631 case -XML_TOK_PROLOG_S
:
4632 if (defaultHandler
) {
4633 reportDefault(parser
, encoding
, s
, next
);
4634 if (ps_parsing
== XML_FINISHED
)
4635 return XML_ERROR_ABORTED
;
4638 return XML_ERROR_NONE
;
4641 return XML_ERROR_NONE
;
4642 case XML_TOK_PROLOG_S
:
4644 reportDefault(parser
, encoding
, s
, next
);
4647 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4648 return XML_ERROR_NO_MEMORY
;
4650 case XML_TOK_COMMENT
:
4651 if (!reportComment(parser
, encoding
, s
, next
))
4652 return XML_ERROR_NO_MEMORY
;
4654 case XML_TOK_INVALID
:
4656 return XML_ERROR_INVALID_TOKEN
;
4657 case XML_TOK_PARTIAL
:
4658 if (!ps_finalBuffer
) {
4660 return XML_ERROR_NONE
;
4662 return XML_ERROR_UNCLOSED_TOKEN
;
4663 case XML_TOK_PARTIAL_CHAR
:
4664 if (!ps_finalBuffer
) {
4666 return XML_ERROR_NONE
;
4668 return XML_ERROR_PARTIAL_CHAR
;
4670 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4672 eventPtr
= s
= next
;
4673 switch (ps_parsing
) {
4676 return XML_ERROR_NONE
;
4678 return XML_ERROR_ABORTED
;
4684 static enum XML_Error
4685 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4686 XML_Bool betweenDecl
)
4688 const char *textStart
, *textEnd
;
4690 enum XML_Error result
;
4691 OPEN_INTERNAL_ENTITY
*openEntity
;
4693 if (freeInternalEntities
) {
4694 openEntity
= freeInternalEntities
;
4695 freeInternalEntities
= openEntity
->next
;
4698 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4700 return XML_ERROR_NO_MEMORY
;
4702 entity
->open
= XML_TRUE
;
4703 entity
->processed
= 0;
4704 openEntity
->next
= openInternalEntities
;
4705 openInternalEntities
= openEntity
;
4706 openEntity
->entity
= entity
;
4707 openEntity
->startTagLevel
= tagLevel
;
4708 openEntity
->betweenDecl
= betweenDecl
;
4709 openEntity
->internalEventPtr
= NULL
;
4710 openEntity
->internalEventEndPtr
= NULL
;
4711 textStart
= (char *)entity
->textPtr
;
4712 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4715 if (entity
->is_param
) {
4716 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4717 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4718 next
, &next
, XML_FALSE
);
4721 #endif /* XML_DTD */
4722 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4723 textEnd
, &next
, XML_FALSE
);
4725 if (result
== XML_ERROR_NONE
) {
4726 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4727 entity
->processed
= (int)(next
- textStart
);
4728 processor
= internalEntityProcessor
;
4731 entity
->open
= XML_FALSE
;
4732 openInternalEntities
= openEntity
->next
;
4733 /* put openEntity back in list of free instances */
4734 openEntity
->next
= freeInternalEntities
;
4735 freeInternalEntities
= openEntity
;
4741 static enum XML_Error PTRCALL
4742 internalEntityProcessor(XML_Parser parser
,
4745 const char **nextPtr
)
4748 const char *textStart
, *textEnd
;
4750 enum XML_Error result
;
4751 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4753 return XML_ERROR_UNEXPECTED_STATE
;
4755 entity
= openEntity
->entity
;
4756 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4757 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4760 if (entity
->is_param
) {
4761 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4762 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4763 next
, &next
, XML_FALSE
);
4766 #endif /* XML_DTD */
4767 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4768 textStart
, textEnd
, &next
, XML_FALSE
);
4770 if (result
!= XML_ERROR_NONE
)
4772 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4773 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4777 entity
->open
= XML_FALSE
;
4778 openInternalEntities
= openEntity
->next
;
4779 /* put openEntity back in list of free instances */
4780 openEntity
->next
= freeInternalEntities
;
4781 freeInternalEntities
= openEntity
;
4785 if (entity
->is_param
) {
4787 processor
= prologProcessor
;
4788 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4789 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4790 (XML_Bool
)!ps_finalBuffer
);
4793 #endif /* XML_DTD */
4795 processor
= contentProcessor
;
4796 /* see externalEntityContentProcessor vs contentProcessor */
4797 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4798 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4802 static enum XML_Error PTRCALL
4803 errorProcessor(XML_Parser parser
,
4806 const char **nextPtr
)
4811 static enum XML_Error
4812 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4813 const char *ptr
, const char *end
,
4816 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4820 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4822 if (!poolAppendChar(pool
, XML_T('\0')))
4823 return XML_ERROR_NO_MEMORY
;
4824 return XML_ERROR_NONE
;
4827 static enum XML_Error
4828 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4829 const char *ptr
, const char *end
,
4832 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4835 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4838 return XML_ERROR_NONE
;
4839 case XML_TOK_INVALID
:
4840 if (enc
== encoding
)
4842 return XML_ERROR_INVALID_TOKEN
;
4843 case XML_TOK_PARTIAL
:
4844 if (enc
== encoding
)
4846 return XML_ERROR_INVALID_TOKEN
;
4847 case XML_TOK_CHAR_REF
:
4849 XML_Char buf
[XML_ENCODE_MAX
];
4851 int n
= XmlCharRefNumber(enc
, ptr
);
4853 if (enc
== encoding
)
4855 return XML_ERROR_BAD_CHAR_REF
;
4858 && n
== 0x20 /* space */
4859 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4861 n
= XmlEncode(n
, (ICHAR
*)buf
);
4863 if (enc
== encoding
)
4865 return XML_ERROR_BAD_CHAR_REF
;
4867 for (i
= 0; i
< n
; i
++) {
4868 if (!poolAppendChar(pool
, buf
[i
]))
4869 return XML_ERROR_NO_MEMORY
;
4873 case XML_TOK_DATA_CHARS
:
4874 if (!poolAppend(pool
, enc
, ptr
, next
))
4875 return XML_ERROR_NO_MEMORY
;
4877 case XML_TOK_TRAILING_CR
:
4878 next
= ptr
+ enc
->minBytesPerChar
;
4880 case XML_TOK_ATTRIBUTE_VALUE_S
:
4881 case XML_TOK_DATA_NEWLINE
:
4882 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4884 if (!poolAppendChar(pool
, 0x20))
4885 return XML_ERROR_NO_MEMORY
;
4887 case XML_TOK_ENTITY_REF
:
4889 const XML_Char
*name
;
4891 char checkEntityDecl
;
4892 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4893 ptr
+ enc
->minBytesPerChar
,
4894 next
- enc
->minBytesPerChar
);
4896 if (!poolAppendChar(pool
, ch
))
4897 return XML_ERROR_NO_MEMORY
;
4900 name
= poolStoreString(&temp2Pool
, enc
,
4901 ptr
+ enc
->minBytesPerChar
,
4902 next
- enc
->minBytesPerChar
);
4904 return XML_ERROR_NO_MEMORY
;
4905 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4906 poolDiscard(&temp2Pool
);
4907 /* First, determine if a check for an existing declaration is needed;
4908 if yes, check that the entity exists, and that it is internal.
4910 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4913 prologState
.documentEntity
&&
4914 #endif /* XML_DTD */
4916 ? !openInternalEntities
4917 : !dtd
->hasParamEntityRefs
);
4918 else /* if (pool == &tempPool): we are called from content */
4919 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4920 if (checkEntityDecl
) {
4922 return XML_ERROR_UNDEFINED_ENTITY
;
4923 else if (!entity
->is_internal
)
4924 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4927 /* Cannot report skipped entity here - see comments on
4928 skippedEntityHandler.
4929 if (skippedEntityHandler)
4930 skippedEntityHandler(handlerArg, name, 0);
4932 /* Cannot call the default handler because this would be
4933 out of sync with the call to the startElementHandler.
4934 if ((pool == &tempPool) && defaultHandler)
4935 reportDefault(parser, enc, ptr, next);
4940 if (enc
== encoding
)
4942 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4944 if (entity
->notation
) {
4945 if (enc
== encoding
)
4947 return XML_ERROR_BINARY_ENTITY_REF
;
4949 if (!entity
->textPtr
) {
4950 if (enc
== encoding
)
4952 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4955 enum XML_Error result
;
4956 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4957 entity
->open
= XML_TRUE
;
4958 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4959 (char *)entity
->textPtr
,
4960 (char *)textEnd
, pool
);
4961 entity
->open
= XML_FALSE
;
4968 if (enc
== encoding
)
4970 return XML_ERROR_UNEXPECTED_STATE
;
4977 static enum XML_Error
4978 storeEntityValue(XML_Parser parser
,
4979 const ENCODING
*enc
,
4980 const char *entityTextPtr
,
4981 const char *entityTextEnd
)
4983 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4984 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4985 enum XML_Error result
= XML_ERROR_NONE
;
4987 int oldInEntityValue
= prologState
.inEntityValue
;
4988 prologState
.inEntityValue
= 1;
4989 #endif /* XML_DTD */
4990 /* never return Null for the value argument in EntityDeclHandler,
4991 since this would indicate an external entity; therefore we
4992 have to make sure that entityValuePool.start is not null */
4993 if (!pool
->blocks
) {
4994 if (!poolGrow(pool
))
4995 return XML_ERROR_NO_MEMORY
;
5000 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5002 case XML_TOK_PARAM_ENTITY_REF
:
5004 if (isParamEntity
|| enc
!= encoding
) {
5005 const XML_Char
*name
;
5007 name
= poolStoreString(&tempPool
, enc
,
5008 entityTextPtr
+ enc
->minBytesPerChar
,
5009 next
- enc
->minBytesPerChar
);
5011 result
= XML_ERROR_NO_MEMORY
;
5012 goto endEntityValue
;
5014 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
5015 poolDiscard(&tempPool
);
5017 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5018 /* cannot report skipped entity here - see comments on
5019 skippedEntityHandler
5020 if (skippedEntityHandler)
5021 skippedEntityHandler(handlerArg, name, 0);
5023 dtd
->keepProcessing
= dtd
->standalone
;
5024 goto endEntityValue
;
5027 if (enc
== encoding
)
5028 eventPtr
= entityTextPtr
;
5029 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5030 goto endEntityValue
;
5032 if (entity
->systemId
) {
5033 if (externalEntityRefHandler
) {
5034 dtd
->paramEntityRead
= XML_FALSE
;
5035 entity
->open
= XML_TRUE
;
5036 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5040 entity
->publicId
)) {
5041 entity
->open
= XML_FALSE
;
5042 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5043 goto endEntityValue
;
5045 entity
->open
= XML_FALSE
;
5046 if (!dtd
->paramEntityRead
)
5047 dtd
->keepProcessing
= dtd
->standalone
;
5050 dtd
->keepProcessing
= dtd
->standalone
;
5053 entity
->open
= XML_TRUE
;
5054 result
= storeEntityValue(parser
,
5056 (char *)entity
->textPtr
,
5057 (char *)(entity
->textPtr
5058 + entity
->textLen
));
5059 entity
->open
= XML_FALSE
;
5061 goto endEntityValue
;
5065 #endif /* XML_DTD */
5066 /* In the internal subset, PE references are not legal
5067 within markup declarations, e.g entity values in this case. */
5068 eventPtr
= entityTextPtr
;
5069 result
= XML_ERROR_PARAM_ENTITY_REF
;
5070 goto endEntityValue
;
5072 result
= XML_ERROR_NONE
;
5073 goto endEntityValue
;
5074 case XML_TOK_ENTITY_REF
:
5075 case XML_TOK_DATA_CHARS
:
5076 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5077 result
= XML_ERROR_NO_MEMORY
;
5078 goto endEntityValue
;
5081 case XML_TOK_TRAILING_CR
:
5082 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5084 case XML_TOK_DATA_NEWLINE
:
5085 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5086 result
= XML_ERROR_NO_MEMORY
;
5087 goto endEntityValue
;
5089 *(pool
->ptr
)++ = 0xA;
5091 case XML_TOK_CHAR_REF
:
5093 XML_Char buf
[XML_ENCODE_MAX
];
5095 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5097 if (enc
== encoding
)
5098 eventPtr
= entityTextPtr
;
5099 result
= XML_ERROR_BAD_CHAR_REF
;
5100 goto endEntityValue
;
5102 n
= XmlEncode(n
, (ICHAR
*)buf
);
5104 if (enc
== encoding
)
5105 eventPtr
= entityTextPtr
;
5106 result
= XML_ERROR_BAD_CHAR_REF
;
5107 goto endEntityValue
;
5109 for (i
= 0; i
< n
; i
++) {
5110 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5111 result
= XML_ERROR_NO_MEMORY
;
5112 goto endEntityValue
;
5114 *(pool
->ptr
)++ = buf
[i
];
5118 case XML_TOK_PARTIAL
:
5119 if (enc
== encoding
)
5120 eventPtr
= entityTextPtr
;
5121 result
= XML_ERROR_INVALID_TOKEN
;
5122 goto endEntityValue
;
5123 case XML_TOK_INVALID
:
5124 if (enc
== encoding
)
5126 result
= XML_ERROR_INVALID_TOKEN
;
5127 goto endEntityValue
;
5129 if (enc
== encoding
)
5130 eventPtr
= entityTextPtr
;
5131 result
= XML_ERROR_UNEXPECTED_STATE
;
5132 goto endEntityValue
;
5134 entityTextPtr
= next
;
5138 prologState
.inEntityValue
= oldInEntityValue
;
5139 #endif /* XML_DTD */
5143 static void FASTCALL
5144 normalizeLines(XML_Char
*s
)
5148 if (*s
== XML_T('\0'))
5167 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5168 const char *start
, const char *end
)
5170 const XML_Char
*target
;
5173 if (!processingInstructionHandler
) {
5175 reportDefault(parser
, enc
, start
, end
);
5178 start
+= enc
->minBytesPerChar
* 2;
5179 tem
= start
+ XmlNameLength(enc
, start
);
5180 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5183 poolFinish(&tempPool
);
5184 data
= poolStoreString(&tempPool
, enc
,
5186 end
- enc
->minBytesPerChar
*2);
5189 normalizeLines(data
);
5190 processingInstructionHandler(handlerArg
, target
, data
);
5191 poolClear(&tempPool
);
5196 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5197 const char *start
, const char *end
)
5200 if (!commentHandler
) {
5202 reportDefault(parser
, enc
, start
, end
);
5205 data
= poolStoreString(&tempPool
,
5207 start
+ enc
->minBytesPerChar
* 4,
5208 end
- enc
->minBytesPerChar
* 3);
5211 normalizeLines(data
);
5212 commentHandler(handlerArg
, data
);
5213 poolClear(&tempPool
);
5218 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5219 const char *s
, const char *end
)
5221 if (MUST_CONVERT(enc
, s
)) {
5222 const char **eventPP
;
5223 const char **eventEndPP
;
5224 if (enc
== encoding
) {
5225 eventPP
= &eventPtr
;
5226 eventEndPP
= &eventEndPtr
;
5229 eventPP
= &(openInternalEntities
->internalEventPtr
);
5230 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5233 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5234 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5236 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5241 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5246 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5247 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5249 DEFAULT_ATTRIBUTE
*att
;
5250 if (value
|| isId
) {
5251 /* The handling of default attributes gets messed up if we have
5252 a default which duplicates a non-default. */
5254 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5255 if (attId
== type
->defaultAtts
[i
].id
)
5257 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5258 type
->idAtt
= attId
;
5260 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5261 if (type
->allocDefaultAtts
== 0) {
5262 type
->allocDefaultAtts
= 8;
5263 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5264 * sizeof(DEFAULT_ATTRIBUTE
));
5265 if (!type
->defaultAtts
)
5269 DEFAULT_ATTRIBUTE
*temp
;
5270 int count
= type
->allocDefaultAtts
* 2;
5271 temp
= (DEFAULT_ATTRIBUTE
*)
5272 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5275 type
->allocDefaultAtts
= count
;
5276 type
->defaultAtts
= temp
;
5279 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5282 att
->isCdata
= isCdata
;
5284 attId
->maybeTokenized
= XML_TRUE
;
5285 type
->nDefaultAtts
+= 1;
5290 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5292 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5293 const XML_Char
*name
;
5294 for (name
= elementType
->name
; *name
; name
++) {
5295 if (*name
== XML_T(ASCII_COLON
)) {
5298 for (s
= elementType
->name
; s
!= name
; s
++) {
5299 if (!poolAppendChar(&dtd
->pool
, *s
))
5302 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5304 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5308 if (prefix
->name
== poolStart(&dtd
->pool
))
5309 poolFinish(&dtd
->pool
);
5311 poolDiscard(&dtd
->pool
);
5312 elementType
->prefix
= prefix
;
5319 static ATTRIBUTE_ID
*
5320 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5321 const char *start
, const char *end
)
5323 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5325 const XML_Char
*name
;
5326 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5328 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5331 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5333 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5336 if (id
->name
!= name
)
5337 poolDiscard(&dtd
->pool
);
5339 poolFinish(&dtd
->pool
);
5342 else if (name
[0] == XML_T(ASCII_x
)
5343 && name
[1] == XML_T(ASCII_m
)
5344 && name
[2] == XML_T(ASCII_l
)
5345 && name
[3] == XML_T(ASCII_n
)
5346 && name
[4] == XML_T(ASCII_s
)
5347 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5348 if (name
[5] == XML_T('\0'))
5349 id
->prefix
= &dtd
->defaultPrefix
;
5351 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5352 id
->xmlns
= XML_TRUE
;
5356 for (i
= 0; name
[i
]; i
++) {
5357 /* attributes without prefix are *not* in the default namespace */
5358 if (name
[i
] == XML_T(ASCII_COLON
)) {
5360 for (j
= 0; j
< i
; j
++) {
5361 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5364 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5366 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5368 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5369 poolFinish(&dtd
->pool
);
5371 poolDiscard(&dtd
->pool
);
5380 #define CONTEXT_SEP XML_T(ASCII_FF)
5382 static const XML_Char
*
5383 getContext(XML_Parser parser
)
5385 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5386 HASH_TABLE_ITER iter
;
5387 XML_Bool needSep
= XML_FALSE
;
5389 if (dtd
->defaultPrefix
.binding
) {
5392 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5394 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5395 if (namespaceSeparator
)
5397 for (i
= 0; i
< len
; i
++)
5398 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5403 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5408 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5411 if (!prefix
->binding
)
5413 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5415 for (s
= prefix
->name
; *s
; s
++)
5416 if (!poolAppendChar(&tempPool
, *s
))
5418 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5420 len
= prefix
->binding
->uriLen
;
5421 if (namespaceSeparator
)
5423 for (i
= 0; i
< len
; i
++)
5424 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5430 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5433 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5438 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5440 for (s
= e
->name
; *s
; s
++)
5441 if (!poolAppendChar(&tempPool
, *s
))
5446 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5448 return tempPool
.start
;
5452 setContext(XML_Parser parser
, const XML_Char
*context
)
5454 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5455 const XML_Char
*s
= context
;
5457 while (*context
!= XML_T('\0')) {
5458 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5460 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5462 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5465 if (*s
!= XML_T('\0'))
5468 poolDiscard(&tempPool
);
5470 else if (*s
== XML_T(ASCII_EQUALS
)) {
5472 if (poolLength(&tempPool
) == 0)
5473 prefix
= &dtd
->defaultPrefix
;
5475 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5477 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5481 if (prefix
->name
== poolStart(&tempPool
)) {
5482 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5486 poolDiscard(&tempPool
);
5488 for (context
= s
+ 1;
5489 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5491 if (!poolAppendChar(&tempPool
, *context
))
5493 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5495 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5496 &inheritedBindings
) != XML_ERROR_NONE
)
5498 poolDiscard(&tempPool
);
5499 if (*context
!= XML_T('\0'))
5504 if (!poolAppendChar(&tempPool
, *s
))
5512 static void FASTCALL
5513 normalizePublicId(XML_Char
*publicId
)
5515 XML_Char
*p
= publicId
;
5517 for (s
= publicId
; *s
; s
++) {
5522 if (p
!= publicId
&& p
[-1] != 0x20)
5529 if (p
!= publicId
&& p
[-1] == 0x20)
5535 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5537 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5540 poolInit(&(p
->pool
), ms
);
5541 poolInit(&(p
->entityValuePool
), ms
);
5542 hashTableInit(&(p
->generalEntities
), ms
);
5543 hashTableInit(&(p
->elementTypes
), ms
);
5544 hashTableInit(&(p
->attributeIds
), ms
);
5545 hashTableInit(&(p
->prefixes
), ms
);
5547 p
->paramEntityRead
= XML_FALSE
;
5548 hashTableInit(&(p
->paramEntities
), ms
);
5549 #endif /* XML_DTD */
5550 p
->defaultPrefix
.name
= NULL
;
5551 p
->defaultPrefix
.binding
= NULL
;
5553 p
->in_eldecl
= XML_FALSE
;
5554 p
->scaffIndex
= NULL
;
5559 p
->contentStringLen
= 0;
5561 p
->keepProcessing
= XML_TRUE
;
5562 p
->hasParamEntityRefs
= XML_FALSE
;
5563 p
->standalone
= XML_FALSE
;
5568 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5570 HASH_TABLE_ITER iter
;
5571 hashTableIterInit(&iter
, &(p
->elementTypes
));
5573 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5576 if (e
->allocDefaultAtts
!= 0)
5577 ms
->free_fcn(e
->defaultAtts
);
5579 hashTableClear(&(p
->generalEntities
));
5581 p
->paramEntityRead
= XML_FALSE
;
5582 hashTableClear(&(p
->paramEntities
));
5583 #endif /* XML_DTD */
5584 hashTableClear(&(p
->elementTypes
));
5585 hashTableClear(&(p
->attributeIds
));
5586 hashTableClear(&(p
->prefixes
));
5587 poolClear(&(p
->pool
));
5588 poolClear(&(p
->entityValuePool
));
5589 p
->defaultPrefix
.name
= NULL
;
5590 p
->defaultPrefix
.binding
= NULL
;
5592 p
->in_eldecl
= XML_FALSE
;
5594 ms
->free_fcn(p
->scaffIndex
);
5595 p
->scaffIndex
= NULL
;
5596 ms
->free_fcn(p
->scaffold
);
5602 p
->contentStringLen
= 0;
5604 p
->keepProcessing
= XML_TRUE
;
5605 p
->hasParamEntityRefs
= XML_FALSE
;
5606 p
->standalone
= XML_FALSE
;
5610 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5612 HASH_TABLE_ITER iter
;
5613 hashTableIterInit(&iter
, &(p
->elementTypes
));
5615 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5618 if (e
->allocDefaultAtts
!= 0)
5619 ms
->free_fcn(e
->defaultAtts
);
5621 hashTableDestroy(&(p
->generalEntities
));
5623 hashTableDestroy(&(p
->paramEntities
));
5624 #endif /* XML_DTD */
5625 hashTableDestroy(&(p
->elementTypes
));
5626 hashTableDestroy(&(p
->attributeIds
));
5627 hashTableDestroy(&(p
->prefixes
));
5628 poolDestroy(&(p
->pool
));
5629 poolDestroy(&(p
->entityValuePool
));
5631 ms
->free_fcn(p
->scaffIndex
);
5632 ms
->free_fcn(p
->scaffold
);
5637 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5638 The new DTD has already been initialized.
5641 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5643 HASH_TABLE_ITER iter
;
5645 /* Copy the prefix table. */
5647 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5649 const XML_Char
*name
;
5650 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5653 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5656 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5660 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5662 /* Copy the attribute id table. */
5666 const XML_Char
*name
;
5667 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5671 /* Remember to allocate the scratch byte before the name. */
5672 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5674 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5678 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5679 sizeof(ATTRIBUTE_ID
));
5682 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5684 newA
->xmlns
= oldA
->xmlns
;
5685 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5686 newA
->prefix
= &newDtd
->defaultPrefix
;
5688 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5689 oldA
->prefix
->name
, 0);
5693 /* Copy the element type table. */
5695 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5700 const XML_Char
*name
;
5701 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5704 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5707 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5708 sizeof(ELEMENT_TYPE
));
5711 if (oldE
->nDefaultAtts
) {
5712 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5713 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5714 if (!newE
->defaultAtts
) {
5720 newE
->idAtt
= (ATTRIBUTE_ID
*)
5721 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5722 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5724 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5725 oldE
->prefix
->name
, 0);
5726 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5727 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5728 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5729 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5730 if (oldE
->defaultAtts
[i
].value
) {
5731 newE
->defaultAtts
[i
].value
5732 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5733 if (!newE
->defaultAtts
[i
].value
)
5737 newE
->defaultAtts
[i
].value
= NULL
;
5741 /* Copy the entity tables. */
5742 if (!copyEntityTable(&(newDtd
->generalEntities
),
5744 &(oldDtd
->generalEntities
)))
5748 if (!copyEntityTable(&(newDtd
->paramEntities
),
5750 &(oldDtd
->paramEntities
)))
5752 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5753 #endif /* XML_DTD */
5755 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5756 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5757 newDtd
->standalone
= oldDtd
->standalone
;
5759 /* Don't want deep copying for scaffolding */
5760 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5761 newDtd
->scaffold
= oldDtd
->scaffold
;
5762 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5763 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5764 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5765 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5771 copyEntityTable(HASH_TABLE
*newTable
,
5772 STRING_POOL
*newPool
,
5773 const HASH_TABLE
*oldTable
)
5775 HASH_TABLE_ITER iter
;
5776 const XML_Char
*cachedOldBase
= NULL
;
5777 const XML_Char
*cachedNewBase
= NULL
;
5779 hashTableIterInit(&iter
, oldTable
);
5783 const XML_Char
*name
;
5784 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5787 name
= poolCopyString(newPool
, oldE
->name
);
5790 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5793 if (oldE
->systemId
) {
5794 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5797 newE
->systemId
= tem
;
5799 if (oldE
->base
== cachedOldBase
)
5800 newE
->base
= cachedNewBase
;
5802 cachedOldBase
= oldE
->base
;
5803 tem
= poolCopyString(newPool
, cachedOldBase
);
5806 cachedNewBase
= newE
->base
= tem
;
5809 if (oldE
->publicId
) {
5810 tem
= poolCopyString(newPool
, oldE
->publicId
);
5813 newE
->publicId
= tem
;
5817 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5821 newE
->textPtr
= tem
;
5822 newE
->textLen
= oldE
->textLen
;
5824 if (oldE
->notation
) {
5825 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5828 newE
->notation
= tem
;
5830 newE
->is_param
= oldE
->is_param
;
5831 newE
->is_internal
= oldE
->is_internal
;
5836 #define INIT_POWER 6
5838 static XML_Bool FASTCALL
5839 keyeq(KEY s1
, KEY s2
)
5841 for (; *s1
== *s2
; s1
++, s2
++)
5847 static unsigned long FASTCALL
5850 unsigned long h
= 0;
5852 h
= CHAR_HASH(h
, *s
++);
5857 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5860 if (table
->size
== 0) {
5864 table
->power
= INIT_POWER
;
5865 /* table->size is a power of 2 */
5866 table
->size
= (size_t)1 << INIT_POWER
;
5867 tsize
= table
->size
* sizeof(NAMED
*);
5868 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5873 memset(table
->v
, 0, tsize
);
5874 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5877 unsigned long h
= hash(name
);
5878 unsigned long mask
= (unsigned long)table
->size
- 1;
5879 unsigned char step
= 0;
5881 while (table
->v
[i
]) {
5882 if (keyeq(name
, table
->v
[i
]->name
))
5885 step
= PROBE_STEP(h
, mask
, table
->power
);
5886 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5891 /* check for overflow (table is half full) */
5892 if (table
->used
>> (table
->power
- 1)) {
5893 unsigned char newPower
= table
->power
+ 1;
5894 size_t newSize
= (size_t)1 << newPower
;
5895 unsigned long newMask
= (unsigned long)newSize
- 1;
5896 size_t tsize
= newSize
* sizeof(NAMED
*);
5897 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5900 memset(newV
, 0, tsize
);
5901 for (i
= 0; i
< table
->size
; i
++)
5903 unsigned long newHash
= hash(table
->v
[i
]->name
);
5904 size_t j
= newHash
& newMask
;
5908 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5909 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5911 newV
[j
] = table
->v
[i
];
5913 table
->mem
->free_fcn(table
->v
);
5915 table
->power
= newPower
;
5916 table
->size
= newSize
;
5919 while (table
->v
[i
]) {
5921 step
= PROBE_STEP(h
, newMask
, newPower
);
5922 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5926 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5929 memset(table
->v
[i
], 0, createSize
);
5930 table
->v
[i
]->name
= name
;
5935 static void FASTCALL
5936 hashTableClear(HASH_TABLE
*table
)
5939 for (i
= 0; i
< table
->size
; i
++) {
5940 table
->mem
->free_fcn(table
->v
[i
]);
5946 static void FASTCALL
5947 hashTableDestroy(HASH_TABLE
*table
)
5950 for (i
= 0; i
< table
->size
; i
++)
5951 table
->mem
->free_fcn(table
->v
[i
]);
5952 table
->mem
->free_fcn(table
->v
);
5955 static void FASTCALL
5956 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5965 static void FASTCALL
5966 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5969 iter
->end
= iter
->p
+ table
->size
;
5972 static NAMED
* FASTCALL
5973 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5975 while (iter
->p
!= iter
->end
) {
5976 NAMED
*tem
= *(iter
->p
)++;
5983 static void FASTCALL
5984 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5986 pool
->blocks
= NULL
;
5987 pool
->freeBlocks
= NULL
;
5994 static void FASTCALL
5995 poolClear(STRING_POOL
*pool
)
5997 if (!pool
->freeBlocks
)
5998 pool
->freeBlocks
= pool
->blocks
;
6000 BLOCK
*p
= pool
->blocks
;
6002 BLOCK
*tem
= p
->next
;
6003 p
->next
= pool
->freeBlocks
;
6004 pool
->freeBlocks
= p
;
6008 pool
->blocks
= NULL
;
6014 static void FASTCALL
6015 poolDestroy(STRING_POOL
*pool
)
6017 BLOCK
*p
= pool
->blocks
;
6019 BLOCK
*tem
= p
->next
;
6020 pool
->mem
->free_fcn(p
);
6023 p
= pool
->freeBlocks
;
6025 BLOCK
*tem
= p
->next
;
6026 pool
->mem
->free_fcn(p
);
6032 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6033 const char *ptr
, const char *end
)
6035 if (!pool
->ptr
&& !poolGrow(pool
))
6038 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6041 if (!poolGrow(pool
))
6047 static const XML_Char
* FASTCALL
6048 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6051 if (!poolAppendChar(pool
, *s
))
6059 static const XML_Char
*
6060 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6062 if (!pool
->ptr
&& !poolGrow(pool
))
6064 for (; n
> 0; --n
, s
++) {
6065 if (!poolAppendChar(pool
, *s
))
6073 static const XML_Char
* FASTCALL
6074 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6077 if (!poolAppendChar(pool
, *s
))
6085 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6086 const char *ptr
, const char *end
)
6088 if (!poolAppend(pool
, enc
, ptr
, end
))
6090 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6096 static XML_Bool FASTCALL
6097 poolGrow(STRING_POOL
*pool
)
6099 if (pool
->freeBlocks
) {
6100 if (pool
->start
== 0) {
6101 pool
->blocks
= pool
->freeBlocks
;
6102 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6103 pool
->blocks
->next
= NULL
;
6104 pool
->start
= pool
->blocks
->s
;
6105 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6106 pool
->ptr
= pool
->start
;
6109 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6110 BLOCK
*tem
= pool
->freeBlocks
->next
;
6111 pool
->freeBlocks
->next
= pool
->blocks
;
6112 pool
->blocks
= pool
->freeBlocks
;
6113 pool
->freeBlocks
= tem
;
6114 memcpy(pool
->blocks
->s
, pool
->start
,
6115 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6116 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6117 pool
->start
= pool
->blocks
->s
;
6118 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6122 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6123 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6124 pool
->blocks
= (BLOCK
*)
6125 pool
->mem
->realloc_fcn(pool
->blocks
,
6127 + blockSize
* sizeof(XML_Char
)));
6128 if (pool
->blocks
== NULL
)
6130 pool
->blocks
->size
= blockSize
;
6131 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6132 pool
->start
= pool
->blocks
->s
;
6133 pool
->end
= pool
->start
+ blockSize
;
6137 int blockSize
= (int)(pool
->end
- pool
->start
);
6138 if (blockSize
< INIT_BLOCK_SIZE
)
6139 blockSize
= INIT_BLOCK_SIZE
;
6142 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6143 + blockSize
* sizeof(XML_Char
));
6146 tem
->size
= blockSize
;
6147 tem
->next
= pool
->blocks
;
6149 if (pool
->ptr
!= pool
->start
)
6150 memcpy(tem
->s
, pool
->start
,
6151 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6152 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6153 pool
->start
= tem
->s
;
6154 pool
->end
= tem
->s
+ blockSize
;
6160 nextScaffoldPart(XML_Parser parser
)
6162 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6163 CONTENT_SCAFFOLD
* me
;
6166 if (!dtd
->scaffIndex
) {
6167 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6168 if (!dtd
->scaffIndex
)
6170 dtd
->scaffIndex
[0] = 0;
6173 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6174 CONTENT_SCAFFOLD
*temp
;
6175 if (dtd
->scaffold
) {
6176 temp
= (CONTENT_SCAFFOLD
*)
6177 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6180 dtd
->scaffSize
*= 2;
6183 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6184 * sizeof(CONTENT_SCAFFOLD
));
6187 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6189 dtd
->scaffold
= temp
;
6191 next
= dtd
->scaffCount
++;
6192 me
= &dtd
->scaffold
[next
];
6193 if (dtd
->scaffLevel
) {
6194 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6195 if (parent
->lastchild
) {
6196 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6198 if (!parent
->childcnt
)
6199 parent
->firstchild
= next
;
6200 parent
->lastchild
= next
;
6203 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6208 build_node(XML_Parser parser
,
6211 XML_Content
**contpos
,
6214 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6215 dest
->type
= dtd
->scaffold
[src_node
].type
;
6216 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6217 if (dest
->type
== XML_CTYPE_NAME
) {
6218 const XML_Char
*src
;
6219 dest
->name
= *strpos
;
6220 src
= dtd
->scaffold
[src_node
].name
;
6222 *(*strpos
)++ = *src
;
6227 dest
->numchildren
= 0;
6228 dest
->children
= NULL
;
6233 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6234 dest
->children
= *contpos
;
6235 *contpos
+= dest
->numchildren
;
6236 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6237 i
< dest
->numchildren
;
6238 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6239 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6245 static XML_Content
*
6246 build_model (XML_Parser parser
)
6248 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6252 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6253 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6255 ret
= (XML_Content
*)MALLOC(allocsize
);
6259 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6262 build_node(parser
, 0, ret
, &cpos
, &str
);
6266 static ELEMENT_TYPE
*
6267 getElementType(XML_Parser parser
,
6268 const ENCODING
*enc
,
6272 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6273 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6278 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6281 if (ret
->name
!= name
)
6282 poolDiscard(&dtd
->pool
);
6284 poolFinish(&dtd
->pool
);
6285 if (!setElementTypePrefix(parser
, ret
))