1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
5 #define XML_BUILDING_EXPAT 1
7 #ifdef COMPILED_FROM_DSP
9 #elif defined(MACOS_CLASSIC)
10 #include "macconfig.h"
11 #elif defined(__amigaos4__)
12 #include "amigaconfig.h"
13 #elif defined(HAVE_EXPAT_CONFIG_H)
14 #include <expat_config.h>
15 #endif /* ndef COMPILED_FROM_DSP */
18 #include <string.h> /* memset(), memcpy() */
21 #if defined(UEFI_C_SOURCE)
22 #include <expat/expat.h>
28 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
29 #define XmlConvert XmlUtf16Convert
30 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
31 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
32 #define XmlEncode XmlUtf16Encode
33 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 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 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
673 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
674 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
675 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
679 XML_ParserCreate_MM(const XML_Char
*encodingName
,
680 const XML_Memory_Handling_Suite
*memsuite
,
681 const XML_Char
*nameSep
)
683 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
684 if (parser
!= NULL
&& ns
) {
685 /* implicit context only set for root parser, since child
686 parsers (i.e. external entity parsers) will inherit it
688 if (!setContext(parser
, implicitContext
)) {
689 XML_ParserFree(parser
);
697 parserCreate(const XML_Char
*encodingName
,
698 const XML_Memory_Handling_Suite
*memsuite
,
699 const XML_Char
*nameSep
,
705 XML_Memory_Handling_Suite
*mtemp
;
706 parser
= (XML_Parser
)
707 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
708 if (parser
!= NULL
) {
709 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
710 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
711 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
712 mtemp
->free_fcn
= memsuite
->free_fcn
;
716 XML_Memory_Handling_Suite
*mtemp
;
717 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
718 if (parser
!= NULL
) {
719 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
720 mtemp
->malloc_fcn
= malloc
;
721 mtemp
->realloc_fcn
= realloc
;
722 mtemp
->free_fcn
= free
;
732 attsSize
= INIT_ATTS_SIZE
;
733 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
738 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
739 if (dataBuf
== NULL
) {
744 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
749 _dtd
= dtdCreate(&parser
->m_mem
);
758 freeBindingList
= NULL
;
760 freeInternalEntities
= NULL
;
763 groupConnector
= NULL
;
765 unknownEncodingHandler
= NULL
;
766 unknownEncodingHandlerData
= NULL
;
768 namespaceSeparator
= '!';
770 ns_triplets
= XML_FALSE
;
776 poolInit(&tempPool
, &(parser
->m_mem
));
777 poolInit(&temp2Pool
, &(parser
->m_mem
));
778 parserInit(parser
, encodingName
);
780 if (encodingName
&& !protocolEncodingName
) {
781 XML_ParserFree(parser
);
787 internalEncoding
= XmlGetInternalEncodingNS();
788 namespaceSeparator
= *nameSep
;
791 internalEncoding
= XmlGetInternalEncoding();
798 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
800 processor
= prologInitProcessor
;
801 XmlPrologStateInit(&prologState
);
802 protocolEncodingName
= (encodingName
!= NULL
803 ? poolCopyString(&tempPool
, encodingName
)
806 XmlInitEncoding(&initEncoding
, &encoding
, 0);
809 startElementHandler
= NULL
;
810 endElementHandler
= NULL
;
811 characterDataHandler
= NULL
;
812 processingInstructionHandler
= NULL
;
813 commentHandler
= NULL
;
814 startCdataSectionHandler
= NULL
;
815 endCdataSectionHandler
= NULL
;
816 defaultHandler
= NULL
;
817 startDoctypeDeclHandler
= NULL
;
818 endDoctypeDeclHandler
= NULL
;
819 unparsedEntityDeclHandler
= NULL
;
820 notationDeclHandler
= NULL
;
821 startNamespaceDeclHandler
= NULL
;
822 endNamespaceDeclHandler
= NULL
;
823 notStandaloneHandler
= NULL
;
824 externalEntityRefHandler
= NULL
;
825 externalEntityRefHandlerArg
= parser
;
826 skippedEntityHandler
= NULL
;
827 elementDeclHandler
= NULL
;
828 attlistDeclHandler
= NULL
;
829 entityDeclHandler
= NULL
;
830 xmlDeclHandler
= NULL
;
833 parseEndByteIndex
= 0;
835 declElementType
= NULL
;
836 declAttributeId
= NULL
;
841 declAttributeType
= NULL
;
842 declNotationName
= NULL
;
843 declNotationPublicId
= NULL
;
844 declAttributeIsCdata
= XML_FALSE
;
845 declAttributeIsId
= XML_FALSE
;
846 memset(&position
, 0, sizeof(POSITION
));
847 errorCode
= XML_ERROR_NONE
;
851 openInternalEntities
= NULL
;
852 defaultExpandInternalEntities
= XML_TRUE
;
855 inheritedBindings
= NULL
;
857 unknownEncodingMem
= NULL
;
858 unknownEncodingRelease
= NULL
;
859 unknownEncodingData
= NULL
;
861 ps_parsing
= XML_INITIALIZED
;
863 isParamEntity
= XML_FALSE
;
864 useForeignDTD
= XML_FALSE
;
865 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
869 /* moves list of bindings to freeBindingList */
871 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
874 BINDING
*b
= bindings
;
875 bindings
= bindings
->nextTagBinding
;
876 b
->nextTagBinding
= freeBindingList
;
882 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
885 OPEN_INTERNAL_ENTITY
*openEntityList
;
888 /* move tagStack to freeTagList */
893 tag
->parent
= freeTagList
;
894 moveToFreeBindingList(parser
, tag
->bindings
);
895 tag
->bindings
= NULL
;
898 /* move openInternalEntities to freeInternalEntities */
899 openEntityList
= openInternalEntities
;
900 while (openEntityList
) {
901 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
902 openEntityList
= openEntity
->next
;
903 openEntity
->next
= freeInternalEntities
;
904 freeInternalEntities
= openEntity
;
906 moveToFreeBindingList(parser
, inheritedBindings
);
907 FREE(unknownEncodingMem
);
908 if (unknownEncodingRelease
)
909 unknownEncodingRelease(unknownEncodingData
);
910 poolClear(&tempPool
);
911 poolClear(&temp2Pool
);
912 parserInit(parser
, encodingName
);
913 dtdReset(_dtd
, &parser
->m_mem
);
914 return setContext(parser
, implicitContext
);
917 enum XML_Status XMLCALL
918 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
920 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
921 XXX There's no way for the caller to determine which of the
922 XXX possible error cases caused the XML_STATUS_ERROR return.
924 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
925 return XML_STATUS_ERROR
;
926 if (encodingName
== NULL
)
927 protocolEncodingName
= NULL
;
929 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
930 if (!protocolEncodingName
)
931 return XML_STATUS_ERROR
;
933 return XML_STATUS_OK
;
937 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
938 const XML_Char
*context
,
939 const XML_Char
*encodingName
)
941 XML_Parser parser
= oldParser
;
944 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
945 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
946 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
947 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
948 = processingInstructionHandler
;
949 XML_CommentHandler oldCommentHandler
= commentHandler
;
950 XML_StartCdataSectionHandler oldStartCdataSectionHandler
951 = startCdataSectionHandler
;
952 XML_EndCdataSectionHandler oldEndCdataSectionHandler
953 = endCdataSectionHandler
;
954 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
955 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
956 = unparsedEntityDeclHandler
;
957 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
958 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
959 = startNamespaceDeclHandler
;
960 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
961 = endNamespaceDeclHandler
;
962 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
963 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
964 = externalEntityRefHandler
;
965 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
966 XML_UnknownEncodingHandler oldUnknownEncodingHandler
967 = unknownEncodingHandler
;
968 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
969 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
970 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
971 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
972 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
974 void *oldUserData
= userData
;
975 void *oldHandlerArg
= handlerArg
;
976 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
977 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
979 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
980 int oldInEntityValue
= prologState
.inEntityValue
;
982 XML_Bool oldns_triplets
= ns_triplets
;
989 /* Note that the magical uses of the pre-processor to make field
990 access look more like C++ require that `parser' be overwritten
991 here. This makes this function more painful to follow than it
996 *tmp
= namespaceSeparator
;
997 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
1000 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1006 startElementHandler
= oldStartElementHandler
;
1007 endElementHandler
= oldEndElementHandler
;
1008 characterDataHandler
= oldCharacterDataHandler
;
1009 processingInstructionHandler
= oldProcessingInstructionHandler
;
1010 commentHandler
= oldCommentHandler
;
1011 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1012 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1013 defaultHandler
= oldDefaultHandler
;
1014 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1015 notationDeclHandler
= oldNotationDeclHandler
;
1016 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1017 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1018 notStandaloneHandler
= oldNotStandaloneHandler
;
1019 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1020 skippedEntityHandler
= oldSkippedEntityHandler
;
1021 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1022 elementDeclHandler
= oldElementDeclHandler
;
1023 attlistDeclHandler
= oldAttlistDeclHandler
;
1024 entityDeclHandler
= oldEntityDeclHandler
;
1025 xmlDeclHandler
= oldXmlDeclHandler
;
1026 declElementType
= oldDeclElementType
;
1027 userData
= oldUserData
;
1028 if (oldUserData
== oldHandlerArg
)
1029 handlerArg
= userData
;
1031 handlerArg
= parser
;
1032 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1033 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1034 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1035 ns_triplets
= oldns_triplets
;
1036 parentParser
= oldParser
;
1038 paramEntityParsing
= oldParamEntityParsing
;
1039 prologState
.inEntityValue
= oldInEntityValue
;
1041 #endif /* XML_DTD */
1042 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1043 || !setContext(parser
, context
)) {
1044 XML_ParserFree(parser
);
1047 processor
= externalEntityInitProcessor
;
1051 /* The DTD instance referenced by _dtd is shared between the document's
1052 root parser and external PE parsers, therefore one does not need to
1053 call setContext. In addition, one also *must* not call setContext,
1054 because this would overwrite existing prefix->binding pointers in
1055 _dtd with ones that get destroyed with the external PE parser.
1056 This would leave those prefixes with dangling pointers.
1058 isParamEntity
= XML_TRUE
;
1059 XmlPrologStateInitExternalEntity(&prologState
);
1060 processor
= externalParEntInitProcessor
;
1062 #endif /* XML_DTD */
1066 static void FASTCALL
1067 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1070 BINDING
*b
= bindings
;
1073 bindings
= b
->nextTagBinding
;
1080 XML_ParserFree(XML_Parser parser
)
1083 OPEN_INTERNAL_ENTITY
*entityList
;
1086 /* free tagStack and freeTagList */
1090 if (tagList
== NULL
) {
1091 if (freeTagList
== NULL
)
1093 tagList
= freeTagList
;
1097 tagList
= tagList
->parent
;
1099 destroyBindings(p
->bindings
, parser
);
1102 /* free openInternalEntities and freeInternalEntities */
1103 entityList
= openInternalEntities
;
1105 OPEN_INTERNAL_ENTITY
*openEntity
;
1106 if (entityList
== NULL
) {
1107 if (freeInternalEntities
== NULL
)
1109 entityList
= freeInternalEntities
;
1110 freeInternalEntities
= NULL
;
1112 openEntity
= entityList
;
1113 entityList
= entityList
->next
;
1117 destroyBindings(freeBindingList
, parser
);
1118 destroyBindings(inheritedBindings
, parser
);
1119 poolDestroy(&tempPool
);
1120 poolDestroy(&temp2Pool
);
1122 /* external parameter entity parsers share the DTD structure
1123 parser->m_dtd with the root parser, so we must not destroy it
1125 if (!isParamEntity
&& _dtd
)
1128 #endif /* XML_DTD */
1129 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1131 FREE(groupConnector
);
1135 FREE(unknownEncodingMem
);
1136 if (unknownEncodingRelease
)
1137 unknownEncodingRelease(unknownEncodingData
);
1142 XML_UseParserAsHandlerArg(XML_Parser parser
)
1144 handlerArg
= parser
;
1147 enum XML_Error XMLCALL
1148 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1151 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1152 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1153 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1154 useForeignDTD
= useDTD
;
1155 return XML_ERROR_NONE
;
1157 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1162 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1164 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1165 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1167 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1171 XML_SetUserData(XML_Parser parser
, void *p
)
1173 if (handlerArg
== userData
)
1174 handlerArg
= userData
= p
;
1179 enum XML_Status XMLCALL
1180 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1183 p
= poolCopyString(&_dtd
->pool
, p
);
1185 return XML_STATUS_ERROR
;
1190 return XML_STATUS_OK
;
1193 const XML_Char
* XMLCALL
1194 XML_GetBase(XML_Parser parser
)
1200 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1202 return nSpecifiedAtts
;
1206 XML_GetIdAttributeIndex(XML_Parser parser
)
1212 XML_SetElementHandler(XML_Parser parser
,
1213 XML_StartElementHandler start
,
1214 XML_EndElementHandler end
)
1216 startElementHandler
= start
;
1217 endElementHandler
= end
;
1221 XML_SetStartElementHandler(XML_Parser parser
,
1222 XML_StartElementHandler start
) {
1223 startElementHandler
= start
;
1227 XML_SetEndElementHandler(XML_Parser parser
,
1228 XML_EndElementHandler end
) {
1229 endElementHandler
= end
;
1233 XML_SetCharacterDataHandler(XML_Parser parser
,
1234 XML_CharacterDataHandler handler
)
1236 characterDataHandler
= handler
;
1240 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1241 XML_ProcessingInstructionHandler handler
)
1243 processingInstructionHandler
= handler
;
1247 XML_SetCommentHandler(XML_Parser parser
,
1248 XML_CommentHandler handler
)
1250 commentHandler
= handler
;
1254 XML_SetCdataSectionHandler(XML_Parser parser
,
1255 XML_StartCdataSectionHandler start
,
1256 XML_EndCdataSectionHandler end
)
1258 startCdataSectionHandler
= start
;
1259 endCdataSectionHandler
= end
;
1263 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1264 XML_StartCdataSectionHandler start
) {
1265 startCdataSectionHandler
= start
;
1269 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1270 XML_EndCdataSectionHandler end
) {
1271 endCdataSectionHandler
= end
;
1275 XML_SetDefaultHandler(XML_Parser parser
,
1276 XML_DefaultHandler handler
)
1278 defaultHandler
= handler
;
1279 defaultExpandInternalEntities
= XML_FALSE
;
1283 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1284 XML_DefaultHandler handler
)
1286 defaultHandler
= handler
;
1287 defaultExpandInternalEntities
= XML_TRUE
;
1291 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1292 XML_StartDoctypeDeclHandler start
,
1293 XML_EndDoctypeDeclHandler end
)
1295 startDoctypeDeclHandler
= start
;
1296 endDoctypeDeclHandler
= end
;
1300 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1301 XML_StartDoctypeDeclHandler start
) {
1302 startDoctypeDeclHandler
= start
;
1306 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1307 XML_EndDoctypeDeclHandler end
) {
1308 endDoctypeDeclHandler
= end
;
1312 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1313 XML_UnparsedEntityDeclHandler handler
)
1315 unparsedEntityDeclHandler
= handler
;
1319 XML_SetNotationDeclHandler(XML_Parser parser
,
1320 XML_NotationDeclHandler handler
)
1322 notationDeclHandler
= handler
;
1326 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1327 XML_StartNamespaceDeclHandler start
,
1328 XML_EndNamespaceDeclHandler end
)
1330 startNamespaceDeclHandler
= start
;
1331 endNamespaceDeclHandler
= end
;
1335 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1336 XML_StartNamespaceDeclHandler start
) {
1337 startNamespaceDeclHandler
= start
;
1341 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1342 XML_EndNamespaceDeclHandler end
) {
1343 endNamespaceDeclHandler
= end
;
1347 XML_SetNotStandaloneHandler(XML_Parser parser
,
1348 XML_NotStandaloneHandler handler
)
1350 notStandaloneHandler
= handler
;
1354 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1355 XML_ExternalEntityRefHandler handler
)
1357 externalEntityRefHandler
= handler
;
1361 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1364 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1366 externalEntityRefHandlerArg
= parser
;
1370 XML_SetSkippedEntityHandler(XML_Parser parser
,
1371 XML_SkippedEntityHandler handler
)
1373 skippedEntityHandler
= handler
;
1377 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1378 XML_UnknownEncodingHandler handler
,
1381 unknownEncodingHandler
= handler
;
1382 unknownEncodingHandlerData
= data
;
1386 XML_SetElementDeclHandler(XML_Parser parser
,
1387 XML_ElementDeclHandler eldecl
)
1389 elementDeclHandler
= eldecl
;
1393 XML_SetAttlistDeclHandler(XML_Parser parser
,
1394 XML_AttlistDeclHandler attdecl
)
1396 attlistDeclHandler
= attdecl
;
1400 XML_SetEntityDeclHandler(XML_Parser parser
,
1401 XML_EntityDeclHandler handler
)
1403 entityDeclHandler
= handler
;
1407 XML_SetXmlDeclHandler(XML_Parser parser
,
1408 XML_XmlDeclHandler handler
) {
1409 xmlDeclHandler
= handler
;
1413 XML_SetParamEntityParsing(XML_Parser parser
,
1414 enum XML_ParamEntityParsing peParsing
)
1416 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1417 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1420 paramEntityParsing
= peParsing
;
1423 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1427 enum XML_Status XMLCALL
1428 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1430 switch (ps_parsing
) {
1432 errorCode
= XML_ERROR_SUSPENDED
;
1433 return XML_STATUS_ERROR
;
1435 errorCode
= XML_ERROR_FINISHED
;
1436 return XML_STATUS_ERROR
;
1438 ps_parsing
= XML_PARSING
;
1442 ps_finalBuffer
= (XML_Bool
)isFinal
;
1444 return XML_STATUS_OK
;
1445 positionPtr
= bufferPtr
;
1446 parseEndPtr
= bufferEnd
;
1448 /* If data are left over from last buffer, and we now know that these
1449 data are the final chunk of input, then we have to check them again
1450 to detect errors based on that fact.
1452 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1454 if (errorCode
== XML_ERROR_NONE
) {
1455 switch (ps_parsing
) {
1457 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1458 positionPtr
= bufferPtr
;
1459 return XML_STATUS_SUSPENDED
;
1460 case XML_INITIALIZED
:
1462 ps_parsing
= XML_FINISHED
;
1465 return XML_STATUS_OK
;
1468 eventEndPtr
= eventPtr
;
1469 processor
= errorProcessor
;
1470 return XML_STATUS_ERROR
;
1472 #ifndef XML_CONTEXT_BYTES
1473 else if (bufferPtr
== bufferEnd
) {
1476 enum XML_Error result
;
1477 parseEndByteIndex
+= len
;
1479 ps_finalBuffer
= (XML_Bool
)isFinal
;
1481 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1483 if (errorCode
!= XML_ERROR_NONE
) {
1484 eventEndPtr
= eventPtr
;
1485 processor
= errorProcessor
;
1486 return XML_STATUS_ERROR
;
1489 switch (ps_parsing
) {
1491 result
= XML_STATUS_SUSPENDED
;
1493 case XML_INITIALIZED
:
1495 result
= XML_STATUS_OK
;
1497 ps_parsing
= XML_FINISHED
;
1502 /* XML_FINISHED case required by compiler - but not tested - djv */
1503 return XML_STATUS_OK
;
1507 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1508 nLeftOver
= s
+ len
- end
;
1510 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1511 /* FIXME avoid integer overflow */
1513 temp
= (buffer
== NULL
1514 ? (char *)MALLOC(len
* 2)
1515 : (char *)REALLOC(buffer
, len
* 2));
1517 errorCode
= XML_ERROR_NO_MEMORY
;
1518 return XML_STATUS_ERROR
;
1522 errorCode
= XML_ERROR_NO_MEMORY
;
1523 eventPtr
= eventEndPtr
= NULL
;
1524 processor
= errorProcessor
;
1525 return XML_STATUS_ERROR
;
1527 bufferLim
= buffer
+ len
* 2;
1529 memcpy(buffer
, end
, nLeftOver
);
1532 bufferEnd
= buffer
+ nLeftOver
;
1533 positionPtr
= bufferPtr
;
1534 parseEndPtr
= bufferEnd
;
1535 eventPtr
= bufferPtr
;
1536 eventEndPtr
= bufferPtr
;
1539 #endif /* not defined XML_CONTEXT_BYTES */
1541 void *buff
= XML_GetBuffer(parser
, len
);
1543 return XML_STATUS_ERROR
;
1545 memcpy(buff
, s
, len
);
1546 return XML_ParseBuffer(parser
, len
, isFinal
);
1551 enum XML_Status XMLCALL
1552 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1555 enum XML_Status result
= XML_STATUS_OK
;
1557 switch (ps_parsing
) {
1559 errorCode
= XML_ERROR_SUSPENDED
;
1560 return XML_STATUS_ERROR
;
1562 errorCode
= XML_ERROR_FINISHED
;
1563 return XML_STATUS_ERROR
;
1565 ps_parsing
= XML_PARSING
;
1569 positionPtr
= start
;
1571 parseEndPtr
= bufferEnd
;
1572 parseEndByteIndex
+= len
;
1573 ps_finalBuffer
= (XML_Bool
)isFinal
;
1575 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1577 if (errorCode
!= XML_ERROR_NONE
) {
1578 eventEndPtr
= eventPtr
;
1579 processor
= errorProcessor
;
1580 return XML_STATUS_ERROR
;
1583 switch (ps_parsing
) {
1585 result
= XML_STATUS_SUSPENDED
;
1587 case XML_INITIALIZED
:
1590 ps_parsing
= XML_FINISHED
;
1593 default: ; /* should not happen */
1597 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1598 positionPtr
= bufferPtr
;
1603 XML_GetBuffer(XML_Parser parser
, int len
)
1605 switch (ps_parsing
) {
1607 errorCode
= XML_ERROR_SUSPENDED
;
1610 errorCode
= XML_ERROR_FINISHED
;
1615 if (len
> bufferLim
- bufferEnd
) {
1616 /* FIXME avoid integer overflow */
1617 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1618 #ifdef XML_CONTEXT_BYTES
1619 int keep
= (int)(bufferPtr
- buffer
);
1621 if (keep
> XML_CONTEXT_BYTES
)
1622 keep
= XML_CONTEXT_BYTES
;
1624 #endif /* defined XML_CONTEXT_BYTES */
1625 if (neededSize
<= bufferLim
- buffer
) {
1626 #ifdef XML_CONTEXT_BYTES
1627 if (keep
< bufferPtr
- buffer
) {
1628 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1629 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1630 bufferEnd
-= offset
;
1631 bufferPtr
-= offset
;
1634 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1635 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1637 #endif /* not defined XML_CONTEXT_BYTES */
1641 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1642 if (bufferSize
== 0)
1643 bufferSize
= INIT_BUFFER_SIZE
;
1646 } while (bufferSize
< neededSize
);
1647 newBuf
= (char *)MALLOC(bufferSize
);
1649 errorCode
= XML_ERROR_NO_MEMORY
;
1652 bufferLim
= newBuf
+ bufferSize
;
1653 #ifdef XML_CONTEXT_BYTES
1655 int keep
= (int)(bufferPtr
- buffer
);
1656 if (keep
> XML_CONTEXT_BYTES
)
1657 keep
= XML_CONTEXT_BYTES
;
1658 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1661 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1662 bufferPtr
= buffer
+ keep
;
1665 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1666 bufferPtr
= buffer
= newBuf
;
1670 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1673 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1674 bufferPtr
= buffer
= newBuf
;
1675 #endif /* not defined XML_CONTEXT_BYTES */
1681 enum XML_Status XMLCALL
1682 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1684 switch (ps_parsing
) {
1687 errorCode
= XML_ERROR_SUSPENDED
;
1688 return XML_STATUS_ERROR
;
1690 ps_parsing
= XML_FINISHED
;
1693 errorCode
= XML_ERROR_FINISHED
;
1694 return XML_STATUS_ERROR
;
1698 if (isParamEntity
) {
1699 errorCode
= XML_ERROR_SUSPEND_PE
;
1700 return XML_STATUS_ERROR
;
1703 ps_parsing
= XML_SUSPENDED
;
1706 ps_parsing
= XML_FINISHED
;
1708 return XML_STATUS_OK
;
1711 enum XML_Status XMLCALL
1712 XML_ResumeParser(XML_Parser parser
)
1714 enum XML_Status result
= XML_STATUS_OK
;
1716 if (ps_parsing
!= XML_SUSPENDED
) {
1717 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1718 return XML_STATUS_ERROR
;
1720 ps_parsing
= XML_PARSING
;
1722 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1724 if (errorCode
!= XML_ERROR_NONE
) {
1725 eventEndPtr
= eventPtr
;
1726 processor
= errorProcessor
;
1727 return XML_STATUS_ERROR
;
1730 switch (ps_parsing
) {
1732 result
= XML_STATUS_SUSPENDED
;
1734 case XML_INITIALIZED
:
1736 if (ps_finalBuffer
) {
1737 ps_parsing
= XML_FINISHED
;
1744 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1745 positionPtr
= bufferPtr
;
1750 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1752 assert(status
!= NULL
);
1753 *status
= parser
->m_parsingStatus
;
1756 enum XML_Error XMLCALL
1757 XML_GetErrorCode(XML_Parser parser
)
1763 XML_GetCurrentByteIndex(XML_Parser parser
)
1766 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1771 XML_GetCurrentByteCount(XML_Parser parser
)
1773 if (eventEndPtr
&& eventPtr
)
1774 return (int)(eventEndPtr
- eventPtr
);
1778 const char * XMLCALL
1779 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1781 #ifdef XML_CONTEXT_BYTES
1782 if (eventPtr
&& buffer
) {
1783 *offset
= (int)(eventPtr
- buffer
);
1784 *size
= (int)(bufferEnd
- buffer
);
1787 #endif /* defined XML_CONTEXT_BYTES */
1792 XML_GetCurrentLineNumber(XML_Parser parser
)
1794 if (eventPtr
&& eventPtr
>= positionPtr
) {
1795 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1796 positionPtr
= eventPtr
;
1798 return position
.lineNumber
+ 1;
1802 XML_GetCurrentColumnNumber(XML_Parser parser
)
1804 if (eventPtr
&& eventPtr
>= positionPtr
) {
1805 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1806 positionPtr
= eventPtr
;
1808 return position
.columnNumber
;
1812 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1818 XML_MemMalloc(XML_Parser parser
, size_t size
)
1820 return MALLOC(size
);
1824 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1826 return REALLOC(ptr
, size
);
1830 XML_MemFree(XML_Parser parser
, void *ptr
)
1836 XML_DefaultCurrent(XML_Parser parser
)
1838 if (defaultHandler
) {
1839 if (openInternalEntities
)
1840 reportDefault(parser
,
1842 openInternalEntities
->internalEventPtr
,
1843 openInternalEntities
->internalEventEndPtr
);
1845 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1849 const XML_LChar
* XMLCALL
1850 XML_ErrorString(enum XML_Error code
)
1852 static const XML_LChar
* const message
[] = {
1854 XML_L("out of memory"),
1855 XML_L("syntax error"),
1856 XML_L("no element found"),
1857 XML_L("not well-formed (invalid token)"),
1858 XML_L("unclosed token"),
1859 XML_L("partial character"),
1860 XML_L("mismatched tag"),
1861 XML_L("duplicate attribute"),
1862 XML_L("junk after document element"),
1863 XML_L("illegal parameter entity reference"),
1864 XML_L("undefined entity"),
1865 XML_L("recursive entity reference"),
1866 XML_L("asynchronous entity"),
1867 XML_L("reference to invalid character number"),
1868 XML_L("reference to binary entity"),
1869 XML_L("reference to external entity in attribute"),
1870 XML_L("XML or text declaration not at start of entity"),
1871 XML_L("unknown encoding"),
1872 XML_L("encoding specified in XML declaration is incorrect"),
1873 XML_L("unclosed CDATA section"),
1874 XML_L("error in processing external entity reference"),
1875 XML_L("document is not standalone"),
1876 XML_L("unexpected parser state - please send a bug report"),
1877 XML_L("entity declared in parameter entity"),
1878 XML_L("requested feature requires XML_DTD support in Expat"),
1879 XML_L("cannot change setting once parsing has begun"),
1880 XML_L("unbound prefix"),
1881 XML_L("must not undeclare prefix"),
1882 XML_L("incomplete markup in parameter entity"),
1883 XML_L("XML declaration not well-formed"),
1884 XML_L("text declaration not well-formed"),
1885 XML_L("illegal character(s) in public id"),
1886 XML_L("parser suspended"),
1887 XML_L("parser not suspended"),
1888 XML_L("parsing aborted"),
1889 XML_L("parsing finished"),
1890 XML_L("cannot suspend in external parameter entity"),
1891 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1892 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1893 XML_L("prefix must not be bound to one of the reserved namespace names")
1895 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1896 return message
[code
];
1900 const XML_LChar
* XMLCALL
1901 XML_ExpatVersion(void) {
1903 /* V1 is used to string-ize the version number. However, it would
1904 string-ize the actual version macro *names* unless we get them
1905 substituted before being passed to V1. CPP is defined to expand
1906 a macro, then rescan for more expansions. Thus, we use V2 to expand
1907 the version macros, then CPP will expand the resulting V1() macro
1908 with the correct numerals. */
1909 /* ### I'm assuming cpp is portable in this respect... */
1911 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1912 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1914 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1920 XML_Expat_Version XMLCALL
1921 XML_ExpatVersionInfo(void)
1923 XML_Expat_Version version
;
1925 version
.major
= XML_MAJOR_VERSION
;
1926 version
.minor
= XML_MINOR_VERSION
;
1927 version
.micro
= XML_MICRO_VERSION
;
1932 const XML_Feature
* XMLCALL
1933 XML_GetFeatureList(void)
1935 static const XML_Feature features
[] = {
1936 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1938 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1941 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1943 #ifdef XML_UNICODE_WCHAR_T
1944 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1947 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1949 #ifdef XML_CONTEXT_BYTES
1950 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1954 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1957 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1959 {XML_FEATURE_END
, NULL
, 0}
1965 /* Initially tag->rawName always points into the parse buffer;
1966 for those TAG instances opened while the current parse buffer was
1967 processed, and not yet closed, we need to store tag->rawName in a more
1968 permanent location, since the parse buffer is about to be discarded.
1971 storeRawNames(XML_Parser parser
)
1973 TAG
*tag
= tagStack
;
1976 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1977 char *rawNameBuf
= tag
->buf
+ nameLen
;
1978 /* Stop if already stored. Since tagStack is a stack, we can stop
1979 at the first entry that has already been copied; everything
1980 below it in the stack is already been accounted for in a
1981 previous call to this function.
1983 if (tag
->rawName
== rawNameBuf
)
1985 /* For re-use purposes we need to ensure that the
1986 size of tag->buf is a multiple of sizeof(XML_Char).
1988 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1989 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1990 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1993 /* if tag->name.str points to tag->buf (only when namespace
1994 processing is off) then we have to update it
1996 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1997 tag
->name
.str
= (XML_Char
*)temp
;
1998 /* if tag->name.localPart is set (when namespace processing is on)
1999 then update it as well, since it will always point into tag->buf
2001 if (tag
->name
.localPart
)
2002 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2003 (XML_Char
*)tag
->buf
);
2005 tag
->bufEnd
= temp
+ bufSize
;
2006 rawNameBuf
= temp
+ nameLen
;
2008 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2009 tag
->rawName
= rawNameBuf
;
2015 static enum XML_Error PTRCALL
2016 contentProcessor(XML_Parser parser
,
2019 const char **endPtr
)
2021 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2022 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2023 if (result
== XML_ERROR_NONE
) {
2024 if (!storeRawNames(parser
))
2025 return XML_ERROR_NO_MEMORY
;
2030 static enum XML_Error PTRCALL
2031 externalEntityInitProcessor(XML_Parser parser
,
2034 const char **endPtr
)
2036 enum XML_Error result
= initializeEncoding(parser
);
2037 if (result
!= XML_ERROR_NONE
)
2039 processor
= externalEntityInitProcessor2
;
2040 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2043 static enum XML_Error PTRCALL
2044 externalEntityInitProcessor2(XML_Parser parser
,
2047 const char **endPtr
)
2049 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2050 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2053 /* If we are at the end of the buffer, this would cause the next stage,
2054 i.e. externalEntityInitProcessor3, to pass control directly to
2055 doContent (by detecting XML_TOK_NONE) without processing any xml text
2056 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2058 if (next
== end
&& !ps_finalBuffer
) {
2060 return XML_ERROR_NONE
;
2064 case XML_TOK_PARTIAL
:
2065 if (!ps_finalBuffer
) {
2067 return XML_ERROR_NONE
;
2070 return XML_ERROR_UNCLOSED_TOKEN
;
2071 case XML_TOK_PARTIAL_CHAR
:
2072 if (!ps_finalBuffer
) {
2074 return XML_ERROR_NONE
;
2077 return XML_ERROR_PARTIAL_CHAR
;
2079 processor
= externalEntityInitProcessor3
;
2080 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2083 static enum XML_Error PTRCALL
2084 externalEntityInitProcessor3(XML_Parser parser
,
2087 const char **endPtr
)
2090 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2092 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2096 case XML_TOK_XML_DECL
:
2098 enum XML_Error result
;
2099 result
= processXmlDecl(parser
, 1, start
, next
);
2100 if (result
!= XML_ERROR_NONE
)
2102 switch (ps_parsing
) {
2105 return XML_ERROR_NONE
;
2107 return XML_ERROR_ABORTED
;
2113 case XML_TOK_PARTIAL
:
2114 if (!ps_finalBuffer
) {
2116 return XML_ERROR_NONE
;
2118 return XML_ERROR_UNCLOSED_TOKEN
;
2119 case XML_TOK_PARTIAL_CHAR
:
2120 if (!ps_finalBuffer
) {
2122 return XML_ERROR_NONE
;
2124 return XML_ERROR_PARTIAL_CHAR
;
2126 processor
= externalEntityContentProcessor
;
2128 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2131 static enum XML_Error PTRCALL
2132 externalEntityContentProcessor(XML_Parser parser
,
2135 const char **endPtr
)
2137 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2138 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2139 if (result
== XML_ERROR_NONE
) {
2140 if (!storeRawNames(parser
))
2141 return XML_ERROR_NO_MEMORY
;
2146 static enum XML_Error
2147 doContent(XML_Parser parser
,
2149 const ENCODING
*enc
,
2152 const char **nextPtr
,
2155 /* save one level of indirection */
2156 DTD
* const dtd
= _dtd
;
2158 const char **eventPP
;
2159 const char **eventEndPP
;
2160 if (enc
== encoding
) {
2161 eventPP
= &eventPtr
;
2162 eventEndPP
= &eventEndPtr
;
2165 eventPP
= &(openInternalEntities
->internalEventPtr
);
2166 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2171 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2172 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2175 case XML_TOK_TRAILING_CR
:
2178 return XML_ERROR_NONE
;
2181 if (characterDataHandler
) {
2183 characterDataHandler(handlerArg
, &c
, 1);
2185 else if (defaultHandler
)
2186 reportDefault(parser
, enc
, s
, end
);
2187 /* We are at the end of the final buffer, should we check for
2188 XML_SUSPENDED, XML_FINISHED?
2190 if (startTagLevel
== 0)
2191 return XML_ERROR_NO_ELEMENTS
;
2192 if (tagLevel
!= startTagLevel
)
2193 return XML_ERROR_ASYNC_ENTITY
;
2195 return XML_ERROR_NONE
;
2199 return XML_ERROR_NONE
;
2201 if (startTagLevel
> 0) {
2202 if (tagLevel
!= startTagLevel
)
2203 return XML_ERROR_ASYNC_ENTITY
;
2205 return XML_ERROR_NONE
;
2207 return XML_ERROR_NO_ELEMENTS
;
2208 case XML_TOK_INVALID
:
2210 return XML_ERROR_INVALID_TOKEN
;
2211 case XML_TOK_PARTIAL
:
2214 return XML_ERROR_NONE
;
2216 return XML_ERROR_UNCLOSED_TOKEN
;
2217 case XML_TOK_PARTIAL_CHAR
:
2220 return XML_ERROR_NONE
;
2222 return XML_ERROR_PARTIAL_CHAR
;
2223 case XML_TOK_ENTITY_REF
:
2225 const XML_Char
*name
;
2227 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2228 s
+ enc
->minBytesPerChar
,
2229 next
- enc
->minBytesPerChar
);
2231 if (characterDataHandler
)
2232 characterDataHandler(handlerArg
, &ch
, 1);
2233 else if (defaultHandler
)
2234 reportDefault(parser
, enc
, s
, next
);
2237 name
= poolStoreString(&dtd
->pool
, enc
,
2238 s
+ enc
->minBytesPerChar
,
2239 next
- enc
->minBytesPerChar
);
2241 return XML_ERROR_NO_MEMORY
;
2242 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2243 poolDiscard(&dtd
->pool
);
2244 /* First, determine if a check for an existing declaration is needed;
2245 if yes, check that the entity exists, and that it is internal,
2246 otherwise call the skipped entity or default handler.
2248 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2250 return XML_ERROR_UNDEFINED_ENTITY
;
2251 else if (!entity
->is_internal
)
2252 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2255 if (skippedEntityHandler
)
2256 skippedEntityHandler(handlerArg
, name
, 0);
2257 else if (defaultHandler
)
2258 reportDefault(parser
, enc
, s
, next
);
2262 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2263 if (entity
->notation
)
2264 return XML_ERROR_BINARY_ENTITY_REF
;
2265 if (entity
->textPtr
) {
2266 enum XML_Error result
;
2267 if (!defaultExpandInternalEntities
) {
2268 if (skippedEntityHandler
)
2269 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2270 else if (defaultHandler
)
2271 reportDefault(parser
, enc
, s
, next
);
2274 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2275 if (result
!= XML_ERROR_NONE
)
2278 else if (externalEntityRefHandler
) {
2279 const XML_Char
*context
;
2280 entity
->open
= XML_TRUE
;
2281 context
= getContext(parser
);
2282 entity
->open
= XML_FALSE
;
2284 return XML_ERROR_NO_MEMORY
;
2285 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2290 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2291 poolDiscard(&tempPool
);
2293 else if (defaultHandler
)
2294 reportDefault(parser
, enc
, s
, next
);
2297 case XML_TOK_START_TAG_NO_ATTS
:
2299 case XML_TOK_START_TAG_WITH_ATTS
:
2302 enum XML_Error result
;
2306 freeTagList
= freeTagList
->parent
;
2309 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2311 return XML_ERROR_NO_MEMORY
;
2312 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2315 return XML_ERROR_NO_MEMORY
;
2317 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2319 tag
->bindings
= NULL
;
2320 tag
->parent
= tagStack
;
2322 tag
->name
.localPart
= NULL
;
2323 tag
->name
.prefix
= NULL
;
2324 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2325 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2328 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2329 const char *fromPtr
= tag
->rawName
;
2330 toPtr
= (XML_Char
*)tag
->buf
;
2335 &fromPtr
, rawNameEnd
,
2336 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2337 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2338 if (fromPtr
== rawNameEnd
) {
2339 tag
->name
.strLen
= convLen
;
2342 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2344 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2346 return XML_ERROR_NO_MEMORY
;
2348 tag
->bufEnd
= temp
+ bufSize
;
2349 toPtr
= (XML_Char
*)temp
+ convLen
;
2353 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2354 *toPtr
= XML_T('\0');
2355 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2358 if (startElementHandler
)
2359 startElementHandler(handlerArg
, tag
->name
.str
,
2360 (const XML_Char
**)atts
);
2361 else if (defaultHandler
)
2362 reportDefault(parser
, enc
, s
, next
);
2363 poolClear(&tempPool
);
2366 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2368 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2370 const char *rawName
= s
+ enc
->minBytesPerChar
;
2371 enum XML_Error result
;
2372 BINDING
*bindings
= NULL
;
2373 XML_Bool noElmHandlers
= XML_TRUE
;
2375 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2376 rawName
+ XmlNameLength(enc
, rawName
));
2378 return XML_ERROR_NO_MEMORY
;
2379 poolFinish(&tempPool
);
2380 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2383 poolFinish(&tempPool
);
2384 if (startElementHandler
) {
2385 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2386 noElmHandlers
= XML_FALSE
;
2388 if (endElementHandler
) {
2389 if (startElementHandler
)
2390 *eventPP
= *eventEndPP
;
2391 endElementHandler(handlerArg
, name
.str
);
2392 noElmHandlers
= XML_FALSE
;
2394 if (noElmHandlers
&& defaultHandler
)
2395 reportDefault(parser
, enc
, s
, next
);
2396 poolClear(&tempPool
);
2398 BINDING
*b
= bindings
;
2399 if (endNamespaceDeclHandler
)
2400 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2401 bindings
= bindings
->nextTagBinding
;
2402 b
->nextTagBinding
= freeBindingList
;
2403 freeBindingList
= b
;
2404 b
->prefix
->binding
= b
->prevPrefixBinding
;
2408 return epilogProcessor(parser
, next
, end
, nextPtr
);
2410 case XML_TOK_END_TAG
:
2411 if (tagLevel
== startTagLevel
)
2412 return XML_ERROR_ASYNC_ENTITY
;
2415 const char *rawName
;
2416 TAG
*tag
= tagStack
;
2417 tagStack
= tag
->parent
;
2418 tag
->parent
= freeTagList
;
2420 rawName
= s
+ enc
->minBytesPerChar
*2;
2421 len
= XmlNameLength(enc
, rawName
);
2422 if (len
!= tag
->rawNameLength
2423 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2425 return XML_ERROR_TAG_MISMATCH
;
2428 if (endElementHandler
) {
2429 const XML_Char
*localPart
;
2430 const XML_Char
*prefix
;
2432 localPart
= tag
->name
.localPart
;
2433 if (ns
&& localPart
) {
2434 /* localPart and prefix may have been overwritten in
2435 tag->name.str, since this points to the binding->uri
2436 buffer which gets re-used; so we have to add them again
2438 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2439 /* don't need to check for space - already done in storeAtts() */
2440 while (*localPart
) *uri
++ = *localPart
++;
2441 prefix
= (XML_Char
*)tag
->name
.prefix
;
2442 if (ns_triplets
&& prefix
) {
2443 *uri
++ = namespaceSeparator
;
2444 while (*prefix
) *uri
++ = *prefix
++;
2448 endElementHandler(handlerArg
, tag
->name
.str
);
2450 else if (defaultHandler
)
2451 reportDefault(parser
, enc
, s
, next
);
2452 while (tag
->bindings
) {
2453 BINDING
*b
= tag
->bindings
;
2454 if (endNamespaceDeclHandler
)
2455 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2456 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2457 b
->nextTagBinding
= freeBindingList
;
2458 freeBindingList
= b
;
2459 b
->prefix
->binding
= b
->prevPrefixBinding
;
2462 return epilogProcessor(parser
, next
, end
, nextPtr
);
2465 case XML_TOK_CHAR_REF
:
2467 int n
= XmlCharRefNumber(enc
, s
);
2469 return XML_ERROR_BAD_CHAR_REF
;
2470 if (characterDataHandler
) {
2471 XML_Char buf
[XML_ENCODE_MAX
];
2472 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2474 else if (defaultHandler
)
2475 reportDefault(parser
, enc
, s
, next
);
2478 case XML_TOK_XML_DECL
:
2479 return XML_ERROR_MISPLACED_XML_PI
;
2480 case XML_TOK_DATA_NEWLINE
:
2481 if (characterDataHandler
) {
2483 characterDataHandler(handlerArg
, &c
, 1);
2485 else if (defaultHandler
)
2486 reportDefault(parser
, enc
, s
, next
);
2488 case XML_TOK_CDATA_SECT_OPEN
:
2490 enum XML_Error result
;
2491 if (startCdataSectionHandler
)
2492 startCdataSectionHandler(handlerArg
);
2494 /* Suppose you doing a transformation on a document that involves
2495 changing only the character data. You set up a defaultHandler
2496 and a characterDataHandler. The defaultHandler simply copies
2497 characters through. The characterDataHandler does the
2498 transformation and writes the characters out escaping them as
2499 necessary. This case will fail to work if we leave out the
2500 following two lines (because & and < inside CDATA sections will
2501 be incorrectly escaped).
2503 However, now we have a start/endCdataSectionHandler, so it seems
2504 easier to let the user deal with this.
2506 else if (characterDataHandler
)
2507 characterDataHandler(handlerArg
, dataBuf
, 0);
2509 else if (defaultHandler
)
2510 reportDefault(parser
, enc
, s
, next
);
2511 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2512 if (result
!= XML_ERROR_NONE
)
2515 processor
= cdataSectionProcessor
;
2520 case XML_TOK_TRAILING_RSQB
:
2523 return XML_ERROR_NONE
;
2525 if (characterDataHandler
) {
2526 if (MUST_CONVERT(enc
, s
)) {
2527 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2528 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2529 characterDataHandler(handlerArg
, dataBuf
,
2530 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2533 characterDataHandler(handlerArg
,
2535 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2537 else if (defaultHandler
)
2538 reportDefault(parser
, enc
, s
, end
);
2539 /* We are at the end of the final buffer, should we check for
2540 XML_SUSPENDED, XML_FINISHED?
2542 if (startTagLevel
== 0) {
2544 return XML_ERROR_NO_ELEMENTS
;
2546 if (tagLevel
!= startTagLevel
) {
2548 return XML_ERROR_ASYNC_ENTITY
;
2551 return XML_ERROR_NONE
;
2552 case XML_TOK_DATA_CHARS
:
2553 if (characterDataHandler
) {
2554 if (MUST_CONVERT(enc
, s
)) {
2556 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2557 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2559 characterDataHandler(handlerArg
, dataBuf
,
2560 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2567 characterDataHandler(handlerArg
,
2569 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2571 else if (defaultHandler
)
2572 reportDefault(parser
, enc
, s
, next
);
2575 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2576 return XML_ERROR_NO_MEMORY
;
2578 case XML_TOK_COMMENT
:
2579 if (!reportComment(parser
, enc
, s
, next
))
2580 return XML_ERROR_NO_MEMORY
;
2584 reportDefault(parser
, enc
, s
, next
);
2587 *eventPP
= s
= next
;
2588 switch (ps_parsing
) {
2591 return XML_ERROR_NONE
;
2593 return XML_ERROR_ABORTED
;
2600 /* Precondition: all arguments must be non-NULL;
2602 - normalize attributes
2603 - check attributes for well-formedness
2604 - generate namespace aware attribute names (URI, prefix)
2605 - build list of attributes for startElementHandler
2606 - default attributes
2607 - process namespace declarations (check and report them)
2608 - generate namespace aware element name (URI, prefix)
2610 static enum XML_Error
2611 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2612 const char *attStr
, TAG_NAME
*tagNamePtr
,
2613 BINDING
**bindingsPtr
)
2615 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2616 ELEMENT_TYPE
*elementType
;
2618 const XML_Char
**appAtts
; /* the attribute list for the application */
2626 const XML_Char
*localPart
;
2628 /* lookup the element type name */
2629 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2631 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2633 return XML_ERROR_NO_MEMORY
;
2634 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2635 sizeof(ELEMENT_TYPE
));
2637 return XML_ERROR_NO_MEMORY
;
2638 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2639 return XML_ERROR_NO_MEMORY
;
2641 nDefaultAtts
= elementType
->nDefaultAtts
;
2643 /* get the attributes from the tokenizer */
2644 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2645 if (n
+ nDefaultAtts
> attsSize
) {
2646 int oldAttsSize
= attsSize
;
2648 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2649 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2651 return XML_ERROR_NO_MEMORY
;
2653 if (n
> oldAttsSize
)
2654 XmlGetAttributes(enc
, attStr
, n
, atts
);
2657 appAtts
= (const XML_Char
**)atts
;
2658 for (i
= 0; i
< n
; i
++) {
2659 /* add the name and value to the attribute list */
2660 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2662 + XmlNameLength(enc
, atts
[i
].name
));
2664 return XML_ERROR_NO_MEMORY
;
2665 /* Detect duplicate attributes by their QNames. This does not work when
2666 namespace processing is turned on and different prefixes for the same
2667 namespace are used. For this case we have a check further down.
2669 if ((attId
->name
)[-1]) {
2670 if (enc
== encoding
)
2671 eventPtr
= atts
[i
].name
;
2672 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2674 (attId
->name
)[-1] = 1;
2675 appAtts
[attIndex
++] = attId
->name
;
2676 if (!atts
[i
].normalized
) {
2677 enum XML_Error result
;
2678 XML_Bool isCdata
= XML_TRUE
;
2680 /* figure out whether declared as other than CDATA */
2681 if (attId
->maybeTokenized
) {
2683 for (j
= 0; j
< nDefaultAtts
; j
++) {
2684 if (attId
== elementType
->defaultAtts
[j
].id
) {
2685 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2691 /* normalize the attribute value */
2692 result
= storeAttributeValue(parser
, enc
, isCdata
,
2693 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2697 appAtts
[attIndex
] = poolStart(&tempPool
);
2698 poolFinish(&tempPool
);
2701 /* the value did not need normalizing */
2702 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2704 if (appAtts
[attIndex
] == 0)
2705 return XML_ERROR_NO_MEMORY
;
2706 poolFinish(&tempPool
);
2708 /* handle prefixed attribute names */
2709 if (attId
->prefix
) {
2711 /* deal with namespace declarations here */
2712 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2713 appAtts
[attIndex
], bindingsPtr
);
2719 /* deal with other prefixed names later */
2722 (attId
->name
)[-1] = 2;
2729 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2730 nSpecifiedAtts
= attIndex
;
2731 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2732 for (i
= 0; i
< attIndex
; i
+= 2)
2733 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2741 /* do attribute defaulting */
2742 for (i
= 0; i
< nDefaultAtts
; i
++) {
2743 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2744 if (!(da
->id
->name
)[-1] && da
->value
) {
2745 if (da
->id
->prefix
) {
2746 if (da
->id
->xmlns
) {
2747 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2748 da
->value
, bindingsPtr
);
2753 (da
->id
->name
)[-1] = 2;
2755 appAtts
[attIndex
++] = da
->id
->name
;
2756 appAtts
[attIndex
++] = da
->value
;
2760 (da
->id
->name
)[-1] = 1;
2761 appAtts
[attIndex
++] = da
->id
->name
;
2762 appAtts
[attIndex
++] = da
->value
;
2766 appAtts
[attIndex
] = 0;
2768 /* expand prefixed attribute names, check for duplicates,
2769 and clear flags that say whether attributes were specified */
2772 int j
; /* hash table index */
2773 unsigned long version
= nsAttsVersion
;
2774 int nsAttsSize
= (int)1 << nsAttsPower
;
2775 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2776 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2778 /* hash table size must also be a power of 2 and >= 8 */
2779 while (nPrefixes
>> nsAttsPower
++);
2780 if (nsAttsPower
< 3)
2782 nsAttsSize
= (int)1 << nsAttsPower
;
2783 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2785 return XML_ERROR_NO_MEMORY
;
2787 version
= 0; /* force re-initialization of nsAtts hash table */
2789 /* using a version flag saves us from initializing nsAtts every time */
2790 if (!version
) { /* initialize version flags when version wraps around */
2791 version
= INIT_ATTS_VERSION
;
2792 for (j
= nsAttsSize
; j
!= 0; )
2793 nsAtts
[--j
].version
= version
;
2795 nsAttsVersion
= --version
;
2797 /* expand prefixed names and check for duplicates */
2798 for (; i
< attIndex
; i
+= 2) {
2799 const XML_Char
*s
= appAtts
[i
];
2800 if (s
[-1] == 2) { /* prefixed */
2803 unsigned long uriHash
= 0;
2804 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2805 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2807 return XML_ERROR_NO_MEMORY
;
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(':'))
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(':'))
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 'h', 't', 't', 'p', ':', '/', '/',
2949 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2950 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2951 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2953 static const int xmlLen
=
2954 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2955 static const XML_Char xmlnsNamespace
[] = {
2956 'h', 't', 't', 'p', ':', '/', '/',
2957 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2958 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
2960 static const int xmlnsLen
=
2961 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2963 XML_Bool mustBeXML
= XML_FALSE
;
2964 XML_Bool isXML
= XML_TRUE
;
2965 XML_Bool isXMLNS
= XML_TRUE
;
2970 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2971 if (*uri
== XML_T('\0') && prefix
->name
)
2972 return XML_ERROR_UNDECLARING_PREFIX
;
2975 && prefix
->name
[0] == XML_T('x')
2976 && prefix
->name
[1] == XML_T('m')
2977 && prefix
->name
[2] == XML_T('l')) {
2979 /* Not allowed to bind xmlns */
2980 if (prefix
->name
[3] == XML_T('n')
2981 && prefix
->name
[4] == XML_T('s')
2982 && prefix
->name
[5] == XML_T('\0'))
2983 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2985 if (prefix
->name
[3] == XML_T('\0'))
2986 mustBeXML
= XML_TRUE
;
2989 for (len
= 0; uri
[len
]; len
++) {
2990 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
2993 if (!mustBeXML
&& isXMLNS
2994 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
2995 isXMLNS
= XML_FALSE
;
2997 isXML
= isXML
&& len
== xmlLen
;
2998 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3000 if (mustBeXML
!= isXML
)
3001 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3002 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3005 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3007 if (namespaceSeparator
)
3009 if (freeBindingList
) {
3010 b
= freeBindingList
;
3011 if (len
> b
->uriAlloc
) {
3012 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3013 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3015 return XML_ERROR_NO_MEMORY
;
3017 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3019 freeBindingList
= b
->nextTagBinding
;
3022 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3024 return XML_ERROR_NO_MEMORY
;
3025 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3028 return XML_ERROR_NO_MEMORY
;
3030 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3033 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3034 if (namespaceSeparator
)
3035 b
->uri
[len
- 1] = namespaceSeparator
;
3038 b
->prevPrefixBinding
= prefix
->binding
;
3039 /* NULL binding when default namespace undeclared */
3040 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3041 prefix
->binding
= NULL
;
3043 prefix
->binding
= b
;
3044 b
->nextTagBinding
= *bindingsPtr
;
3046 /* if attId == NULL then we are not starting a namespace scope */
3047 if (attId
&& startNamespaceDeclHandler
)
3048 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3049 prefix
->binding
? uri
: 0);
3050 return XML_ERROR_NONE
;
3053 /* The idea here is to avoid using stack for each CDATA section when
3054 the whole file is parsed with one call.
3056 static enum XML_Error PTRCALL
3057 cdataSectionProcessor(XML_Parser parser
,
3060 const char **endPtr
)
3062 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3063 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3064 if (result
!= XML_ERROR_NONE
)
3067 if (parentParser
) { /* we are parsing an external entity */
3068 processor
= externalEntityContentProcessor
;
3069 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3072 processor
= contentProcessor
;
3073 return contentProcessor(parser
, start
, end
, endPtr
);
3079 /* startPtr gets set to non-null if the section is closed, and to null if
3080 the section is not yet closed.
3082 static enum XML_Error
3083 doCdataSection(XML_Parser parser
,
3084 const ENCODING
*enc
,
3085 const char **startPtr
,
3087 const char **nextPtr
,
3090 const char *s
= *startPtr
;
3091 const char **eventPP
;
3092 const char **eventEndPP
;
3093 if (enc
== encoding
) {
3094 eventPP
= &eventPtr
;
3096 eventEndPP
= &eventEndPtr
;
3099 eventPP
= &(openInternalEntities
->internalEventPtr
);
3100 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3107 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3110 case XML_TOK_CDATA_SECT_CLOSE
:
3111 if (endCdataSectionHandler
)
3112 endCdataSectionHandler(handlerArg
);
3114 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3115 else if (characterDataHandler
)
3116 characterDataHandler(handlerArg
, dataBuf
, 0);
3118 else if (defaultHandler
)
3119 reportDefault(parser
, enc
, s
, next
);
3122 if (ps_parsing
== XML_FINISHED
)
3123 return XML_ERROR_ABORTED
;
3125 return XML_ERROR_NONE
;
3126 case XML_TOK_DATA_NEWLINE
:
3127 if (characterDataHandler
) {
3129 characterDataHandler(handlerArg
, &c
, 1);
3131 else if (defaultHandler
)
3132 reportDefault(parser
, enc
, s
, next
);
3134 case XML_TOK_DATA_CHARS
:
3135 if (characterDataHandler
) {
3136 if (MUST_CONVERT(enc
, s
)) {
3138 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3139 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3141 characterDataHandler(handlerArg
, dataBuf
,
3142 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3149 characterDataHandler(handlerArg
,
3151 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3153 else if (defaultHandler
)
3154 reportDefault(parser
, enc
, s
, next
);
3156 case XML_TOK_INVALID
:
3158 return XML_ERROR_INVALID_TOKEN
;
3159 case XML_TOK_PARTIAL_CHAR
:
3162 return XML_ERROR_NONE
;
3164 return XML_ERROR_PARTIAL_CHAR
;
3165 case XML_TOK_PARTIAL
:
3169 return XML_ERROR_NONE
;
3171 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3174 return XML_ERROR_UNEXPECTED_STATE
;
3177 *eventPP
= s
= next
;
3178 switch (ps_parsing
) {
3181 return XML_ERROR_NONE
;
3183 return XML_ERROR_ABORTED
;
3192 /* The idea here is to avoid using stack for each IGNORE section when
3193 the whole file is parsed with one call.
3195 static enum XML_Error PTRCALL
3196 ignoreSectionProcessor(XML_Parser parser
,
3199 const char **endPtr
)
3201 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3202 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3203 if (result
!= XML_ERROR_NONE
)
3206 processor
= prologProcessor
;
3207 return prologProcessor(parser
, start
, end
, endPtr
);
3212 /* startPtr gets set to non-null is the section is closed, and to null
3213 if the section is not yet closed.
3215 static enum XML_Error
3216 doIgnoreSection(XML_Parser parser
,
3217 const ENCODING
*enc
,
3218 const char **startPtr
,
3220 const char **nextPtr
,
3225 const char *s
= *startPtr
;
3226 const char **eventPP
;
3227 const char **eventEndPP
;
3228 if (enc
== encoding
) {
3229 eventPP
= &eventPtr
;
3231 eventEndPP
= &eventEndPtr
;
3234 eventPP
= &(openInternalEntities
->internalEventPtr
);
3235 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3239 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3242 case XML_TOK_IGNORE_SECT
:
3244 reportDefault(parser
, enc
, s
, next
);
3247 if (ps_parsing
== XML_FINISHED
)
3248 return XML_ERROR_ABORTED
;
3250 return XML_ERROR_NONE
;
3251 case XML_TOK_INVALID
:
3253 return XML_ERROR_INVALID_TOKEN
;
3254 case XML_TOK_PARTIAL_CHAR
:
3257 return XML_ERROR_NONE
;
3259 return XML_ERROR_PARTIAL_CHAR
;
3260 case XML_TOK_PARTIAL
:
3264 return XML_ERROR_NONE
;
3266 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3269 return XML_ERROR_UNEXPECTED_STATE
;
3274 #endif /* XML_DTD */
3276 static enum XML_Error
3277 initializeEncoding(XML_Parser parser
)
3281 char encodingBuf
[128];
3282 if (!protocolEncodingName
)
3286 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3287 if (i
== sizeof(encodingBuf
) - 1
3288 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3289 encodingBuf
[0] = '\0';
3292 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3294 encodingBuf
[i
] = '\0';
3298 s
= protocolEncodingName
;
3300 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3301 return XML_ERROR_NONE
;
3302 return handleUnknownEncoding(parser
, protocolEncodingName
);
3305 static enum XML_Error
3306 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3307 const char *s
, const char *next
)
3309 const char *encodingName
= NULL
;
3310 const XML_Char
*storedEncName
= NULL
;
3311 const ENCODING
*newEncoding
= NULL
;
3312 const char *version
= NULL
;
3313 const char *versionend
;
3314 const XML_Char
*storedversion
= NULL
;
3315 int standalone
= -1;
3318 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3328 if (isGeneralTextEntity
)
3329 return XML_ERROR_TEXT_DECL
;
3331 return XML_ERROR_XML_DECL
;
3333 if (!isGeneralTextEntity
&& standalone
== 1) {
3334 _dtd
->standalone
= XML_TRUE
;
3336 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3337 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3338 #endif /* XML_DTD */
3340 if (xmlDeclHandler
) {
3341 if (encodingName
!= NULL
) {
3342 storedEncName
= poolStoreString(&temp2Pool
,
3346 + XmlNameLength(encoding
, encodingName
));
3348 return XML_ERROR_NO_MEMORY
;
3349 poolFinish(&temp2Pool
);
3352 storedversion
= poolStoreString(&temp2Pool
,
3355 versionend
- encoding
->minBytesPerChar
);
3357 return XML_ERROR_NO_MEMORY
;
3359 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3361 else if (defaultHandler
)
3362 reportDefault(parser
, encoding
, s
, next
);
3363 if (protocolEncodingName
== NULL
) {
3365 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3366 eventPtr
= encodingName
;
3367 return XML_ERROR_INCORRECT_ENCODING
;
3369 encoding
= newEncoding
;
3371 else if (encodingName
) {
3372 enum XML_Error result
;
3373 if (!storedEncName
) {
3374 storedEncName
= poolStoreString(
3375 &temp2Pool
, encoding
, encodingName
,
3376 encodingName
+ XmlNameLength(encoding
, encodingName
));
3378 return XML_ERROR_NO_MEMORY
;
3380 result
= handleUnknownEncoding(parser
, storedEncName
);
3381 poolClear(&temp2Pool
);
3382 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3383 eventPtr
= encodingName
;
3388 if (storedEncName
|| storedversion
)
3389 poolClear(&temp2Pool
);
3391 return XML_ERROR_NONE
;
3394 static enum XML_Error
3395 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3397 if (unknownEncodingHandler
) {
3400 for (i
= 0; i
< 256; i
++)
3402 info
.convert
= NULL
;
3404 info
.release
= NULL
;
3405 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3408 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3409 if (!unknownEncodingMem
) {
3411 info
.release(info
.data
);
3412 return XML_ERROR_NO_MEMORY
;
3415 ? XmlInitUnknownEncodingNS
3416 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3421 unknownEncodingData
= info
.data
;
3422 unknownEncodingRelease
= info
.release
;
3424 return XML_ERROR_NONE
;
3427 if (info
.release
!= NULL
)
3428 info
.release(info
.data
);
3430 return XML_ERROR_UNKNOWN_ENCODING
;
3433 static enum XML_Error PTRCALL
3434 prologInitProcessor(XML_Parser parser
,
3437 const char **nextPtr
)
3439 enum XML_Error result
= initializeEncoding(parser
);
3440 if (result
!= XML_ERROR_NONE
)
3442 processor
= prologProcessor
;
3443 return prologProcessor(parser
, s
, end
, nextPtr
);
3448 static enum XML_Error PTRCALL
3449 externalParEntInitProcessor(XML_Parser parser
,
3452 const char **nextPtr
)
3454 enum XML_Error result
= initializeEncoding(parser
);
3455 if (result
!= XML_ERROR_NONE
)
3458 /* we know now that XML_Parse(Buffer) has been called,
3459 so we consider the external parameter entity read */
3460 _dtd
->paramEntityRead
= XML_TRUE
;
3462 if (prologState
.inEntityValue
) {
3463 processor
= entityValueInitProcessor
;
3464 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3467 processor
= externalParEntProcessor
;
3468 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3472 static enum XML_Error PTRCALL
3473 entityValueInitProcessor(XML_Parser parser
,
3476 const char **nextPtr
)
3479 const char *start
= s
;
3480 const char *next
= start
;
3484 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3487 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3489 return XML_ERROR_NONE
;
3492 case XML_TOK_INVALID
:
3493 return XML_ERROR_INVALID_TOKEN
;
3494 case XML_TOK_PARTIAL
:
3495 return XML_ERROR_UNCLOSED_TOKEN
;
3496 case XML_TOK_PARTIAL_CHAR
:
3497 return XML_ERROR_PARTIAL_CHAR
;
3498 case XML_TOK_NONE
: /* start == end */
3502 /* found end of entity value - can store it now */
3503 return storeEntityValue(parser
, encoding
, s
, end
);
3505 else if (tok
== XML_TOK_XML_DECL
) {
3506 enum XML_Error result
;
3507 result
= processXmlDecl(parser
, 0, start
, next
);
3508 if (result
!= XML_ERROR_NONE
)
3510 switch (ps_parsing
) {
3513 return XML_ERROR_NONE
;
3515 return XML_ERROR_ABORTED
;
3519 /* stop scanning for text declaration - we found one */
3520 processor
= entityValueProcessor
;
3521 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3523 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3524 return XML_TOK_NONE on the next call, which would then cause the
3525 function to exit with *nextPtr set to s - that is what we want for other
3526 tokens, but not for the BOM - we would rather like to skip it;
3527 then, when this routine is entered the next time, XmlPrologTok will
3528 return XML_TOK_INVALID, since the BOM is still in the buffer
3530 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3532 return XML_ERROR_NONE
;
3539 static enum XML_Error PTRCALL
3540 externalParEntProcessor(XML_Parser parser
,
3543 const char **nextPtr
)
3545 const char *next
= s
;
3548 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3550 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3552 return XML_ERROR_NONE
;
3555 case XML_TOK_INVALID
:
3556 return XML_ERROR_INVALID_TOKEN
;
3557 case XML_TOK_PARTIAL
:
3558 return XML_ERROR_UNCLOSED_TOKEN
;
3559 case XML_TOK_PARTIAL_CHAR
:
3560 return XML_ERROR_PARTIAL_CHAR
;
3561 case XML_TOK_NONE
: /* start == end */
3566 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3567 However, when parsing an external subset, doProlog will not accept a BOM
3568 as valid, and report a syntax error, so we have to skip the BOM
3570 else if (tok
== XML_TOK_BOM
) {
3572 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3575 processor
= prologProcessor
;
3576 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3577 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3580 static enum XML_Error PTRCALL
3581 entityValueProcessor(XML_Parser parser
,
3584 const char **nextPtr
)
3586 const char *start
= s
;
3587 const char *next
= s
;
3588 const ENCODING
*enc
= encoding
;
3592 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3594 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3596 return XML_ERROR_NONE
;
3599 case XML_TOK_INVALID
:
3600 return XML_ERROR_INVALID_TOKEN
;
3601 case XML_TOK_PARTIAL
:
3602 return XML_ERROR_UNCLOSED_TOKEN
;
3603 case XML_TOK_PARTIAL_CHAR
:
3604 return XML_ERROR_PARTIAL_CHAR
;
3605 case XML_TOK_NONE
: /* start == end */
3609 /* found end of entity value - can store it now */
3610 return storeEntityValue(parser
, enc
, s
, end
);
3616 #endif /* XML_DTD */
3618 static enum XML_Error PTRCALL
3619 prologProcessor(XML_Parser parser
,
3622 const char **nextPtr
)
3624 const char *next
= s
;
3625 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3626 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3627 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3630 static enum XML_Error
3631 doProlog(XML_Parser parser
,
3632 const ENCODING
*enc
,
3637 const char **nextPtr
,
3641 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3642 #endif /* XML_DTD */
3643 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3644 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3645 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3646 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3647 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3648 static const XML_Char atypeENTITIES
[] =
3649 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3650 static const XML_Char atypeNMTOKEN
[] = {
3651 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3652 static const XML_Char atypeNMTOKENS
[] = {
3653 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3654 static const XML_Char notationPrefix
[] = {
3655 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3656 static const XML_Char enumValueSep
[] = { '|', '\0' };
3657 static const XML_Char enumValueStart
[] = { '(', '\0' };
3659 /* save one level of indirection */
3660 DTD
* const dtd
= _dtd
;
3662 const char **eventPP
;
3663 const char **eventEndPP
;
3664 enum XML_Content_Quant quant
;
3666 if (enc
== encoding
) {
3667 eventPP
= &eventPtr
;
3668 eventEndPP
= &eventEndPtr
;
3671 eventPP
= &(openInternalEntities
->internalEventPtr
);
3672 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3677 XML_Bool handleDefault
= XML_TRUE
;
3681 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3683 return XML_ERROR_NONE
;
3686 case XML_TOK_INVALID
:
3688 return XML_ERROR_INVALID_TOKEN
;
3689 case XML_TOK_PARTIAL
:
3690 return XML_ERROR_UNCLOSED_TOKEN
;
3691 case XML_TOK_PARTIAL_CHAR
:
3692 return XML_ERROR_PARTIAL_CHAR
;
3693 case -XML_TOK_PROLOG_S
:
3698 /* for internal PE NOT referenced between declarations */
3699 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3701 return XML_ERROR_NONE
;
3703 /* WFC: PE Between Declarations - must check that PE contains
3704 complete markup, not only for external PEs, but also for
3705 internal PEs if the reference occurs between declarations.
3707 if (isParamEntity
|| enc
!= encoding
) {
3708 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3710 return XML_ERROR_INCOMPLETE_PE
;
3712 return XML_ERROR_NONE
;
3714 #endif /* XML_DTD */
3715 return XML_ERROR_NO_ELEMENTS
;
3722 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3724 case XML_ROLE_XML_DECL
:
3726 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3727 if (result
!= XML_ERROR_NONE
)
3730 handleDefault
= XML_FALSE
;
3733 case XML_ROLE_DOCTYPE_NAME
:
3734 if (startDoctypeDeclHandler
) {
3735 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3737 return XML_ERROR_NO_MEMORY
;
3738 poolFinish(&tempPool
);
3739 doctypePubid
= NULL
;
3740 handleDefault
= XML_FALSE
;
3742 doctypeSysid
= NULL
; /* always initialize to NULL */
3744 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3745 if (startDoctypeDeclHandler
) {
3746 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3749 poolClear(&tempPool
);
3750 handleDefault
= XML_FALSE
;
3754 case XML_ROLE_TEXT_DECL
:
3756 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3757 if (result
!= XML_ERROR_NONE
)
3760 handleDefault
= XML_FALSE
;
3763 #endif /* XML_DTD */
3764 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3766 useForeignDTD
= XML_FALSE
;
3767 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3771 return XML_ERROR_NO_MEMORY
;
3772 #endif /* XML_DTD */
3773 dtd
->hasParamEntityRefs
= XML_TRUE
;
3774 if (startDoctypeDeclHandler
) {
3775 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3776 return XML_ERROR_PUBLICID
;
3777 doctypePubid
= poolStoreString(&tempPool
, enc
,
3778 s
+ enc
->minBytesPerChar
,
3779 next
- enc
->minBytesPerChar
);
3781 return XML_ERROR_NO_MEMORY
;
3782 normalizePublicId((XML_Char
*)doctypePubid
);
3783 poolFinish(&tempPool
);
3784 handleDefault
= XML_FALSE
;
3785 goto alreadyChecked
;
3788 case XML_ROLE_ENTITY_PUBLIC_ID
:
3789 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3790 return XML_ERROR_PUBLICID
;
3792 if (dtd
->keepProcessing
&& declEntity
) {
3793 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3795 s
+ enc
->minBytesPerChar
,
3796 next
- enc
->minBytesPerChar
);
3798 return XML_ERROR_NO_MEMORY
;
3799 normalizePublicId(tem
);
3800 declEntity
->publicId
= tem
;
3801 poolFinish(&dtd
->pool
);
3802 if (entityDeclHandler
)
3803 handleDefault
= XML_FALSE
;
3806 case XML_ROLE_DOCTYPE_CLOSE
:
3808 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3809 doctypeSysid
, doctypePubid
, 0);
3810 poolClear(&tempPool
);
3811 handleDefault
= XML_FALSE
;
3813 /* doctypeSysid will be non-NULL in the case of a previous
3814 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3815 was not set, indicating an external subset
3818 if (doctypeSysid
|| useForeignDTD
) {
3819 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3820 dtd
->hasParamEntityRefs
= XML_TRUE
;
3821 if (paramEntityParsing
&& externalEntityRefHandler
) {
3822 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3826 return XML_ERROR_NO_MEMORY
;
3828 entity
->base
= curBase
;
3829 dtd
->paramEntityRead
= XML_FALSE
;
3830 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3835 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3836 if (dtd
->paramEntityRead
) {
3837 if (!dtd
->standalone
&&
3838 notStandaloneHandler
&&
3839 !notStandaloneHandler(handlerArg
))
3840 return XML_ERROR_NOT_STANDALONE
;
3842 /* if we didn't read the foreign DTD then this means that there
3843 is no external subset and we must reset dtd->hasParamEntityRefs
3845 else if (!doctypeSysid
)
3846 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3847 /* end of DTD - no need to update dtd->keepProcessing */
3849 useForeignDTD
= XML_FALSE
;
3851 #endif /* XML_DTD */
3852 if (endDoctypeDeclHandler
) {
3853 endDoctypeDeclHandler(handlerArg
);
3854 handleDefault
= XML_FALSE
;
3857 case XML_ROLE_INSTANCE_START
:
3859 /* if there is no DOCTYPE declaration then now is the
3860 last chance to read the foreign DTD
3862 if (useForeignDTD
) {
3863 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3864 dtd
->hasParamEntityRefs
= XML_TRUE
;
3865 if (paramEntityParsing
&& externalEntityRefHandler
) {
3866 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3870 return XML_ERROR_NO_MEMORY
;
3871 entity
->base
= curBase
;
3872 dtd
->paramEntityRead
= XML_FALSE
;
3873 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3878 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3879 if (dtd
->paramEntityRead
) {
3880 if (!dtd
->standalone
&&
3881 notStandaloneHandler
&&
3882 !notStandaloneHandler(handlerArg
))
3883 return XML_ERROR_NOT_STANDALONE
;
3885 /* if we didn't read the foreign DTD then this means that there
3886 is no external subset and we must reset dtd->hasParamEntityRefs
3889 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3890 /* end of DTD - no need to update dtd->keepProcessing */
3893 #endif /* XML_DTD */
3894 processor
= contentProcessor
;
3895 return contentProcessor(parser
, s
, end
, nextPtr
);
3896 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3897 declElementType
= getElementType(parser
, enc
, s
, next
);
3898 if (!declElementType
)
3899 return XML_ERROR_NO_MEMORY
;
3900 goto checkAttListDeclHandler
;
3901 case XML_ROLE_ATTRIBUTE_NAME
:
3902 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3903 if (!declAttributeId
)
3904 return XML_ERROR_NO_MEMORY
;
3905 declAttributeIsCdata
= XML_FALSE
;
3906 declAttributeType
= NULL
;
3907 declAttributeIsId
= XML_FALSE
;
3908 goto checkAttListDeclHandler
;
3909 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3910 declAttributeIsCdata
= XML_TRUE
;
3911 declAttributeType
= atypeCDATA
;
3912 goto checkAttListDeclHandler
;
3913 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3914 declAttributeIsId
= XML_TRUE
;
3915 declAttributeType
= atypeID
;
3916 goto checkAttListDeclHandler
;
3917 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3918 declAttributeType
= atypeIDREF
;
3919 goto checkAttListDeclHandler
;
3920 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3921 declAttributeType
= atypeIDREFS
;
3922 goto checkAttListDeclHandler
;
3923 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3924 declAttributeType
= atypeENTITY
;
3925 goto checkAttListDeclHandler
;
3926 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3927 declAttributeType
= atypeENTITIES
;
3928 goto checkAttListDeclHandler
;
3929 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3930 declAttributeType
= atypeNMTOKEN
;
3931 goto checkAttListDeclHandler
;
3932 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3933 declAttributeType
= atypeNMTOKENS
;
3934 checkAttListDeclHandler
:
3935 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3936 handleDefault
= XML_FALSE
;
3938 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3939 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3940 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3941 const XML_Char
*prefix
;
3942 if (declAttributeType
) {
3943 prefix
= enumValueSep
;
3946 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3950 if (!poolAppendString(&tempPool
, prefix
))
3951 return XML_ERROR_NO_MEMORY
;
3952 if (!poolAppend(&tempPool
, enc
, s
, next
))
3953 return XML_ERROR_NO_MEMORY
;
3954 declAttributeType
= tempPool
.start
;
3955 handleDefault
= XML_FALSE
;
3958 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3959 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3960 if (dtd
->keepProcessing
) {
3961 if (!defineAttribute(declElementType
, declAttributeId
,
3962 declAttributeIsCdata
, declAttributeIsId
,
3964 return XML_ERROR_NO_MEMORY
;
3965 if (attlistDeclHandler
&& declAttributeType
) {
3966 if (*declAttributeType
== XML_T('(')
3967 || (*declAttributeType
== XML_T('N')
3968 && declAttributeType
[1] == XML_T('O'))) {
3969 /* Enumerated or Notation type */
3970 if (!poolAppendChar(&tempPool
, XML_T(')'))
3971 || !poolAppendChar(&tempPool
, XML_T('\0')))
3972 return XML_ERROR_NO_MEMORY
;
3973 declAttributeType
= tempPool
.start
;
3974 poolFinish(&tempPool
);
3977 attlistDeclHandler(handlerArg
, declElementType
->name
,
3978 declAttributeId
->name
, declAttributeType
,
3979 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3980 poolClear(&tempPool
);
3981 handleDefault
= XML_FALSE
;
3985 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3986 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3987 if (dtd
->keepProcessing
) {
3988 const XML_Char
*attVal
;
3989 enum XML_Error result
=
3990 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3991 s
+ enc
->minBytesPerChar
,
3992 next
- enc
->minBytesPerChar
,
3996 attVal
= poolStart(&dtd
->pool
);
3997 poolFinish(&dtd
->pool
);
3998 /* ID attributes aren't allowed to have a default */
3999 if (!defineAttribute(declElementType
, declAttributeId
,
4000 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4001 return XML_ERROR_NO_MEMORY
;
4002 if (attlistDeclHandler
&& declAttributeType
) {
4003 if (*declAttributeType
== XML_T('(')
4004 || (*declAttributeType
== XML_T('N')
4005 && declAttributeType
[1] == XML_T('O'))) {
4006 /* Enumerated or Notation type */
4007 if (!poolAppendChar(&tempPool
, XML_T(')'))
4008 || !poolAppendChar(&tempPool
, XML_T('\0')))
4009 return XML_ERROR_NO_MEMORY
;
4010 declAttributeType
= tempPool
.start
;
4011 poolFinish(&tempPool
);
4014 attlistDeclHandler(handlerArg
, declElementType
->name
,
4015 declAttributeId
->name
, declAttributeType
,
4017 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4018 poolClear(&tempPool
);
4019 handleDefault
= XML_FALSE
;
4023 case XML_ROLE_ENTITY_VALUE
:
4024 if (dtd
->keepProcessing
) {
4025 enum XML_Error result
= storeEntityValue(parser
, enc
,
4026 s
+ enc
->minBytesPerChar
,
4027 next
- enc
->minBytesPerChar
);
4029 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4030 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4031 poolFinish(&dtd
->entityValuePool
);
4032 if (entityDeclHandler
) {
4034 entityDeclHandler(handlerArg
,
4036 declEntity
->is_param
,
4037 declEntity
->textPtr
,
4038 declEntity
->textLen
,
4040 handleDefault
= XML_FALSE
;
4044 poolDiscard(&dtd
->entityValuePool
);
4045 if (result
!= XML_ERROR_NONE
)
4049 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4051 useForeignDTD
= XML_FALSE
;
4052 #endif /* XML_DTD */
4053 dtd
->hasParamEntityRefs
= XML_TRUE
;
4054 if (startDoctypeDeclHandler
) {
4055 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4056 s
+ enc
->minBytesPerChar
,
4057 next
- enc
->minBytesPerChar
);
4058 if (doctypeSysid
== NULL
)
4059 return XML_ERROR_NO_MEMORY
;
4060 poolFinish(&tempPool
);
4061 handleDefault
= XML_FALSE
;
4065 /* use externalSubsetName to make doctypeSysid non-NULL
4066 for the case where no startDoctypeDeclHandler is set */
4067 doctypeSysid
= externalSubsetName
;
4068 #endif /* XML_DTD */
4069 if (!dtd
->standalone
4071 && !paramEntityParsing
4072 #endif /* XML_DTD */
4073 && notStandaloneHandler
4074 && !notStandaloneHandler(handlerArg
))
4075 return XML_ERROR_NOT_STANDALONE
;
4080 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4084 return XML_ERROR_NO_MEMORY
;
4085 declEntity
->publicId
= NULL
;
4088 #endif /* XML_DTD */
4089 case XML_ROLE_ENTITY_SYSTEM_ID
:
4090 if (dtd
->keepProcessing
&& declEntity
) {
4091 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4092 s
+ enc
->minBytesPerChar
,
4093 next
- enc
->minBytesPerChar
);
4094 if (!declEntity
->systemId
)
4095 return XML_ERROR_NO_MEMORY
;
4096 declEntity
->base
= curBase
;
4097 poolFinish(&dtd
->pool
);
4098 if (entityDeclHandler
)
4099 handleDefault
= XML_FALSE
;
4102 case XML_ROLE_ENTITY_COMPLETE
:
4103 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4105 entityDeclHandler(handlerArg
,
4107 declEntity
->is_param
,
4110 declEntity
->systemId
,
4111 declEntity
->publicId
,
4113 handleDefault
= XML_FALSE
;
4116 case XML_ROLE_ENTITY_NOTATION_NAME
:
4117 if (dtd
->keepProcessing
&& declEntity
) {
4118 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4119 if (!declEntity
->notation
)
4120 return XML_ERROR_NO_MEMORY
;
4121 poolFinish(&dtd
->pool
);
4122 if (unparsedEntityDeclHandler
) {
4124 unparsedEntityDeclHandler(handlerArg
,
4127 declEntity
->systemId
,
4128 declEntity
->publicId
,
4129 declEntity
->notation
);
4130 handleDefault
= XML_FALSE
;
4132 else if (entityDeclHandler
) {
4134 entityDeclHandler(handlerArg
,
4138 declEntity
->systemId
,
4139 declEntity
->publicId
,
4140 declEntity
->notation
);
4141 handleDefault
= XML_FALSE
;
4145 case XML_ROLE_GENERAL_ENTITY_NAME
:
4147 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4151 if (dtd
->keepProcessing
) {
4152 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4154 return XML_ERROR_NO_MEMORY
;
4155 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4158 return XML_ERROR_NO_MEMORY
;
4159 if (declEntity
->name
!= name
) {
4160 poolDiscard(&dtd
->pool
);
4164 poolFinish(&dtd
->pool
);
4165 declEntity
->publicId
= NULL
;
4166 declEntity
->is_param
= XML_FALSE
;
4167 /* if we have a parent parser or are reading an internal parameter
4168 entity, then the entity declaration is not considered "internal"
4170 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4171 if (entityDeclHandler
)
4172 handleDefault
= XML_FALSE
;
4176 poolDiscard(&dtd
->pool
);
4181 case XML_ROLE_PARAM_ENTITY_NAME
:
4183 if (dtd
->keepProcessing
) {
4184 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4186 return XML_ERROR_NO_MEMORY
;
4187 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4188 name
, sizeof(ENTITY
));
4190 return XML_ERROR_NO_MEMORY
;
4191 if (declEntity
->name
!= name
) {
4192 poolDiscard(&dtd
->pool
);
4196 poolFinish(&dtd
->pool
);
4197 declEntity
->publicId
= NULL
;
4198 declEntity
->is_param
= XML_TRUE
;
4199 /* if we have a parent parser or are reading an internal parameter
4200 entity, then the entity declaration is not considered "internal"
4202 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4203 if (entityDeclHandler
)
4204 handleDefault
= XML_FALSE
;
4208 poolDiscard(&dtd
->pool
);
4211 #else /* not XML_DTD */
4213 #endif /* XML_DTD */
4215 case XML_ROLE_NOTATION_NAME
:
4216 declNotationPublicId
= NULL
;
4217 declNotationName
= NULL
;
4218 if (notationDeclHandler
) {
4219 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4220 if (!declNotationName
)
4221 return XML_ERROR_NO_MEMORY
;
4222 poolFinish(&tempPool
);
4223 handleDefault
= XML_FALSE
;
4226 case XML_ROLE_NOTATION_PUBLIC_ID
:
4227 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4228 return XML_ERROR_PUBLICID
;
4229 if (declNotationName
) { /* means notationDeclHandler != NULL */
4230 XML_Char
*tem
= poolStoreString(&tempPool
,
4232 s
+ enc
->minBytesPerChar
,
4233 next
- enc
->minBytesPerChar
);
4235 return XML_ERROR_NO_MEMORY
;
4236 normalizePublicId(tem
);
4237 declNotationPublicId
= tem
;
4238 poolFinish(&tempPool
);
4239 handleDefault
= XML_FALSE
;
4242 case XML_ROLE_NOTATION_SYSTEM_ID
:
4243 if (declNotationName
&& notationDeclHandler
) {
4244 const XML_Char
*systemId
4245 = poolStoreString(&tempPool
, enc
,
4246 s
+ enc
->minBytesPerChar
,
4247 next
- enc
->minBytesPerChar
);
4249 return XML_ERROR_NO_MEMORY
;
4251 notationDeclHandler(handlerArg
,
4255 declNotationPublicId
);
4256 handleDefault
= XML_FALSE
;
4258 poolClear(&tempPool
);
4260 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4261 if (declNotationPublicId
&& notationDeclHandler
) {
4263 notationDeclHandler(handlerArg
,
4267 declNotationPublicId
);
4268 handleDefault
= XML_FALSE
;
4270 poolClear(&tempPool
);
4272 case XML_ROLE_ERROR
:
4274 case XML_TOK_PARAM_ENTITY_REF
:
4275 /* PE references in internal subset are
4276 not allowed within declarations. */
4277 return XML_ERROR_PARAM_ENTITY_REF
;
4278 case XML_TOK_XML_DECL
:
4279 return XML_ERROR_MISPLACED_XML_PI
;
4281 return XML_ERROR_SYNTAX
;
4284 case XML_ROLE_IGNORE_SECT
:
4286 enum XML_Error result
;
4288 reportDefault(parser
, enc
, s
, next
);
4289 handleDefault
= XML_FALSE
;
4290 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4291 if (result
!= XML_ERROR_NONE
)
4294 processor
= ignoreSectionProcessor
;
4299 #endif /* XML_DTD */
4300 case XML_ROLE_GROUP_OPEN
:
4301 if (prologState
.level
>= groupSize
) {
4303 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4305 return XML_ERROR_NO_MEMORY
;
4306 groupConnector
= temp
;
4307 if (dtd
->scaffIndex
) {
4308 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4309 groupSize
* sizeof(int));
4311 return XML_ERROR_NO_MEMORY
;
4312 dtd
->scaffIndex
= temp
;
4316 groupConnector
= (char *)MALLOC(groupSize
= 32);
4317 if (!groupConnector
)
4318 return XML_ERROR_NO_MEMORY
;
4321 groupConnector
[prologState
.level
] = 0;
4322 if (dtd
->in_eldecl
) {
4323 int myindex
= nextScaffoldPart(parser
);
4325 return XML_ERROR_NO_MEMORY
;
4326 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4328 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4329 if (elementDeclHandler
)
4330 handleDefault
= XML_FALSE
;
4333 case XML_ROLE_GROUP_SEQUENCE
:
4334 if (groupConnector
[prologState
.level
] == '|')
4335 return XML_ERROR_SYNTAX
;
4336 groupConnector
[prologState
.level
] = ',';
4337 if (dtd
->in_eldecl
&& elementDeclHandler
)
4338 handleDefault
= XML_FALSE
;
4340 case XML_ROLE_GROUP_CHOICE
:
4341 if (groupConnector
[prologState
.level
] == ',')
4342 return XML_ERROR_SYNTAX
;
4344 && !groupConnector
[prologState
.level
]
4345 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4348 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4350 if (elementDeclHandler
)
4351 handleDefault
= XML_FALSE
;
4353 groupConnector
[prologState
.level
] = '|';
4355 case XML_ROLE_PARAM_ENTITY_REF
:
4357 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4358 dtd
->hasParamEntityRefs
= XML_TRUE
;
4359 if (!paramEntityParsing
)
4360 dtd
->keepProcessing
= dtd
->standalone
;
4362 const XML_Char
*name
;
4364 name
= poolStoreString(&dtd
->pool
, enc
,
4365 s
+ enc
->minBytesPerChar
,
4366 next
- enc
->minBytesPerChar
);
4368 return XML_ERROR_NO_MEMORY
;
4369 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4370 poolDiscard(&dtd
->pool
);
4371 /* first, determine if a check for an existing declaration is needed;
4372 if yes, check that the entity exists, and that it is internal,
4373 otherwise call the skipped entity handler
4375 if (prologState
.documentEntity
&&
4377 ? !openInternalEntities
4378 : !dtd
->hasParamEntityRefs
)) {
4380 return XML_ERROR_UNDEFINED_ENTITY
;
4381 else if (!entity
->is_internal
)
4382 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4385 dtd
->keepProcessing
= dtd
->standalone
;
4386 /* cannot report skipped entities in declarations */
4387 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4388 skippedEntityHandler(handlerArg
, name
, 1);
4389 handleDefault
= XML_FALSE
;
4394 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4395 if (entity
->textPtr
) {
4396 enum XML_Error result
;
4397 XML_Bool betweenDecl
=
4398 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4399 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4400 if (result
!= XML_ERROR_NONE
)
4402 handleDefault
= XML_FALSE
;
4405 if (externalEntityRefHandler
) {
4406 dtd
->paramEntityRead
= XML_FALSE
;
4407 entity
->open
= XML_TRUE
;
4408 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4412 entity
->publicId
)) {
4413 entity
->open
= XML_FALSE
;
4414 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4416 entity
->open
= XML_FALSE
;
4417 handleDefault
= XML_FALSE
;
4418 if (!dtd
->paramEntityRead
) {
4419 dtd
->keepProcessing
= dtd
->standalone
;
4424 dtd
->keepProcessing
= dtd
->standalone
;
4428 #endif /* XML_DTD */
4429 if (!dtd
->standalone
&&
4430 notStandaloneHandler
&&
4431 !notStandaloneHandler(handlerArg
))
4432 return XML_ERROR_NOT_STANDALONE
;
4435 /* Element declaration stuff */
4437 case XML_ROLE_ELEMENT_NAME
:
4438 if (elementDeclHandler
) {
4439 declElementType
= getElementType(parser
, enc
, s
, next
);
4440 if (!declElementType
)
4441 return XML_ERROR_NO_MEMORY
;
4442 dtd
->scaffLevel
= 0;
4443 dtd
->scaffCount
= 0;
4444 dtd
->in_eldecl
= XML_TRUE
;
4445 handleDefault
= XML_FALSE
;
4449 case XML_ROLE_CONTENT_ANY
:
4450 case XML_ROLE_CONTENT_EMPTY
:
4451 if (dtd
->in_eldecl
) {
4452 if (elementDeclHandler
) {
4453 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4455 return XML_ERROR_NO_MEMORY
;
4456 content
->quant
= XML_CQUANT_NONE
;
4457 content
->name
= NULL
;
4458 content
->numchildren
= 0;
4459 content
->children
= NULL
;
4460 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4464 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4465 handleDefault
= XML_FALSE
;
4467 dtd
->in_eldecl
= XML_FALSE
;
4471 case XML_ROLE_CONTENT_PCDATA
:
4472 if (dtd
->in_eldecl
) {
4473 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4475 if (elementDeclHandler
)
4476 handleDefault
= XML_FALSE
;
4480 case XML_ROLE_CONTENT_ELEMENT
:
4481 quant
= XML_CQUANT_NONE
;
4482 goto elementContent
;
4483 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4484 quant
= XML_CQUANT_OPT
;
4485 goto elementContent
;
4486 case XML_ROLE_CONTENT_ELEMENT_REP
:
4487 quant
= XML_CQUANT_REP
;
4488 goto elementContent
;
4489 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4490 quant
= XML_CQUANT_PLUS
;
4492 if (dtd
->in_eldecl
) {
4494 const XML_Char
*name
;
4496 const char *nxt
= (quant
== XML_CQUANT_NONE
4498 : next
- enc
->minBytesPerChar
);
4499 int myindex
= nextScaffoldPart(parser
);
4501 return XML_ERROR_NO_MEMORY
;
4502 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4503 dtd
->scaffold
[myindex
].quant
= quant
;
4504 el
= getElementType(parser
, enc
, s
, nxt
);
4506 return XML_ERROR_NO_MEMORY
;
4508 dtd
->scaffold
[myindex
].name
= name
;
4510 for (; name
[nameLen
++]; );
4511 dtd
->contentStringLen
+= nameLen
;
4512 if (elementDeclHandler
)
4513 handleDefault
= XML_FALSE
;
4517 case XML_ROLE_GROUP_CLOSE
:
4518 quant
= XML_CQUANT_NONE
;
4520 case XML_ROLE_GROUP_CLOSE_OPT
:
4521 quant
= XML_CQUANT_OPT
;
4523 case XML_ROLE_GROUP_CLOSE_REP
:
4524 quant
= XML_CQUANT_REP
;
4526 case XML_ROLE_GROUP_CLOSE_PLUS
:
4527 quant
= XML_CQUANT_PLUS
;
4529 if (dtd
->in_eldecl
) {
4530 if (elementDeclHandler
)
4531 handleDefault
= XML_FALSE
;
4533 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4534 if (dtd
->scaffLevel
== 0) {
4535 if (!handleDefault
) {
4536 XML_Content
*model
= build_model(parser
);
4538 return XML_ERROR_NO_MEMORY
;
4540 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4542 dtd
->in_eldecl
= XML_FALSE
;
4543 dtd
->contentStringLen
= 0;
4547 /* End element declaration stuff */
4550 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4551 return XML_ERROR_NO_MEMORY
;
4552 handleDefault
= XML_FALSE
;
4554 case XML_ROLE_COMMENT
:
4555 if (!reportComment(parser
, enc
, s
, next
))
4556 return XML_ERROR_NO_MEMORY
;
4557 handleDefault
= XML_FALSE
;
4562 handleDefault
= XML_FALSE
;
4566 case XML_ROLE_DOCTYPE_NONE
:
4567 if (startDoctypeDeclHandler
)
4568 handleDefault
= XML_FALSE
;
4570 case XML_ROLE_ENTITY_NONE
:
4571 if (dtd
->keepProcessing
&& entityDeclHandler
)
4572 handleDefault
= XML_FALSE
;
4574 case XML_ROLE_NOTATION_NONE
:
4575 if (notationDeclHandler
)
4576 handleDefault
= XML_FALSE
;
4578 case XML_ROLE_ATTLIST_NONE
:
4579 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4580 handleDefault
= XML_FALSE
;
4582 case XML_ROLE_ELEMENT_NONE
:
4583 if (elementDeclHandler
)
4584 handleDefault
= XML_FALSE
;
4586 } /* end of big switch */
4588 if (handleDefault
&& defaultHandler
)
4589 reportDefault(parser
, enc
, s
, next
);
4591 switch (ps_parsing
) {
4594 return XML_ERROR_NONE
;
4596 return XML_ERROR_ABORTED
;
4599 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4605 static enum XML_Error PTRCALL
4606 epilogProcessor(XML_Parser parser
,
4609 const char **nextPtr
)
4611 processor
= epilogProcessor
;
4614 const char *next
= NULL
;
4615 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4618 /* report partial linebreak - it might be the last token */
4619 case -XML_TOK_PROLOG_S
:
4620 if (defaultHandler
) {
4621 reportDefault(parser
, encoding
, s
, next
);
4622 if (ps_parsing
== XML_FINISHED
)
4623 return XML_ERROR_ABORTED
;
4626 return XML_ERROR_NONE
;
4629 return XML_ERROR_NONE
;
4630 case XML_TOK_PROLOG_S
:
4632 reportDefault(parser
, encoding
, s
, next
);
4635 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4636 return XML_ERROR_NO_MEMORY
;
4638 case XML_TOK_COMMENT
:
4639 if (!reportComment(parser
, encoding
, s
, next
))
4640 return XML_ERROR_NO_MEMORY
;
4642 case XML_TOK_INVALID
:
4644 return XML_ERROR_INVALID_TOKEN
;
4645 case XML_TOK_PARTIAL
:
4646 if (!ps_finalBuffer
) {
4648 return XML_ERROR_NONE
;
4650 return XML_ERROR_UNCLOSED_TOKEN
;
4651 case XML_TOK_PARTIAL_CHAR
:
4652 if (!ps_finalBuffer
) {
4654 return XML_ERROR_NONE
;
4656 return XML_ERROR_PARTIAL_CHAR
;
4658 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4660 eventPtr
= s
= next
;
4661 switch (ps_parsing
) {
4664 return XML_ERROR_NONE
;
4666 return XML_ERROR_ABORTED
;
4672 static enum XML_Error
4673 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4674 XML_Bool betweenDecl
)
4676 const char *textStart
, *textEnd
;
4678 enum XML_Error result
;
4679 OPEN_INTERNAL_ENTITY
*openEntity
;
4681 if (freeInternalEntities
) {
4682 openEntity
= freeInternalEntities
;
4683 freeInternalEntities
= openEntity
->next
;
4686 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4688 return XML_ERROR_NO_MEMORY
;
4690 entity
->open
= XML_TRUE
;
4691 entity
->processed
= 0;
4692 openEntity
->next
= openInternalEntities
;
4693 openInternalEntities
= openEntity
;
4694 openEntity
->entity
= entity
;
4695 openEntity
->startTagLevel
= tagLevel
;
4696 openEntity
->betweenDecl
= betweenDecl
;
4697 openEntity
->internalEventPtr
= NULL
;
4698 openEntity
->internalEventEndPtr
= NULL
;
4699 textStart
= (char *)entity
->textPtr
;
4700 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4703 if (entity
->is_param
) {
4704 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4705 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4706 next
, &next
, XML_FALSE
);
4709 #endif /* XML_DTD */
4710 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4711 textEnd
, &next
, XML_FALSE
);
4713 if (result
== XML_ERROR_NONE
) {
4714 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4715 entity
->processed
= (int)(next
- textStart
);
4716 processor
= internalEntityProcessor
;
4719 entity
->open
= XML_FALSE
;
4720 openInternalEntities
= openEntity
->next
;
4721 /* put openEntity back in list of free instances */
4722 openEntity
->next
= freeInternalEntities
;
4723 freeInternalEntities
= openEntity
;
4729 static enum XML_Error PTRCALL
4730 internalEntityProcessor(XML_Parser parser
,
4733 const char **nextPtr
)
4736 const char *textStart
, *textEnd
;
4738 enum XML_Error result
;
4739 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4741 return XML_ERROR_UNEXPECTED_STATE
;
4743 entity
= openEntity
->entity
;
4744 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4745 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4748 if (entity
->is_param
) {
4749 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4750 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4751 next
, &next
, XML_FALSE
);
4754 #endif /* XML_DTD */
4755 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4756 textStart
, textEnd
, &next
, XML_FALSE
);
4758 if (result
!= XML_ERROR_NONE
)
4760 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4761 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4765 entity
->open
= XML_FALSE
;
4766 openInternalEntities
= openEntity
->next
;
4767 /* put openEntity back in list of free instances */
4768 openEntity
->next
= freeInternalEntities
;
4769 freeInternalEntities
= openEntity
;
4773 if (entity
->is_param
) {
4775 processor
= prologProcessor
;
4776 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4777 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4778 (XML_Bool
)!ps_finalBuffer
);
4781 #endif /* XML_DTD */
4783 processor
= contentProcessor
;
4784 /* see externalEntityContentProcessor vs contentProcessor */
4785 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4786 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4790 static enum XML_Error PTRCALL
4791 errorProcessor(XML_Parser parser
,
4794 const char **nextPtr
)
4799 static enum XML_Error
4800 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4801 const char *ptr
, const char *end
,
4804 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4808 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4810 if (!poolAppendChar(pool
, XML_T('\0')))
4811 return XML_ERROR_NO_MEMORY
;
4812 return XML_ERROR_NONE
;
4815 static enum XML_Error
4816 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4817 const char *ptr
, const char *end
,
4820 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4823 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4826 return XML_ERROR_NONE
;
4827 case XML_TOK_INVALID
:
4828 if (enc
== encoding
)
4830 return XML_ERROR_INVALID_TOKEN
;
4831 case XML_TOK_PARTIAL
:
4832 if (enc
== encoding
)
4834 return XML_ERROR_INVALID_TOKEN
;
4835 case XML_TOK_CHAR_REF
:
4837 XML_Char buf
[XML_ENCODE_MAX
];
4839 int n
= XmlCharRefNumber(enc
, ptr
);
4841 if (enc
== encoding
)
4843 return XML_ERROR_BAD_CHAR_REF
;
4846 && n
== 0x20 /* space */
4847 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4849 n
= XmlEncode(n
, (ICHAR
*)buf
);
4851 if (enc
== encoding
)
4853 return XML_ERROR_BAD_CHAR_REF
;
4855 for (i
= 0; i
< n
; i
++) {
4856 if (!poolAppendChar(pool
, buf
[i
]))
4857 return XML_ERROR_NO_MEMORY
;
4861 case XML_TOK_DATA_CHARS
:
4862 if (!poolAppend(pool
, enc
, ptr
, next
))
4863 return XML_ERROR_NO_MEMORY
;
4865 case XML_TOK_TRAILING_CR
:
4866 next
= ptr
+ enc
->minBytesPerChar
;
4868 case XML_TOK_ATTRIBUTE_VALUE_S
:
4869 case XML_TOK_DATA_NEWLINE
:
4870 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4872 if (!poolAppendChar(pool
, 0x20))
4873 return XML_ERROR_NO_MEMORY
;
4875 case XML_TOK_ENTITY_REF
:
4877 const XML_Char
*name
;
4879 char checkEntityDecl
;
4880 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4881 ptr
+ enc
->minBytesPerChar
,
4882 next
- enc
->minBytesPerChar
);
4884 if (!poolAppendChar(pool
, ch
))
4885 return XML_ERROR_NO_MEMORY
;
4888 name
= poolStoreString(&temp2Pool
, enc
,
4889 ptr
+ enc
->minBytesPerChar
,
4890 next
- enc
->minBytesPerChar
);
4892 return XML_ERROR_NO_MEMORY
;
4893 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4894 poolDiscard(&temp2Pool
);
4895 /* First, determine if a check for an existing declaration is needed;
4896 if yes, check that the entity exists, and that it is internal.
4898 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4901 prologState
.documentEntity
&&
4902 #endif /* XML_DTD */
4904 ? !openInternalEntities
4905 : !dtd
->hasParamEntityRefs
);
4906 else /* if (pool == &tempPool): we are called from content */
4907 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4908 if (checkEntityDecl
) {
4910 return XML_ERROR_UNDEFINED_ENTITY
;
4911 else if (!entity
->is_internal
)
4912 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4915 /* Cannot report skipped entity here - see comments on
4916 skippedEntityHandler.
4917 if (skippedEntityHandler)
4918 skippedEntityHandler(handlerArg, name, 0);
4920 /* Cannot call the default handler because this would be
4921 out of sync with the call to the startElementHandler.
4922 if ((pool == &tempPool) && defaultHandler)
4923 reportDefault(parser, enc, ptr, next);
4928 if (enc
== encoding
)
4930 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4932 if (entity
->notation
) {
4933 if (enc
== encoding
)
4935 return XML_ERROR_BINARY_ENTITY_REF
;
4937 if (!entity
->textPtr
) {
4938 if (enc
== encoding
)
4940 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4943 enum XML_Error result
;
4944 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4945 entity
->open
= XML_TRUE
;
4946 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4947 (char *)entity
->textPtr
,
4948 (char *)textEnd
, pool
);
4949 entity
->open
= XML_FALSE
;
4956 if (enc
== encoding
)
4958 return XML_ERROR_UNEXPECTED_STATE
;
4965 static enum XML_Error
4966 storeEntityValue(XML_Parser parser
,
4967 const ENCODING
*enc
,
4968 const char *entityTextPtr
,
4969 const char *entityTextEnd
)
4971 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4972 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4973 enum XML_Error result
= XML_ERROR_NONE
;
4975 int oldInEntityValue
= prologState
.inEntityValue
;
4976 prologState
.inEntityValue
= 1;
4977 #endif /* XML_DTD */
4978 /* never return Null for the value argument in EntityDeclHandler,
4979 since this would indicate an external entity; therefore we
4980 have to make sure that entityValuePool.start is not null */
4981 if (!pool
->blocks
) {
4982 if (!poolGrow(pool
))
4983 return XML_ERROR_NO_MEMORY
;
4988 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4990 case XML_TOK_PARAM_ENTITY_REF
:
4992 if (isParamEntity
|| enc
!= encoding
) {
4993 const XML_Char
*name
;
4995 name
= poolStoreString(&tempPool
, enc
,
4996 entityTextPtr
+ enc
->minBytesPerChar
,
4997 next
- enc
->minBytesPerChar
);
4999 result
= XML_ERROR_NO_MEMORY
;
5000 goto endEntityValue
;
5002 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
5003 poolDiscard(&tempPool
);
5005 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5006 /* cannot report skipped entity here - see comments on
5007 skippedEntityHandler
5008 if (skippedEntityHandler)
5009 skippedEntityHandler(handlerArg, name, 0);
5011 dtd
->keepProcessing
= dtd
->standalone
;
5012 goto endEntityValue
;
5015 if (enc
== encoding
)
5016 eventPtr
= entityTextPtr
;
5017 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5018 goto endEntityValue
;
5020 if (entity
->systemId
) {
5021 if (externalEntityRefHandler
) {
5022 dtd
->paramEntityRead
= XML_FALSE
;
5023 entity
->open
= XML_TRUE
;
5024 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5028 entity
->publicId
)) {
5029 entity
->open
= XML_FALSE
;
5030 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5031 goto endEntityValue
;
5033 entity
->open
= XML_FALSE
;
5034 if (!dtd
->paramEntityRead
)
5035 dtd
->keepProcessing
= dtd
->standalone
;
5038 dtd
->keepProcessing
= dtd
->standalone
;
5041 entity
->open
= XML_TRUE
;
5042 result
= storeEntityValue(parser
,
5044 (char *)entity
->textPtr
,
5045 (char *)(entity
->textPtr
5046 + entity
->textLen
));
5047 entity
->open
= XML_FALSE
;
5049 goto endEntityValue
;
5053 #endif /* XML_DTD */
5054 /* In the internal subset, PE references are not legal
5055 within markup declarations, e.g entity values in this case. */
5056 eventPtr
= entityTextPtr
;
5057 result
= XML_ERROR_PARAM_ENTITY_REF
;
5058 goto endEntityValue
;
5060 result
= XML_ERROR_NONE
;
5061 goto endEntityValue
;
5062 case XML_TOK_ENTITY_REF
:
5063 case XML_TOK_DATA_CHARS
:
5064 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5065 result
= XML_ERROR_NO_MEMORY
;
5066 goto endEntityValue
;
5069 case XML_TOK_TRAILING_CR
:
5070 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5072 case XML_TOK_DATA_NEWLINE
:
5073 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5074 result
= XML_ERROR_NO_MEMORY
;
5075 goto endEntityValue
;
5077 *(pool
->ptr
)++ = 0xA;
5079 case XML_TOK_CHAR_REF
:
5081 XML_Char buf
[XML_ENCODE_MAX
];
5083 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5085 if (enc
== encoding
)
5086 eventPtr
= entityTextPtr
;
5087 result
= XML_ERROR_BAD_CHAR_REF
;
5088 goto endEntityValue
;
5090 n
= XmlEncode(n
, (ICHAR
*)buf
);
5092 if (enc
== encoding
)
5093 eventPtr
= entityTextPtr
;
5094 result
= XML_ERROR_BAD_CHAR_REF
;
5095 goto endEntityValue
;
5097 for (i
= 0; i
< n
; i
++) {
5098 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5099 result
= XML_ERROR_NO_MEMORY
;
5100 goto endEntityValue
;
5102 *(pool
->ptr
)++ = buf
[i
];
5106 case XML_TOK_PARTIAL
:
5107 if (enc
== encoding
)
5108 eventPtr
= entityTextPtr
;
5109 result
= XML_ERROR_INVALID_TOKEN
;
5110 goto endEntityValue
;
5111 case XML_TOK_INVALID
:
5112 if (enc
== encoding
)
5114 result
= XML_ERROR_INVALID_TOKEN
;
5115 goto endEntityValue
;
5117 if (enc
== encoding
)
5118 eventPtr
= entityTextPtr
;
5119 result
= XML_ERROR_UNEXPECTED_STATE
;
5120 goto endEntityValue
;
5122 entityTextPtr
= next
;
5126 prologState
.inEntityValue
= oldInEntityValue
;
5127 #endif /* XML_DTD */
5131 static void FASTCALL
5132 normalizeLines(XML_Char
*s
)
5136 if (*s
== XML_T('\0'))
5155 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5156 const char *start
, const char *end
)
5158 const XML_Char
*target
;
5161 if (!processingInstructionHandler
) {
5163 reportDefault(parser
, enc
, start
, end
);
5166 start
+= enc
->minBytesPerChar
* 2;
5167 tem
= start
+ XmlNameLength(enc
, start
);
5168 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5171 poolFinish(&tempPool
);
5172 data
= poolStoreString(&tempPool
, enc
,
5174 end
- enc
->minBytesPerChar
*2);
5177 normalizeLines(data
);
5178 processingInstructionHandler(handlerArg
, target
, data
);
5179 poolClear(&tempPool
);
5184 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5185 const char *start
, const char *end
)
5188 if (!commentHandler
) {
5190 reportDefault(parser
, enc
, start
, end
);
5193 data
= poolStoreString(&tempPool
,
5195 start
+ enc
->minBytesPerChar
* 4,
5196 end
- enc
->minBytesPerChar
* 3);
5199 normalizeLines(data
);
5200 commentHandler(handlerArg
, data
);
5201 poolClear(&tempPool
);
5206 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5207 const char *s
, const char *end
)
5209 if (MUST_CONVERT(enc
, s
)) {
5210 const char **eventPP
;
5211 const char **eventEndPP
;
5212 if (enc
== encoding
) {
5213 eventPP
= &eventPtr
;
5214 eventEndPP
= &eventEndPtr
;
5217 eventPP
= &(openInternalEntities
->internalEventPtr
);
5218 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5221 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5222 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5224 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5229 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5234 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5235 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5237 DEFAULT_ATTRIBUTE
*att
;
5238 if (value
|| isId
) {
5239 /* The handling of default attributes gets messed up if we have
5240 a default which duplicates a non-default. */
5242 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5243 if (attId
== type
->defaultAtts
[i
].id
)
5245 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5246 type
->idAtt
= attId
;
5248 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5249 if (type
->allocDefaultAtts
== 0) {
5250 type
->allocDefaultAtts
= 8;
5251 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5252 * sizeof(DEFAULT_ATTRIBUTE
));
5253 if (!type
->defaultAtts
)
5257 DEFAULT_ATTRIBUTE
*temp
;
5258 int count
= type
->allocDefaultAtts
* 2;
5259 temp
= (DEFAULT_ATTRIBUTE
*)
5260 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5263 type
->allocDefaultAtts
= count
;
5264 type
->defaultAtts
= temp
;
5267 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5270 att
->isCdata
= isCdata
;
5272 attId
->maybeTokenized
= XML_TRUE
;
5273 type
->nDefaultAtts
+= 1;
5278 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5280 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5281 const XML_Char
*name
;
5282 for (name
= elementType
->name
; *name
; name
++) {
5283 if (*name
== XML_T(':')) {
5286 for (s
= elementType
->name
; s
!= name
; s
++) {
5287 if (!poolAppendChar(&dtd
->pool
, *s
))
5290 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5292 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5296 if (prefix
->name
== poolStart(&dtd
->pool
))
5297 poolFinish(&dtd
->pool
);
5299 poolDiscard(&dtd
->pool
);
5300 elementType
->prefix
= prefix
;
5307 static ATTRIBUTE_ID
*
5308 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5309 const char *start
, const char *end
)
5311 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5313 const XML_Char
*name
;
5314 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5316 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5319 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5321 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5324 if (id
->name
!= name
)
5325 poolDiscard(&dtd
->pool
);
5327 poolFinish(&dtd
->pool
);
5330 else if (name
[0] == XML_T('x')
5331 && name
[1] == XML_T('m')
5332 && name
[2] == XML_T('l')
5333 && name
[3] == XML_T('n')
5334 && name
[4] == XML_T('s')
5335 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
5336 if (name
[5] == XML_T('\0'))
5337 id
->prefix
= &dtd
->defaultPrefix
;
5339 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5340 id
->xmlns
= XML_TRUE
;
5344 for (i
= 0; name
[i
]; i
++) {
5345 /* attributes without prefix are *not* in the default namespace */
5346 if (name
[i
] == XML_T(':')) {
5348 for (j
= 0; j
< i
; j
++) {
5349 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5352 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5354 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5358 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5359 poolFinish(&dtd
->pool
);
5361 poolDiscard(&dtd
->pool
);
5370 #define CONTEXT_SEP XML_T('\f')
5372 static const XML_Char
*
5373 getContext(XML_Parser parser
)
5375 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5376 HASH_TABLE_ITER iter
;
5377 XML_Bool needSep
= XML_FALSE
;
5379 if (dtd
->defaultPrefix
.binding
) {
5382 if (!poolAppendChar(&tempPool
, XML_T('=')))
5384 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5385 if (namespaceSeparator
)
5387 for (i
= 0; i
< len
; i
++)
5388 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5393 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5398 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5401 if (!prefix
->binding
)
5403 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5405 for (s
= prefix
->name
; *s
; s
++)
5406 if (!poolAppendChar(&tempPool
, *s
))
5408 if (!poolAppendChar(&tempPool
, XML_T('=')))
5410 len
= prefix
->binding
->uriLen
;
5411 if (namespaceSeparator
)
5413 for (i
= 0; i
< len
; i
++)
5414 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5420 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5423 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5428 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5430 for (s
= e
->name
; *s
; s
++)
5431 if (!poolAppendChar(&tempPool
, *s
))
5436 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5438 return tempPool
.start
;
5442 setContext(XML_Parser parser
, const XML_Char
*context
)
5444 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5445 const XML_Char
*s
= context
;
5447 while (*context
!= XML_T('\0')) {
5448 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5450 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5452 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5455 if (*s
!= XML_T('\0'))
5458 poolDiscard(&tempPool
);
5460 else if (*s
== XML_T('=')) {
5462 if (poolLength(&tempPool
) == 0)
5463 prefix
= &dtd
->defaultPrefix
;
5465 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5467 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5471 if (prefix
->name
== poolStart(&tempPool
)) {
5472 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5476 poolDiscard(&tempPool
);
5478 for (context
= s
+ 1;
5479 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5481 if (!poolAppendChar(&tempPool
, *context
))
5483 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5485 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5486 &inheritedBindings
) != XML_ERROR_NONE
)
5488 poolDiscard(&tempPool
);
5489 if (*context
!= XML_T('\0'))
5494 if (!poolAppendChar(&tempPool
, *s
))
5502 static void FASTCALL
5503 normalizePublicId(XML_Char
*publicId
)
5505 XML_Char
*p
= publicId
;
5507 for (s
= publicId
; *s
; s
++) {
5512 if (p
!= publicId
&& p
[-1] != 0x20)
5519 if (p
!= publicId
&& p
[-1] == 0x20)
5525 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5527 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5530 poolInit(&(p
->pool
), ms
);
5531 poolInit(&(p
->entityValuePool
), ms
);
5532 hashTableInit(&(p
->generalEntities
), ms
);
5533 hashTableInit(&(p
->elementTypes
), ms
);
5534 hashTableInit(&(p
->attributeIds
), ms
);
5535 hashTableInit(&(p
->prefixes
), ms
);
5537 p
->paramEntityRead
= XML_FALSE
;
5538 hashTableInit(&(p
->paramEntities
), ms
);
5539 #endif /* XML_DTD */
5540 p
->defaultPrefix
.name
= NULL
;
5541 p
->defaultPrefix
.binding
= NULL
;
5543 p
->in_eldecl
= XML_FALSE
;
5544 p
->scaffIndex
= NULL
;
5549 p
->contentStringLen
= 0;
5551 p
->keepProcessing
= XML_TRUE
;
5552 p
->hasParamEntityRefs
= XML_FALSE
;
5553 p
->standalone
= XML_FALSE
;
5558 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5560 HASH_TABLE_ITER iter
;
5561 hashTableIterInit(&iter
, &(p
->elementTypes
));
5563 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5566 if (e
->allocDefaultAtts
!= 0)
5567 ms
->free_fcn(e
->defaultAtts
);
5569 hashTableClear(&(p
->generalEntities
));
5571 p
->paramEntityRead
= XML_FALSE
;
5572 hashTableClear(&(p
->paramEntities
));
5573 #endif /* XML_DTD */
5574 hashTableClear(&(p
->elementTypes
));
5575 hashTableClear(&(p
->attributeIds
));
5576 hashTableClear(&(p
->prefixes
));
5577 poolClear(&(p
->pool
));
5578 poolClear(&(p
->entityValuePool
));
5579 p
->defaultPrefix
.name
= NULL
;
5580 p
->defaultPrefix
.binding
= NULL
;
5582 p
->in_eldecl
= XML_FALSE
;
5584 ms
->free_fcn(p
->scaffIndex
);
5585 p
->scaffIndex
= NULL
;
5586 ms
->free_fcn(p
->scaffold
);
5592 p
->contentStringLen
= 0;
5594 p
->keepProcessing
= XML_TRUE
;
5595 p
->hasParamEntityRefs
= XML_FALSE
;
5596 p
->standalone
= XML_FALSE
;
5600 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5602 HASH_TABLE_ITER iter
;
5603 hashTableIterInit(&iter
, &(p
->elementTypes
));
5605 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5608 if (e
->allocDefaultAtts
!= 0)
5609 ms
->free_fcn(e
->defaultAtts
);
5611 hashTableDestroy(&(p
->generalEntities
));
5613 hashTableDestroy(&(p
->paramEntities
));
5614 #endif /* XML_DTD */
5615 hashTableDestroy(&(p
->elementTypes
));
5616 hashTableDestroy(&(p
->attributeIds
));
5617 hashTableDestroy(&(p
->prefixes
));
5618 poolDestroy(&(p
->pool
));
5619 poolDestroy(&(p
->entityValuePool
));
5621 ms
->free_fcn(p
->scaffIndex
);
5622 ms
->free_fcn(p
->scaffold
);
5627 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5628 The new DTD has already been initialized.
5631 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5633 HASH_TABLE_ITER iter
;
5635 /* Copy the prefix table. */
5637 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5639 const XML_Char
*name
;
5640 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5643 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5646 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5650 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5652 /* Copy the attribute id table. */
5656 const XML_Char
*name
;
5657 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5661 /* Remember to allocate the scratch byte before the name. */
5662 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5664 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5668 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5669 sizeof(ATTRIBUTE_ID
));
5672 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5674 newA
->xmlns
= oldA
->xmlns
;
5675 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5676 newA
->prefix
= &newDtd
->defaultPrefix
;
5678 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5679 oldA
->prefix
->name
, 0);
5683 /* Copy the element type table. */
5685 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5690 const XML_Char
*name
;
5691 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5694 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5697 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5698 sizeof(ELEMENT_TYPE
));
5701 if (oldE
->nDefaultAtts
) {
5702 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5703 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5704 if (!newE
->defaultAtts
) {
5710 newE
->idAtt
= (ATTRIBUTE_ID
*)
5711 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5712 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5714 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5715 oldE
->prefix
->name
, 0);
5716 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5717 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5718 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5719 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5720 if (oldE
->defaultAtts
[i
].value
) {
5721 newE
->defaultAtts
[i
].value
5722 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5723 if (!newE
->defaultAtts
[i
].value
)
5727 newE
->defaultAtts
[i
].value
= NULL
;
5731 /* Copy the entity tables. */
5732 if (!copyEntityTable(&(newDtd
->generalEntities
),
5734 &(oldDtd
->generalEntities
)))
5738 if (!copyEntityTable(&(newDtd
->paramEntities
),
5740 &(oldDtd
->paramEntities
)))
5742 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5743 #endif /* XML_DTD */
5745 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5746 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5747 newDtd
->standalone
= oldDtd
->standalone
;
5749 /* Don't want deep copying for scaffolding */
5750 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5751 newDtd
->scaffold
= oldDtd
->scaffold
;
5752 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5753 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5754 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5755 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5761 copyEntityTable(HASH_TABLE
*newTable
,
5762 STRING_POOL
*newPool
,
5763 const HASH_TABLE
*oldTable
)
5765 HASH_TABLE_ITER iter
;
5766 const XML_Char
*cachedOldBase
= NULL
;
5767 const XML_Char
*cachedNewBase
= NULL
;
5769 hashTableIterInit(&iter
, oldTable
);
5773 const XML_Char
*name
;
5774 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5777 name
= poolCopyString(newPool
, oldE
->name
);
5780 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5783 if (oldE
->systemId
) {
5784 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5787 newE
->systemId
= tem
;
5789 if (oldE
->base
== cachedOldBase
)
5790 newE
->base
= cachedNewBase
;
5792 cachedOldBase
= oldE
->base
;
5793 tem
= poolCopyString(newPool
, cachedOldBase
);
5796 cachedNewBase
= newE
->base
= tem
;
5799 if (oldE
->publicId
) {
5800 tem
= poolCopyString(newPool
, oldE
->publicId
);
5803 newE
->publicId
= tem
;
5807 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5811 newE
->textPtr
= tem
;
5812 newE
->textLen
= oldE
->textLen
;
5814 if (oldE
->notation
) {
5815 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5818 newE
->notation
= tem
;
5820 newE
->is_param
= oldE
->is_param
;
5821 newE
->is_internal
= oldE
->is_internal
;
5826 #define INIT_POWER 6
5828 static XML_Bool FASTCALL
5829 keyeq(KEY s1
, KEY s2
)
5831 for (; *s1
== *s2
; s1
++, s2
++)
5837 static unsigned long FASTCALL
5840 unsigned long h
= 0;
5842 h
= CHAR_HASH(h
, *s
++);
5847 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5850 if (table
->size
== 0) {
5854 table
->power
= INIT_POWER
;
5855 /* table->size is a power of 2 */
5856 table
->size
= (size_t)1 << INIT_POWER
;
5857 tsize
= table
->size
* sizeof(NAMED
*);
5858 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5863 memset(table
->v
, 0, tsize
);
5864 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5867 unsigned long h
= hash(name
);
5868 unsigned long mask
= (unsigned long)table
->size
- 1;
5869 unsigned char step
= 0;
5871 while (table
->v
[i
]) {
5872 if (keyeq(name
, table
->v
[i
]->name
))
5875 step
= PROBE_STEP(h
, mask
, table
->power
);
5876 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5881 /* check for overflow (table is half full) */
5882 if (table
->used
>> (table
->power
- 1)) {
5883 unsigned char newPower
= table
->power
+ 1;
5884 size_t newSize
= (size_t)1 << newPower
;
5885 unsigned long newMask
= (unsigned long)newSize
- 1;
5886 size_t tsize
= newSize
* sizeof(NAMED
*);
5887 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5890 memset(newV
, 0, tsize
);
5891 for (i
= 0; i
< table
->size
; i
++)
5893 unsigned long newHash
= hash(table
->v
[i
]->name
);
5894 size_t j
= newHash
& newMask
;
5898 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5899 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5901 newV
[j
] = table
->v
[i
];
5903 table
->mem
->free_fcn(table
->v
);
5905 table
->power
= newPower
;
5906 table
->size
= newSize
;
5909 while (table
->v
[i
]) {
5911 step
= PROBE_STEP(h
, newMask
, newPower
);
5912 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5916 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5919 memset(table
->v
[i
], 0, createSize
);
5920 table
->v
[i
]->name
= name
;
5925 static void FASTCALL
5926 hashTableClear(HASH_TABLE
*table
)
5929 for (i
= 0; i
< table
->size
; i
++) {
5930 table
->mem
->free_fcn(table
->v
[i
]);
5936 static void FASTCALL
5937 hashTableDestroy(HASH_TABLE
*table
)
5940 for (i
= 0; i
< table
->size
; i
++)
5941 table
->mem
->free_fcn(table
->v
[i
]);
5942 table
->mem
->free_fcn(table
->v
);
5945 static void FASTCALL
5946 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5955 static void FASTCALL
5956 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5959 iter
->end
= iter
->p
+ table
->size
;
5962 static NAMED
* FASTCALL
5963 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5965 while (iter
->p
!= iter
->end
) {
5966 NAMED
*tem
= *(iter
->p
)++;
5973 static void FASTCALL
5974 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5976 pool
->blocks
= NULL
;
5977 pool
->freeBlocks
= NULL
;
5984 static void FASTCALL
5985 poolClear(STRING_POOL
*pool
)
5987 if (!pool
->freeBlocks
)
5988 pool
->freeBlocks
= pool
->blocks
;
5990 BLOCK
*p
= pool
->blocks
;
5992 BLOCK
*tem
= p
->next
;
5993 p
->next
= pool
->freeBlocks
;
5994 pool
->freeBlocks
= p
;
5998 pool
->blocks
= NULL
;
6004 static void FASTCALL
6005 poolDestroy(STRING_POOL
*pool
)
6007 BLOCK
*p
= pool
->blocks
;
6009 BLOCK
*tem
= p
->next
;
6010 pool
->mem
->free_fcn(p
);
6013 p
= pool
->freeBlocks
;
6015 BLOCK
*tem
= p
->next
;
6016 pool
->mem
->free_fcn(p
);
6022 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6023 const char *ptr
, const char *end
)
6025 if (!pool
->ptr
&& !poolGrow(pool
))
6028 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6031 if (!poolGrow(pool
))
6037 static const XML_Char
* FASTCALL
6038 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6041 if (!poolAppendChar(pool
, *s
))
6049 static const XML_Char
*
6050 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6052 if (!pool
->ptr
&& !poolGrow(pool
))
6054 for (; n
> 0; --n
, s
++) {
6055 if (!poolAppendChar(pool
, *s
))
6063 static const XML_Char
* FASTCALL
6064 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6067 if (!poolAppendChar(pool
, *s
))
6075 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6076 const char *ptr
, const char *end
)
6078 if (!poolAppend(pool
, enc
, ptr
, end
))
6080 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6086 static XML_Bool FASTCALL
6087 poolGrow(STRING_POOL
*pool
)
6089 if (pool
->freeBlocks
) {
6090 if (pool
->start
== 0) {
6091 pool
->blocks
= pool
->freeBlocks
;
6092 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6093 pool
->blocks
->next
= NULL
;
6094 pool
->start
= pool
->blocks
->s
;
6095 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6096 pool
->ptr
= pool
->start
;
6099 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6100 BLOCK
*tem
= pool
->freeBlocks
->next
;
6101 pool
->freeBlocks
->next
= pool
->blocks
;
6102 pool
->blocks
= pool
->freeBlocks
;
6103 pool
->freeBlocks
= tem
;
6104 memcpy(pool
->blocks
->s
, pool
->start
,
6105 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6106 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6107 pool
->start
= pool
->blocks
->s
;
6108 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6112 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6113 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6114 pool
->blocks
= (BLOCK
*)
6115 pool
->mem
->realloc_fcn(pool
->blocks
,
6117 + blockSize
* sizeof(XML_Char
)));
6118 if (pool
->blocks
== NULL
)
6120 pool
->blocks
->size
= blockSize
;
6121 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6122 pool
->start
= pool
->blocks
->s
;
6123 pool
->end
= pool
->start
+ blockSize
;
6127 int blockSize
= (int)(pool
->end
- pool
->start
);
6128 if (blockSize
< INIT_BLOCK_SIZE
)
6129 blockSize
= INIT_BLOCK_SIZE
;
6132 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6133 + blockSize
* sizeof(XML_Char
));
6136 tem
->size
= blockSize
;
6137 tem
->next
= pool
->blocks
;
6139 if (pool
->ptr
!= pool
->start
)
6140 memcpy(tem
->s
, pool
->start
,
6141 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6142 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6143 pool
->start
= tem
->s
;
6144 pool
->end
= tem
->s
+ blockSize
;
6150 nextScaffoldPart(XML_Parser parser
)
6152 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6153 CONTENT_SCAFFOLD
* me
;
6156 if (!dtd
->scaffIndex
) {
6157 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6158 if (!dtd
->scaffIndex
)
6160 dtd
->scaffIndex
[0] = 0;
6163 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6164 CONTENT_SCAFFOLD
*temp
;
6165 if (dtd
->scaffold
) {
6166 temp
= (CONTENT_SCAFFOLD
*)
6167 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6170 dtd
->scaffSize
*= 2;
6173 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6174 * sizeof(CONTENT_SCAFFOLD
));
6177 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6179 dtd
->scaffold
= temp
;
6181 next
= dtd
->scaffCount
++;
6182 me
= &dtd
->scaffold
[next
];
6183 if (dtd
->scaffLevel
) {
6184 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6185 if (parent
->lastchild
) {
6186 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6188 if (!parent
->childcnt
)
6189 parent
->firstchild
= next
;
6190 parent
->lastchild
= next
;
6193 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6198 build_node(XML_Parser parser
,
6201 XML_Content
**contpos
,
6204 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6205 dest
->type
= dtd
->scaffold
[src_node
].type
;
6206 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6207 if (dest
->type
== XML_CTYPE_NAME
) {
6208 const XML_Char
*src
;
6209 dest
->name
= *strpos
;
6210 src
= dtd
->scaffold
[src_node
].name
;
6212 *(*strpos
)++ = *src
;
6217 dest
->numchildren
= 0;
6218 dest
->children
= NULL
;
6223 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6224 dest
->children
= *contpos
;
6225 *contpos
+= dest
->numchildren
;
6226 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6227 i
< dest
->numchildren
;
6228 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6229 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6235 static XML_Content
*
6236 build_model (XML_Parser parser
)
6238 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6242 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6243 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6245 ret
= (XML_Content
*)MALLOC(allocsize
);
6249 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6252 build_node(parser
, 0, ret
, &cpos
, &str
);
6256 static ELEMENT_TYPE
*
6257 getElementType(XML_Parser parser
,
6258 const ENCODING
*enc
,
6262 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6263 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6268 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6271 if (ret
->name
!= name
)
6272 poolDiscard(&dtd
->pool
);
6274 poolFinish(&dtd
->pool
);
6275 if (!setElementTypePrefix(parser
, ret
))