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(__amigaos__)
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 eventPtr
= eventEndPtr
= NULL
;
1517 processor
= errorProcessor
;
1518 return XML_STATUS_ERROR
;
1521 bufferLim
= buffer
+ len
* 2;
1523 memcpy(buffer
, end
, nLeftOver
);
1526 bufferEnd
= buffer
+ nLeftOver
;
1527 positionPtr
= bufferPtr
;
1528 parseEndPtr
= bufferEnd
;
1529 eventPtr
= bufferPtr
;
1530 eventEndPtr
= bufferPtr
;
1533 #endif /* not defined XML_CONTEXT_BYTES */
1535 void *buff
= XML_GetBuffer(parser
, len
);
1537 return XML_STATUS_ERROR
;
1539 memcpy(buff
, s
, len
);
1540 return XML_ParseBuffer(parser
, len
, isFinal
);
1545 enum XML_Status XMLCALL
1546 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1549 enum XML_Status result
= XML_STATUS_OK
;
1551 switch (ps_parsing
) {
1553 errorCode
= XML_ERROR_SUSPENDED
;
1554 return XML_STATUS_ERROR
;
1556 errorCode
= XML_ERROR_FINISHED
;
1557 return XML_STATUS_ERROR
;
1559 ps_parsing
= XML_PARSING
;
1563 positionPtr
= start
;
1565 parseEndPtr
= bufferEnd
;
1566 parseEndByteIndex
+= len
;
1567 ps_finalBuffer
= (XML_Bool
)isFinal
;
1569 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1571 if (errorCode
!= XML_ERROR_NONE
) {
1572 eventEndPtr
= eventPtr
;
1573 processor
= errorProcessor
;
1574 return XML_STATUS_ERROR
;
1577 switch (ps_parsing
) {
1579 result
= XML_STATUS_SUSPENDED
;
1581 case XML_INITIALIZED
:
1584 ps_parsing
= XML_FINISHED
;
1587 default: ; /* should not happen */
1591 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1592 positionPtr
= bufferPtr
;
1597 XML_GetBuffer(XML_Parser parser
, int len
)
1599 switch (ps_parsing
) {
1601 errorCode
= XML_ERROR_SUSPENDED
;
1604 errorCode
= XML_ERROR_FINISHED
;
1609 if (len
> bufferLim
- bufferEnd
) {
1610 /* FIXME avoid integer overflow */
1611 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1612 #ifdef XML_CONTEXT_BYTES
1613 int keep
= (int)(bufferPtr
- buffer
);
1615 if (keep
> XML_CONTEXT_BYTES
)
1616 keep
= XML_CONTEXT_BYTES
;
1618 #endif /* defined XML_CONTEXT_BYTES */
1619 if (neededSize
<= bufferLim
- buffer
) {
1620 #ifdef XML_CONTEXT_BYTES
1621 if (keep
< bufferPtr
- buffer
) {
1622 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1623 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1624 bufferEnd
-= offset
;
1625 bufferPtr
-= offset
;
1628 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1629 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1631 #endif /* not defined XML_CONTEXT_BYTES */
1635 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1636 if (bufferSize
== 0)
1637 bufferSize
= INIT_BUFFER_SIZE
;
1640 } while (bufferSize
< neededSize
);
1641 newBuf
= (char *)MALLOC(bufferSize
);
1643 errorCode
= XML_ERROR_NO_MEMORY
;
1646 bufferLim
= newBuf
+ bufferSize
;
1647 #ifdef XML_CONTEXT_BYTES
1649 int keep
= (int)(bufferPtr
- buffer
);
1650 if (keep
> XML_CONTEXT_BYTES
)
1651 keep
= XML_CONTEXT_BYTES
;
1652 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1655 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1656 bufferPtr
= buffer
+ keep
;
1659 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1660 bufferPtr
= buffer
= newBuf
;
1664 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1667 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1668 bufferPtr
= buffer
= newBuf
;
1669 #endif /* not defined XML_CONTEXT_BYTES */
1671 eventPtr
= eventEndPtr
= NULL
;
1677 enum XML_Status XMLCALL
1678 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1680 switch (ps_parsing
) {
1683 errorCode
= XML_ERROR_SUSPENDED
;
1684 return XML_STATUS_ERROR
;
1686 ps_parsing
= XML_FINISHED
;
1689 errorCode
= XML_ERROR_FINISHED
;
1690 return XML_STATUS_ERROR
;
1694 if (isParamEntity
) {
1695 errorCode
= XML_ERROR_SUSPEND_PE
;
1696 return XML_STATUS_ERROR
;
1699 ps_parsing
= XML_SUSPENDED
;
1702 ps_parsing
= XML_FINISHED
;
1704 return XML_STATUS_OK
;
1707 enum XML_Status XMLCALL
1708 XML_ResumeParser(XML_Parser parser
)
1710 enum XML_Status result
= XML_STATUS_OK
;
1712 if (ps_parsing
!= XML_SUSPENDED
) {
1713 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1714 return XML_STATUS_ERROR
;
1716 ps_parsing
= XML_PARSING
;
1718 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1720 if (errorCode
!= XML_ERROR_NONE
) {
1721 eventEndPtr
= eventPtr
;
1722 processor
= errorProcessor
;
1723 return XML_STATUS_ERROR
;
1726 switch (ps_parsing
) {
1728 result
= XML_STATUS_SUSPENDED
;
1730 case XML_INITIALIZED
:
1732 if (ps_finalBuffer
) {
1733 ps_parsing
= XML_FINISHED
;
1740 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1741 positionPtr
= bufferPtr
;
1746 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1748 assert(status
!= NULL
);
1749 *status
= parser
->m_parsingStatus
;
1752 enum XML_Error XMLCALL
1753 XML_GetErrorCode(XML_Parser parser
)
1759 XML_GetCurrentByteIndex(XML_Parser parser
)
1762 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1767 XML_GetCurrentByteCount(XML_Parser parser
)
1769 if (eventEndPtr
&& eventPtr
)
1770 return (int)(eventEndPtr
- eventPtr
);
1774 const char * XMLCALL
1775 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1777 #ifdef XML_CONTEXT_BYTES
1778 if (eventPtr
&& buffer
) {
1779 *offset
= (int)(eventPtr
- buffer
);
1780 *size
= (int)(bufferEnd
- buffer
);
1783 #endif /* defined XML_CONTEXT_BYTES */
1788 XML_GetCurrentLineNumber(XML_Parser parser
)
1790 if (eventPtr
&& eventPtr
>= positionPtr
) {
1791 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1792 positionPtr
= eventPtr
;
1794 return position
.lineNumber
+ 1;
1798 XML_GetCurrentColumnNumber(XML_Parser parser
)
1800 if (eventPtr
&& eventPtr
>= positionPtr
) {
1801 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1802 positionPtr
= eventPtr
;
1804 return position
.columnNumber
;
1808 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1814 XML_MemMalloc(XML_Parser parser
, size_t size
)
1816 return MALLOC(size
);
1820 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1822 return REALLOC(ptr
, size
);
1826 XML_MemFree(XML_Parser parser
, void *ptr
)
1832 XML_DefaultCurrent(XML_Parser parser
)
1834 if (defaultHandler
) {
1835 if (openInternalEntities
)
1836 reportDefault(parser
,
1838 openInternalEntities
->internalEventPtr
,
1839 openInternalEntities
->internalEventEndPtr
);
1841 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1845 const XML_LChar
* XMLCALL
1846 XML_ErrorString(enum XML_Error code
)
1848 static const XML_LChar
* const message
[] = {
1850 XML_L("out of memory"),
1851 XML_L("syntax error"),
1852 XML_L("no element found"),
1853 XML_L("not well-formed (invalid token)"),
1854 XML_L("unclosed token"),
1855 XML_L("partial character"),
1856 XML_L("mismatched tag"),
1857 XML_L("duplicate attribute"),
1858 XML_L("junk after document element"),
1859 XML_L("illegal parameter entity reference"),
1860 XML_L("undefined entity"),
1861 XML_L("recursive entity reference"),
1862 XML_L("asynchronous entity"),
1863 XML_L("reference to invalid character number"),
1864 XML_L("reference to binary entity"),
1865 XML_L("reference to external entity in attribute"),
1866 XML_L("XML or text declaration not at start of entity"),
1867 XML_L("unknown encoding"),
1868 XML_L("encoding specified in XML declaration is incorrect"),
1869 XML_L("unclosed CDATA section"),
1870 XML_L("error in processing external entity reference"),
1871 XML_L("document is not standalone"),
1872 XML_L("unexpected parser state - please send a bug report"),
1873 XML_L("entity declared in parameter entity"),
1874 XML_L("requested feature requires XML_DTD support in Expat"),
1875 XML_L("cannot change setting once parsing has begun"),
1876 XML_L("unbound prefix"),
1877 XML_L("must not undeclare prefix"),
1878 XML_L("incomplete markup in parameter entity"),
1879 XML_L("XML declaration not well-formed"),
1880 XML_L("text declaration not well-formed"),
1881 XML_L("illegal character(s) in public id"),
1882 XML_L("parser suspended"),
1883 XML_L("parser not suspended"),
1884 XML_L("parsing aborted"),
1885 XML_L("parsing finished"),
1886 XML_L("cannot suspend in external parameter entity"),
1887 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1888 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1889 XML_L("prefix must not be bound to one of the reserved namespace names")
1891 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1892 return message
[code
];
1896 const XML_LChar
* XMLCALL
1897 XML_ExpatVersion(void) {
1899 /* V1 is used to string-ize the version number. However, it would
1900 string-ize the actual version macro *names* unless we get them
1901 substituted before being passed to V1. CPP is defined to expand
1902 a macro, then rescan for more expansions. Thus, we use V2 to expand
1903 the version macros, then CPP will expand the resulting V1() macro
1904 with the correct numerals. */
1905 /* ### I'm assuming cpp is portable in this respect... */
1907 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1908 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1910 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1916 XML_Expat_Version XMLCALL
1917 XML_ExpatVersionInfo(void)
1919 XML_Expat_Version version
;
1921 version
.major
= XML_MAJOR_VERSION
;
1922 version
.minor
= XML_MINOR_VERSION
;
1923 version
.micro
= XML_MICRO_VERSION
;
1928 const XML_Feature
* XMLCALL
1929 XML_GetFeatureList(void)
1931 static const XML_Feature features
[] = {
1932 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1934 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1937 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1939 #ifdef XML_UNICODE_WCHAR_T
1940 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1943 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1945 #ifdef XML_CONTEXT_BYTES
1946 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1950 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1953 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1955 #ifdef XML_LARGE_SIZE
1956 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
1958 {XML_FEATURE_END
, NULL
, 0}
1964 /* Initially tag->rawName always points into the parse buffer;
1965 for those TAG instances opened while the current parse buffer was
1966 processed, and not yet closed, we need to store tag->rawName in a more
1967 permanent location, since the parse buffer is about to be discarded.
1970 storeRawNames(XML_Parser parser
)
1972 TAG
*tag
= tagStack
;
1975 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1976 char *rawNameBuf
= tag
->buf
+ nameLen
;
1977 /* Stop if already stored. Since tagStack is a stack, we can stop
1978 at the first entry that has already been copied; everything
1979 below it in the stack is already been accounted for in a
1980 previous call to this function.
1982 if (tag
->rawName
== rawNameBuf
)
1984 /* For re-use purposes we need to ensure that the
1985 size of tag->buf is a multiple of sizeof(XML_Char).
1987 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1988 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1989 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1992 /* if tag->name.str points to tag->buf (only when namespace
1993 processing is off) then we have to update it
1995 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1996 tag
->name
.str
= (XML_Char
*)temp
;
1997 /* if tag->name.localPart is set (when namespace processing is on)
1998 then update it as well, since it will always point into tag->buf
2000 if (tag
->name
.localPart
)
2001 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2002 (XML_Char
*)tag
->buf
);
2004 tag
->bufEnd
= temp
+ bufSize
;
2005 rawNameBuf
= temp
+ nameLen
;
2007 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2008 tag
->rawName
= rawNameBuf
;
2014 static enum XML_Error PTRCALL
2015 contentProcessor(XML_Parser parser
,
2018 const char **endPtr
)
2020 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2021 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2022 if (result
== XML_ERROR_NONE
) {
2023 if (!storeRawNames(parser
))
2024 return XML_ERROR_NO_MEMORY
;
2029 static enum XML_Error PTRCALL
2030 externalEntityInitProcessor(XML_Parser parser
,
2033 const char **endPtr
)
2035 enum XML_Error result
= initializeEncoding(parser
);
2036 if (result
!= XML_ERROR_NONE
)
2038 processor
= externalEntityInitProcessor2
;
2039 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2042 static enum XML_Error PTRCALL
2043 externalEntityInitProcessor2(XML_Parser parser
,
2046 const char **endPtr
)
2048 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2049 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2052 /* If we are at the end of the buffer, this would cause the next stage,
2053 i.e. externalEntityInitProcessor3, to pass control directly to
2054 doContent (by detecting XML_TOK_NONE) without processing any xml text
2055 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2057 if (next
== end
&& !ps_finalBuffer
) {
2059 return XML_ERROR_NONE
;
2063 case XML_TOK_PARTIAL
:
2064 if (!ps_finalBuffer
) {
2066 return XML_ERROR_NONE
;
2069 return XML_ERROR_UNCLOSED_TOKEN
;
2070 case XML_TOK_PARTIAL_CHAR
:
2071 if (!ps_finalBuffer
) {
2073 return XML_ERROR_NONE
;
2076 return XML_ERROR_PARTIAL_CHAR
;
2078 processor
= externalEntityInitProcessor3
;
2079 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2082 static enum XML_Error PTRCALL
2083 externalEntityInitProcessor3(XML_Parser parser
,
2086 const char **endPtr
)
2089 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2091 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2095 case XML_TOK_XML_DECL
:
2097 enum XML_Error result
;
2098 result
= processXmlDecl(parser
, 1, start
, next
);
2099 if (result
!= XML_ERROR_NONE
)
2101 switch (ps_parsing
) {
2104 return XML_ERROR_NONE
;
2106 return XML_ERROR_ABORTED
;
2112 case XML_TOK_PARTIAL
:
2113 if (!ps_finalBuffer
) {
2115 return XML_ERROR_NONE
;
2117 return XML_ERROR_UNCLOSED_TOKEN
;
2118 case XML_TOK_PARTIAL_CHAR
:
2119 if (!ps_finalBuffer
) {
2121 return XML_ERROR_NONE
;
2123 return XML_ERROR_PARTIAL_CHAR
;
2125 processor
= externalEntityContentProcessor
;
2127 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2130 static enum XML_Error PTRCALL
2131 externalEntityContentProcessor(XML_Parser parser
,
2134 const char **endPtr
)
2136 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2137 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2138 if (result
== XML_ERROR_NONE
) {
2139 if (!storeRawNames(parser
))
2140 return XML_ERROR_NO_MEMORY
;
2145 static enum XML_Error
2146 doContent(XML_Parser parser
,
2148 const ENCODING
*enc
,
2151 const char **nextPtr
,
2154 /* save one level of indirection */
2155 DTD
* const dtd
= _dtd
;
2157 const char **eventPP
;
2158 const char **eventEndPP
;
2159 if (enc
== encoding
) {
2160 eventPP
= &eventPtr
;
2161 eventEndPP
= &eventEndPtr
;
2164 eventPP
= &(openInternalEntities
->internalEventPtr
);
2165 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2170 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2171 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2174 case XML_TOK_TRAILING_CR
:
2177 return XML_ERROR_NONE
;
2180 if (characterDataHandler
) {
2182 characterDataHandler(handlerArg
, &c
, 1);
2184 else if (defaultHandler
)
2185 reportDefault(parser
, enc
, s
, end
);
2186 /* We are at the end of the final buffer, should we check for
2187 XML_SUSPENDED, XML_FINISHED?
2189 if (startTagLevel
== 0)
2190 return XML_ERROR_NO_ELEMENTS
;
2191 if (tagLevel
!= startTagLevel
)
2192 return XML_ERROR_ASYNC_ENTITY
;
2194 return XML_ERROR_NONE
;
2198 return XML_ERROR_NONE
;
2200 if (startTagLevel
> 0) {
2201 if (tagLevel
!= startTagLevel
)
2202 return XML_ERROR_ASYNC_ENTITY
;
2204 return XML_ERROR_NONE
;
2206 return XML_ERROR_NO_ELEMENTS
;
2207 case XML_TOK_INVALID
:
2209 return XML_ERROR_INVALID_TOKEN
;
2210 case XML_TOK_PARTIAL
:
2213 return XML_ERROR_NONE
;
2215 return XML_ERROR_UNCLOSED_TOKEN
;
2216 case XML_TOK_PARTIAL_CHAR
:
2219 return XML_ERROR_NONE
;
2221 return XML_ERROR_PARTIAL_CHAR
;
2222 case XML_TOK_ENTITY_REF
:
2224 const XML_Char
*name
;
2226 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2227 s
+ enc
->minBytesPerChar
,
2228 next
- enc
->minBytesPerChar
);
2230 if (characterDataHandler
)
2231 characterDataHandler(handlerArg
, &ch
, 1);
2232 else if (defaultHandler
)
2233 reportDefault(parser
, enc
, s
, next
);
2236 name
= poolStoreString(&dtd
->pool
, enc
,
2237 s
+ enc
->minBytesPerChar
,
2238 next
- enc
->minBytesPerChar
);
2240 return XML_ERROR_NO_MEMORY
;
2241 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2242 poolDiscard(&dtd
->pool
);
2243 /* First, determine if a check for an existing declaration is needed;
2244 if yes, check that the entity exists, and that it is internal,
2245 otherwise call the skipped entity or default handler.
2247 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2249 return XML_ERROR_UNDEFINED_ENTITY
;
2250 else if (!entity
->is_internal
)
2251 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2254 if (skippedEntityHandler
)
2255 skippedEntityHandler(handlerArg
, name
, 0);
2256 else if (defaultHandler
)
2257 reportDefault(parser
, enc
, s
, next
);
2261 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2262 if (entity
->notation
)
2263 return XML_ERROR_BINARY_ENTITY_REF
;
2264 if (entity
->textPtr
) {
2265 enum XML_Error result
;
2266 if (!defaultExpandInternalEntities
) {
2267 if (skippedEntityHandler
)
2268 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2269 else if (defaultHandler
)
2270 reportDefault(parser
, enc
, s
, next
);
2273 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2274 if (result
!= XML_ERROR_NONE
)
2277 else if (externalEntityRefHandler
) {
2278 const XML_Char
*context
;
2279 entity
->open
= XML_TRUE
;
2280 context
= getContext(parser
);
2281 entity
->open
= XML_FALSE
;
2283 return XML_ERROR_NO_MEMORY
;
2284 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2289 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2290 poolDiscard(&tempPool
);
2292 else if (defaultHandler
)
2293 reportDefault(parser
, enc
, s
, next
);
2296 case XML_TOK_START_TAG_NO_ATTS
:
2298 case XML_TOK_START_TAG_WITH_ATTS
:
2301 enum XML_Error result
;
2305 freeTagList
= freeTagList
->parent
;
2308 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2310 return XML_ERROR_NO_MEMORY
;
2311 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2314 return XML_ERROR_NO_MEMORY
;
2316 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2318 tag
->bindings
= NULL
;
2319 tag
->parent
= tagStack
;
2321 tag
->name
.localPart
= NULL
;
2322 tag
->name
.prefix
= NULL
;
2323 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2324 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2327 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2328 const char *fromPtr
= tag
->rawName
;
2329 toPtr
= (XML_Char
*)tag
->buf
;
2334 &fromPtr
, rawNameEnd
,
2335 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2336 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2337 if (fromPtr
== rawNameEnd
) {
2338 tag
->name
.strLen
= convLen
;
2341 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2343 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2345 return XML_ERROR_NO_MEMORY
;
2347 tag
->bufEnd
= temp
+ bufSize
;
2348 toPtr
= (XML_Char
*)temp
+ convLen
;
2352 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2353 *toPtr
= XML_T('\0');
2354 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2357 if (startElementHandler
)
2358 startElementHandler(handlerArg
, tag
->name
.str
,
2359 (const XML_Char
**)atts
);
2360 else if (defaultHandler
)
2361 reportDefault(parser
, enc
, s
, next
);
2362 poolClear(&tempPool
);
2365 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2367 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2369 const char *rawName
= s
+ enc
->minBytesPerChar
;
2370 enum XML_Error result
;
2371 BINDING
*bindings
= NULL
;
2372 XML_Bool noElmHandlers
= XML_TRUE
;
2374 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2375 rawName
+ XmlNameLength(enc
, rawName
));
2377 return XML_ERROR_NO_MEMORY
;
2378 poolFinish(&tempPool
);
2379 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2382 poolFinish(&tempPool
);
2383 if (startElementHandler
) {
2384 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2385 noElmHandlers
= XML_FALSE
;
2387 if (endElementHandler
) {
2388 if (startElementHandler
)
2389 *eventPP
= *eventEndPP
;
2390 endElementHandler(handlerArg
, name
.str
);
2391 noElmHandlers
= XML_FALSE
;
2393 if (noElmHandlers
&& defaultHandler
)
2394 reportDefault(parser
, enc
, s
, next
);
2395 poolClear(&tempPool
);
2397 BINDING
*b
= bindings
;
2398 if (endNamespaceDeclHandler
)
2399 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2400 bindings
= bindings
->nextTagBinding
;
2401 b
->nextTagBinding
= freeBindingList
;
2402 freeBindingList
= b
;
2403 b
->prefix
->binding
= b
->prevPrefixBinding
;
2407 return epilogProcessor(parser
, next
, end
, nextPtr
);
2409 case XML_TOK_END_TAG
:
2410 if (tagLevel
== startTagLevel
)
2411 return XML_ERROR_ASYNC_ENTITY
;
2414 const char *rawName
;
2415 TAG
*tag
= tagStack
;
2416 tagStack
= tag
->parent
;
2417 tag
->parent
= freeTagList
;
2419 rawName
= s
+ enc
->minBytesPerChar
*2;
2420 len
= XmlNameLength(enc
, rawName
);
2421 if (len
!= tag
->rawNameLength
2422 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2424 return XML_ERROR_TAG_MISMATCH
;
2427 if (endElementHandler
) {
2428 const XML_Char
*localPart
;
2429 const XML_Char
*prefix
;
2431 localPart
= tag
->name
.localPart
;
2432 if (ns
&& localPart
) {
2433 /* localPart and prefix may have been overwritten in
2434 tag->name.str, since this points to the binding->uri
2435 buffer which gets re-used; so we have to add them again
2437 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2438 /* don't need to check for space - already done in storeAtts() */
2439 while (*localPart
) *uri
++ = *localPart
++;
2440 prefix
= (XML_Char
*)tag
->name
.prefix
;
2441 if (ns_triplets
&& prefix
) {
2442 *uri
++ = namespaceSeparator
;
2443 while (*prefix
) *uri
++ = *prefix
++;
2447 endElementHandler(handlerArg
, tag
->name
.str
);
2449 else if (defaultHandler
)
2450 reportDefault(parser
, enc
, s
, next
);
2451 while (tag
->bindings
) {
2452 BINDING
*b
= tag
->bindings
;
2453 if (endNamespaceDeclHandler
)
2454 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2455 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2456 b
->nextTagBinding
= freeBindingList
;
2457 freeBindingList
= b
;
2458 b
->prefix
->binding
= b
->prevPrefixBinding
;
2461 return epilogProcessor(parser
, next
, end
, nextPtr
);
2464 case XML_TOK_CHAR_REF
:
2466 int n
= XmlCharRefNumber(enc
, s
);
2468 return XML_ERROR_BAD_CHAR_REF
;
2469 if (characterDataHandler
) {
2470 XML_Char buf
[XML_ENCODE_MAX
];
2471 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2473 else if (defaultHandler
)
2474 reportDefault(parser
, enc
, s
, next
);
2477 case XML_TOK_XML_DECL
:
2478 return XML_ERROR_MISPLACED_XML_PI
;
2479 case XML_TOK_DATA_NEWLINE
:
2480 if (characterDataHandler
) {
2482 characterDataHandler(handlerArg
, &c
, 1);
2484 else if (defaultHandler
)
2485 reportDefault(parser
, enc
, s
, next
);
2487 case XML_TOK_CDATA_SECT_OPEN
:
2489 enum XML_Error result
;
2490 if (startCdataSectionHandler
)
2491 startCdataSectionHandler(handlerArg
);
2493 /* Suppose you doing a transformation on a document that involves
2494 changing only the character data. You set up a defaultHandler
2495 and a characterDataHandler. The defaultHandler simply copies
2496 characters through. The characterDataHandler does the
2497 transformation and writes the characters out escaping them as
2498 necessary. This case will fail to work if we leave out the
2499 following two lines (because & and < inside CDATA sections will
2500 be incorrectly escaped).
2502 However, now we have a start/endCdataSectionHandler, so it seems
2503 easier to let the user deal with this.
2505 else if (characterDataHandler
)
2506 characterDataHandler(handlerArg
, dataBuf
, 0);
2508 else if (defaultHandler
)
2509 reportDefault(parser
, enc
, s
, next
);
2510 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2511 if (result
!= XML_ERROR_NONE
)
2514 processor
= cdataSectionProcessor
;
2519 case XML_TOK_TRAILING_RSQB
:
2522 return XML_ERROR_NONE
;
2524 if (characterDataHandler
) {
2525 if (MUST_CONVERT(enc
, s
)) {
2526 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2527 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2528 characterDataHandler(handlerArg
, dataBuf
,
2529 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2532 characterDataHandler(handlerArg
,
2534 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2536 else if (defaultHandler
)
2537 reportDefault(parser
, enc
, s
, end
);
2538 /* We are at the end of the final buffer, should we check for
2539 XML_SUSPENDED, XML_FINISHED?
2541 if (startTagLevel
== 0) {
2543 return XML_ERROR_NO_ELEMENTS
;
2545 if (tagLevel
!= startTagLevel
) {
2547 return XML_ERROR_ASYNC_ENTITY
;
2550 return XML_ERROR_NONE
;
2551 case XML_TOK_DATA_CHARS
:
2553 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2554 if (charDataHandler
) {
2555 if (MUST_CONVERT(enc
, s
)) {
2557 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2558 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2560 charDataHandler(handlerArg
, dataBuf
,
2561 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2568 charDataHandler(handlerArg
,
2570 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2572 else if (defaultHandler
)
2573 reportDefault(parser
, enc
, s
, next
);
2577 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2578 return XML_ERROR_NO_MEMORY
;
2580 case XML_TOK_COMMENT
:
2581 if (!reportComment(parser
, enc
, s
, next
))
2582 return XML_ERROR_NO_MEMORY
;
2586 reportDefault(parser
, enc
, s
, next
);
2589 *eventPP
= s
= next
;
2590 switch (ps_parsing
) {
2593 return XML_ERROR_NONE
;
2595 return XML_ERROR_ABORTED
;
2602 /* Precondition: all arguments must be non-NULL;
2604 - normalize attributes
2605 - check attributes for well-formedness
2606 - generate namespace aware attribute names (URI, prefix)
2607 - build list of attributes for startElementHandler
2608 - default attributes
2609 - process namespace declarations (check and report them)
2610 - generate namespace aware element name (URI, prefix)
2612 static enum XML_Error
2613 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2614 const char *attStr
, TAG_NAME
*tagNamePtr
,
2615 BINDING
**bindingsPtr
)
2617 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2618 ELEMENT_TYPE
*elementType
;
2620 const XML_Char
**appAtts
; /* the attribute list for the application */
2628 const XML_Char
*localPart
;
2630 /* lookup the element type name */
2631 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2633 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2635 return XML_ERROR_NO_MEMORY
;
2636 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2637 sizeof(ELEMENT_TYPE
));
2639 return XML_ERROR_NO_MEMORY
;
2640 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2641 return XML_ERROR_NO_MEMORY
;
2643 nDefaultAtts
= elementType
->nDefaultAtts
;
2645 /* get the attributes from the tokenizer */
2646 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2647 if (n
+ nDefaultAtts
> attsSize
) {
2648 int oldAttsSize
= attsSize
;
2650 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2651 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2653 return XML_ERROR_NO_MEMORY
;
2655 if (n
> oldAttsSize
)
2656 XmlGetAttributes(enc
, attStr
, n
, atts
);
2659 appAtts
= (const XML_Char
**)atts
;
2660 for (i
= 0; i
< n
; i
++) {
2661 /* add the name and value to the attribute list */
2662 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2664 + XmlNameLength(enc
, atts
[i
].name
));
2666 return XML_ERROR_NO_MEMORY
;
2667 /* Detect duplicate attributes by their QNames. This does not work when
2668 namespace processing is turned on and different prefixes for the same
2669 namespace are used. For this case we have a check further down.
2671 if ((attId
->name
)[-1]) {
2672 if (enc
== encoding
)
2673 eventPtr
= atts
[i
].name
;
2674 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2676 (attId
->name
)[-1] = 1;
2677 appAtts
[attIndex
++] = attId
->name
;
2678 if (!atts
[i
].normalized
) {
2679 enum XML_Error result
;
2680 XML_Bool isCdata
= XML_TRUE
;
2682 /* figure out whether declared as other than CDATA */
2683 if (attId
->maybeTokenized
) {
2685 for (j
= 0; j
< nDefaultAtts
; j
++) {
2686 if (attId
== elementType
->defaultAtts
[j
].id
) {
2687 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2693 /* normalize the attribute value */
2694 result
= storeAttributeValue(parser
, enc
, isCdata
,
2695 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2699 appAtts
[attIndex
] = poolStart(&tempPool
);
2700 poolFinish(&tempPool
);
2703 /* the value did not need normalizing */
2704 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2706 if (appAtts
[attIndex
] == 0)
2707 return XML_ERROR_NO_MEMORY
;
2708 poolFinish(&tempPool
);
2710 /* handle prefixed attribute names */
2711 if (attId
->prefix
) {
2713 /* deal with namespace declarations here */
2714 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2715 appAtts
[attIndex
], bindingsPtr
);
2721 /* deal with other prefixed names later */
2724 (attId
->name
)[-1] = 2;
2731 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2732 nSpecifiedAtts
= attIndex
;
2733 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2734 for (i
= 0; i
< attIndex
; i
+= 2)
2735 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2743 /* do attribute defaulting */
2744 for (i
= 0; i
< nDefaultAtts
; i
++) {
2745 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2746 if (!(da
->id
->name
)[-1] && da
->value
) {
2747 if (da
->id
->prefix
) {
2748 if (da
->id
->xmlns
) {
2749 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2750 da
->value
, bindingsPtr
);
2755 (da
->id
->name
)[-1] = 2;
2757 appAtts
[attIndex
++] = da
->id
->name
;
2758 appAtts
[attIndex
++] = da
->value
;
2762 (da
->id
->name
)[-1] = 1;
2763 appAtts
[attIndex
++] = da
->id
->name
;
2764 appAtts
[attIndex
++] = da
->value
;
2768 appAtts
[attIndex
] = 0;
2770 /* expand prefixed attribute names, check for duplicates,
2771 and clear flags that say whether attributes were specified */
2774 int j
; /* hash table index */
2775 unsigned long version
= nsAttsVersion
;
2776 int nsAttsSize
= (int)1 << nsAttsPower
;
2777 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2778 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2780 /* hash table size must also be a power of 2 and >= 8 */
2781 while (nPrefixes
>> nsAttsPower
++);
2782 if (nsAttsPower
< 3)
2784 nsAttsSize
= (int)1 << nsAttsPower
;
2785 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2787 return XML_ERROR_NO_MEMORY
;
2789 version
= 0; /* force re-initialization of nsAtts hash table */
2791 /* using a version flag saves us from initializing nsAtts every time */
2792 if (!version
) { /* initialize version flags when version wraps around */
2793 version
= INIT_ATTS_VERSION
;
2794 for (j
= nsAttsSize
; j
!= 0; )
2795 nsAtts
[--j
].version
= version
;
2797 nsAttsVersion
= --version
;
2799 /* expand prefixed names and check for duplicates */
2800 for (; i
< attIndex
; i
+= 2) {
2801 const XML_Char
*s
= appAtts
[i
];
2802 if (s
[-1] == 2) { /* prefixed */
2805 unsigned long uriHash
= 0;
2806 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2807 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2808 b
= id
->prefix
->binding
;
2810 return XML_ERROR_UNBOUND_PREFIX
;
2812 /* as we expand the name we also calculate its hash value */
2813 for (j
= 0; j
< b
->uriLen
; j
++) {
2814 const XML_Char c
= b
->uri
[j
];
2815 if (!poolAppendChar(&tempPool
, c
))
2816 return XML_ERROR_NO_MEMORY
;
2817 uriHash
= CHAR_HASH(uriHash
, c
);
2819 while (*s
++ != XML_T(ASCII_COLON
))
2821 do { /* copies null terminator */
2822 const XML_Char c
= *s
;
2823 if (!poolAppendChar(&tempPool
, *s
))
2824 return XML_ERROR_NO_MEMORY
;
2825 uriHash
= CHAR_HASH(uriHash
, c
);
2828 { /* Check hash table for duplicate of expanded name (uriName).
2829 Derived from code in lookup(HASH_TABLE *table, ...).
2831 unsigned char step
= 0;
2832 unsigned long mask
= nsAttsSize
- 1;
2833 j
= uriHash
& mask
; /* index into hash table */
2834 while (nsAtts
[j
].version
== version
) {
2835 /* for speed we compare stored hash values first */
2836 if (uriHash
== nsAtts
[j
].hash
) {
2837 const XML_Char
*s1
= poolStart(&tempPool
);
2838 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2839 /* s1 is null terminated, but not s2 */
2840 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2842 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2845 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2846 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2850 if (ns_triplets
) { /* append namespace separator and prefix */
2851 tempPool
.ptr
[-1] = namespaceSeparator
;
2852 s
= b
->prefix
->name
;
2854 if (!poolAppendChar(&tempPool
, *s
))
2855 return XML_ERROR_NO_MEMORY
;
2859 /* store expanded name in attribute list */
2860 s
= poolStart(&tempPool
);
2861 poolFinish(&tempPool
);
2864 /* fill empty slot with new version, uriName and hash value */
2865 nsAtts
[j
].version
= version
;
2866 nsAtts
[j
].hash
= uriHash
;
2867 nsAtts
[j
].uriName
= s
;
2874 else /* not prefixed */
2875 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2878 /* clear flags for the remaining attributes */
2879 for (; i
< attIndex
; i
+= 2)
2880 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2881 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2882 binding
->attId
->name
[-1] = 0;
2885 return XML_ERROR_NONE
;
2887 /* expand the element type name */
2888 if (elementType
->prefix
) {
2889 binding
= elementType
->prefix
->binding
;
2891 return XML_ERROR_UNBOUND_PREFIX
;
2892 localPart
= tagNamePtr
->str
;
2893 while (*localPart
++ != XML_T(ASCII_COLON
))
2896 else if (dtd
->defaultPrefix
.binding
) {
2897 binding
= dtd
->defaultPrefix
.binding
;
2898 localPart
= tagNamePtr
->str
;
2901 return XML_ERROR_NONE
;
2903 if (ns_triplets
&& binding
->prefix
->name
) {
2904 for (; binding
->prefix
->name
[prefixLen
++];)
2905 ; /* prefixLen includes null terminator */
2907 tagNamePtr
->localPart
= localPart
;
2908 tagNamePtr
->uriLen
= binding
->uriLen
;
2909 tagNamePtr
->prefix
= binding
->prefix
->name
;
2910 tagNamePtr
->prefixLen
= prefixLen
;
2911 for (i
= 0; localPart
[i
++];)
2912 ; /* i includes null terminator */
2913 n
= i
+ binding
->uriLen
+ prefixLen
;
2914 if (n
> binding
->uriAlloc
) {
2916 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2918 return XML_ERROR_NO_MEMORY
;
2919 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2920 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2921 for (p
= tagStack
; p
; p
= p
->parent
)
2922 if (p
->name
.str
== binding
->uri
)
2927 /* if namespaceSeparator != '\0' then uri includes it already */
2928 uri
= binding
->uri
+ binding
->uriLen
;
2929 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2930 /* we always have a namespace separator between localPart and prefix */
2933 *uri
= namespaceSeparator
; /* replace null terminator */
2934 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2936 tagNamePtr
->str
= binding
->uri
;
2937 return XML_ERROR_NONE
;
2940 /* addBinding() overwrites the value of prefix->binding without checking.
2941 Therefore one must keep track of the old value outside of addBinding().
2943 static enum XML_Error
2944 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2945 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2947 static const XML_Char xmlNamespace
[] = {
2948 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2949 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2950 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
2951 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
2952 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
2955 static const int xmlLen
=
2956 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2957 static const XML_Char xmlnsNamespace
[] = {
2958 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2959 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2960 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
2961 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
2964 static const int xmlnsLen
=
2965 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2967 XML_Bool mustBeXML
= XML_FALSE
;
2968 XML_Bool isXML
= XML_TRUE
;
2969 XML_Bool isXMLNS
= XML_TRUE
;
2974 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2975 if (*uri
== XML_T('\0') && prefix
->name
)
2976 return XML_ERROR_UNDECLARING_PREFIX
;
2979 && prefix
->name
[0] == XML_T(ASCII_x
)
2980 && prefix
->name
[1] == XML_T(ASCII_m
)
2981 && prefix
->name
[2] == XML_T(ASCII_l
)) {
2983 /* Not allowed to bind xmlns */
2984 if (prefix
->name
[3] == XML_T(ASCII_n
)
2985 && prefix
->name
[4] == XML_T(ASCII_s
)
2986 && prefix
->name
[5] == XML_T('\0'))
2987 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2989 if (prefix
->name
[3] == XML_T('\0'))
2990 mustBeXML
= XML_TRUE
;
2993 for (len
= 0; uri
[len
]; len
++) {
2994 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
2997 if (!mustBeXML
&& isXMLNS
2998 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
2999 isXMLNS
= XML_FALSE
;
3001 isXML
= isXML
&& len
== xmlLen
;
3002 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3004 if (mustBeXML
!= isXML
)
3005 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3006 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3009 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3011 if (namespaceSeparator
)
3013 if (freeBindingList
) {
3014 b
= freeBindingList
;
3015 if (len
> b
->uriAlloc
) {
3016 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3017 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3019 return XML_ERROR_NO_MEMORY
;
3021 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3023 freeBindingList
= b
->nextTagBinding
;
3026 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3028 return XML_ERROR_NO_MEMORY
;
3029 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3032 return XML_ERROR_NO_MEMORY
;
3034 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3037 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3038 if (namespaceSeparator
)
3039 b
->uri
[len
- 1] = namespaceSeparator
;
3042 b
->prevPrefixBinding
= prefix
->binding
;
3043 /* NULL binding when default namespace undeclared */
3044 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3045 prefix
->binding
= NULL
;
3047 prefix
->binding
= b
;
3048 b
->nextTagBinding
= *bindingsPtr
;
3050 /* if attId == NULL then we are not starting a namespace scope */
3051 if (attId
&& startNamespaceDeclHandler
)
3052 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3053 prefix
->binding
? uri
: 0);
3054 return XML_ERROR_NONE
;
3057 /* The idea here is to avoid using stack for each CDATA section when
3058 the whole file is parsed with one call.
3060 static enum XML_Error PTRCALL
3061 cdataSectionProcessor(XML_Parser parser
,
3064 const char **endPtr
)
3066 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3067 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3068 if (result
!= XML_ERROR_NONE
)
3071 if (parentParser
) { /* we are parsing an external entity */
3072 processor
= externalEntityContentProcessor
;
3073 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3076 processor
= contentProcessor
;
3077 return contentProcessor(parser
, start
, end
, endPtr
);
3083 /* startPtr gets set to non-null if the section is closed, and to null if
3084 the section is not yet closed.
3086 static enum XML_Error
3087 doCdataSection(XML_Parser parser
,
3088 const ENCODING
*enc
,
3089 const char **startPtr
,
3091 const char **nextPtr
,
3094 const char *s
= *startPtr
;
3095 const char **eventPP
;
3096 const char **eventEndPP
;
3097 if (enc
== encoding
) {
3098 eventPP
= &eventPtr
;
3100 eventEndPP
= &eventEndPtr
;
3103 eventPP
= &(openInternalEntities
->internalEventPtr
);
3104 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3111 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3114 case XML_TOK_CDATA_SECT_CLOSE
:
3115 if (endCdataSectionHandler
)
3116 endCdataSectionHandler(handlerArg
);
3118 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3119 else if (characterDataHandler
)
3120 characterDataHandler(handlerArg
, dataBuf
, 0);
3122 else if (defaultHandler
)
3123 reportDefault(parser
, enc
, s
, next
);
3126 if (ps_parsing
== XML_FINISHED
)
3127 return XML_ERROR_ABORTED
;
3129 return XML_ERROR_NONE
;
3130 case XML_TOK_DATA_NEWLINE
:
3131 if (characterDataHandler
) {
3133 characterDataHandler(handlerArg
, &c
, 1);
3135 else if (defaultHandler
)
3136 reportDefault(parser
, enc
, s
, next
);
3138 case XML_TOK_DATA_CHARS
:
3140 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3141 if (charDataHandler
) {
3142 if (MUST_CONVERT(enc
, s
)) {
3144 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3145 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3147 charDataHandler(handlerArg
, dataBuf
,
3148 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3155 charDataHandler(handlerArg
,
3157 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3159 else if (defaultHandler
)
3160 reportDefault(parser
, enc
, s
, next
);
3163 case XML_TOK_INVALID
:
3165 return XML_ERROR_INVALID_TOKEN
;
3166 case XML_TOK_PARTIAL_CHAR
:
3169 return XML_ERROR_NONE
;
3171 return XML_ERROR_PARTIAL_CHAR
;
3172 case XML_TOK_PARTIAL
:
3176 return XML_ERROR_NONE
;
3178 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3181 return XML_ERROR_UNEXPECTED_STATE
;
3184 *eventPP
= s
= next
;
3185 switch (ps_parsing
) {
3188 return XML_ERROR_NONE
;
3190 return XML_ERROR_ABORTED
;
3199 /* The idea here is to avoid using stack for each IGNORE section when
3200 the whole file is parsed with one call.
3202 static enum XML_Error PTRCALL
3203 ignoreSectionProcessor(XML_Parser parser
,
3206 const char **endPtr
)
3208 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3209 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3210 if (result
!= XML_ERROR_NONE
)
3213 processor
= prologProcessor
;
3214 return prologProcessor(parser
, start
, end
, endPtr
);
3219 /* startPtr gets set to non-null is the section is closed, and to null
3220 if the section is not yet closed.
3222 static enum XML_Error
3223 doIgnoreSection(XML_Parser parser
,
3224 const ENCODING
*enc
,
3225 const char **startPtr
,
3227 const char **nextPtr
,
3232 const char *s
= *startPtr
;
3233 const char **eventPP
;
3234 const char **eventEndPP
;
3235 if (enc
== encoding
) {
3236 eventPP
= &eventPtr
;
3238 eventEndPP
= &eventEndPtr
;
3241 eventPP
= &(openInternalEntities
->internalEventPtr
);
3242 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3246 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3249 case XML_TOK_IGNORE_SECT
:
3251 reportDefault(parser
, enc
, s
, next
);
3254 if (ps_parsing
== XML_FINISHED
)
3255 return XML_ERROR_ABORTED
;
3257 return XML_ERROR_NONE
;
3258 case XML_TOK_INVALID
:
3260 return XML_ERROR_INVALID_TOKEN
;
3261 case XML_TOK_PARTIAL_CHAR
:
3264 return XML_ERROR_NONE
;
3266 return XML_ERROR_PARTIAL_CHAR
;
3267 case XML_TOK_PARTIAL
:
3271 return XML_ERROR_NONE
;
3273 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3276 return XML_ERROR_UNEXPECTED_STATE
;
3281 #endif /* XML_DTD */
3283 static enum XML_Error
3284 initializeEncoding(XML_Parser parser
)
3288 char encodingBuf
[128];
3289 if (!protocolEncodingName
)
3293 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3294 if (i
== sizeof(encodingBuf
) - 1
3295 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3296 encodingBuf
[0] = '\0';
3299 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3301 encodingBuf
[i
] = '\0';
3305 s
= protocolEncodingName
;
3307 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3308 return XML_ERROR_NONE
;
3309 return handleUnknownEncoding(parser
, protocolEncodingName
);
3312 static enum XML_Error
3313 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3314 const char *s
, const char *next
)
3316 const char *encodingName
= NULL
;
3317 const XML_Char
*storedEncName
= NULL
;
3318 const ENCODING
*newEncoding
= NULL
;
3319 const char *version
= NULL
;
3320 const char *versionend
;
3321 const XML_Char
*storedversion
= NULL
;
3322 int standalone
= -1;
3325 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3335 if (isGeneralTextEntity
)
3336 return XML_ERROR_TEXT_DECL
;
3338 return XML_ERROR_XML_DECL
;
3340 if (!isGeneralTextEntity
&& standalone
== 1) {
3341 _dtd
->standalone
= XML_TRUE
;
3343 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3344 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3345 #endif /* XML_DTD */
3347 if (xmlDeclHandler
) {
3348 if (encodingName
!= NULL
) {
3349 storedEncName
= poolStoreString(&temp2Pool
,
3353 + XmlNameLength(encoding
, encodingName
));
3355 return XML_ERROR_NO_MEMORY
;
3356 poolFinish(&temp2Pool
);
3359 storedversion
= poolStoreString(&temp2Pool
,
3362 versionend
- encoding
->minBytesPerChar
);
3364 return XML_ERROR_NO_MEMORY
;
3366 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3368 else if (defaultHandler
)
3369 reportDefault(parser
, encoding
, s
, next
);
3370 if (protocolEncodingName
== NULL
) {
3372 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3373 eventPtr
= encodingName
;
3374 return XML_ERROR_INCORRECT_ENCODING
;
3376 encoding
= newEncoding
;
3378 else if (encodingName
) {
3379 enum XML_Error result
;
3380 if (!storedEncName
) {
3381 storedEncName
= poolStoreString(
3382 &temp2Pool
, encoding
, encodingName
,
3383 encodingName
+ XmlNameLength(encoding
, encodingName
));
3385 return XML_ERROR_NO_MEMORY
;
3387 result
= handleUnknownEncoding(parser
, storedEncName
);
3388 poolClear(&temp2Pool
);
3389 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3390 eventPtr
= encodingName
;
3395 if (storedEncName
|| storedversion
)
3396 poolClear(&temp2Pool
);
3398 return XML_ERROR_NONE
;
3401 static enum XML_Error
3402 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3404 if (unknownEncodingHandler
) {
3407 for (i
= 0; i
< 256; i
++)
3409 info
.convert
= NULL
;
3411 info
.release
= NULL
;
3412 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3415 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3416 if (!unknownEncodingMem
) {
3418 info
.release(info
.data
);
3419 return XML_ERROR_NO_MEMORY
;
3422 ? XmlInitUnknownEncodingNS
3423 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3428 unknownEncodingData
= info
.data
;
3429 unknownEncodingRelease
= info
.release
;
3431 return XML_ERROR_NONE
;
3434 if (info
.release
!= NULL
)
3435 info
.release(info
.data
);
3437 return XML_ERROR_UNKNOWN_ENCODING
;
3440 static enum XML_Error PTRCALL
3441 prologInitProcessor(XML_Parser parser
,
3444 const char **nextPtr
)
3446 enum XML_Error result
= initializeEncoding(parser
);
3447 if (result
!= XML_ERROR_NONE
)
3449 processor
= prologProcessor
;
3450 return prologProcessor(parser
, s
, end
, nextPtr
);
3455 static enum XML_Error PTRCALL
3456 externalParEntInitProcessor(XML_Parser parser
,
3459 const char **nextPtr
)
3461 enum XML_Error result
= initializeEncoding(parser
);
3462 if (result
!= XML_ERROR_NONE
)
3465 /* we know now that XML_Parse(Buffer) has been called,
3466 so we consider the external parameter entity read */
3467 _dtd
->paramEntityRead
= XML_TRUE
;
3469 if (prologState
.inEntityValue
) {
3470 processor
= entityValueInitProcessor
;
3471 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3474 processor
= externalParEntProcessor
;
3475 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3479 static enum XML_Error PTRCALL
3480 entityValueInitProcessor(XML_Parser parser
,
3483 const char **nextPtr
)
3486 const char *start
= s
;
3487 const char *next
= start
;
3491 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3494 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3496 return XML_ERROR_NONE
;
3499 case XML_TOK_INVALID
:
3500 return XML_ERROR_INVALID_TOKEN
;
3501 case XML_TOK_PARTIAL
:
3502 return XML_ERROR_UNCLOSED_TOKEN
;
3503 case XML_TOK_PARTIAL_CHAR
:
3504 return XML_ERROR_PARTIAL_CHAR
;
3505 case XML_TOK_NONE
: /* start == end */
3509 /* found end of entity value - can store it now */
3510 return storeEntityValue(parser
, encoding
, s
, end
);
3512 else if (tok
== XML_TOK_XML_DECL
) {
3513 enum XML_Error result
;
3514 result
= processXmlDecl(parser
, 0, start
, next
);
3515 if (result
!= XML_ERROR_NONE
)
3517 switch (ps_parsing
) {
3520 return XML_ERROR_NONE
;
3522 return XML_ERROR_ABORTED
;
3526 /* stop scanning for text declaration - we found one */
3527 processor
= entityValueProcessor
;
3528 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3530 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3531 return XML_TOK_NONE on the next call, which would then cause the
3532 function to exit with *nextPtr set to s - that is what we want for other
3533 tokens, but not for the BOM - we would rather like to skip it;
3534 then, when this routine is entered the next time, XmlPrologTok will
3535 return XML_TOK_INVALID, since the BOM is still in the buffer
3537 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3539 return XML_ERROR_NONE
;
3546 static enum XML_Error PTRCALL
3547 externalParEntProcessor(XML_Parser parser
,
3550 const char **nextPtr
)
3552 const char *next
= s
;
3555 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3557 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3559 return XML_ERROR_NONE
;
3562 case XML_TOK_INVALID
:
3563 return XML_ERROR_INVALID_TOKEN
;
3564 case XML_TOK_PARTIAL
:
3565 return XML_ERROR_UNCLOSED_TOKEN
;
3566 case XML_TOK_PARTIAL_CHAR
:
3567 return XML_ERROR_PARTIAL_CHAR
;
3568 case XML_TOK_NONE
: /* start == end */
3573 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3574 However, when parsing an external subset, doProlog will not accept a BOM
3575 as valid, and report a syntax error, so we have to skip the BOM
3577 else if (tok
== XML_TOK_BOM
) {
3579 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3582 processor
= prologProcessor
;
3583 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3584 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3587 static enum XML_Error PTRCALL
3588 entityValueProcessor(XML_Parser parser
,
3591 const char **nextPtr
)
3593 const char *start
= s
;
3594 const char *next
= s
;
3595 const ENCODING
*enc
= encoding
;
3599 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3601 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3603 return XML_ERROR_NONE
;
3606 case XML_TOK_INVALID
:
3607 return XML_ERROR_INVALID_TOKEN
;
3608 case XML_TOK_PARTIAL
:
3609 return XML_ERROR_UNCLOSED_TOKEN
;
3610 case XML_TOK_PARTIAL_CHAR
:
3611 return XML_ERROR_PARTIAL_CHAR
;
3612 case XML_TOK_NONE
: /* start == end */
3616 /* found end of entity value - can store it now */
3617 return storeEntityValue(parser
, enc
, s
, end
);
3623 #endif /* XML_DTD */
3625 static enum XML_Error PTRCALL
3626 prologProcessor(XML_Parser parser
,
3629 const char **nextPtr
)
3631 const char *next
= s
;
3632 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3633 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3634 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3637 static enum XML_Error
3638 doProlog(XML_Parser parser
,
3639 const ENCODING
*enc
,
3644 const char **nextPtr
,
3648 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3649 #endif /* XML_DTD */
3650 static const XML_Char atypeCDATA
[] =
3651 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3652 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3653 static const XML_Char atypeIDREF
[] =
3654 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3655 static const XML_Char atypeIDREFS
[] =
3656 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3657 static const XML_Char atypeENTITY
[] =
3658 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3659 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3660 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3661 static const XML_Char atypeNMTOKEN
[] = {
3662 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3663 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3664 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3665 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3666 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3667 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3668 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3670 /* save one level of indirection */
3671 DTD
* const dtd
= _dtd
;
3673 const char **eventPP
;
3674 const char **eventEndPP
;
3675 enum XML_Content_Quant quant
;
3677 if (enc
== encoding
) {
3678 eventPP
= &eventPtr
;
3679 eventEndPP
= &eventEndPtr
;
3682 eventPP
= &(openInternalEntities
->internalEventPtr
);
3683 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3688 XML_Bool handleDefault
= XML_TRUE
;
3692 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3694 return XML_ERROR_NONE
;
3697 case XML_TOK_INVALID
:
3699 return XML_ERROR_INVALID_TOKEN
;
3700 case XML_TOK_PARTIAL
:
3701 return XML_ERROR_UNCLOSED_TOKEN
;
3702 case XML_TOK_PARTIAL_CHAR
:
3703 return XML_ERROR_PARTIAL_CHAR
;
3704 case -XML_TOK_PROLOG_S
:
3709 /* for internal PE NOT referenced between declarations */
3710 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3712 return XML_ERROR_NONE
;
3714 /* WFC: PE Between Declarations - must check that PE contains
3715 complete markup, not only for external PEs, but also for
3716 internal PEs if the reference occurs between declarations.
3718 if (isParamEntity
|| enc
!= encoding
) {
3719 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3721 return XML_ERROR_INCOMPLETE_PE
;
3723 return XML_ERROR_NONE
;
3725 #endif /* XML_DTD */
3726 return XML_ERROR_NO_ELEMENTS
;
3733 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3735 case XML_ROLE_XML_DECL
:
3737 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3738 if (result
!= XML_ERROR_NONE
)
3741 handleDefault
= XML_FALSE
;
3744 case XML_ROLE_DOCTYPE_NAME
:
3745 if (startDoctypeDeclHandler
) {
3746 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3748 return XML_ERROR_NO_MEMORY
;
3749 poolFinish(&tempPool
);
3750 doctypePubid
= NULL
;
3751 handleDefault
= XML_FALSE
;
3753 doctypeSysid
= NULL
; /* always initialize to NULL */
3755 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3756 if (startDoctypeDeclHandler
) {
3757 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3760 poolClear(&tempPool
);
3761 handleDefault
= XML_FALSE
;
3765 case XML_ROLE_TEXT_DECL
:
3767 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3768 if (result
!= XML_ERROR_NONE
)
3771 handleDefault
= XML_FALSE
;
3774 #endif /* XML_DTD */
3775 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3777 useForeignDTD
= XML_FALSE
;
3778 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3782 return XML_ERROR_NO_MEMORY
;
3783 #endif /* XML_DTD */
3784 dtd
->hasParamEntityRefs
= XML_TRUE
;
3785 if (startDoctypeDeclHandler
) {
3787 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3788 return XML_ERROR_PUBLICID
;
3789 pubId
= poolStoreString(&tempPool
, enc
,
3790 s
+ enc
->minBytesPerChar
,
3791 next
- enc
->minBytesPerChar
);
3793 return XML_ERROR_NO_MEMORY
;
3794 normalizePublicId(pubId
);
3795 poolFinish(&tempPool
);
3796 doctypePubid
= pubId
;
3797 handleDefault
= XML_FALSE
;
3798 goto alreadyChecked
;
3801 case XML_ROLE_ENTITY_PUBLIC_ID
:
3802 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3803 return XML_ERROR_PUBLICID
;
3805 if (dtd
->keepProcessing
&& declEntity
) {
3806 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3808 s
+ enc
->minBytesPerChar
,
3809 next
- enc
->minBytesPerChar
);
3811 return XML_ERROR_NO_MEMORY
;
3812 normalizePublicId(tem
);
3813 declEntity
->publicId
= tem
;
3814 poolFinish(&dtd
->pool
);
3815 if (entityDeclHandler
)
3816 handleDefault
= XML_FALSE
;
3819 case XML_ROLE_DOCTYPE_CLOSE
:
3821 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3822 doctypeSysid
, doctypePubid
, 0);
3823 poolClear(&tempPool
);
3824 handleDefault
= XML_FALSE
;
3826 /* doctypeSysid will be non-NULL in the case of a previous
3827 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3828 was not set, indicating an external subset
3831 if (doctypeSysid
|| useForeignDTD
) {
3832 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3833 dtd
->hasParamEntityRefs
= XML_TRUE
;
3834 if (paramEntityParsing
&& externalEntityRefHandler
) {
3835 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3839 return XML_ERROR_NO_MEMORY
;
3841 entity
->base
= curBase
;
3842 dtd
->paramEntityRead
= XML_FALSE
;
3843 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3848 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3849 if (dtd
->paramEntityRead
) {
3850 if (!dtd
->standalone
&&
3851 notStandaloneHandler
&&
3852 !notStandaloneHandler(handlerArg
))
3853 return XML_ERROR_NOT_STANDALONE
;
3855 /* if we didn't read the foreign DTD then this means that there
3856 is no external subset and we must reset dtd->hasParamEntityRefs
3858 else if (!doctypeSysid
)
3859 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3860 /* end of DTD - no need to update dtd->keepProcessing */
3862 useForeignDTD
= XML_FALSE
;
3864 #endif /* XML_DTD */
3865 if (endDoctypeDeclHandler
) {
3866 endDoctypeDeclHandler(handlerArg
);
3867 handleDefault
= XML_FALSE
;
3870 case XML_ROLE_INSTANCE_START
:
3872 /* if there is no DOCTYPE declaration then now is the
3873 last chance to read the foreign DTD
3875 if (useForeignDTD
) {
3876 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3877 dtd
->hasParamEntityRefs
= XML_TRUE
;
3878 if (paramEntityParsing
&& externalEntityRefHandler
) {
3879 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3883 return XML_ERROR_NO_MEMORY
;
3884 entity
->base
= curBase
;
3885 dtd
->paramEntityRead
= XML_FALSE
;
3886 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3891 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3892 if (dtd
->paramEntityRead
) {
3893 if (!dtd
->standalone
&&
3894 notStandaloneHandler
&&
3895 !notStandaloneHandler(handlerArg
))
3896 return XML_ERROR_NOT_STANDALONE
;
3898 /* if we didn't read the foreign DTD then this means that there
3899 is no external subset and we must reset dtd->hasParamEntityRefs
3902 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3903 /* end of DTD - no need to update dtd->keepProcessing */
3906 #endif /* XML_DTD */
3907 processor
= contentProcessor
;
3908 return contentProcessor(parser
, s
, end
, nextPtr
);
3909 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3910 declElementType
= getElementType(parser
, enc
, s
, next
);
3911 if (!declElementType
)
3912 return XML_ERROR_NO_MEMORY
;
3913 goto checkAttListDeclHandler
;
3914 case XML_ROLE_ATTRIBUTE_NAME
:
3915 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3916 if (!declAttributeId
)
3917 return XML_ERROR_NO_MEMORY
;
3918 declAttributeIsCdata
= XML_FALSE
;
3919 declAttributeType
= NULL
;
3920 declAttributeIsId
= XML_FALSE
;
3921 goto checkAttListDeclHandler
;
3922 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3923 declAttributeIsCdata
= XML_TRUE
;
3924 declAttributeType
= atypeCDATA
;
3925 goto checkAttListDeclHandler
;
3926 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3927 declAttributeIsId
= XML_TRUE
;
3928 declAttributeType
= atypeID
;
3929 goto checkAttListDeclHandler
;
3930 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3931 declAttributeType
= atypeIDREF
;
3932 goto checkAttListDeclHandler
;
3933 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3934 declAttributeType
= atypeIDREFS
;
3935 goto checkAttListDeclHandler
;
3936 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3937 declAttributeType
= atypeENTITY
;
3938 goto checkAttListDeclHandler
;
3939 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3940 declAttributeType
= atypeENTITIES
;
3941 goto checkAttListDeclHandler
;
3942 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3943 declAttributeType
= atypeNMTOKEN
;
3944 goto checkAttListDeclHandler
;
3945 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3946 declAttributeType
= atypeNMTOKENS
;
3947 checkAttListDeclHandler
:
3948 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3949 handleDefault
= XML_FALSE
;
3951 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3952 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3953 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3954 const XML_Char
*prefix
;
3955 if (declAttributeType
) {
3956 prefix
= enumValueSep
;
3959 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3963 if (!poolAppendString(&tempPool
, prefix
))
3964 return XML_ERROR_NO_MEMORY
;
3965 if (!poolAppend(&tempPool
, enc
, s
, next
))
3966 return XML_ERROR_NO_MEMORY
;
3967 declAttributeType
= tempPool
.start
;
3968 handleDefault
= XML_FALSE
;
3971 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3972 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3973 if (dtd
->keepProcessing
) {
3974 if (!defineAttribute(declElementType
, declAttributeId
,
3975 declAttributeIsCdata
, declAttributeIsId
,
3977 return XML_ERROR_NO_MEMORY
;
3978 if (attlistDeclHandler
&& declAttributeType
) {
3979 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
3980 || (*declAttributeType
== XML_T(ASCII_N
)
3981 && declAttributeType
[1] == XML_T(ASCII_O
))) {
3982 /* Enumerated or Notation type */
3983 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
3984 || !poolAppendChar(&tempPool
, XML_T('\0')))
3985 return XML_ERROR_NO_MEMORY
;
3986 declAttributeType
= tempPool
.start
;
3987 poolFinish(&tempPool
);
3990 attlistDeclHandler(handlerArg
, declElementType
->name
,
3991 declAttributeId
->name
, declAttributeType
,
3992 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3993 poolClear(&tempPool
);
3994 handleDefault
= XML_FALSE
;
3998 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3999 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
4000 if (dtd
->keepProcessing
) {
4001 const XML_Char
*attVal
;
4002 enum XML_Error result
=
4003 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4004 s
+ enc
->minBytesPerChar
,
4005 next
- enc
->minBytesPerChar
,
4009 attVal
= poolStart(&dtd
->pool
);
4010 poolFinish(&dtd
->pool
);
4011 /* ID attributes aren't allowed to have a default */
4012 if (!defineAttribute(declElementType
, declAttributeId
,
4013 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4014 return XML_ERROR_NO_MEMORY
;
4015 if (attlistDeclHandler
&& declAttributeType
) {
4016 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4017 || (*declAttributeType
== XML_T(ASCII_N
)
4018 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4019 /* Enumerated or Notation type */
4020 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4021 || !poolAppendChar(&tempPool
, XML_T('\0')))
4022 return XML_ERROR_NO_MEMORY
;
4023 declAttributeType
= tempPool
.start
;
4024 poolFinish(&tempPool
);
4027 attlistDeclHandler(handlerArg
, declElementType
->name
,
4028 declAttributeId
->name
, declAttributeType
,
4030 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4031 poolClear(&tempPool
);
4032 handleDefault
= XML_FALSE
;
4036 case XML_ROLE_ENTITY_VALUE
:
4037 if (dtd
->keepProcessing
) {
4038 enum XML_Error result
= storeEntityValue(parser
, enc
,
4039 s
+ enc
->minBytesPerChar
,
4040 next
- enc
->minBytesPerChar
);
4042 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4043 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4044 poolFinish(&dtd
->entityValuePool
);
4045 if (entityDeclHandler
) {
4047 entityDeclHandler(handlerArg
,
4049 declEntity
->is_param
,
4050 declEntity
->textPtr
,
4051 declEntity
->textLen
,
4053 handleDefault
= XML_FALSE
;
4057 poolDiscard(&dtd
->entityValuePool
);
4058 if (result
!= XML_ERROR_NONE
)
4062 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4064 useForeignDTD
= XML_FALSE
;
4065 #endif /* XML_DTD */
4066 dtd
->hasParamEntityRefs
= XML_TRUE
;
4067 if (startDoctypeDeclHandler
) {
4068 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4069 s
+ enc
->minBytesPerChar
,
4070 next
- enc
->minBytesPerChar
);
4071 if (doctypeSysid
== NULL
)
4072 return XML_ERROR_NO_MEMORY
;
4073 poolFinish(&tempPool
);
4074 handleDefault
= XML_FALSE
;
4078 /* use externalSubsetName to make doctypeSysid non-NULL
4079 for the case where no startDoctypeDeclHandler is set */
4080 doctypeSysid
= externalSubsetName
;
4081 #endif /* XML_DTD */
4082 if (!dtd
->standalone
4084 && !paramEntityParsing
4085 #endif /* XML_DTD */
4086 && notStandaloneHandler
4087 && !notStandaloneHandler(handlerArg
))
4088 return XML_ERROR_NOT_STANDALONE
;
4093 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4097 return XML_ERROR_NO_MEMORY
;
4098 declEntity
->publicId
= NULL
;
4101 #endif /* XML_DTD */
4102 case XML_ROLE_ENTITY_SYSTEM_ID
:
4103 if (dtd
->keepProcessing
&& declEntity
) {
4104 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4105 s
+ enc
->minBytesPerChar
,
4106 next
- enc
->minBytesPerChar
);
4107 if (!declEntity
->systemId
)
4108 return XML_ERROR_NO_MEMORY
;
4109 declEntity
->base
= curBase
;
4110 poolFinish(&dtd
->pool
);
4111 if (entityDeclHandler
)
4112 handleDefault
= XML_FALSE
;
4115 case XML_ROLE_ENTITY_COMPLETE
:
4116 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4118 entityDeclHandler(handlerArg
,
4120 declEntity
->is_param
,
4123 declEntity
->systemId
,
4124 declEntity
->publicId
,
4126 handleDefault
= XML_FALSE
;
4129 case XML_ROLE_ENTITY_NOTATION_NAME
:
4130 if (dtd
->keepProcessing
&& declEntity
) {
4131 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4132 if (!declEntity
->notation
)
4133 return XML_ERROR_NO_MEMORY
;
4134 poolFinish(&dtd
->pool
);
4135 if (unparsedEntityDeclHandler
) {
4137 unparsedEntityDeclHandler(handlerArg
,
4140 declEntity
->systemId
,
4141 declEntity
->publicId
,
4142 declEntity
->notation
);
4143 handleDefault
= XML_FALSE
;
4145 else if (entityDeclHandler
) {
4147 entityDeclHandler(handlerArg
,
4151 declEntity
->systemId
,
4152 declEntity
->publicId
,
4153 declEntity
->notation
);
4154 handleDefault
= XML_FALSE
;
4158 case XML_ROLE_GENERAL_ENTITY_NAME
:
4160 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4164 if (dtd
->keepProcessing
) {
4165 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4167 return XML_ERROR_NO_MEMORY
;
4168 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4171 return XML_ERROR_NO_MEMORY
;
4172 if (declEntity
->name
!= name
) {
4173 poolDiscard(&dtd
->pool
);
4177 poolFinish(&dtd
->pool
);
4178 declEntity
->publicId
= NULL
;
4179 declEntity
->is_param
= XML_FALSE
;
4180 /* if we have a parent parser or are reading an internal parameter
4181 entity, then the entity declaration is not considered "internal"
4183 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4184 if (entityDeclHandler
)
4185 handleDefault
= XML_FALSE
;
4189 poolDiscard(&dtd
->pool
);
4194 case XML_ROLE_PARAM_ENTITY_NAME
:
4196 if (dtd
->keepProcessing
) {
4197 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4199 return XML_ERROR_NO_MEMORY
;
4200 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4201 name
, sizeof(ENTITY
));
4203 return XML_ERROR_NO_MEMORY
;
4204 if (declEntity
->name
!= name
) {
4205 poolDiscard(&dtd
->pool
);
4209 poolFinish(&dtd
->pool
);
4210 declEntity
->publicId
= NULL
;
4211 declEntity
->is_param
= XML_TRUE
;
4212 /* if we have a parent parser or are reading an internal parameter
4213 entity, then the entity declaration is not considered "internal"
4215 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4216 if (entityDeclHandler
)
4217 handleDefault
= XML_FALSE
;
4221 poolDiscard(&dtd
->pool
);
4224 #else /* not XML_DTD */
4226 #endif /* XML_DTD */
4228 case XML_ROLE_NOTATION_NAME
:
4229 declNotationPublicId
= NULL
;
4230 declNotationName
= NULL
;
4231 if (notationDeclHandler
) {
4232 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4233 if (!declNotationName
)
4234 return XML_ERROR_NO_MEMORY
;
4235 poolFinish(&tempPool
);
4236 handleDefault
= XML_FALSE
;
4239 case XML_ROLE_NOTATION_PUBLIC_ID
:
4240 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4241 return XML_ERROR_PUBLICID
;
4242 if (declNotationName
) { /* means notationDeclHandler != NULL */
4243 XML_Char
*tem
= poolStoreString(&tempPool
,
4245 s
+ enc
->minBytesPerChar
,
4246 next
- enc
->minBytesPerChar
);
4248 return XML_ERROR_NO_MEMORY
;
4249 normalizePublicId(tem
);
4250 declNotationPublicId
= tem
;
4251 poolFinish(&tempPool
);
4252 handleDefault
= XML_FALSE
;
4255 case XML_ROLE_NOTATION_SYSTEM_ID
:
4256 if (declNotationName
&& notationDeclHandler
) {
4257 const XML_Char
*systemId
4258 = poolStoreString(&tempPool
, enc
,
4259 s
+ enc
->minBytesPerChar
,
4260 next
- enc
->minBytesPerChar
);
4262 return XML_ERROR_NO_MEMORY
;
4264 notationDeclHandler(handlerArg
,
4268 declNotationPublicId
);
4269 handleDefault
= XML_FALSE
;
4271 poolClear(&tempPool
);
4273 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4274 if (declNotationPublicId
&& notationDeclHandler
) {
4276 notationDeclHandler(handlerArg
,
4280 declNotationPublicId
);
4281 handleDefault
= XML_FALSE
;
4283 poolClear(&tempPool
);
4285 case XML_ROLE_ERROR
:
4287 case XML_TOK_PARAM_ENTITY_REF
:
4288 /* PE references in internal subset are
4289 not allowed within declarations. */
4290 return XML_ERROR_PARAM_ENTITY_REF
;
4291 case XML_TOK_XML_DECL
:
4292 return XML_ERROR_MISPLACED_XML_PI
;
4294 return XML_ERROR_SYNTAX
;
4297 case XML_ROLE_IGNORE_SECT
:
4299 enum XML_Error result
;
4301 reportDefault(parser
, enc
, s
, next
);
4302 handleDefault
= XML_FALSE
;
4303 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4304 if (result
!= XML_ERROR_NONE
)
4307 processor
= ignoreSectionProcessor
;
4312 #endif /* XML_DTD */
4313 case XML_ROLE_GROUP_OPEN
:
4314 if (prologState
.level
>= groupSize
) {
4316 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4318 return XML_ERROR_NO_MEMORY
;
4319 groupConnector
= temp
;
4320 if (dtd
->scaffIndex
) {
4321 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4322 groupSize
* sizeof(int));
4324 return XML_ERROR_NO_MEMORY
;
4325 dtd
->scaffIndex
= temp
;
4329 groupConnector
= (char *)MALLOC(groupSize
= 32);
4330 if (!groupConnector
)
4331 return XML_ERROR_NO_MEMORY
;
4334 groupConnector
[prologState
.level
] = 0;
4335 if (dtd
->in_eldecl
) {
4336 int myindex
= nextScaffoldPart(parser
);
4338 return XML_ERROR_NO_MEMORY
;
4339 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4341 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4342 if (elementDeclHandler
)
4343 handleDefault
= XML_FALSE
;
4346 case XML_ROLE_GROUP_SEQUENCE
:
4347 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4348 return XML_ERROR_SYNTAX
;
4349 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4350 if (dtd
->in_eldecl
&& elementDeclHandler
)
4351 handleDefault
= XML_FALSE
;
4353 case XML_ROLE_GROUP_CHOICE
:
4354 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4355 return XML_ERROR_SYNTAX
;
4357 && !groupConnector
[prologState
.level
]
4358 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4361 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4363 if (elementDeclHandler
)
4364 handleDefault
= XML_FALSE
;
4366 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4368 case XML_ROLE_PARAM_ENTITY_REF
:
4370 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4371 dtd
->hasParamEntityRefs
= XML_TRUE
;
4372 if (!paramEntityParsing
)
4373 dtd
->keepProcessing
= dtd
->standalone
;
4375 const XML_Char
*name
;
4377 name
= poolStoreString(&dtd
->pool
, enc
,
4378 s
+ enc
->minBytesPerChar
,
4379 next
- enc
->minBytesPerChar
);
4381 return XML_ERROR_NO_MEMORY
;
4382 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4383 poolDiscard(&dtd
->pool
);
4384 /* first, determine if a check for an existing declaration is needed;
4385 if yes, check that the entity exists, and that it is internal,
4386 otherwise call the skipped entity handler
4388 if (prologState
.documentEntity
&&
4390 ? !openInternalEntities
4391 : !dtd
->hasParamEntityRefs
)) {
4393 return XML_ERROR_UNDEFINED_ENTITY
;
4394 else if (!entity
->is_internal
)
4395 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4398 dtd
->keepProcessing
= dtd
->standalone
;
4399 /* cannot report skipped entities in declarations */
4400 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4401 skippedEntityHandler(handlerArg
, name
, 1);
4402 handleDefault
= XML_FALSE
;
4407 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4408 if (entity
->textPtr
) {
4409 enum XML_Error result
;
4410 XML_Bool betweenDecl
=
4411 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4412 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4413 if (result
!= XML_ERROR_NONE
)
4415 handleDefault
= XML_FALSE
;
4418 if (externalEntityRefHandler
) {
4419 dtd
->paramEntityRead
= XML_FALSE
;
4420 entity
->open
= XML_TRUE
;
4421 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4425 entity
->publicId
)) {
4426 entity
->open
= XML_FALSE
;
4427 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4429 entity
->open
= XML_FALSE
;
4430 handleDefault
= XML_FALSE
;
4431 if (!dtd
->paramEntityRead
) {
4432 dtd
->keepProcessing
= dtd
->standalone
;
4437 dtd
->keepProcessing
= dtd
->standalone
;
4441 #endif /* XML_DTD */
4442 if (!dtd
->standalone
&&
4443 notStandaloneHandler
&&
4444 !notStandaloneHandler(handlerArg
))
4445 return XML_ERROR_NOT_STANDALONE
;
4448 /* Element declaration stuff */
4450 case XML_ROLE_ELEMENT_NAME
:
4451 if (elementDeclHandler
) {
4452 declElementType
= getElementType(parser
, enc
, s
, next
);
4453 if (!declElementType
)
4454 return XML_ERROR_NO_MEMORY
;
4455 dtd
->scaffLevel
= 0;
4456 dtd
->scaffCount
= 0;
4457 dtd
->in_eldecl
= XML_TRUE
;
4458 handleDefault
= XML_FALSE
;
4462 case XML_ROLE_CONTENT_ANY
:
4463 case XML_ROLE_CONTENT_EMPTY
:
4464 if (dtd
->in_eldecl
) {
4465 if (elementDeclHandler
) {
4466 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4468 return XML_ERROR_NO_MEMORY
;
4469 content
->quant
= XML_CQUANT_NONE
;
4470 content
->name
= NULL
;
4471 content
->numchildren
= 0;
4472 content
->children
= NULL
;
4473 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4477 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4478 handleDefault
= XML_FALSE
;
4480 dtd
->in_eldecl
= XML_FALSE
;
4484 case XML_ROLE_CONTENT_PCDATA
:
4485 if (dtd
->in_eldecl
) {
4486 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4488 if (elementDeclHandler
)
4489 handleDefault
= XML_FALSE
;
4493 case XML_ROLE_CONTENT_ELEMENT
:
4494 quant
= XML_CQUANT_NONE
;
4495 goto elementContent
;
4496 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4497 quant
= XML_CQUANT_OPT
;
4498 goto elementContent
;
4499 case XML_ROLE_CONTENT_ELEMENT_REP
:
4500 quant
= XML_CQUANT_REP
;
4501 goto elementContent
;
4502 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4503 quant
= XML_CQUANT_PLUS
;
4505 if (dtd
->in_eldecl
) {
4507 const XML_Char
*name
;
4509 const char *nxt
= (quant
== XML_CQUANT_NONE
4511 : next
- enc
->minBytesPerChar
);
4512 int myindex
= nextScaffoldPart(parser
);
4514 return XML_ERROR_NO_MEMORY
;
4515 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4516 dtd
->scaffold
[myindex
].quant
= quant
;
4517 el
= getElementType(parser
, enc
, s
, nxt
);
4519 return XML_ERROR_NO_MEMORY
;
4521 dtd
->scaffold
[myindex
].name
= name
;
4523 for (; name
[nameLen
++]; );
4524 dtd
->contentStringLen
+= nameLen
;
4525 if (elementDeclHandler
)
4526 handleDefault
= XML_FALSE
;
4530 case XML_ROLE_GROUP_CLOSE
:
4531 quant
= XML_CQUANT_NONE
;
4533 case XML_ROLE_GROUP_CLOSE_OPT
:
4534 quant
= XML_CQUANT_OPT
;
4536 case XML_ROLE_GROUP_CLOSE_REP
:
4537 quant
= XML_CQUANT_REP
;
4539 case XML_ROLE_GROUP_CLOSE_PLUS
:
4540 quant
= XML_CQUANT_PLUS
;
4542 if (dtd
->in_eldecl
) {
4543 if (elementDeclHandler
)
4544 handleDefault
= XML_FALSE
;
4546 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4547 if (dtd
->scaffLevel
== 0) {
4548 if (!handleDefault
) {
4549 XML_Content
*model
= build_model(parser
);
4551 return XML_ERROR_NO_MEMORY
;
4553 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4555 dtd
->in_eldecl
= XML_FALSE
;
4556 dtd
->contentStringLen
= 0;
4560 /* End element declaration stuff */
4563 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4564 return XML_ERROR_NO_MEMORY
;
4565 handleDefault
= XML_FALSE
;
4567 case XML_ROLE_COMMENT
:
4568 if (!reportComment(parser
, enc
, s
, next
))
4569 return XML_ERROR_NO_MEMORY
;
4570 handleDefault
= XML_FALSE
;
4575 handleDefault
= XML_FALSE
;
4579 case XML_ROLE_DOCTYPE_NONE
:
4580 if (startDoctypeDeclHandler
)
4581 handleDefault
= XML_FALSE
;
4583 case XML_ROLE_ENTITY_NONE
:
4584 if (dtd
->keepProcessing
&& entityDeclHandler
)
4585 handleDefault
= XML_FALSE
;
4587 case XML_ROLE_NOTATION_NONE
:
4588 if (notationDeclHandler
)
4589 handleDefault
= XML_FALSE
;
4591 case XML_ROLE_ATTLIST_NONE
:
4592 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4593 handleDefault
= XML_FALSE
;
4595 case XML_ROLE_ELEMENT_NONE
:
4596 if (elementDeclHandler
)
4597 handleDefault
= XML_FALSE
;
4599 } /* end of big switch */
4601 if (handleDefault
&& defaultHandler
)
4602 reportDefault(parser
, enc
, s
, next
);
4604 switch (ps_parsing
) {
4607 return XML_ERROR_NONE
;
4609 return XML_ERROR_ABORTED
;
4612 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4618 static enum XML_Error PTRCALL
4619 epilogProcessor(XML_Parser parser
,
4622 const char **nextPtr
)
4624 processor
= epilogProcessor
;
4627 const char *next
= NULL
;
4628 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4631 /* report partial linebreak - it might be the last token */
4632 case -XML_TOK_PROLOG_S
:
4633 if (defaultHandler
) {
4634 reportDefault(parser
, encoding
, s
, next
);
4635 if (ps_parsing
== XML_FINISHED
)
4636 return XML_ERROR_ABORTED
;
4639 return XML_ERROR_NONE
;
4642 return XML_ERROR_NONE
;
4643 case XML_TOK_PROLOG_S
:
4645 reportDefault(parser
, encoding
, s
, next
);
4648 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4649 return XML_ERROR_NO_MEMORY
;
4651 case XML_TOK_COMMENT
:
4652 if (!reportComment(parser
, encoding
, s
, next
))
4653 return XML_ERROR_NO_MEMORY
;
4655 case XML_TOK_INVALID
:
4657 return XML_ERROR_INVALID_TOKEN
;
4658 case XML_TOK_PARTIAL
:
4659 if (!ps_finalBuffer
) {
4661 return XML_ERROR_NONE
;
4663 return XML_ERROR_UNCLOSED_TOKEN
;
4664 case XML_TOK_PARTIAL_CHAR
:
4665 if (!ps_finalBuffer
) {
4667 return XML_ERROR_NONE
;
4669 return XML_ERROR_PARTIAL_CHAR
;
4671 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4673 eventPtr
= s
= next
;
4674 switch (ps_parsing
) {
4677 return XML_ERROR_NONE
;
4679 return XML_ERROR_ABORTED
;
4685 static enum XML_Error
4686 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4687 XML_Bool betweenDecl
)
4689 const char *textStart
, *textEnd
;
4691 enum XML_Error result
;
4692 OPEN_INTERNAL_ENTITY
*openEntity
;
4694 if (freeInternalEntities
) {
4695 openEntity
= freeInternalEntities
;
4696 freeInternalEntities
= openEntity
->next
;
4699 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4701 return XML_ERROR_NO_MEMORY
;
4703 entity
->open
= XML_TRUE
;
4704 entity
->processed
= 0;
4705 openEntity
->next
= openInternalEntities
;
4706 openInternalEntities
= openEntity
;
4707 openEntity
->entity
= entity
;
4708 openEntity
->startTagLevel
= tagLevel
;
4709 openEntity
->betweenDecl
= betweenDecl
;
4710 openEntity
->internalEventPtr
= NULL
;
4711 openEntity
->internalEventEndPtr
= NULL
;
4712 textStart
= (char *)entity
->textPtr
;
4713 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4716 if (entity
->is_param
) {
4717 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4718 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4719 next
, &next
, XML_FALSE
);
4722 #endif /* XML_DTD */
4723 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4724 textEnd
, &next
, XML_FALSE
);
4726 if (result
== XML_ERROR_NONE
) {
4727 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4728 entity
->processed
= (int)(next
- textStart
);
4729 processor
= internalEntityProcessor
;
4732 entity
->open
= XML_FALSE
;
4733 openInternalEntities
= openEntity
->next
;
4734 /* put openEntity back in list of free instances */
4735 openEntity
->next
= freeInternalEntities
;
4736 freeInternalEntities
= openEntity
;
4742 static enum XML_Error PTRCALL
4743 internalEntityProcessor(XML_Parser parser
,
4746 const char **nextPtr
)
4749 const char *textStart
, *textEnd
;
4751 enum XML_Error result
;
4752 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4754 return XML_ERROR_UNEXPECTED_STATE
;
4756 entity
= openEntity
->entity
;
4757 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4758 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4761 if (entity
->is_param
) {
4762 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4763 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4764 next
, &next
, XML_FALSE
);
4767 #endif /* XML_DTD */
4768 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4769 textStart
, textEnd
, &next
, XML_FALSE
);
4771 if (result
!= XML_ERROR_NONE
)
4773 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4774 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4778 entity
->open
= XML_FALSE
;
4779 openInternalEntities
= openEntity
->next
;
4780 /* put openEntity back in list of free instances */
4781 openEntity
->next
= freeInternalEntities
;
4782 freeInternalEntities
= openEntity
;
4786 if (entity
->is_param
) {
4788 processor
= prologProcessor
;
4789 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4790 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4791 (XML_Bool
)!ps_finalBuffer
);
4794 #endif /* XML_DTD */
4796 processor
= contentProcessor
;
4797 /* see externalEntityContentProcessor vs contentProcessor */
4798 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4799 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4803 static enum XML_Error PTRCALL
4804 errorProcessor(XML_Parser parser
,
4807 const char **nextPtr
)
4812 static enum XML_Error
4813 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4814 const char *ptr
, const char *end
,
4817 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4821 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4823 if (!poolAppendChar(pool
, XML_T('\0')))
4824 return XML_ERROR_NO_MEMORY
;
4825 return XML_ERROR_NONE
;
4828 static enum XML_Error
4829 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4830 const char *ptr
, const char *end
,
4833 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4836 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4839 return XML_ERROR_NONE
;
4840 case XML_TOK_INVALID
:
4841 if (enc
== encoding
)
4843 return XML_ERROR_INVALID_TOKEN
;
4844 case XML_TOK_PARTIAL
:
4845 if (enc
== encoding
)
4847 return XML_ERROR_INVALID_TOKEN
;
4848 case XML_TOK_CHAR_REF
:
4850 XML_Char buf
[XML_ENCODE_MAX
];
4852 int n
= XmlCharRefNumber(enc
, ptr
);
4854 if (enc
== encoding
)
4856 return XML_ERROR_BAD_CHAR_REF
;
4859 && n
== 0x20 /* space */
4860 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4862 n
= XmlEncode(n
, (ICHAR
*)buf
);
4864 if (enc
== encoding
)
4866 return XML_ERROR_BAD_CHAR_REF
;
4868 for (i
= 0; i
< n
; i
++) {
4869 if (!poolAppendChar(pool
, buf
[i
]))
4870 return XML_ERROR_NO_MEMORY
;
4874 case XML_TOK_DATA_CHARS
:
4875 if (!poolAppend(pool
, enc
, ptr
, next
))
4876 return XML_ERROR_NO_MEMORY
;
4878 case XML_TOK_TRAILING_CR
:
4879 next
= ptr
+ enc
->minBytesPerChar
;
4881 case XML_TOK_ATTRIBUTE_VALUE_S
:
4882 case XML_TOK_DATA_NEWLINE
:
4883 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4885 if (!poolAppendChar(pool
, 0x20))
4886 return XML_ERROR_NO_MEMORY
;
4888 case XML_TOK_ENTITY_REF
:
4890 const XML_Char
*name
;
4892 char checkEntityDecl
;
4893 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4894 ptr
+ enc
->minBytesPerChar
,
4895 next
- enc
->minBytesPerChar
);
4897 if (!poolAppendChar(pool
, ch
))
4898 return XML_ERROR_NO_MEMORY
;
4901 name
= poolStoreString(&temp2Pool
, enc
,
4902 ptr
+ enc
->minBytesPerChar
,
4903 next
- enc
->minBytesPerChar
);
4905 return XML_ERROR_NO_MEMORY
;
4906 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4907 poolDiscard(&temp2Pool
);
4908 /* First, determine if a check for an existing declaration is needed;
4909 if yes, check that the entity exists, and that it is internal.
4911 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4914 prologState
.documentEntity
&&
4915 #endif /* XML_DTD */
4917 ? !openInternalEntities
4918 : !dtd
->hasParamEntityRefs
);
4919 else /* if (pool == &tempPool): we are called from content */
4920 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4921 if (checkEntityDecl
) {
4923 return XML_ERROR_UNDEFINED_ENTITY
;
4924 else if (!entity
->is_internal
)
4925 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4928 /* Cannot report skipped entity here - see comments on
4929 skippedEntityHandler.
4930 if (skippedEntityHandler)
4931 skippedEntityHandler(handlerArg, name, 0);
4933 /* Cannot call the default handler because this would be
4934 out of sync with the call to the startElementHandler.
4935 if ((pool == &tempPool) && defaultHandler)
4936 reportDefault(parser, enc, ptr, next);
4941 if (enc
== encoding
)
4943 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4945 if (entity
->notation
) {
4946 if (enc
== encoding
)
4948 return XML_ERROR_BINARY_ENTITY_REF
;
4950 if (!entity
->textPtr
) {
4951 if (enc
== encoding
)
4953 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4956 enum XML_Error result
;
4957 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4958 entity
->open
= XML_TRUE
;
4959 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4960 (char *)entity
->textPtr
,
4961 (char *)textEnd
, pool
);
4962 entity
->open
= XML_FALSE
;
4969 if (enc
== encoding
)
4971 return XML_ERROR_UNEXPECTED_STATE
;
4978 static enum XML_Error
4979 storeEntityValue(XML_Parser parser
,
4980 const ENCODING
*enc
,
4981 const char *entityTextPtr
,
4982 const char *entityTextEnd
)
4984 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4985 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4986 enum XML_Error result
= XML_ERROR_NONE
;
4988 int oldInEntityValue
= prologState
.inEntityValue
;
4989 prologState
.inEntityValue
= 1;
4990 #endif /* XML_DTD */
4991 /* never return Null for the value argument in EntityDeclHandler,
4992 since this would indicate an external entity; therefore we
4993 have to make sure that entityValuePool.start is not null */
4994 if (!pool
->blocks
) {
4995 if (!poolGrow(pool
))
4996 return XML_ERROR_NO_MEMORY
;
5001 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5003 case XML_TOK_PARAM_ENTITY_REF
:
5005 if (isParamEntity
|| enc
!= encoding
) {
5006 const XML_Char
*name
;
5008 name
= poolStoreString(&tempPool
, enc
,
5009 entityTextPtr
+ enc
->minBytesPerChar
,
5010 next
- enc
->minBytesPerChar
);
5012 result
= XML_ERROR_NO_MEMORY
;
5013 goto endEntityValue
;
5015 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
5016 poolDiscard(&tempPool
);
5018 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5019 /* cannot report skipped entity here - see comments on
5020 skippedEntityHandler
5021 if (skippedEntityHandler)
5022 skippedEntityHandler(handlerArg, name, 0);
5024 dtd
->keepProcessing
= dtd
->standalone
;
5025 goto endEntityValue
;
5028 if (enc
== encoding
)
5029 eventPtr
= entityTextPtr
;
5030 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5031 goto endEntityValue
;
5033 if (entity
->systemId
) {
5034 if (externalEntityRefHandler
) {
5035 dtd
->paramEntityRead
= XML_FALSE
;
5036 entity
->open
= XML_TRUE
;
5037 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5041 entity
->publicId
)) {
5042 entity
->open
= XML_FALSE
;
5043 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5044 goto endEntityValue
;
5046 entity
->open
= XML_FALSE
;
5047 if (!dtd
->paramEntityRead
)
5048 dtd
->keepProcessing
= dtd
->standalone
;
5051 dtd
->keepProcessing
= dtd
->standalone
;
5054 entity
->open
= XML_TRUE
;
5055 result
= storeEntityValue(parser
,
5057 (char *)entity
->textPtr
,
5058 (char *)(entity
->textPtr
5059 + entity
->textLen
));
5060 entity
->open
= XML_FALSE
;
5062 goto endEntityValue
;
5066 #endif /* XML_DTD */
5067 /* In the internal subset, PE references are not legal
5068 within markup declarations, e.g entity values in this case. */
5069 eventPtr
= entityTextPtr
;
5070 result
= XML_ERROR_PARAM_ENTITY_REF
;
5071 goto endEntityValue
;
5073 result
= XML_ERROR_NONE
;
5074 goto endEntityValue
;
5075 case XML_TOK_ENTITY_REF
:
5076 case XML_TOK_DATA_CHARS
:
5077 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5078 result
= XML_ERROR_NO_MEMORY
;
5079 goto endEntityValue
;
5082 case XML_TOK_TRAILING_CR
:
5083 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5085 case XML_TOK_DATA_NEWLINE
:
5086 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5087 result
= XML_ERROR_NO_MEMORY
;
5088 goto endEntityValue
;
5090 *(pool
->ptr
)++ = 0xA;
5092 case XML_TOK_CHAR_REF
:
5094 XML_Char buf
[XML_ENCODE_MAX
];
5096 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5098 if (enc
== encoding
)
5099 eventPtr
= entityTextPtr
;
5100 result
= XML_ERROR_BAD_CHAR_REF
;
5101 goto endEntityValue
;
5103 n
= XmlEncode(n
, (ICHAR
*)buf
);
5105 if (enc
== encoding
)
5106 eventPtr
= entityTextPtr
;
5107 result
= XML_ERROR_BAD_CHAR_REF
;
5108 goto endEntityValue
;
5110 for (i
= 0; i
< n
; i
++) {
5111 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5112 result
= XML_ERROR_NO_MEMORY
;
5113 goto endEntityValue
;
5115 *(pool
->ptr
)++ = buf
[i
];
5119 case XML_TOK_PARTIAL
:
5120 if (enc
== encoding
)
5121 eventPtr
= entityTextPtr
;
5122 result
= XML_ERROR_INVALID_TOKEN
;
5123 goto endEntityValue
;
5124 case XML_TOK_INVALID
:
5125 if (enc
== encoding
)
5127 result
= XML_ERROR_INVALID_TOKEN
;
5128 goto endEntityValue
;
5130 if (enc
== encoding
)
5131 eventPtr
= entityTextPtr
;
5132 result
= XML_ERROR_UNEXPECTED_STATE
;
5133 goto endEntityValue
;
5135 entityTextPtr
= next
;
5139 prologState
.inEntityValue
= oldInEntityValue
;
5140 #endif /* XML_DTD */
5144 static void FASTCALL
5145 normalizeLines(XML_Char
*s
)
5149 if (*s
== XML_T('\0'))
5168 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5169 const char *start
, const char *end
)
5171 const XML_Char
*target
;
5174 if (!processingInstructionHandler
) {
5176 reportDefault(parser
, enc
, start
, end
);
5179 start
+= enc
->minBytesPerChar
* 2;
5180 tem
= start
+ XmlNameLength(enc
, start
);
5181 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5184 poolFinish(&tempPool
);
5185 data
= poolStoreString(&tempPool
, enc
,
5187 end
- enc
->minBytesPerChar
*2);
5190 normalizeLines(data
);
5191 processingInstructionHandler(handlerArg
, target
, data
);
5192 poolClear(&tempPool
);
5197 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5198 const char *start
, const char *end
)
5201 if (!commentHandler
) {
5203 reportDefault(parser
, enc
, start
, end
);
5206 data
= poolStoreString(&tempPool
,
5208 start
+ enc
->minBytesPerChar
* 4,
5209 end
- enc
->minBytesPerChar
* 3);
5212 normalizeLines(data
);
5213 commentHandler(handlerArg
, data
);
5214 poolClear(&tempPool
);
5219 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5220 const char *s
, const char *end
)
5222 if (MUST_CONVERT(enc
, s
)) {
5223 const char **eventPP
;
5224 const char **eventEndPP
;
5225 if (enc
== encoding
) {
5226 eventPP
= &eventPtr
;
5227 eventEndPP
= &eventEndPtr
;
5230 eventPP
= &(openInternalEntities
->internalEventPtr
);
5231 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5234 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5235 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5237 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5242 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5247 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5248 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5250 DEFAULT_ATTRIBUTE
*att
;
5251 if (value
|| isId
) {
5252 /* The handling of default attributes gets messed up if we have
5253 a default which duplicates a non-default. */
5255 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5256 if (attId
== type
->defaultAtts
[i
].id
)
5258 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5259 type
->idAtt
= attId
;
5261 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5262 if (type
->allocDefaultAtts
== 0) {
5263 type
->allocDefaultAtts
= 8;
5264 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5265 * sizeof(DEFAULT_ATTRIBUTE
));
5266 if (!type
->defaultAtts
)
5270 DEFAULT_ATTRIBUTE
*temp
;
5271 int count
= type
->allocDefaultAtts
* 2;
5272 temp
= (DEFAULT_ATTRIBUTE
*)
5273 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5276 type
->allocDefaultAtts
= count
;
5277 type
->defaultAtts
= temp
;
5280 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5283 att
->isCdata
= isCdata
;
5285 attId
->maybeTokenized
= XML_TRUE
;
5286 type
->nDefaultAtts
+= 1;
5291 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5293 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5294 const XML_Char
*name
;
5295 for (name
= elementType
->name
; *name
; name
++) {
5296 if (*name
== XML_T(ASCII_COLON
)) {
5299 for (s
= elementType
->name
; s
!= name
; s
++) {
5300 if (!poolAppendChar(&dtd
->pool
, *s
))
5303 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5305 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5309 if (prefix
->name
== poolStart(&dtd
->pool
))
5310 poolFinish(&dtd
->pool
);
5312 poolDiscard(&dtd
->pool
);
5313 elementType
->prefix
= prefix
;
5320 static ATTRIBUTE_ID
*
5321 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5322 const char *start
, const char *end
)
5324 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5326 const XML_Char
*name
;
5327 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5329 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5332 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5334 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5337 if (id
->name
!= name
)
5338 poolDiscard(&dtd
->pool
);
5340 poolFinish(&dtd
->pool
);
5343 else if (name
[0] == XML_T(ASCII_x
)
5344 && name
[1] == XML_T(ASCII_m
)
5345 && name
[2] == XML_T(ASCII_l
)
5346 && name
[3] == XML_T(ASCII_n
)
5347 && name
[4] == XML_T(ASCII_s
)
5348 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5349 if (name
[5] == XML_T('\0'))
5350 id
->prefix
= &dtd
->defaultPrefix
;
5352 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5353 id
->xmlns
= XML_TRUE
;
5357 for (i
= 0; name
[i
]; i
++) {
5358 /* attributes without prefix are *not* in the default namespace */
5359 if (name
[i
] == XML_T(ASCII_COLON
)) {
5361 for (j
= 0; j
< i
; j
++) {
5362 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5365 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5367 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5369 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5370 poolFinish(&dtd
->pool
);
5372 poolDiscard(&dtd
->pool
);
5381 #define CONTEXT_SEP XML_T(ASCII_FF)
5383 static const XML_Char
*
5384 getContext(XML_Parser parser
)
5386 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5387 HASH_TABLE_ITER iter
;
5388 XML_Bool needSep
= XML_FALSE
;
5390 if (dtd
->defaultPrefix
.binding
) {
5393 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5395 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5396 if (namespaceSeparator
)
5398 for (i
= 0; i
< len
; i
++)
5399 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5404 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5409 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5412 if (!prefix
->binding
)
5414 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5416 for (s
= prefix
->name
; *s
; s
++)
5417 if (!poolAppendChar(&tempPool
, *s
))
5419 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5421 len
= prefix
->binding
->uriLen
;
5422 if (namespaceSeparator
)
5424 for (i
= 0; i
< len
; i
++)
5425 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5431 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5434 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5439 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5441 for (s
= e
->name
; *s
; s
++)
5442 if (!poolAppendChar(&tempPool
, *s
))
5447 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5449 return tempPool
.start
;
5453 setContext(XML_Parser parser
, const XML_Char
*context
)
5455 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5456 const XML_Char
*s
= context
;
5458 while (*context
!= XML_T('\0')) {
5459 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5461 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5463 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5466 if (*s
!= XML_T('\0'))
5469 poolDiscard(&tempPool
);
5471 else if (*s
== XML_T(ASCII_EQUALS
)) {
5473 if (poolLength(&tempPool
) == 0)
5474 prefix
= &dtd
->defaultPrefix
;
5476 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5478 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5482 if (prefix
->name
== poolStart(&tempPool
)) {
5483 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5487 poolDiscard(&tempPool
);
5489 for (context
= s
+ 1;
5490 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5492 if (!poolAppendChar(&tempPool
, *context
))
5494 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5496 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5497 &inheritedBindings
) != XML_ERROR_NONE
)
5499 poolDiscard(&tempPool
);
5500 if (*context
!= XML_T('\0'))
5505 if (!poolAppendChar(&tempPool
, *s
))
5513 static void FASTCALL
5514 normalizePublicId(XML_Char
*publicId
)
5516 XML_Char
*p
= publicId
;
5518 for (s
= publicId
; *s
; s
++) {
5523 if (p
!= publicId
&& p
[-1] != 0x20)
5530 if (p
!= publicId
&& p
[-1] == 0x20)
5536 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5538 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5541 poolInit(&(p
->pool
), ms
);
5542 poolInit(&(p
->entityValuePool
), ms
);
5543 hashTableInit(&(p
->generalEntities
), ms
);
5544 hashTableInit(&(p
->elementTypes
), ms
);
5545 hashTableInit(&(p
->attributeIds
), ms
);
5546 hashTableInit(&(p
->prefixes
), ms
);
5548 p
->paramEntityRead
= XML_FALSE
;
5549 hashTableInit(&(p
->paramEntities
), ms
);
5550 #endif /* XML_DTD */
5551 p
->defaultPrefix
.name
= NULL
;
5552 p
->defaultPrefix
.binding
= NULL
;
5554 p
->in_eldecl
= XML_FALSE
;
5555 p
->scaffIndex
= NULL
;
5560 p
->contentStringLen
= 0;
5562 p
->keepProcessing
= XML_TRUE
;
5563 p
->hasParamEntityRefs
= XML_FALSE
;
5564 p
->standalone
= XML_FALSE
;
5569 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5571 HASH_TABLE_ITER iter
;
5572 hashTableIterInit(&iter
, &(p
->elementTypes
));
5574 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5577 if (e
->allocDefaultAtts
!= 0)
5578 ms
->free_fcn(e
->defaultAtts
);
5580 hashTableClear(&(p
->generalEntities
));
5582 p
->paramEntityRead
= XML_FALSE
;
5583 hashTableClear(&(p
->paramEntities
));
5584 #endif /* XML_DTD */
5585 hashTableClear(&(p
->elementTypes
));
5586 hashTableClear(&(p
->attributeIds
));
5587 hashTableClear(&(p
->prefixes
));
5588 poolClear(&(p
->pool
));
5589 poolClear(&(p
->entityValuePool
));
5590 p
->defaultPrefix
.name
= NULL
;
5591 p
->defaultPrefix
.binding
= NULL
;
5593 p
->in_eldecl
= XML_FALSE
;
5595 ms
->free_fcn(p
->scaffIndex
);
5596 p
->scaffIndex
= NULL
;
5597 ms
->free_fcn(p
->scaffold
);
5603 p
->contentStringLen
= 0;
5605 p
->keepProcessing
= XML_TRUE
;
5606 p
->hasParamEntityRefs
= XML_FALSE
;
5607 p
->standalone
= XML_FALSE
;
5611 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5613 HASH_TABLE_ITER iter
;
5614 hashTableIterInit(&iter
, &(p
->elementTypes
));
5616 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5619 if (e
->allocDefaultAtts
!= 0)
5620 ms
->free_fcn(e
->defaultAtts
);
5622 hashTableDestroy(&(p
->generalEntities
));
5624 hashTableDestroy(&(p
->paramEntities
));
5625 #endif /* XML_DTD */
5626 hashTableDestroy(&(p
->elementTypes
));
5627 hashTableDestroy(&(p
->attributeIds
));
5628 hashTableDestroy(&(p
->prefixes
));
5629 poolDestroy(&(p
->pool
));
5630 poolDestroy(&(p
->entityValuePool
));
5632 ms
->free_fcn(p
->scaffIndex
);
5633 ms
->free_fcn(p
->scaffold
);
5638 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5639 The new DTD has already been initialized.
5642 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5644 HASH_TABLE_ITER iter
;
5646 /* Copy the prefix table. */
5648 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5650 const XML_Char
*name
;
5651 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5654 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5657 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5661 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5663 /* Copy the attribute id table. */
5667 const XML_Char
*name
;
5668 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5672 /* Remember to allocate the scratch byte before the name. */
5673 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5675 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5679 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5680 sizeof(ATTRIBUTE_ID
));
5683 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5685 newA
->xmlns
= oldA
->xmlns
;
5686 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5687 newA
->prefix
= &newDtd
->defaultPrefix
;
5689 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5690 oldA
->prefix
->name
, 0);
5694 /* Copy the element type table. */
5696 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5701 const XML_Char
*name
;
5702 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5705 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5708 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5709 sizeof(ELEMENT_TYPE
));
5712 if (oldE
->nDefaultAtts
) {
5713 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5714 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5715 if (!newE
->defaultAtts
) {
5721 newE
->idAtt
= (ATTRIBUTE_ID
*)
5722 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5723 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5725 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5726 oldE
->prefix
->name
, 0);
5727 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5728 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5729 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5730 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5731 if (oldE
->defaultAtts
[i
].value
) {
5732 newE
->defaultAtts
[i
].value
5733 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5734 if (!newE
->defaultAtts
[i
].value
)
5738 newE
->defaultAtts
[i
].value
= NULL
;
5742 /* Copy the entity tables. */
5743 if (!copyEntityTable(&(newDtd
->generalEntities
),
5745 &(oldDtd
->generalEntities
)))
5749 if (!copyEntityTable(&(newDtd
->paramEntities
),
5751 &(oldDtd
->paramEntities
)))
5753 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5754 #endif /* XML_DTD */
5756 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5757 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5758 newDtd
->standalone
= oldDtd
->standalone
;
5760 /* Don't want deep copying for scaffolding */
5761 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5762 newDtd
->scaffold
= oldDtd
->scaffold
;
5763 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5764 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5765 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5766 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5772 copyEntityTable(HASH_TABLE
*newTable
,
5773 STRING_POOL
*newPool
,
5774 const HASH_TABLE
*oldTable
)
5776 HASH_TABLE_ITER iter
;
5777 const XML_Char
*cachedOldBase
= NULL
;
5778 const XML_Char
*cachedNewBase
= NULL
;
5780 hashTableIterInit(&iter
, oldTable
);
5784 const XML_Char
*name
;
5785 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5788 name
= poolCopyString(newPool
, oldE
->name
);
5791 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5794 if (oldE
->systemId
) {
5795 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5798 newE
->systemId
= tem
;
5800 if (oldE
->base
== cachedOldBase
)
5801 newE
->base
= cachedNewBase
;
5803 cachedOldBase
= oldE
->base
;
5804 tem
= poolCopyString(newPool
, cachedOldBase
);
5807 cachedNewBase
= newE
->base
= tem
;
5810 if (oldE
->publicId
) {
5811 tem
= poolCopyString(newPool
, oldE
->publicId
);
5814 newE
->publicId
= tem
;
5818 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5822 newE
->textPtr
= tem
;
5823 newE
->textLen
= oldE
->textLen
;
5825 if (oldE
->notation
) {
5826 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5829 newE
->notation
= tem
;
5831 newE
->is_param
= oldE
->is_param
;
5832 newE
->is_internal
= oldE
->is_internal
;
5837 #define INIT_POWER 6
5839 static XML_Bool FASTCALL
5840 keyeq(KEY s1
, KEY s2
)
5842 for (; *s1
== *s2
; s1
++, s2
++)
5848 static unsigned long FASTCALL
5851 unsigned long h
= 0;
5853 h
= CHAR_HASH(h
, *s
++);
5858 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5861 if (table
->size
== 0) {
5865 table
->power
= INIT_POWER
;
5866 /* table->size is a power of 2 */
5867 table
->size
= (size_t)1 << INIT_POWER
;
5868 tsize
= table
->size
* sizeof(NAMED
*);
5869 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5874 memset(table
->v
, 0, tsize
);
5875 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5878 unsigned long h
= hash(name
);
5879 unsigned long mask
= (unsigned long)table
->size
- 1;
5880 unsigned char step
= 0;
5882 while (table
->v
[i
]) {
5883 if (keyeq(name
, table
->v
[i
]->name
))
5886 step
= PROBE_STEP(h
, mask
, table
->power
);
5887 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5892 /* check for overflow (table is half full) */
5893 if (table
->used
>> (table
->power
- 1)) {
5894 unsigned char newPower
= table
->power
+ 1;
5895 size_t newSize
= (size_t)1 << newPower
;
5896 unsigned long newMask
= (unsigned long)newSize
- 1;
5897 size_t tsize
= newSize
* sizeof(NAMED
*);
5898 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5901 memset(newV
, 0, tsize
);
5902 for (i
= 0; i
< table
->size
; i
++)
5904 unsigned long newHash
= hash(table
->v
[i
]->name
);
5905 size_t j
= newHash
& newMask
;
5909 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5910 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5912 newV
[j
] = table
->v
[i
];
5914 table
->mem
->free_fcn(table
->v
);
5916 table
->power
= newPower
;
5917 table
->size
= newSize
;
5920 while (table
->v
[i
]) {
5922 step
= PROBE_STEP(h
, newMask
, newPower
);
5923 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5927 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5930 memset(table
->v
[i
], 0, createSize
);
5931 table
->v
[i
]->name
= name
;
5936 static void FASTCALL
5937 hashTableClear(HASH_TABLE
*table
)
5940 for (i
= 0; i
< table
->size
; i
++) {
5941 table
->mem
->free_fcn(table
->v
[i
]);
5947 static void FASTCALL
5948 hashTableDestroy(HASH_TABLE
*table
)
5951 for (i
= 0; i
< table
->size
; i
++)
5952 table
->mem
->free_fcn(table
->v
[i
]);
5953 table
->mem
->free_fcn(table
->v
);
5956 static void FASTCALL
5957 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5966 static void FASTCALL
5967 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5970 iter
->end
= iter
->p
+ table
->size
;
5973 static NAMED
* FASTCALL
5974 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5976 while (iter
->p
!= iter
->end
) {
5977 NAMED
*tem
= *(iter
->p
)++;
5984 static void FASTCALL
5985 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5987 pool
->blocks
= NULL
;
5988 pool
->freeBlocks
= NULL
;
5995 static void FASTCALL
5996 poolClear(STRING_POOL
*pool
)
5998 if (!pool
->freeBlocks
)
5999 pool
->freeBlocks
= pool
->blocks
;
6001 BLOCK
*p
= pool
->blocks
;
6003 BLOCK
*tem
= p
->next
;
6004 p
->next
= pool
->freeBlocks
;
6005 pool
->freeBlocks
= p
;
6009 pool
->blocks
= NULL
;
6015 static void FASTCALL
6016 poolDestroy(STRING_POOL
*pool
)
6018 BLOCK
*p
= pool
->blocks
;
6020 BLOCK
*tem
= p
->next
;
6021 pool
->mem
->free_fcn(p
);
6024 p
= pool
->freeBlocks
;
6026 BLOCK
*tem
= p
->next
;
6027 pool
->mem
->free_fcn(p
);
6033 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6034 const char *ptr
, const char *end
)
6036 if (!pool
->ptr
&& !poolGrow(pool
))
6039 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6042 if (!poolGrow(pool
))
6048 static const XML_Char
* FASTCALL
6049 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6052 if (!poolAppendChar(pool
, *s
))
6060 static const XML_Char
*
6061 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6063 if (!pool
->ptr
&& !poolGrow(pool
))
6065 for (; n
> 0; --n
, s
++) {
6066 if (!poolAppendChar(pool
, *s
))
6074 static const XML_Char
* FASTCALL
6075 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6078 if (!poolAppendChar(pool
, *s
))
6086 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6087 const char *ptr
, const char *end
)
6089 if (!poolAppend(pool
, enc
, ptr
, end
))
6091 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6097 static XML_Bool FASTCALL
6098 poolGrow(STRING_POOL
*pool
)
6100 if (pool
->freeBlocks
) {
6101 if (pool
->start
== 0) {
6102 pool
->blocks
= pool
->freeBlocks
;
6103 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6104 pool
->blocks
->next
= NULL
;
6105 pool
->start
= pool
->blocks
->s
;
6106 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6107 pool
->ptr
= pool
->start
;
6110 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6111 BLOCK
*tem
= pool
->freeBlocks
->next
;
6112 pool
->freeBlocks
->next
= pool
->blocks
;
6113 pool
->blocks
= pool
->freeBlocks
;
6114 pool
->freeBlocks
= tem
;
6115 memcpy(pool
->blocks
->s
, pool
->start
,
6116 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6117 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6118 pool
->start
= pool
->blocks
->s
;
6119 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6123 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6124 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6125 pool
->blocks
= (BLOCK
*)
6126 pool
->mem
->realloc_fcn(pool
->blocks
,
6128 + blockSize
* sizeof(XML_Char
)));
6129 if (pool
->blocks
== NULL
)
6131 pool
->blocks
->size
= blockSize
;
6132 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6133 pool
->start
= pool
->blocks
->s
;
6134 pool
->end
= pool
->start
+ blockSize
;
6138 int blockSize
= (int)(pool
->end
- pool
->start
);
6139 if (blockSize
< INIT_BLOCK_SIZE
)
6140 blockSize
= INIT_BLOCK_SIZE
;
6143 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6144 + blockSize
* sizeof(XML_Char
));
6147 tem
->size
= blockSize
;
6148 tem
->next
= pool
->blocks
;
6150 if (pool
->ptr
!= pool
->start
)
6151 memcpy(tem
->s
, pool
->start
,
6152 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6153 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6154 pool
->start
= tem
->s
;
6155 pool
->end
= tem
->s
+ blockSize
;
6161 nextScaffoldPart(XML_Parser parser
)
6163 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6164 CONTENT_SCAFFOLD
* me
;
6167 if (!dtd
->scaffIndex
) {
6168 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6169 if (!dtd
->scaffIndex
)
6171 dtd
->scaffIndex
[0] = 0;
6174 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6175 CONTENT_SCAFFOLD
*temp
;
6176 if (dtd
->scaffold
) {
6177 temp
= (CONTENT_SCAFFOLD
*)
6178 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6181 dtd
->scaffSize
*= 2;
6184 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6185 * sizeof(CONTENT_SCAFFOLD
));
6188 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6190 dtd
->scaffold
= temp
;
6192 next
= dtd
->scaffCount
++;
6193 me
= &dtd
->scaffold
[next
];
6194 if (dtd
->scaffLevel
) {
6195 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6196 if (parent
->lastchild
) {
6197 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6199 if (!parent
->childcnt
)
6200 parent
->firstchild
= next
;
6201 parent
->lastchild
= next
;
6204 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6209 build_node(XML_Parser parser
,
6212 XML_Content
**contpos
,
6215 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6216 dest
->type
= dtd
->scaffold
[src_node
].type
;
6217 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6218 if (dest
->type
== XML_CTYPE_NAME
) {
6219 const XML_Char
*src
;
6220 dest
->name
= *strpos
;
6221 src
= dtd
->scaffold
[src_node
].name
;
6223 *(*strpos
)++ = *src
;
6228 dest
->numchildren
= 0;
6229 dest
->children
= NULL
;
6234 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6235 dest
->children
= *contpos
;
6236 *contpos
+= dest
->numchildren
;
6237 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6238 i
< dest
->numchildren
;
6239 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6240 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6246 static XML_Content
*
6247 build_model (XML_Parser parser
)
6249 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6253 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6254 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6256 ret
= (XML_Content
*)MALLOC(allocsize
);
6260 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6263 build_node(parser
, 0, ret
, &cpos
, &str
);
6267 static ELEMENT_TYPE
*
6268 getElementType(XML_Parser parser
,
6269 const ENCODING
*enc
,
6273 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6274 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6279 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6282 if (ret
->name
!= name
)
6283 poolDiscard(&dtd
->pool
);
6285 poolFinish(&dtd
->pool
);
6286 if (!setElementTypePrefix(parser
, ret
))