1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
9 #define XML_BUILDING_EXPAT 1
11 #ifdef COMPILED_FROM_DSP
12 #include "winconfig.h"
13 #elif defined(MACOS_CLASSIC)
14 #include "macconfig.h"
15 #elif defined(HAVE_EXPAT_CONFIG_H)
16 #include <expat_config.h>
17 #endif /* ndef COMPILED_FROM_DSP */
22 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
23 #define XmlConvert XmlUtf16Convert
24 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
25 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
26 #define XmlEncode XmlUtf16Encode
27 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
28 typedef unsigned short ICHAR
;
30 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
31 #define XmlConvert XmlUtf8Convert
32 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
33 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
34 #define XmlEncode XmlUtf8Encode
35 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
42 #define XmlInitEncodingNS XmlInitEncoding
43 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
44 #undef XmlGetInternalEncodingNS
45 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
46 #define XmlParseXmlDeclNS XmlParseXmlDecl
52 #ifdef XML_UNICODE_WCHAR_T
53 #define XML_T(x) (const wchar_t)x
54 #define XML_L(x) L ## x
56 #define XML_T(x) (const unsigned short)x
67 /* Round up n to be a multiple of sz, where sz is a power of 2. */
68 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
70 /* Handle the case where memmove() doesn't exist. */
73 #define memmove(d,s,l) bcopy((s),(d),(l))
75 #error memmove does not exist on this platform, nor is a substitute available
76 #endif /* HAVE_BCOPY */
77 #endif /* HAVE_MEMMOVE */
83 typedef const XML_Char
*KEY
;
94 const XML_Memory_Handling_Suite
*mem
;
97 /* Basic character hash algorithm, taken from Python's string hash:
98 h = h * 1000003 ^ character, the constant being a prime number.
102 #define CHAR_HASH(h, c) \
103 (((h) * 0xF4243) ^ (unsigned short)(c))
105 #define CHAR_HASH(h, c) \
106 (((h) * 0xF4243) ^ (unsigned char)(c))
109 /* For probing (after a collision) we need a step size relative prime
110 to the hash table size, which is a power of 2. We use double-hashing,
111 since we can calculate a second hash value cheaply by taking those bits
112 of the first hash value that were discarded (masked out) when the table
113 index was calculated: index = hash & mask, where mask = table->size - 1.
114 We limit the maximum step size to table->size / 4 (mask >> 2) and make
115 it odd, since odd numbers are always relative prime to a power of 2.
117 #define SECOND_HASH(hash, mask, power) \
118 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
119 #define PROBE_STEP(hash, mask, power) \
120 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
127 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
128 #define INIT_DATA_BUF_SIZE 1024
129 #define INIT_ATTS_SIZE 16
130 #define INIT_ATTS_VERSION 0xFFFFFFFF
131 #define INIT_BLOCK_SIZE 1024
132 #define INIT_BUFFER_SIZE 1024
134 #define EXPAND_SPARE 24
136 typedef struct binding
{
137 struct prefix
*prefix
;
138 struct binding
*nextTagBinding
;
139 struct binding
*prevPrefixBinding
;
140 const struct attribute_id
*attId
;
146 typedef struct prefix
{
147 const XML_Char
*name
;
153 const XML_Char
*localPart
;
154 const XML_Char
*prefix
;
160 /* TAG represents an open element.
161 The name of the element is stored in both the document and API
162 encodings. The memory buffer 'buf' is a separately-allocated
163 memory area which stores the name. During the XML_Parse()/
164 XMLParseBuffer() when the element is open, the memory for the 'raw'
165 version of the name (in the document encoding) is shared with the
166 document buffer. If the element is open across calls to
167 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
168 contain the 'raw' name as well.
170 A parser re-uses these structures, maintaining a list of allocated
171 TAG objects in a free list.
174 struct tag
*parent
; /* parent of this element */
175 const char *rawName
; /* tagName in the original encoding */
177 TAG_NAME name
; /* tagName in the API encoding */
178 char *buf
; /* buffer for name components */
179 char *bufEnd
; /* end of the buffer */
184 const XML_Char
*name
;
185 const XML_Char
*textPtr
;
186 int textLen
; /* length in XML_Chars */
187 int processed
; /* # of processed bytes - when suspended */
188 const XML_Char
*systemId
;
189 const XML_Char
*base
;
190 const XML_Char
*publicId
;
191 const XML_Char
*notation
;
194 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
198 enum XML_Content_Type type
;
199 enum XML_Content_Quant quant
;
200 const XML_Char
* name
;
207 #define INIT_SCAFFOLD_ELEMENTS 32
209 typedef struct block
{
221 const XML_Memory_Handling_Suite
*mem
;
224 /* The XML_Char before the name is used to determine whether
225 an attribute has been specified. */
226 typedef struct attribute_id
{
229 XML_Bool maybeTokenized
;
234 const ATTRIBUTE_ID
*id
;
236 const XML_Char
*value
;
240 unsigned long version
;
242 const XML_Char
*uriName
;
246 const XML_Char
*name
;
248 const ATTRIBUTE_ID
*idAtt
;
250 int allocDefaultAtts
;
251 DEFAULT_ATTRIBUTE
*defaultAtts
;
255 HASH_TABLE generalEntities
;
256 HASH_TABLE elementTypes
;
257 HASH_TABLE attributeIds
;
260 STRING_POOL entityValuePool
;
261 /* false once a parameter entity reference has been skipped */
262 XML_Bool keepProcessing
;
263 /* true once an internal or external PE reference has been encountered;
264 this includes the reference to an external subset */
265 XML_Bool hasParamEntityRefs
;
268 /* indicates if external PE has been read */
269 XML_Bool paramEntityRead
;
270 HASH_TABLE paramEntities
;
272 PREFIX defaultPrefix
;
273 /* === scaffolding for building content model === */
275 CONTENT_SCAFFOLD
*scaffold
;
276 unsigned contentStringLen
;
283 typedef struct open_internal_entity
{
284 const char *internalEventPtr
;
285 const char *internalEventEndPtr
;
286 struct open_internal_entity
*next
;
289 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
290 } OPEN_INTERNAL_ENTITY
;
292 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
295 const char **endPtr
);
297 static Processor prologProcessor
;
298 static Processor prologInitProcessor
;
299 static Processor contentProcessor
;
300 static Processor cdataSectionProcessor
;
302 static Processor ignoreSectionProcessor
;
303 static Processor externalParEntProcessor
;
304 static Processor externalParEntInitProcessor
;
305 static Processor entityValueProcessor
;
306 static Processor entityValueInitProcessor
;
308 static Processor epilogProcessor
;
309 static Processor errorProcessor
;
310 static Processor externalEntityInitProcessor
;
311 static Processor externalEntityInitProcessor2
;
312 static Processor externalEntityInitProcessor3
;
313 static Processor externalEntityContentProcessor
;
314 static Processor internalEntityProcessor
;
316 static enum XML_Error
317 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
318 static enum XML_Error
319 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
320 const char *s
, const char *next
);
321 static enum XML_Error
322 initializeEncoding(XML_Parser parser
);
323 static enum XML_Error
324 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
325 const char *end
, int tok
, const char *next
, const char **nextPtr
,
327 static enum XML_Error
328 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
329 XML_Bool betweenDecl
);
330 static enum XML_Error
331 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
332 const char *start
, const char *end
, const char **endPtr
,
334 static enum XML_Error
335 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
336 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
338 static enum XML_Error
339 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
340 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
343 static enum XML_Error
344 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
345 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
346 static enum XML_Error
347 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
348 const XML_Char
*uri
, BINDING
**bindingsPtr
);
350 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
351 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
352 static enum XML_Error
353 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
354 const char *, const char *, STRING_POOL
*);
355 static enum XML_Error
356 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
357 const char *, const char *, STRING_POOL
*);
358 static ATTRIBUTE_ID
*
359 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
362 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
363 static enum XML_Error
364 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
367 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
368 const char *start
, const char *end
);
370 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
373 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
376 static const XML_Char
* getContext(XML_Parser parser
);
378 setContext(XML_Parser parser
, const XML_Char
*context
);
380 static void FASTCALL
normalizePublicId(XML_Char
*s
);
382 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
383 /* do not call if parentParser != NULL */
384 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
386 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
388 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
390 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
393 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
395 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
396 static void FASTCALL
hashTableClear(HASH_TABLE
*);
397 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
399 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
400 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
403 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
404 static void FASTCALL
poolClear(STRING_POOL
*);
405 static void FASTCALL
poolDestroy(STRING_POOL
*);
407 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
408 const char *ptr
, const char *end
);
410 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
411 const char *ptr
, const char *end
);
412 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
413 static const XML_Char
* FASTCALL
414 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
415 static const XML_Char
*
416 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
417 static const XML_Char
* FASTCALL
418 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
420 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
421 static XML_Content
* build_model(XML_Parser parser
);
422 static ELEMENT_TYPE
*
423 getElementType(XML_Parser parser
, const ENCODING
*enc
,
424 const char *ptr
, const char *end
);
427 parserCreate(const XML_Char
*encodingName
,
428 const XML_Memory_Handling_Suite
*memsuite
,
429 const XML_Char
*nameSep
,
432 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
434 #define poolStart(pool) ((pool)->start)
435 #define poolEnd(pool) ((pool)->ptr)
436 #define poolLength(pool) ((pool)->ptr - (pool)->start)
437 #define poolChop(pool) ((void)--(pool->ptr))
438 #define poolLastChar(pool) (((pool)->ptr)[-1])
439 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
440 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
441 #define poolAppendChar(pool, c) \
442 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
444 : ((*((pool)->ptr)++ = c), 1))
446 struct XML_ParserStruct
{
447 /* The first member must be userData so that the XML_GetUserData
452 const XML_Memory_Handling_Suite m_mem
;
453 /* first character to be parsed */
454 const char *m_bufferPtr
;
455 /* past last character to be parsed */
457 /* allocated end of buffer */
458 const char *m_bufferLim
;
459 long m_parseEndByteIndex
;
460 const char *m_parseEndPtr
;
462 XML_Char
*m_dataBufEnd
;
463 XML_StartElementHandler m_startElementHandler
;
464 XML_EndElementHandler m_endElementHandler
;
465 XML_CharacterDataHandler m_characterDataHandler
;
466 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
467 XML_CommentHandler m_commentHandler
;
468 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
469 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
470 XML_DefaultHandler m_defaultHandler
;
471 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
472 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
473 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
474 XML_NotationDeclHandler m_notationDeclHandler
;
475 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
476 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
477 XML_NotStandaloneHandler m_notStandaloneHandler
;
478 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
479 XML_Parser m_externalEntityRefHandlerArg
;
480 XML_SkippedEntityHandler m_skippedEntityHandler
;
481 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
482 XML_ElementDeclHandler m_elementDeclHandler
;
483 XML_AttlistDeclHandler m_attlistDeclHandler
;
484 XML_EntityDeclHandler m_entityDeclHandler
;
485 XML_XmlDeclHandler m_xmlDeclHandler
;
486 const ENCODING
*m_encoding
;
487 INIT_ENCODING m_initEncoding
;
488 const ENCODING
*m_internalEncoding
;
489 const XML_Char
*m_protocolEncodingName
;
491 XML_Bool m_ns_triplets
;
492 void *m_unknownEncodingMem
;
493 void *m_unknownEncodingData
;
494 void *m_unknownEncodingHandlerData
;
495 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
496 PROLOG_STATE m_prologState
;
497 Processor
*m_processor
;
498 enum XML_Error m_errorCode
;
499 const char *m_eventPtr
;
500 const char *m_eventEndPtr
;
501 const char *m_positionPtr
;
502 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
503 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
504 XML_Bool m_defaultExpandInternalEntities
;
506 ENTITY
*m_declEntity
;
507 const XML_Char
*m_doctypeName
;
508 const XML_Char
*m_doctypeSysid
;
509 const XML_Char
*m_doctypePubid
;
510 const XML_Char
*m_declAttributeType
;
511 const XML_Char
*m_declNotationName
;
512 const XML_Char
*m_declNotationPublicId
;
513 ELEMENT_TYPE
*m_declElementType
;
514 ATTRIBUTE_ID
*m_declAttributeId
;
515 XML_Bool m_declAttributeIsCdata
;
516 XML_Bool m_declAttributeIsId
;
518 const XML_Char
*m_curBase
;
521 BINDING
*m_inheritedBindings
;
522 BINDING
*m_freeBindingList
;
524 int m_nSpecifiedAtts
;
528 unsigned long m_nsAttsVersion
;
529 unsigned char m_nsAttsPower
;
531 STRING_POOL m_tempPool
;
532 STRING_POOL m_temp2Pool
;
533 char *m_groupConnector
;
534 unsigned int m_groupSize
;
535 XML_Char m_namespaceSeparator
;
536 XML_Parser m_parentParser
;
537 XML_ParsingStatus m_parsingStatus
;
539 XML_Bool m_isParamEntity
;
540 XML_Bool m_useForeignDTD
;
541 enum XML_ParamEntityParsing m_paramEntityParsing
;
545 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
546 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
547 #define FREE(p) (parser->m_mem.free_fcn((p)))
549 #define userData (parser->m_userData)
550 #define handlerArg (parser->m_handlerArg)
551 #define startElementHandler (parser->m_startElementHandler)
552 #define endElementHandler (parser->m_endElementHandler)
553 #define characterDataHandler (parser->m_characterDataHandler)
554 #define processingInstructionHandler \
555 (parser->m_processingInstructionHandler)
556 #define commentHandler (parser->m_commentHandler)
557 #define startCdataSectionHandler \
558 (parser->m_startCdataSectionHandler)
559 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
560 #define defaultHandler (parser->m_defaultHandler)
561 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
562 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
563 #define unparsedEntityDeclHandler \
564 (parser->m_unparsedEntityDeclHandler)
565 #define notationDeclHandler (parser->m_notationDeclHandler)
566 #define startNamespaceDeclHandler \
567 (parser->m_startNamespaceDeclHandler)
568 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
569 #define notStandaloneHandler (parser->m_notStandaloneHandler)
570 #define externalEntityRefHandler \
571 (parser->m_externalEntityRefHandler)
572 #define externalEntityRefHandlerArg \
573 (parser->m_externalEntityRefHandlerArg)
574 #define internalEntityRefHandler \
575 (parser->m_internalEntityRefHandler)
576 #define skippedEntityHandler (parser->m_skippedEntityHandler)
577 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
578 #define elementDeclHandler (parser->m_elementDeclHandler)
579 #define attlistDeclHandler (parser->m_attlistDeclHandler)
580 #define entityDeclHandler (parser->m_entityDeclHandler)
581 #define xmlDeclHandler (parser->m_xmlDeclHandler)
582 #define encoding (parser->m_encoding)
583 #define initEncoding (parser->m_initEncoding)
584 #define internalEncoding (parser->m_internalEncoding)
585 #define unknownEncodingMem (parser->m_unknownEncodingMem)
586 #define unknownEncodingData (parser->m_unknownEncodingData)
587 #define unknownEncodingHandlerData \
588 (parser->m_unknownEncodingHandlerData)
589 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
590 #define protocolEncodingName (parser->m_protocolEncodingName)
591 #define ns (parser->m_ns)
592 #define ns_triplets (parser->m_ns_triplets)
593 #define prologState (parser->m_prologState)
594 #define processor (parser->m_processor)
595 #define errorCode (parser->m_errorCode)
596 #define eventPtr (parser->m_eventPtr)
597 #define eventEndPtr (parser->m_eventEndPtr)
598 #define positionPtr (parser->m_positionPtr)
599 #define position (parser->m_position)
600 #define openInternalEntities (parser->m_openInternalEntities)
601 #define freeInternalEntities (parser->m_freeInternalEntities)
602 #define defaultExpandInternalEntities \
603 (parser->m_defaultExpandInternalEntities)
604 #define tagLevel (parser->m_tagLevel)
605 #define buffer (parser->m_buffer)
606 #define bufferPtr (parser->m_bufferPtr)
607 #define bufferEnd (parser->m_bufferEnd)
608 #define parseEndByteIndex (parser->m_parseEndByteIndex)
609 #define parseEndPtr (parser->m_parseEndPtr)
610 #define bufferLim (parser->m_bufferLim)
611 #define dataBuf (parser->m_dataBuf)
612 #define dataBufEnd (parser->m_dataBufEnd)
613 #define _dtd (parser->m_dtd)
614 #define curBase (parser->m_curBase)
615 #define declEntity (parser->m_declEntity)
616 #define doctypeName (parser->m_doctypeName)
617 #define doctypeSysid (parser->m_doctypeSysid)
618 #define doctypePubid (parser->m_doctypePubid)
619 #define declAttributeType (parser->m_declAttributeType)
620 #define declNotationName (parser->m_declNotationName)
621 #define declNotationPublicId (parser->m_declNotationPublicId)
622 #define declElementType (parser->m_declElementType)
623 #define declAttributeId (parser->m_declAttributeId)
624 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
625 #define declAttributeIsId (parser->m_declAttributeIsId)
626 #define freeTagList (parser->m_freeTagList)
627 #define freeBindingList (parser->m_freeBindingList)
628 #define inheritedBindings (parser->m_inheritedBindings)
629 #define tagStack (parser->m_tagStack)
630 #define atts (parser->m_atts)
631 #define attsSize (parser->m_attsSize)
632 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
633 #define idAttIndex (parser->m_idAttIndex)
634 #define nsAtts (parser->m_nsAtts)
635 #define nsAttsVersion (parser->m_nsAttsVersion)
636 #define nsAttsPower (parser->m_nsAttsPower)
637 #define tempPool (parser->m_tempPool)
638 #define temp2Pool (parser->m_temp2Pool)
639 #define groupConnector (parser->m_groupConnector)
640 #define groupSize (parser->m_groupSize)
641 #define namespaceSeparator (parser->m_namespaceSeparator)
642 #define parentParser (parser->m_parentParser)
643 #define parsing (parser->m_parsingStatus.parsing)
644 #define finalBuffer (parser->m_parsingStatus.finalBuffer)
646 #define isParamEntity (parser->m_isParamEntity)
647 #define useForeignDTD (parser->m_useForeignDTD)
648 #define paramEntityParsing (parser->m_paramEntityParsing)
652 XML_ParserCreate(const XML_Char
*encodingName
)
654 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
658 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
662 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
665 static const XML_Char implicitContext
[] = {
666 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
667 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
668 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
669 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
673 XML_ParserCreate_MM(const XML_Char
*encodingName
,
674 const XML_Memory_Handling_Suite
*memsuite
,
675 const XML_Char
*nameSep
)
677 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
678 if (parser
!= NULL
&& ns
) {
679 /* implicit context only set for root parser, since child
680 parsers (i.e. external entity parsers) will inherit it
682 if (!setContext(parser
, implicitContext
)) {
683 XML_ParserFree(parser
);
691 parserCreate(const XML_Char
*encodingName
,
692 const XML_Memory_Handling_Suite
*memsuite
,
693 const XML_Char
*nameSep
,
699 XML_Memory_Handling_Suite
*mtemp
;
700 parser
= (XML_Parser
)
701 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
702 if (parser
!= NULL
) {
703 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
704 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
705 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
706 mtemp
->free_fcn
= memsuite
->free_fcn
;
710 XML_Memory_Handling_Suite
*mtemp
;
711 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
712 if (parser
!= NULL
) {
713 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
714 mtemp
->malloc_fcn
= malloc
;
715 mtemp
->realloc_fcn
= realloc
;
716 mtemp
->free_fcn
= free
;
726 attsSize
= INIT_ATTS_SIZE
;
727 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
732 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
733 if (dataBuf
== NULL
) {
738 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
743 _dtd
= dtdCreate(&parser
->m_mem
);
752 freeBindingList
= NULL
;
754 freeInternalEntities
= NULL
;
757 groupConnector
= NULL
;
759 unknownEncodingHandler
= NULL
;
760 unknownEncodingHandlerData
= NULL
;
762 namespaceSeparator
= '!';
764 ns_triplets
= XML_FALSE
;
770 poolInit(&tempPool
, &(parser
->m_mem
));
771 poolInit(&temp2Pool
, &(parser
->m_mem
));
772 parserInit(parser
, encodingName
);
774 if (encodingName
&& !protocolEncodingName
) {
775 XML_ParserFree(parser
);
781 internalEncoding
= XmlGetInternalEncodingNS();
782 namespaceSeparator
= *nameSep
;
785 internalEncoding
= XmlGetInternalEncoding();
792 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
794 processor
= prologInitProcessor
;
795 XmlPrologStateInit(&prologState
);
796 protocolEncodingName
= (encodingName
!= NULL
797 ? poolCopyString(&tempPool
, encodingName
)
800 XmlInitEncoding(&initEncoding
, &encoding
, 0);
803 startElementHandler
= NULL
;
804 endElementHandler
= NULL
;
805 characterDataHandler
= NULL
;
806 processingInstructionHandler
= NULL
;
807 commentHandler
= NULL
;
808 startCdataSectionHandler
= NULL
;
809 endCdataSectionHandler
= NULL
;
810 defaultHandler
= NULL
;
811 startDoctypeDeclHandler
= NULL
;
812 endDoctypeDeclHandler
= NULL
;
813 unparsedEntityDeclHandler
= NULL
;
814 notationDeclHandler
= NULL
;
815 startNamespaceDeclHandler
= NULL
;
816 endNamespaceDeclHandler
= NULL
;
817 notStandaloneHandler
= NULL
;
818 externalEntityRefHandler
= NULL
;
819 externalEntityRefHandlerArg
= parser
;
820 skippedEntityHandler
= NULL
;
821 elementDeclHandler
= NULL
;
822 attlistDeclHandler
= NULL
;
823 entityDeclHandler
= NULL
;
824 xmlDeclHandler
= NULL
;
827 parseEndByteIndex
= 0;
829 declElementType
= NULL
;
830 declAttributeId
= NULL
;
835 declAttributeType
= NULL
;
836 declNotationName
= NULL
;
837 declNotationPublicId
= NULL
;
838 declAttributeIsCdata
= XML_FALSE
;
839 declAttributeIsId
= XML_FALSE
;
840 memset(&position
, 0, sizeof(POSITION
));
841 errorCode
= XML_ERROR_NONE
;
845 openInternalEntities
= NULL
;
846 defaultExpandInternalEntities
= XML_TRUE
;
849 inheritedBindings
= NULL
;
851 unknownEncodingMem
= NULL
;
852 unknownEncodingRelease
= NULL
;
853 unknownEncodingData
= NULL
;
855 parsing
= XML_INITIALIZED
;
857 isParamEntity
= XML_FALSE
;
858 useForeignDTD
= XML_FALSE
;
859 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
863 /* moves list of bindings to freeBindingList */
865 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
868 BINDING
*b
= bindings
;
869 bindings
= bindings
->nextTagBinding
;
870 b
->nextTagBinding
= freeBindingList
;
876 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
879 OPEN_INTERNAL_ENTITY
*openEntityList
;
882 /* move tagStack to freeTagList */
887 tag
->parent
= freeTagList
;
888 moveToFreeBindingList(parser
, tag
->bindings
);
889 tag
->bindings
= NULL
;
892 /* move openInternalEntities to freeInternalEntities */
893 openEntityList
= openInternalEntities
;
894 while (openEntityList
) {
895 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
896 openEntityList
= openEntity
->next
;
897 openEntity
->next
= freeInternalEntities
;
898 freeInternalEntities
= openEntity
;
900 moveToFreeBindingList(parser
, inheritedBindings
);
901 FREE(unknownEncodingMem
);
902 if (unknownEncodingRelease
)
903 unknownEncodingRelease(unknownEncodingData
);
904 poolClear(&tempPool
);
905 poolClear(&temp2Pool
);
906 parserInit(parser
, encodingName
);
907 dtdReset(_dtd
, &parser
->m_mem
);
908 return setContext(parser
, implicitContext
);
911 enum XML_Status XMLCALL
912 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
914 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
915 XXX There's no way for the caller to determine which of the
916 XXX possible error cases caused the XML_STATUS_ERROR return.
918 if (parsing
== XML_PARSING
|| parsing
== XML_SUSPENDED
)
919 return XML_STATUS_ERROR
;
920 if (encodingName
== NULL
)
921 protocolEncodingName
= NULL
;
923 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
924 if (!protocolEncodingName
)
925 return XML_STATUS_ERROR
;
927 return XML_STATUS_OK
;
931 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
932 const XML_Char
*context
,
933 const XML_Char
*encodingName
)
935 XML_Parser parser
= oldParser
;
938 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
939 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
940 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
941 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
942 = processingInstructionHandler
;
943 XML_CommentHandler oldCommentHandler
= commentHandler
;
944 XML_StartCdataSectionHandler oldStartCdataSectionHandler
945 = startCdataSectionHandler
;
946 XML_EndCdataSectionHandler oldEndCdataSectionHandler
947 = endCdataSectionHandler
;
948 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
949 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
950 = unparsedEntityDeclHandler
;
951 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
952 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
953 = startNamespaceDeclHandler
;
954 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
955 = endNamespaceDeclHandler
;
956 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
957 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
958 = externalEntityRefHandler
;
959 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
960 XML_UnknownEncodingHandler oldUnknownEncodingHandler
961 = unknownEncodingHandler
;
962 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
963 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
964 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
965 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
966 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
968 void *oldUserData
= userData
;
969 void *oldHandlerArg
= handlerArg
;
970 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
971 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
973 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
974 int oldInEntityValue
= prologState
.inEntityValue
;
976 XML_Bool oldns_triplets
= ns_triplets
;
983 /* Note that the magical uses of the pre-processor to make field
984 access look more like C++ require that `parser' be overwritten
985 here. This makes this function more painful to follow than it
990 *tmp
= namespaceSeparator
;
991 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
994 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1000 startElementHandler
= oldStartElementHandler
;
1001 endElementHandler
= oldEndElementHandler
;
1002 characterDataHandler
= oldCharacterDataHandler
;
1003 processingInstructionHandler
= oldProcessingInstructionHandler
;
1004 commentHandler
= oldCommentHandler
;
1005 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1006 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1007 defaultHandler
= oldDefaultHandler
;
1008 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1009 notationDeclHandler
= oldNotationDeclHandler
;
1010 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1011 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1012 notStandaloneHandler
= oldNotStandaloneHandler
;
1013 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1014 skippedEntityHandler
= oldSkippedEntityHandler
;
1015 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1016 elementDeclHandler
= oldElementDeclHandler
;
1017 attlistDeclHandler
= oldAttlistDeclHandler
;
1018 entityDeclHandler
= oldEntityDeclHandler
;
1019 xmlDeclHandler
= oldXmlDeclHandler
;
1020 declElementType
= oldDeclElementType
;
1021 userData
= oldUserData
;
1022 if (oldUserData
== oldHandlerArg
)
1023 handlerArg
= userData
;
1025 handlerArg
= parser
;
1026 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1027 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1028 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1029 ns_triplets
= oldns_triplets
;
1030 parentParser
= oldParser
;
1032 paramEntityParsing
= oldParamEntityParsing
;
1033 prologState
.inEntityValue
= oldInEntityValue
;
1035 #endif /* XML_DTD */
1036 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1037 || !setContext(parser
, context
)) {
1038 XML_ParserFree(parser
);
1041 processor
= externalEntityInitProcessor
;
1045 /* The DTD instance referenced by _dtd is shared between the document's
1046 root parser and external PE parsers, therefore one does not need to
1047 call setContext. In addition, one also *must* not call setContext,
1048 because this would overwrite existing prefix->binding pointers in
1049 _dtd with ones that get destroyed with the external PE parser.
1050 This would leave those prefixes with dangling pointers.
1052 isParamEntity
= XML_TRUE
;
1053 XmlPrologStateInitExternalEntity(&prologState
);
1054 processor
= externalParEntInitProcessor
;
1056 #endif /* XML_DTD */
1060 static void FASTCALL
1061 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1064 BINDING
*b
= bindings
;
1067 bindings
= b
->nextTagBinding
;
1074 XML_ParserFree(XML_Parser parser
)
1077 OPEN_INTERNAL_ENTITY
*entityList
;
1080 /* free tagStack and freeTagList */
1084 if (tagList
== NULL
) {
1085 if (freeTagList
== NULL
)
1087 tagList
= freeTagList
;
1091 tagList
= tagList
->parent
;
1093 destroyBindings(p
->bindings
, parser
);
1096 /* free openInternalEntities and freeInternalEntities */
1097 entityList
= openInternalEntities
;
1099 OPEN_INTERNAL_ENTITY
*openEntity
;
1100 if (entityList
== NULL
) {
1101 if (freeInternalEntities
== NULL
)
1103 entityList
= freeInternalEntities
;
1104 freeInternalEntities
= NULL
;
1106 openEntity
= entityList
;
1107 entityList
= entityList
->next
;
1111 destroyBindings(freeBindingList
, parser
);
1112 destroyBindings(inheritedBindings
, parser
);
1113 poolDestroy(&tempPool
);
1114 poolDestroy(&temp2Pool
);
1116 /* external parameter entity parsers share the DTD structure
1117 parser->m_dtd with the root parser, so we must not destroy it
1119 if (!isParamEntity
&& _dtd
)
1122 #endif /* XML_DTD */
1123 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1125 FREE(groupConnector
);
1129 FREE(unknownEncodingMem
);
1130 if (unknownEncodingRelease
)
1131 unknownEncodingRelease(unknownEncodingData
);
1136 XML_UseParserAsHandlerArg(XML_Parser parser
)
1138 handlerArg
= parser
;
1141 enum XML_Error XMLCALL
1142 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1145 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1146 if (parsing
== XML_PARSING
|| parsing
== XML_SUSPENDED
)
1147 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1148 useForeignDTD
= useDTD
;
1149 return XML_ERROR_NONE
;
1151 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1156 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1158 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1159 if (parsing
== XML_PARSING
|| parsing
== XML_SUSPENDED
)
1161 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1165 XML_SetUserData(XML_Parser parser
, void *p
)
1167 if (handlerArg
== userData
)
1168 handlerArg
= userData
= p
;
1173 enum XML_Status XMLCALL
1174 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1177 p
= poolCopyString(&_dtd
->pool
, p
);
1179 return XML_STATUS_ERROR
;
1184 return XML_STATUS_OK
;
1187 const XML_Char
* XMLCALL
1188 XML_GetBase(XML_Parser parser
)
1194 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1196 return nSpecifiedAtts
;
1200 XML_GetIdAttributeIndex(XML_Parser parser
)
1206 XML_SetElementHandler(XML_Parser parser
,
1207 XML_StartElementHandler start
,
1208 XML_EndElementHandler end
)
1210 startElementHandler
= start
;
1211 endElementHandler
= end
;
1215 XML_SetStartElementHandler(XML_Parser parser
,
1216 XML_StartElementHandler start
) {
1217 startElementHandler
= start
;
1221 XML_SetEndElementHandler(XML_Parser parser
,
1222 XML_EndElementHandler end
) {
1223 endElementHandler
= end
;
1227 XML_SetCharacterDataHandler(XML_Parser parser
,
1228 XML_CharacterDataHandler handler
)
1230 characterDataHandler
= handler
;
1234 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1235 XML_ProcessingInstructionHandler handler
)
1237 processingInstructionHandler
= handler
;
1241 XML_SetCommentHandler(XML_Parser parser
,
1242 XML_CommentHandler handler
)
1244 commentHandler
= handler
;
1248 XML_SetCdataSectionHandler(XML_Parser parser
,
1249 XML_StartCdataSectionHandler start
,
1250 XML_EndCdataSectionHandler end
)
1252 startCdataSectionHandler
= start
;
1253 endCdataSectionHandler
= end
;
1257 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1258 XML_StartCdataSectionHandler start
) {
1259 startCdataSectionHandler
= start
;
1263 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1264 XML_EndCdataSectionHandler end
) {
1265 endCdataSectionHandler
= end
;
1269 XML_SetDefaultHandler(XML_Parser parser
,
1270 XML_DefaultHandler handler
)
1272 defaultHandler
= handler
;
1273 defaultExpandInternalEntities
= XML_FALSE
;
1277 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1278 XML_DefaultHandler handler
)
1280 defaultHandler
= handler
;
1281 defaultExpandInternalEntities
= XML_TRUE
;
1285 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1286 XML_StartDoctypeDeclHandler start
,
1287 XML_EndDoctypeDeclHandler end
)
1289 startDoctypeDeclHandler
= start
;
1290 endDoctypeDeclHandler
= end
;
1294 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1295 XML_StartDoctypeDeclHandler start
) {
1296 startDoctypeDeclHandler
= start
;
1300 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1301 XML_EndDoctypeDeclHandler end
) {
1302 endDoctypeDeclHandler
= end
;
1306 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1307 XML_UnparsedEntityDeclHandler handler
)
1309 unparsedEntityDeclHandler
= handler
;
1313 XML_SetNotationDeclHandler(XML_Parser parser
,
1314 XML_NotationDeclHandler handler
)
1316 notationDeclHandler
= handler
;
1320 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1321 XML_StartNamespaceDeclHandler start
,
1322 XML_EndNamespaceDeclHandler end
)
1324 startNamespaceDeclHandler
= start
;
1325 endNamespaceDeclHandler
= end
;
1329 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1330 XML_StartNamespaceDeclHandler start
) {
1331 startNamespaceDeclHandler
= start
;
1335 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1336 XML_EndNamespaceDeclHandler end
) {
1337 endNamespaceDeclHandler
= end
;
1341 XML_SetNotStandaloneHandler(XML_Parser parser
,
1342 XML_NotStandaloneHandler handler
)
1344 notStandaloneHandler
= handler
;
1348 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1349 XML_ExternalEntityRefHandler handler
)
1351 externalEntityRefHandler
= handler
;
1355 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1358 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1360 externalEntityRefHandlerArg
= parser
;
1364 XML_SetSkippedEntityHandler(XML_Parser parser
,
1365 XML_SkippedEntityHandler handler
)
1367 skippedEntityHandler
= handler
;
1371 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1372 XML_UnknownEncodingHandler handler
,
1375 unknownEncodingHandler
= handler
;
1376 unknownEncodingHandlerData
= data
;
1380 XML_SetElementDeclHandler(XML_Parser parser
,
1381 XML_ElementDeclHandler eldecl
)
1383 elementDeclHandler
= eldecl
;
1387 XML_SetAttlistDeclHandler(XML_Parser parser
,
1388 XML_AttlistDeclHandler attdecl
)
1390 attlistDeclHandler
= attdecl
;
1394 XML_SetEntityDeclHandler(XML_Parser parser
,
1395 XML_EntityDeclHandler handler
)
1397 entityDeclHandler
= handler
;
1401 XML_SetXmlDeclHandler(XML_Parser parser
,
1402 XML_XmlDeclHandler handler
) {
1403 xmlDeclHandler
= handler
;
1407 XML_SetParamEntityParsing(XML_Parser parser
,
1408 enum XML_ParamEntityParsing peParsing
)
1410 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1411 if (parsing
== XML_PARSING
|| parsing
== XML_SUSPENDED
)
1414 paramEntityParsing
= peParsing
;
1417 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1421 enum XML_Status XMLCALL
1422 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1426 errorCode
= XML_ERROR_SUSPENDED
;
1427 return XML_STATUS_ERROR
;
1429 errorCode
= XML_ERROR_FINISHED
;
1430 return XML_STATUS_ERROR
;
1432 parsing
= XML_PARSING
;
1436 finalBuffer
= (XML_Bool
)isFinal
;
1438 return XML_STATUS_OK
;
1439 positionPtr
= bufferPtr
;
1440 parseEndPtr
= bufferEnd
;
1442 /* If data are left over from last buffer, and we now know that these
1443 data are the final chunk of input, then we have to check them again
1444 to detect errors based on this information.
1446 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1448 if (errorCode
== XML_ERROR_NONE
) {
1451 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1452 positionPtr
= bufferPtr
;
1453 return XML_STATUS_SUSPENDED
;
1454 case XML_INITIALIZED
:
1456 parsing
= XML_FINISHED
;
1459 return XML_STATUS_OK
;
1462 eventEndPtr
= eventPtr
;
1463 processor
= errorProcessor
;
1464 return XML_STATUS_ERROR
;
1466 #ifndef XML_CONTEXT_BYTES
1467 else if (bufferPtr
== bufferEnd
) {
1470 enum XML_Error result
;
1471 parseEndByteIndex
+= len
;
1473 finalBuffer
= (XML_Bool
)isFinal
;
1475 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1477 if (errorCode
!= XML_ERROR_NONE
) {
1478 eventEndPtr
= eventPtr
;
1479 processor
= errorProcessor
;
1480 return XML_STATUS_ERROR
;
1485 result
= XML_STATUS_SUSPENDED
;
1487 case XML_INITIALIZED
:
1489 result
= XML_STATUS_OK
;
1491 parsing
= XML_FINISHED
;
1497 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1499 nLeftOver
= s
+ len
- end
;
1501 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1502 /* FIXME avoid integer overflow */
1504 temp
= (buffer
== NULL
1505 ? (char *)MALLOC(len
* 2)
1506 : (char *)REALLOC(buffer
, len
* 2));
1508 errorCode
= XML_ERROR_NO_MEMORY
;
1509 return XML_STATUS_ERROR
;
1513 errorCode
= XML_ERROR_NO_MEMORY
;
1514 eventPtr
= eventEndPtr
= NULL
;
1515 processor
= errorProcessor
;
1516 return XML_STATUS_ERROR
;
1518 bufferLim
= buffer
+ len
* 2;
1520 memcpy(buffer
, end
, nLeftOver
);
1522 bufferEnd
= buffer
+ nLeftOver
;
1526 #endif /* not defined XML_CONTEXT_BYTES */
1528 void *buff
= XML_GetBuffer(parser
, len
);
1530 return XML_STATUS_ERROR
;
1532 memcpy(buff
, s
, len
);
1533 return XML_ParseBuffer(parser
, len
, isFinal
);
1538 enum XML_Status XMLCALL
1539 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1542 enum XML_Status result
= XML_STATUS_OK
;
1546 errorCode
= XML_ERROR_SUSPENDED
;
1547 return XML_STATUS_ERROR
;
1549 errorCode
= XML_ERROR_FINISHED
;
1550 return XML_STATUS_ERROR
;
1552 parsing
= XML_PARSING
;
1556 positionPtr
= start
;
1558 parseEndPtr
= bufferEnd
;
1559 parseEndByteIndex
+= len
;
1560 finalBuffer
= (XML_Bool
)isFinal
;
1562 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1564 if (errorCode
!= XML_ERROR_NONE
) {
1565 eventEndPtr
= eventPtr
;
1566 processor
= errorProcessor
;
1567 return XML_STATUS_ERROR
;
1572 result
= XML_STATUS_SUSPENDED
;
1574 case XML_INITIALIZED
:
1577 parsing
= XML_FINISHED
;
1580 default: ; /* should not happen */
1584 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1585 positionPtr
= bufferPtr
;
1590 XML_GetBuffer(XML_Parser parser
, int len
)
1594 errorCode
= XML_ERROR_SUSPENDED
;
1597 errorCode
= XML_ERROR_FINISHED
;
1602 if (len
> bufferLim
- bufferEnd
) {
1603 /* FIXME avoid integer overflow */
1604 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1605 #ifdef XML_CONTEXT_BYTES
1606 int keep
= bufferPtr
- buffer
;
1608 if (keep
> XML_CONTEXT_BYTES
)
1609 keep
= XML_CONTEXT_BYTES
;
1611 #endif /* defined XML_CONTEXT_BYTES */
1612 if (neededSize
<= bufferLim
- buffer
) {
1613 #ifdef XML_CONTEXT_BYTES
1614 if (keep
< bufferPtr
- buffer
) {
1615 int offset
= (bufferPtr
- buffer
) - keep
;
1616 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1617 bufferEnd
-= offset
;
1618 bufferPtr
-= offset
;
1621 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1622 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1624 #endif /* not defined XML_CONTEXT_BYTES */
1628 int bufferSize
= bufferLim
- bufferPtr
;
1629 if (bufferSize
== 0)
1630 bufferSize
= INIT_BUFFER_SIZE
;
1633 } while (bufferSize
< neededSize
);
1634 newBuf
= (char *)MALLOC(bufferSize
);
1636 errorCode
= XML_ERROR_NO_MEMORY
;
1639 bufferLim
= newBuf
+ bufferSize
;
1640 #ifdef XML_CONTEXT_BYTES
1642 int keep
= bufferPtr
- buffer
;
1643 if (keep
> XML_CONTEXT_BYTES
)
1644 keep
= XML_CONTEXT_BYTES
;
1645 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1648 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1649 bufferPtr
= buffer
+ keep
;
1652 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1653 bufferPtr
= buffer
= newBuf
;
1657 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1660 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1661 bufferPtr
= buffer
= newBuf
;
1662 #endif /* not defined XML_CONTEXT_BYTES */
1668 enum XML_Status XMLCALL
1669 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1674 errorCode
= XML_ERROR_SUSPENDED
;
1675 return XML_STATUS_ERROR
;
1677 parsing
= XML_FINISHED
;
1680 errorCode
= XML_ERROR_FINISHED
;
1681 return XML_STATUS_ERROR
;
1685 if (isParamEntity
) {
1686 errorCode
= XML_ERROR_SUSPEND_PE
;
1687 return XML_STATUS_ERROR
;
1690 parsing
= XML_SUSPENDED
;
1693 parsing
= XML_FINISHED
;
1695 return XML_STATUS_OK
;
1698 enum XML_Status XMLCALL
1699 XML_ResumeParser(XML_Parser parser
)
1701 enum XML_Status result
= XML_STATUS_OK
;
1703 if (parsing
!= XML_SUSPENDED
) {
1704 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1705 return XML_STATUS_ERROR
;
1707 parsing
= XML_PARSING
;
1709 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1711 if (errorCode
!= XML_ERROR_NONE
) {
1712 eventEndPtr
= eventPtr
;
1713 processor
= errorProcessor
;
1714 return XML_STATUS_ERROR
;
1719 result
= XML_STATUS_SUSPENDED
;
1721 case XML_INITIALIZED
:
1724 parsing
= XML_FINISHED
;
1731 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1732 positionPtr
= bufferPtr
;
1737 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1739 assert(status
!= NULL
);
1740 *status
= parser
->m_parsingStatus
;
1743 enum XML_Error XMLCALL
1744 XML_GetErrorCode(XML_Parser parser
)
1750 XML_GetCurrentByteIndex(XML_Parser parser
)
1753 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1758 XML_GetCurrentByteCount(XML_Parser parser
)
1760 if (eventEndPtr
&& eventPtr
)
1761 return eventEndPtr
- eventPtr
;
1765 const char * XMLCALL
1766 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1768 #ifdef XML_CONTEXT_BYTES
1769 if (eventPtr
&& buffer
) {
1770 *offset
= eventPtr
- buffer
;
1771 *size
= bufferEnd
- buffer
;
1774 #endif /* defined XML_CONTEXT_BYTES */
1779 XML_GetCurrentLineNumber(XML_Parser parser
)
1781 if (eventPtr
&& eventPtr
>= positionPtr
) {
1782 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1783 positionPtr
= eventPtr
;
1785 return position
.lineNumber
+ 1;
1789 XML_GetCurrentColumnNumber(XML_Parser parser
)
1791 if (eventPtr
&& eventPtr
>= positionPtr
) {
1792 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1793 positionPtr
= eventPtr
;
1795 return position
.columnNumber
;
1799 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1805 XML_MemMalloc(XML_Parser parser
, size_t size
)
1807 return MALLOC(size
);
1811 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1813 return REALLOC(ptr
, size
);
1817 XML_MemFree(XML_Parser parser
, void *ptr
)
1823 XML_DefaultCurrent(XML_Parser parser
)
1825 if (defaultHandler
) {
1826 if (openInternalEntities
)
1827 reportDefault(parser
,
1829 openInternalEntities
->internalEventPtr
,
1830 openInternalEntities
->internalEventEndPtr
);
1832 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1836 const XML_LChar
* XMLCALL
1837 XML_ErrorString(enum XML_Error code
)
1839 static const XML_LChar
* const message
[] = {
1841 XML_L("out of memory"),
1842 XML_L("syntax error"),
1843 XML_L("no element found"),
1844 XML_L("not well-formed (invalid token)"),
1845 XML_L("unclosed token"),
1846 XML_L("partial character"),
1847 XML_L("mismatched tag"),
1848 XML_L("duplicate attribute"),
1849 XML_L("junk after document element"),
1850 XML_L("illegal parameter entity reference"),
1851 XML_L("undefined entity"),
1852 XML_L("recursive entity reference"),
1853 XML_L("asynchronous entity"),
1854 XML_L("reference to invalid character number"),
1855 XML_L("reference to binary entity"),
1856 XML_L("reference to external entity in attribute"),
1857 XML_L("xml declaration not at start of external entity"),
1858 XML_L("unknown encoding"),
1859 XML_L("encoding specified in XML declaration is incorrect"),
1860 XML_L("unclosed CDATA section"),
1861 XML_L("error in processing external entity reference"),
1862 XML_L("document is not standalone"),
1863 XML_L("unexpected parser state - please send a bug report"),
1864 XML_L("entity declared in parameter entity"),
1865 XML_L("requested feature requires XML_DTD support in Expat"),
1866 XML_L("cannot change setting once parsing has begun"),
1867 XML_L("unbound prefix"),
1868 XML_L("must not undeclare prefix"),
1869 XML_L("incomplete markup in parameter entity"),
1870 XML_L("XML declaration not well-formed"),
1871 XML_L("text declaration not well-formed"),
1872 XML_L("illegal character(s) in public id"),
1873 XML_L("parser suspended"),
1874 XML_L("parser not suspended"),
1875 XML_L("parsing aborted"),
1876 XML_L("parsing finished"),
1877 XML_L("cannot suspend in external parameter entity")
1879 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1880 return message
[code
];
1884 const XML_LChar
* XMLCALL
1885 XML_ExpatVersion(void) {
1887 /* V1 is used to string-ize the version number. However, it would
1888 string-ize the actual version macro *names* unless we get them
1889 substituted before being passed to V1. CPP is defined to expand
1890 a macro, then rescan for more expansions. Thus, we use V2 to expand
1891 the version macros, then CPP will expand the resulting V1() macro
1892 with the correct numerals. */
1893 /* ### I'm assuming cpp is portable in this respect... */
1895 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1896 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1898 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1904 XML_Expat_Version XMLCALL
1905 XML_ExpatVersionInfo(void)
1907 XML_Expat_Version version
;
1909 version
.major
= XML_MAJOR_VERSION
;
1910 version
.minor
= XML_MINOR_VERSION
;
1911 version
.micro
= XML_MICRO_VERSION
;
1916 const XML_Feature
* XMLCALL
1917 XML_GetFeatureList(void)
1919 static const XML_Feature features
[] = {
1920 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1922 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1925 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1927 #ifdef XML_UNICODE_WCHAR_T
1928 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1931 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1933 #ifdef XML_CONTEXT_BYTES
1934 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1938 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1940 {XML_FEATURE_END
, NULL
, 0}
1946 /* Initially tag->rawName always points into the parse buffer;
1947 for those TAG instances opened while the current parse buffer was
1948 processed, and not yet closed, we need to store tag->rawName in a more
1949 permanent location, since the parse buffer is about to be discarded.
1952 storeRawNames(XML_Parser parser
)
1954 TAG
*tag
= tagStack
;
1957 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1958 char *rawNameBuf
= tag
->buf
+ nameLen
;
1959 /* Stop if already stored. Since tagStack is a stack, we can stop
1960 at the first entry that has already been copied; everything
1961 below it in the stack is already been accounted for in a
1962 previous call to this function.
1964 if (tag
->rawName
== rawNameBuf
)
1966 /* For re-use purposes we need to ensure that the
1967 size of tag->buf is a multiple of sizeof(XML_Char).
1969 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1970 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1971 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1974 /* if tag->name.str points to tag->buf (only when namespace
1975 processing is off) then we have to update it
1977 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
1978 tag
->name
.str
= (XML_Char
*)temp
;
1979 /* if tag->name.localPart is set (when namespace processing is on)
1980 then update it as well, since it will always point into tag->buf
1982 if (tag
->name
.localPart
)
1983 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
1984 (XML_Char
*)tag
->buf
);
1986 tag
->bufEnd
= temp
+ bufSize
;
1987 rawNameBuf
= temp
+ nameLen
;
1989 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1990 tag
->rawName
= rawNameBuf
;
1996 static enum XML_Error PTRCALL
1997 contentProcessor(XML_Parser parser
,
2000 const char **endPtr
)
2002 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2003 endPtr
, (XML_Bool
)!finalBuffer
);
2004 if (result
== XML_ERROR_NONE
) {
2005 if (!storeRawNames(parser
))
2006 return XML_ERROR_NO_MEMORY
;
2011 static enum XML_Error PTRCALL
2012 externalEntityInitProcessor(XML_Parser parser
,
2015 const char **endPtr
)
2017 enum XML_Error result
= initializeEncoding(parser
);
2018 if (result
!= XML_ERROR_NONE
)
2020 processor
= externalEntityInitProcessor2
;
2021 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2024 static enum XML_Error PTRCALL
2025 externalEntityInitProcessor2(XML_Parser parser
,
2028 const char **endPtr
)
2030 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2031 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2034 /* If we are at the end of the buffer, this would cause the next stage,
2035 i.e. externalEntityInitProcessor3, to pass control directly to
2036 doContent (by detecting XML_TOK_NONE) without processing any xml text
2037 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2039 if (next
== end
&& !finalBuffer
) {
2041 return XML_ERROR_NONE
;
2045 case XML_TOK_PARTIAL
:
2048 return XML_ERROR_NONE
;
2051 return XML_ERROR_UNCLOSED_TOKEN
;
2052 case XML_TOK_PARTIAL_CHAR
:
2055 return XML_ERROR_NONE
;
2058 return XML_ERROR_PARTIAL_CHAR
;
2060 processor
= externalEntityInitProcessor3
;
2061 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2064 static enum XML_Error PTRCALL
2065 externalEntityInitProcessor3(XML_Parser parser
,
2068 const char **endPtr
)
2071 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2073 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2077 case XML_TOK_XML_DECL
:
2079 enum XML_Error result
;
2080 result
= processXmlDecl(parser
, 1, start
, next
);
2081 if (result
!= XML_ERROR_NONE
)
2086 return XML_ERROR_NONE
;
2088 return XML_ERROR_ABORTED
;
2094 case XML_TOK_PARTIAL
:
2097 return XML_ERROR_NONE
;
2099 return XML_ERROR_UNCLOSED_TOKEN
;
2100 case XML_TOK_PARTIAL_CHAR
:
2103 return XML_ERROR_NONE
;
2105 return XML_ERROR_PARTIAL_CHAR
;
2107 processor
= externalEntityContentProcessor
;
2109 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2112 static enum XML_Error PTRCALL
2113 externalEntityContentProcessor(XML_Parser parser
,
2116 const char **endPtr
)
2118 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2119 endPtr
, (XML_Bool
)!finalBuffer
);
2120 if (result
== XML_ERROR_NONE
) {
2121 if (!storeRawNames(parser
))
2122 return XML_ERROR_NO_MEMORY
;
2127 static enum XML_Error
2128 doContent(XML_Parser parser
,
2130 const ENCODING
*enc
,
2133 const char **nextPtr
,
2136 /* save one level of indirection */
2137 DTD
* const dtd
= _dtd
;
2139 const char **eventPP
;
2140 const char **eventEndPP
;
2141 if (enc
== encoding
) {
2142 eventPP
= &eventPtr
;
2143 eventEndPP
= &eventEndPtr
;
2146 eventPP
= &(openInternalEntities
->internalEventPtr
);
2147 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2152 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2153 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2156 case XML_TOK_TRAILING_CR
:
2159 return XML_ERROR_NONE
;
2162 if (characterDataHandler
) {
2164 characterDataHandler(handlerArg
, &c
, 1);
2166 else if (defaultHandler
)
2167 reportDefault(parser
, enc
, s
, end
);
2168 /* We are at the end of the final buffer, should we check for
2169 XML_SUSPENDED, XML_FINISHED?
2171 if (startTagLevel
== 0)
2172 return XML_ERROR_NO_ELEMENTS
;
2173 if (tagLevel
!= startTagLevel
)
2174 return XML_ERROR_ASYNC_ENTITY
;
2176 return XML_ERROR_NONE
;
2180 return XML_ERROR_NONE
;
2182 if (startTagLevel
> 0) {
2183 if (tagLevel
!= startTagLevel
)
2184 return XML_ERROR_ASYNC_ENTITY
;
2186 return XML_ERROR_NONE
;
2188 return XML_ERROR_NO_ELEMENTS
;
2189 case XML_TOK_INVALID
:
2191 return XML_ERROR_INVALID_TOKEN
;
2192 case XML_TOK_PARTIAL
:
2195 return XML_ERROR_NONE
;
2197 return XML_ERROR_UNCLOSED_TOKEN
;
2198 case XML_TOK_PARTIAL_CHAR
:
2201 return XML_ERROR_NONE
;
2203 return XML_ERROR_PARTIAL_CHAR
;
2204 case XML_TOK_ENTITY_REF
:
2206 const XML_Char
*name
;
2208 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2209 s
+ enc
->minBytesPerChar
,
2210 next
- enc
->minBytesPerChar
);
2212 if (characterDataHandler
)
2213 characterDataHandler(handlerArg
, &ch
, 1);
2214 else if (defaultHandler
)
2215 reportDefault(parser
, enc
, s
, next
);
2218 name
= poolStoreString(&dtd
->pool
, enc
,
2219 s
+ enc
->minBytesPerChar
,
2220 next
- enc
->minBytesPerChar
);
2222 return XML_ERROR_NO_MEMORY
;
2223 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2224 poolDiscard(&dtd
->pool
);
2225 /* First, determine if a check for an existing declaration is needed;
2226 if yes, check that the entity exists, and that it is internal,
2227 otherwise call the skipped entity or default handler.
2229 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2231 return XML_ERROR_UNDEFINED_ENTITY
;
2232 else if (!entity
->is_internal
)
2233 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2236 if (skippedEntityHandler
)
2237 skippedEntityHandler(handlerArg
, name
, 0);
2238 else if (defaultHandler
)
2239 reportDefault(parser
, enc
, s
, next
);
2243 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2244 if (entity
->notation
)
2245 return XML_ERROR_BINARY_ENTITY_REF
;
2246 if (entity
->textPtr
) {
2247 enum XML_Error result
;
2248 if (!defaultExpandInternalEntities
) {
2249 if (skippedEntityHandler
)
2250 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2251 else if (defaultHandler
)
2252 reportDefault(parser
, enc
, s
, next
);
2255 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2256 if (result
!= XML_ERROR_NONE
)
2259 else if (externalEntityRefHandler
) {
2260 const XML_Char
*context
;
2261 entity
->open
= XML_TRUE
;
2262 context
= getContext(parser
);
2263 entity
->open
= XML_FALSE
;
2265 return XML_ERROR_NO_MEMORY
;
2266 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2271 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2272 poolDiscard(&tempPool
);
2274 else if (defaultHandler
)
2275 reportDefault(parser
, enc
, s
, next
);
2278 case XML_TOK_START_TAG_NO_ATTS
:
2280 case XML_TOK_START_TAG_WITH_ATTS
:
2283 enum XML_Error result
;
2287 freeTagList
= freeTagList
->parent
;
2290 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2292 return XML_ERROR_NO_MEMORY
;
2293 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2296 return XML_ERROR_NO_MEMORY
;
2298 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2300 tag
->bindings
= NULL
;
2301 tag
->parent
= tagStack
;
2303 tag
->name
.localPart
= NULL
;
2304 tag
->name
.prefix
= NULL
;
2305 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2306 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2309 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2310 const char *fromPtr
= tag
->rawName
;
2311 toPtr
= (XML_Char
*)tag
->buf
;
2316 &fromPtr
, rawNameEnd
,
2317 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2318 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2319 if (fromPtr
== rawNameEnd
) {
2320 tag
->name
.strLen
= convLen
;
2323 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2325 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2327 return XML_ERROR_NO_MEMORY
;
2329 tag
->bufEnd
= temp
+ bufSize
;
2330 toPtr
= (XML_Char
*)temp
+ convLen
;
2334 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2335 *toPtr
= XML_T('\0');
2336 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2339 if (startElementHandler
)
2340 startElementHandler(handlerArg
, tag
->name
.str
,
2341 (const XML_Char
**)atts
);
2342 else if (defaultHandler
)
2343 reportDefault(parser
, enc
, s
, next
);
2344 poolClear(&tempPool
);
2347 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2349 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2351 const char *rawName
= s
+ enc
->minBytesPerChar
;
2352 enum XML_Error result
;
2353 BINDING
*bindings
= NULL
;
2354 XML_Bool noElmHandlers
= XML_TRUE
;
2356 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2357 rawName
+ XmlNameLength(enc
, rawName
));
2359 return XML_ERROR_NO_MEMORY
;
2360 poolFinish(&tempPool
);
2361 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2364 poolFinish(&tempPool
);
2365 if (startElementHandler
) {
2366 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2367 noElmHandlers
= XML_FALSE
;
2369 if (endElementHandler
) {
2370 if (startElementHandler
)
2371 *eventPP
= *eventEndPP
;
2372 endElementHandler(handlerArg
, name
.str
);
2373 noElmHandlers
= XML_FALSE
;
2375 if (noElmHandlers
&& defaultHandler
)
2376 reportDefault(parser
, enc
, s
, next
);
2377 poolClear(&tempPool
);
2379 BINDING
*b
= bindings
;
2380 if (endNamespaceDeclHandler
)
2381 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2382 bindings
= bindings
->nextTagBinding
;
2383 b
->nextTagBinding
= freeBindingList
;
2384 freeBindingList
= b
;
2385 b
->prefix
->binding
= b
->prevPrefixBinding
;
2389 return epilogProcessor(parser
, next
, end
, nextPtr
);
2391 case XML_TOK_END_TAG
:
2392 if (tagLevel
== startTagLevel
)
2393 return XML_ERROR_ASYNC_ENTITY
;
2396 const char *rawName
;
2397 TAG
*tag
= tagStack
;
2398 tagStack
= tag
->parent
;
2399 tag
->parent
= freeTagList
;
2401 rawName
= s
+ enc
->minBytesPerChar
*2;
2402 len
= XmlNameLength(enc
, rawName
);
2403 if (len
!= tag
->rawNameLength
2404 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2406 return XML_ERROR_TAG_MISMATCH
;
2409 if (endElementHandler
) {
2410 const XML_Char
*localPart
;
2411 const XML_Char
*prefix
;
2413 localPart
= tag
->name
.localPart
;
2414 if (ns
&& localPart
) {
2415 /* localPart and prefix may have been overwritten in
2416 tag->name.str, since this points to the binding->uri
2417 buffer which gets re-used; so we have to add them again
2419 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2420 /* don't need to check for space - already done in storeAtts() */
2421 while (*localPart
) *uri
++ = *localPart
++;
2422 prefix
= (XML_Char
*)tag
->name
.prefix
;
2423 if (ns_triplets
&& prefix
) {
2424 *uri
++ = namespaceSeparator
;
2425 while (*prefix
) *uri
++ = *prefix
++;
2429 endElementHandler(handlerArg
, tag
->name
.str
);
2431 else if (defaultHandler
)
2432 reportDefault(parser
, enc
, s
, next
);
2433 while (tag
->bindings
) {
2434 BINDING
*b
= tag
->bindings
;
2435 if (endNamespaceDeclHandler
)
2436 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2437 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2438 b
->nextTagBinding
= freeBindingList
;
2439 freeBindingList
= b
;
2440 b
->prefix
->binding
= b
->prevPrefixBinding
;
2443 return epilogProcessor(parser
, next
, end
, nextPtr
);
2446 case XML_TOK_CHAR_REF
:
2448 int n
= XmlCharRefNumber(enc
, s
);
2450 return XML_ERROR_BAD_CHAR_REF
;
2451 if (characterDataHandler
) {
2452 XML_Char buf
[XML_ENCODE_MAX
];
2453 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2455 else if (defaultHandler
)
2456 reportDefault(parser
, enc
, s
, next
);
2459 case XML_TOK_XML_DECL
:
2460 return XML_ERROR_MISPLACED_XML_PI
;
2461 case XML_TOK_DATA_NEWLINE
:
2462 if (characterDataHandler
) {
2464 characterDataHandler(handlerArg
, &c
, 1);
2466 else if (defaultHandler
)
2467 reportDefault(parser
, enc
, s
, next
);
2469 case XML_TOK_CDATA_SECT_OPEN
:
2471 enum XML_Error result
;
2472 if (startCdataSectionHandler
)
2473 startCdataSectionHandler(handlerArg
);
2475 /* Suppose you doing a transformation on a document that involves
2476 changing only the character data. You set up a defaultHandler
2477 and a characterDataHandler. The defaultHandler simply copies
2478 characters through. The characterDataHandler does the
2479 transformation and writes the characters out escaping them as
2480 necessary. This case will fail to work if we leave out the
2481 following two lines (because & and < inside CDATA sections will
2482 be incorrectly escaped).
2484 However, now we have a start/endCdataSectionHandler, so it seems
2485 easier to let the user deal with this.
2487 else if (characterDataHandler
)
2488 characterDataHandler(handlerArg
, dataBuf
, 0);
2490 else if (defaultHandler
)
2491 reportDefault(parser
, enc
, s
, next
);
2492 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2493 if (result
!= XML_ERROR_NONE
)
2496 processor
= cdataSectionProcessor
;
2501 case XML_TOK_TRAILING_RSQB
:
2504 return XML_ERROR_NONE
;
2506 if (characterDataHandler
) {
2507 if (MUST_CONVERT(enc
, s
)) {
2508 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2509 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2510 characterDataHandler(handlerArg
, dataBuf
,
2511 dataPtr
- (ICHAR
*)dataBuf
);
2514 characterDataHandler(handlerArg
,
2516 (XML_Char
*)end
- (XML_Char
*)s
);
2518 else if (defaultHandler
)
2519 reportDefault(parser
, enc
, s
, end
);
2520 /* We are at the end of the final buffer, should we check for
2521 XML_SUSPENDED, XML_FINISHED?
2523 if (startTagLevel
== 0) {
2525 return XML_ERROR_NO_ELEMENTS
;
2527 if (tagLevel
!= startTagLevel
) {
2529 return XML_ERROR_ASYNC_ENTITY
;
2532 return XML_ERROR_NONE
;
2533 case XML_TOK_DATA_CHARS
:
2534 if (characterDataHandler
) {
2535 if (MUST_CONVERT(enc
, s
)) {
2537 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2538 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2540 characterDataHandler(handlerArg
, dataBuf
,
2541 dataPtr
- (ICHAR
*)dataBuf
);
2548 characterDataHandler(handlerArg
,
2550 (XML_Char
*)next
- (XML_Char
*)s
);
2552 else if (defaultHandler
)
2553 reportDefault(parser
, enc
, s
, next
);
2556 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2557 return XML_ERROR_NO_MEMORY
;
2559 case XML_TOK_COMMENT
:
2560 if (!reportComment(parser
, enc
, s
, next
))
2561 return XML_ERROR_NO_MEMORY
;
2565 reportDefault(parser
, enc
, s
, next
);
2568 *eventPP
= s
= next
;
2572 return XML_ERROR_NONE
;
2574 return XML_ERROR_ABORTED
;
2581 /* Precondition: all arguments must be non-NULL;
2583 - normalize attributes
2584 - check attributes for well-formedness
2585 - generate namespace aware attribute names (URI, prefix)
2586 - build list of attributes for startElementHandler
2587 - default attributes
2588 - process namespace declarations (check and report them)
2589 - generate namespace aware element name (URI, prefix)
2591 static enum XML_Error
2592 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2593 const char *attStr
, TAG_NAME
*tagNamePtr
,
2594 BINDING
**bindingsPtr
)
2596 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2597 ELEMENT_TYPE
*elementType
;
2599 const XML_Char
**appAtts
; /* the attribute list for the application */
2607 const XML_Char
*localPart
;
2609 /* lookup the element type name */
2610 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2612 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2614 return XML_ERROR_NO_MEMORY
;
2615 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2616 sizeof(ELEMENT_TYPE
));
2618 return XML_ERROR_NO_MEMORY
;
2619 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2620 return XML_ERROR_NO_MEMORY
;
2622 nDefaultAtts
= elementType
->nDefaultAtts
;
2624 /* get the attributes from the tokenizer */
2625 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2626 if (n
+ nDefaultAtts
> attsSize
) {
2627 int oldAttsSize
= attsSize
;
2629 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2630 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2632 return XML_ERROR_NO_MEMORY
;
2634 if (n
> oldAttsSize
)
2635 XmlGetAttributes(enc
, attStr
, n
, atts
);
2638 appAtts
= (const XML_Char
**)atts
;
2639 for (i
= 0; i
< n
; i
++) {
2640 /* add the name and value to the attribute list */
2641 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2643 + XmlNameLength(enc
, atts
[i
].name
));
2645 return XML_ERROR_NO_MEMORY
;
2646 /* Detect duplicate attributes by their QNames. This does not work when
2647 namespace processing is turned on and different prefixes for the same
2648 namespace are used. For this case we have a check further down.
2650 if ((attId
->name
)[-1]) {
2651 if (enc
== encoding
)
2652 eventPtr
= atts
[i
].name
;
2653 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2655 (attId
->name
)[-1] = 1;
2656 appAtts
[attIndex
++] = attId
->name
;
2657 if (!atts
[i
].normalized
) {
2658 enum XML_Error result
;
2659 XML_Bool isCdata
= XML_TRUE
;
2661 /* figure out whether declared as other than CDATA */
2662 if (attId
->maybeTokenized
) {
2664 for (j
= 0; j
< nDefaultAtts
; j
++) {
2665 if (attId
== elementType
->defaultAtts
[j
].id
) {
2666 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2672 /* normalize the attribute value */
2673 result
= storeAttributeValue(parser
, enc
, isCdata
,
2674 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2678 appAtts
[attIndex
] = poolStart(&tempPool
);
2679 poolFinish(&tempPool
);
2682 /* the value did not need normalizing */
2683 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2685 if (appAtts
[attIndex
] == 0)
2686 return XML_ERROR_NO_MEMORY
;
2687 poolFinish(&tempPool
);
2689 /* handle prefixed attribute names */
2690 if (attId
->prefix
) {
2692 /* deal with namespace declarations here */
2693 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2694 appAtts
[attIndex
], bindingsPtr
);
2700 /* deal with other prefixed names later */
2703 (attId
->name
)[-1] = 2;
2710 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2711 nSpecifiedAtts
= attIndex
;
2712 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2713 for (i
= 0; i
< attIndex
; i
+= 2)
2714 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2722 /* do attribute defaulting */
2723 for (i
= 0; i
< nDefaultAtts
; i
++) {
2724 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2725 if (!(da
->id
->name
)[-1] && da
->value
) {
2726 if (da
->id
->prefix
) {
2727 if (da
->id
->xmlns
) {
2728 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2729 da
->value
, bindingsPtr
);
2734 (da
->id
->name
)[-1] = 2;
2736 appAtts
[attIndex
++] = da
->id
->name
;
2737 appAtts
[attIndex
++] = da
->value
;
2741 (da
->id
->name
)[-1] = 1;
2742 appAtts
[attIndex
++] = da
->id
->name
;
2743 appAtts
[attIndex
++] = da
->value
;
2747 appAtts
[attIndex
] = 0;
2749 /* expand prefixed attribute names, check for duplicates,
2750 and clear flags that say whether attributes were specified */
2753 int j
; /* hash table index */
2754 unsigned long version
= nsAttsVersion
;
2755 int nsAttsSize
= (int)1 << nsAttsPower
;
2756 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2757 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2759 /* hash table size must also be a power of 2 and >= 8 */
2760 while (nPrefixes
>> nsAttsPower
++);
2761 if (nsAttsPower
< 3)
2763 nsAttsSize
= (int)1 << nsAttsPower
;
2764 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2766 return XML_ERROR_NO_MEMORY
;
2768 version
= 0; /* force re-initialization of nsAtts hash table */
2770 /* using a version flag saves us from initializing nsAtts every time */
2771 if (!version
) { /* initialize version flags when version wraps around */
2772 version
= INIT_ATTS_VERSION
;
2773 for (j
= nsAttsSize
; j
!= 0; )
2774 nsAtts
[--j
].version
= version
;
2776 nsAttsVersion
= --version
;
2778 /* expand prefixed names and check for duplicates */
2779 for (; i
< attIndex
; i
+= 2) {
2780 const XML_Char
*s
= appAtts
[i
];
2781 if (s
[-1] == 2) { /* prefixed */
2784 unsigned long uriHash
= 0;
2785 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2786 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2787 b
= id
->prefix
->binding
;
2789 return XML_ERROR_UNBOUND_PREFIX
;
2791 /* as we expand the name we also calculate its hash value */
2792 for (j
= 0; j
< b
->uriLen
; j
++) {
2793 const XML_Char c
= b
->uri
[j
];
2794 if (!poolAppendChar(&tempPool
, c
))
2795 return XML_ERROR_NO_MEMORY
;
2796 uriHash
= CHAR_HASH(uriHash
, c
);
2798 while (*s
++ != XML_T(':'))
2800 do { /* copies null terminator */
2801 const XML_Char c
= *s
;
2802 if (!poolAppendChar(&tempPool
, *s
))
2803 return XML_ERROR_NO_MEMORY
;
2804 uriHash
= CHAR_HASH(uriHash
, c
);
2807 { /* Check hash table for duplicate of expanded name (uriName).
2808 Derived from code in lookup(HASH_TABLE *table, ...).
2810 unsigned char step
= 0;
2811 unsigned long mask
= nsAttsSize
- 1;
2812 j
= uriHash
& mask
; /* index into hash table */
2813 while (nsAtts
[j
].version
== version
) {
2814 /* for speed we compare stored hash values first */
2815 if (uriHash
== nsAtts
[j
].hash
) {
2816 const XML_Char
*s1
= poolStart(&tempPool
);
2817 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2818 /* s1 is null terminated, but not s2 */
2819 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2821 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2824 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2825 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2829 if (ns_triplets
) { /* append namespace separator and prefix */
2830 tempPool
.ptr
[-1] = namespaceSeparator
;
2831 s
= b
->prefix
->name
;
2833 if (!poolAppendChar(&tempPool
, *s
))
2834 return XML_ERROR_NO_MEMORY
;
2838 /* store expanded name in attribute list */
2839 s
= poolStart(&tempPool
);
2840 poolFinish(&tempPool
);
2843 /* fill empty slot with new version, uriName and hash value */
2844 nsAtts
[j
].version
= version
;
2845 nsAtts
[j
].hash
= uriHash
;
2846 nsAtts
[j
].uriName
= s
;
2851 else /* not prefixed */
2852 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2855 /* clear flags for the remaining attributes */
2856 for (; i
< attIndex
; i
+= 2)
2857 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2858 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2859 binding
->attId
->name
[-1] = 0;
2862 return XML_ERROR_NONE
;
2864 /* expand the element type name */
2865 if (elementType
->prefix
) {
2866 binding
= elementType
->prefix
->binding
;
2868 return XML_ERROR_UNBOUND_PREFIX
;
2869 localPart
= tagNamePtr
->str
;
2870 while (*localPart
++ != XML_T(':'))
2873 else if (dtd
->defaultPrefix
.binding
) {
2874 binding
= dtd
->defaultPrefix
.binding
;
2875 localPart
= tagNamePtr
->str
;
2878 return XML_ERROR_NONE
;
2880 if (ns_triplets
&& binding
->prefix
->name
) {
2881 for (; binding
->prefix
->name
[prefixLen
++];)
2882 ; /* prefixLen includes null terminator */
2884 tagNamePtr
->localPart
= localPart
;
2885 tagNamePtr
->uriLen
= binding
->uriLen
;
2886 tagNamePtr
->prefix
= binding
->prefix
->name
;
2887 tagNamePtr
->prefixLen
= prefixLen
;
2888 for (i
= 0; localPart
[i
++];)
2889 ; /* i includes null terminator */
2890 n
= i
+ binding
->uriLen
+ prefixLen
;
2891 if (n
> binding
->uriAlloc
) {
2893 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2895 return XML_ERROR_NO_MEMORY
;
2896 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2897 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2898 for (p
= tagStack
; p
; p
= p
->parent
)
2899 if (p
->name
.str
== binding
->uri
)
2904 /* if namespaceSeparator != '\0' then uri includes it already */
2905 uri
= binding
->uri
+ binding
->uriLen
;
2906 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2907 /* we always have a namespace separator between localPart and prefix */
2910 *uri
= namespaceSeparator
; /* replace null terminator */
2911 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2913 tagNamePtr
->str
= binding
->uri
;
2914 return XML_ERROR_NONE
;
2917 /* addBinding() overwrites the value of prefix->binding without checking.
2918 Therefore one must keep track of the old value outside of addBinding().
2920 static enum XML_Error
2921 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2922 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2927 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2928 if (*uri
== XML_T('\0') && prefix
->name
)
2929 return XML_ERROR_UNDECLARING_PREFIX
;
2931 for (len
= 0; uri
[len
]; len
++)
2933 if (namespaceSeparator
)
2935 if (freeBindingList
) {
2936 b
= freeBindingList
;
2937 if (len
> b
->uriAlloc
) {
2938 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
2939 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2941 return XML_ERROR_NO_MEMORY
;
2943 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2945 freeBindingList
= b
->nextTagBinding
;
2948 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
2950 return XML_ERROR_NO_MEMORY
;
2951 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2954 return XML_ERROR_NO_MEMORY
;
2956 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2959 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2960 if (namespaceSeparator
)
2961 b
->uri
[len
- 1] = namespaceSeparator
;
2964 b
->prevPrefixBinding
= prefix
->binding
;
2965 /* NULL binding when default namespace undeclared */
2966 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
2967 prefix
->binding
= NULL
;
2969 prefix
->binding
= b
;
2970 b
->nextTagBinding
= *bindingsPtr
;
2972 /* if attId == NULL then we are not starting a namespace scope */
2973 if (attId
&& startNamespaceDeclHandler
)
2974 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2975 prefix
->binding
? uri
: 0);
2976 return XML_ERROR_NONE
;
2979 /* The idea here is to avoid using stack for each CDATA section when
2980 the whole file is parsed with one call.
2982 static enum XML_Error PTRCALL
2983 cdataSectionProcessor(XML_Parser parser
,
2986 const char **endPtr
)
2988 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
2989 endPtr
, (XML_Bool
)!finalBuffer
);
2990 if (result
!= XML_ERROR_NONE
)
2993 if (parentParser
) { /* we are parsing an external entity */
2994 processor
= externalEntityContentProcessor
;
2995 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2998 processor
= contentProcessor
;
2999 return contentProcessor(parser
, start
, end
, endPtr
);
3005 /* startPtr gets set to non-null if the section is closed, and to null if
3006 the section is not yet closed.
3008 static enum XML_Error
3009 doCdataSection(XML_Parser parser
,
3010 const ENCODING
*enc
,
3011 const char **startPtr
,
3013 const char **nextPtr
,
3016 const char *s
= *startPtr
;
3017 const char **eventPP
;
3018 const char **eventEndPP
;
3019 if (enc
== encoding
) {
3020 eventPP
= &eventPtr
;
3022 eventEndPP
= &eventEndPtr
;
3025 eventPP
= &(openInternalEntities
->internalEventPtr
);
3026 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3033 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3036 case XML_TOK_CDATA_SECT_CLOSE
:
3037 if (endCdataSectionHandler
)
3038 endCdataSectionHandler(handlerArg
);
3040 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3041 else if (characterDataHandler
)
3042 characterDataHandler(handlerArg
, dataBuf
, 0);
3044 else if (defaultHandler
)
3045 reportDefault(parser
, enc
, s
, next
);
3048 if (parsing
== XML_FINISHED
)
3049 return XML_ERROR_ABORTED
;
3051 return XML_ERROR_NONE
;
3052 case XML_TOK_DATA_NEWLINE
:
3053 if (characterDataHandler
) {
3055 characterDataHandler(handlerArg
, &c
, 1);
3057 else if (defaultHandler
)
3058 reportDefault(parser
, enc
, s
, next
);
3060 case XML_TOK_DATA_CHARS
:
3061 if (characterDataHandler
) {
3062 if (MUST_CONVERT(enc
, s
)) {
3064 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3065 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3067 characterDataHandler(handlerArg
, dataBuf
,
3068 dataPtr
- (ICHAR
*)dataBuf
);
3075 characterDataHandler(handlerArg
,
3077 (XML_Char
*)next
- (XML_Char
*)s
);
3079 else if (defaultHandler
)
3080 reportDefault(parser
, enc
, s
, next
);
3082 case XML_TOK_INVALID
:
3084 return XML_ERROR_INVALID_TOKEN
;
3085 case XML_TOK_PARTIAL_CHAR
:
3088 return XML_ERROR_NONE
;
3090 return XML_ERROR_PARTIAL_CHAR
;
3091 case XML_TOK_PARTIAL
:
3095 return XML_ERROR_NONE
;
3097 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3100 return XML_ERROR_UNEXPECTED_STATE
;
3103 *eventPP
= s
= next
;
3107 return XML_ERROR_NONE
;
3109 return XML_ERROR_ABORTED
;
3118 /* The idea here is to avoid using stack for each IGNORE section when
3119 the whole file is parsed with one call.
3121 static enum XML_Error PTRCALL
3122 ignoreSectionProcessor(XML_Parser parser
,
3125 const char **endPtr
)
3127 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3128 endPtr
, (XML_Bool
)!finalBuffer
);
3129 if (result
!= XML_ERROR_NONE
)
3132 processor
= prologProcessor
;
3133 return prologProcessor(parser
, start
, end
, endPtr
);
3138 /* startPtr gets set to non-null is the section is closed, and to null
3139 if the section is not yet closed.
3141 static enum XML_Error
3142 doIgnoreSection(XML_Parser parser
,
3143 const ENCODING
*enc
,
3144 const char **startPtr
,
3146 const char **nextPtr
,
3151 const char *s
= *startPtr
;
3152 const char **eventPP
;
3153 const char **eventEndPP
;
3154 if (enc
== encoding
) {
3155 eventPP
= &eventPtr
;
3157 eventEndPP
= &eventEndPtr
;
3160 eventPP
= &(openInternalEntities
->internalEventPtr
);
3161 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3165 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3168 case XML_TOK_IGNORE_SECT
:
3170 reportDefault(parser
, enc
, s
, next
);
3173 if (parsing
== XML_FINISHED
)
3174 return XML_ERROR_ABORTED
;
3176 return XML_ERROR_NONE
;
3177 case XML_TOK_INVALID
:
3179 return XML_ERROR_INVALID_TOKEN
;
3180 case XML_TOK_PARTIAL_CHAR
:
3183 return XML_ERROR_NONE
;
3185 return XML_ERROR_PARTIAL_CHAR
;
3186 case XML_TOK_PARTIAL
:
3190 return XML_ERROR_NONE
;
3192 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3195 return XML_ERROR_UNEXPECTED_STATE
;
3200 #endif /* XML_DTD */
3202 static enum XML_Error
3203 initializeEncoding(XML_Parser parser
)
3207 char encodingBuf
[128];
3208 if (!protocolEncodingName
)
3212 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3213 if (i
== sizeof(encodingBuf
) - 1
3214 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3215 encodingBuf
[0] = '\0';
3218 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3220 encodingBuf
[i
] = '\0';
3224 s
= protocolEncodingName
;
3226 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3227 return XML_ERROR_NONE
;
3228 return handleUnknownEncoding(parser
, protocolEncodingName
);
3231 static enum XML_Error
3232 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3233 const char *s
, const char *next
)
3235 const char *encodingName
= NULL
;
3236 const XML_Char
*storedEncName
= NULL
;
3237 const ENCODING
*newEncoding
= NULL
;
3238 const char *version
= NULL
;
3239 const char *versionend
;
3240 const XML_Char
*storedversion
= NULL
;
3241 int standalone
= -1;
3244 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3254 if (isGeneralTextEntity
)
3255 return XML_ERROR_TEXT_DECL
;
3257 return XML_ERROR_XML_DECL
;
3259 if (!isGeneralTextEntity
&& standalone
== 1) {
3260 _dtd
->standalone
= XML_TRUE
;
3262 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3263 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3264 #endif /* XML_DTD */
3266 if (xmlDeclHandler
) {
3267 if (encodingName
!= NULL
) {
3268 storedEncName
= poolStoreString(&temp2Pool
,
3272 + XmlNameLength(encoding
, encodingName
));
3274 return XML_ERROR_NO_MEMORY
;
3275 poolFinish(&temp2Pool
);
3278 storedversion
= poolStoreString(&temp2Pool
,
3281 versionend
- encoding
->minBytesPerChar
);
3283 return XML_ERROR_NO_MEMORY
;
3285 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3287 else if (defaultHandler
)
3288 reportDefault(parser
, encoding
, s
, next
);
3289 if (protocolEncodingName
== NULL
) {
3291 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3292 eventPtr
= encodingName
;
3293 return XML_ERROR_INCORRECT_ENCODING
;
3295 encoding
= newEncoding
;
3297 else if (encodingName
) {
3298 enum XML_Error result
;
3299 if (!storedEncName
) {
3300 storedEncName
= poolStoreString(
3301 &temp2Pool
, encoding
, encodingName
,
3302 encodingName
+ XmlNameLength(encoding
, encodingName
));
3304 return XML_ERROR_NO_MEMORY
;
3306 result
= handleUnknownEncoding(parser
, storedEncName
);
3307 poolClear(&temp2Pool
);
3308 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3309 eventPtr
= encodingName
;
3314 if (storedEncName
|| storedversion
)
3315 poolClear(&temp2Pool
);
3317 return XML_ERROR_NONE
;
3320 static enum XML_Error
3321 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3323 if (unknownEncodingHandler
) {
3326 for (i
= 0; i
< 256; i
++)
3328 info
.convert
= NULL
;
3330 info
.release
= NULL
;
3331 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3334 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3335 if (!unknownEncodingMem
) {
3337 info
.release(info
.data
);
3338 return XML_ERROR_NO_MEMORY
;
3341 ? XmlInitUnknownEncodingNS
3342 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3347 unknownEncodingData
= info
.data
;
3348 unknownEncodingRelease
= info
.release
;
3350 return XML_ERROR_NONE
;
3353 if (info
.release
!= NULL
)
3354 info
.release(info
.data
);
3356 return XML_ERROR_UNKNOWN_ENCODING
;
3359 static enum XML_Error PTRCALL
3360 prologInitProcessor(XML_Parser parser
,
3363 const char **nextPtr
)
3365 enum XML_Error result
= initializeEncoding(parser
);
3366 if (result
!= XML_ERROR_NONE
)
3368 processor
= prologProcessor
;
3369 return prologProcessor(parser
, s
, end
, nextPtr
);
3374 static enum XML_Error PTRCALL
3375 externalParEntInitProcessor(XML_Parser parser
,
3378 const char **nextPtr
)
3380 enum XML_Error result
= initializeEncoding(parser
);
3381 if (result
!= XML_ERROR_NONE
)
3384 /* we know now that XML_Parse(Buffer) has been called,
3385 so we consider the external parameter entity read */
3386 _dtd
->paramEntityRead
= XML_TRUE
;
3388 if (prologState
.inEntityValue
) {
3389 processor
= entityValueInitProcessor
;
3390 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3393 processor
= externalParEntProcessor
;
3394 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3398 static enum XML_Error PTRCALL
3399 entityValueInitProcessor(XML_Parser parser
,
3402 const char **nextPtr
)
3405 const char *start
= s
;
3406 const char *next
= start
;
3410 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3413 if (!finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3415 return XML_ERROR_NONE
;
3418 case XML_TOK_INVALID
:
3419 return XML_ERROR_INVALID_TOKEN
;
3420 case XML_TOK_PARTIAL
:
3421 return XML_ERROR_UNCLOSED_TOKEN
;
3422 case XML_TOK_PARTIAL_CHAR
:
3423 return XML_ERROR_PARTIAL_CHAR
;
3424 case XML_TOK_NONE
: /* start == end */
3428 /* found end of entity value - can store it now */
3429 return storeEntityValue(parser
, encoding
, s
, end
);
3431 else if (tok
== XML_TOK_XML_DECL
) {
3432 enum XML_Error result
;
3433 result
= processXmlDecl(parser
, 0, start
, next
);
3434 if (result
!= XML_ERROR_NONE
)
3439 return XML_ERROR_NONE
;
3441 return XML_ERROR_ABORTED
;
3445 /* stop scanning for text declaration - we found one */
3446 processor
= entityValueProcessor
;
3447 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3449 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3450 return XML_TOK_NONE on the next call, which would then cause the
3451 function to exit with *nextPtr set to s - that is what we want for other
3452 tokens, but not for the BOM - we would rather like to skip it;
3453 then, when this routine is entered the next time, XmlPrologTok will
3454 return XML_TOK_INVALID, since the BOM is still in the buffer
3456 else if (tok
== XML_TOK_BOM
&& next
== end
&& !finalBuffer
) {
3458 return XML_ERROR_NONE
;
3465 static enum XML_Error PTRCALL
3466 externalParEntProcessor(XML_Parser parser
,
3469 const char **nextPtr
)
3471 const char *next
= s
;
3474 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3476 if (!finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3478 return XML_ERROR_NONE
;
3481 case XML_TOK_INVALID
:
3482 return XML_ERROR_INVALID_TOKEN
;
3483 case XML_TOK_PARTIAL
:
3484 return XML_ERROR_UNCLOSED_TOKEN
;
3485 case XML_TOK_PARTIAL_CHAR
:
3486 return XML_ERROR_PARTIAL_CHAR
;
3487 case XML_TOK_NONE
: /* start == end */
3492 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3493 However, when parsing an external subset, doProlog will not accept a BOM
3494 as valid, and report a syntax error, so we have to skip the BOM
3496 else if (tok
== XML_TOK_BOM
) {
3498 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3501 processor
= prologProcessor
;
3502 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3503 nextPtr
, (XML_Bool
)!finalBuffer
);
3506 static enum XML_Error PTRCALL
3507 entityValueProcessor(XML_Parser parser
,
3510 const char **nextPtr
)
3512 const char *start
= s
;
3513 const char *next
= s
;
3514 const ENCODING
*enc
= encoding
;
3518 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3520 if (!finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3522 return XML_ERROR_NONE
;
3525 case XML_TOK_INVALID
:
3526 return XML_ERROR_INVALID_TOKEN
;
3527 case XML_TOK_PARTIAL
:
3528 return XML_ERROR_UNCLOSED_TOKEN
;
3529 case XML_TOK_PARTIAL_CHAR
:
3530 return XML_ERROR_PARTIAL_CHAR
;
3531 case XML_TOK_NONE
: /* start == end */
3535 /* found end of entity value - can store it now */
3536 return storeEntityValue(parser
, enc
, s
, end
);
3542 #endif /* XML_DTD */
3544 static enum XML_Error PTRCALL
3545 prologProcessor(XML_Parser parser
,
3548 const char **nextPtr
)
3550 const char *next
= s
;
3551 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3552 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3553 nextPtr
, (XML_Bool
)!finalBuffer
);
3556 static enum XML_Error
3557 doProlog(XML_Parser parser
,
3558 const ENCODING
*enc
,
3563 const char **nextPtr
,
3567 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3568 #endif /* XML_DTD */
3569 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3570 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3571 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3572 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3573 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3574 static const XML_Char atypeENTITIES
[] =
3575 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3576 static const XML_Char atypeNMTOKEN
[] = {
3577 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3578 static const XML_Char atypeNMTOKENS
[] = {
3579 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3580 static const XML_Char notationPrefix
[] = {
3581 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3582 static const XML_Char enumValueSep
[] = { '|', '\0' };
3583 static const XML_Char enumValueStart
[] = { '(', '\0' };
3585 /* save one level of indirection */
3586 DTD
* const dtd
= _dtd
;
3588 const char **eventPP
;
3589 const char **eventEndPP
;
3590 enum XML_Content_Quant quant
;
3592 if (enc
== encoding
) {
3593 eventPP
= &eventPtr
;
3594 eventEndPP
= &eventEndPtr
;
3597 eventPP
= &(openInternalEntities
->internalEventPtr
);
3598 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3603 XML_Bool handleDefault
= XML_TRUE
;
3607 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3609 return XML_ERROR_NONE
;
3612 case XML_TOK_INVALID
:
3614 return XML_ERROR_INVALID_TOKEN
;
3615 case XML_TOK_PARTIAL
:
3616 return XML_ERROR_UNCLOSED_TOKEN
;
3617 case XML_TOK_PARTIAL_CHAR
:
3618 return XML_ERROR_PARTIAL_CHAR
;
3621 /* for internal PE NOT referenced between declarations */
3622 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3624 return XML_ERROR_NONE
;
3626 /* WFC: PE Between Declarations - must check that PE contains
3627 complete markup, not only for external PEs, but also for
3628 internal PEs if the reference occurs between declarations.
3630 if (isParamEntity
|| enc
!= encoding
) {
3631 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3633 return XML_ERROR_INCOMPLETE_PE
;
3635 return XML_ERROR_NONE
;
3637 #endif /* XML_DTD */
3638 return XML_ERROR_NO_ELEMENTS
;
3645 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3647 case XML_ROLE_XML_DECL
:
3649 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3650 if (result
!= XML_ERROR_NONE
)
3653 handleDefault
= XML_FALSE
;
3656 case XML_ROLE_DOCTYPE_NAME
:
3657 if (startDoctypeDeclHandler
) {
3658 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3660 return XML_ERROR_NO_MEMORY
;
3661 poolFinish(&tempPool
);
3662 doctypePubid
= NULL
;
3663 handleDefault
= XML_FALSE
;
3665 doctypeSysid
= NULL
; /* always initialize to NULL */
3667 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3668 if (startDoctypeDeclHandler
) {
3669 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3672 poolClear(&tempPool
);
3673 handleDefault
= XML_FALSE
;
3677 case XML_ROLE_TEXT_DECL
:
3679 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3680 if (result
!= XML_ERROR_NONE
)
3683 handleDefault
= XML_FALSE
;
3686 #endif /* XML_DTD */
3687 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3689 useForeignDTD
= XML_FALSE
;
3690 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3694 return XML_ERROR_NO_MEMORY
;
3695 #endif /* XML_DTD */
3696 dtd
->hasParamEntityRefs
= XML_TRUE
;
3697 if (startDoctypeDeclHandler
) {
3698 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3699 return XML_ERROR_PUBLICID
;
3700 doctypePubid
= poolStoreString(&tempPool
, enc
,
3701 s
+ enc
->minBytesPerChar
,
3702 next
- enc
->minBytesPerChar
);
3704 return XML_ERROR_NO_MEMORY
;
3705 normalizePublicId((XML_Char
*)doctypePubid
);
3706 poolFinish(&tempPool
);
3707 handleDefault
= XML_FALSE
;
3708 goto alreadyChecked
;
3711 case XML_ROLE_ENTITY_PUBLIC_ID
:
3712 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3713 return XML_ERROR_PUBLICID
;
3715 if (dtd
->keepProcessing
&& declEntity
) {
3716 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3718 s
+ enc
->minBytesPerChar
,
3719 next
- enc
->minBytesPerChar
);
3721 return XML_ERROR_NO_MEMORY
;
3722 normalizePublicId(tem
);
3723 declEntity
->publicId
= tem
;
3724 poolFinish(&dtd
->pool
);
3725 if (entityDeclHandler
)
3726 handleDefault
= XML_FALSE
;
3729 case XML_ROLE_DOCTYPE_CLOSE
:
3731 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3732 doctypeSysid
, doctypePubid
, 0);
3733 poolClear(&tempPool
);
3734 handleDefault
= XML_FALSE
;
3736 /* doctypeSysid will be non-NULL in the case of a previous
3737 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3738 was not set, indicating an external subset
3741 if (doctypeSysid
|| useForeignDTD
) {
3742 dtd
->hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3743 if (paramEntityParsing
&& externalEntityRefHandler
) {
3744 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3748 return XML_ERROR_NO_MEMORY
;
3750 entity
->base
= curBase
;
3751 dtd
->paramEntityRead
= XML_FALSE
;
3752 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3757 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3758 if (dtd
->paramEntityRead
&&
3760 notStandaloneHandler
&&
3761 !notStandaloneHandler(handlerArg
))
3762 return XML_ERROR_NOT_STANDALONE
;
3763 /* end of DTD - no need to update dtd->keepProcessing */
3765 useForeignDTD
= XML_FALSE
;
3767 #endif /* XML_DTD */
3768 if (endDoctypeDeclHandler
) {
3769 endDoctypeDeclHandler(handlerArg
);
3770 handleDefault
= XML_FALSE
;
3773 case XML_ROLE_INSTANCE_START
:
3775 /* if there is no DOCTYPE declaration then now is the
3776 last chance to read the foreign DTD
3778 if (useForeignDTD
) {
3779 dtd
->hasParamEntityRefs
= XML_TRUE
;
3780 if (paramEntityParsing
&& externalEntityRefHandler
) {
3781 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3785 return XML_ERROR_NO_MEMORY
;
3786 entity
->base
= curBase
;
3787 dtd
->paramEntityRead
= XML_FALSE
;
3788 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3793 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3794 if (dtd
->paramEntityRead
&&
3796 notStandaloneHandler
&&
3797 !notStandaloneHandler(handlerArg
))
3798 return XML_ERROR_NOT_STANDALONE
;
3799 /* end of DTD - no need to update dtd->keepProcessing */
3802 #endif /* XML_DTD */
3803 processor
= contentProcessor
;
3804 return contentProcessor(parser
, s
, end
, nextPtr
);
3805 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3806 declElementType
= getElementType(parser
, enc
, s
, next
);
3807 if (!declElementType
)
3808 return XML_ERROR_NO_MEMORY
;
3809 goto checkAttListDeclHandler
;
3810 case XML_ROLE_ATTRIBUTE_NAME
:
3811 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3812 if (!declAttributeId
)
3813 return XML_ERROR_NO_MEMORY
;
3814 declAttributeIsCdata
= XML_FALSE
;
3815 declAttributeType
= NULL
;
3816 declAttributeIsId
= XML_FALSE
;
3817 goto checkAttListDeclHandler
;
3818 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3819 declAttributeIsCdata
= XML_TRUE
;
3820 declAttributeType
= atypeCDATA
;
3821 goto checkAttListDeclHandler
;
3822 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3823 declAttributeIsId
= XML_TRUE
;
3824 declAttributeType
= atypeID
;
3825 goto checkAttListDeclHandler
;
3826 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3827 declAttributeType
= atypeIDREF
;
3828 goto checkAttListDeclHandler
;
3829 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3830 declAttributeType
= atypeIDREFS
;
3831 goto checkAttListDeclHandler
;
3832 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3833 declAttributeType
= atypeENTITY
;
3834 goto checkAttListDeclHandler
;
3835 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3836 declAttributeType
= atypeENTITIES
;
3837 goto checkAttListDeclHandler
;
3838 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3839 declAttributeType
= atypeNMTOKEN
;
3840 goto checkAttListDeclHandler
;
3841 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3842 declAttributeType
= atypeNMTOKENS
;
3843 checkAttListDeclHandler
:
3844 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3845 handleDefault
= XML_FALSE
;
3847 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3848 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3849 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3850 const XML_Char
*prefix
;
3851 if (declAttributeType
) {
3852 prefix
= enumValueSep
;
3855 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3859 if (!poolAppendString(&tempPool
, prefix
))
3860 return XML_ERROR_NO_MEMORY
;
3861 if (!poolAppend(&tempPool
, enc
, s
, next
))
3862 return XML_ERROR_NO_MEMORY
;
3863 declAttributeType
= tempPool
.start
;
3864 handleDefault
= XML_FALSE
;
3867 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3868 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3869 if (dtd
->keepProcessing
) {
3870 if (!defineAttribute(declElementType
, declAttributeId
,
3871 declAttributeIsCdata
, declAttributeIsId
,
3873 return XML_ERROR_NO_MEMORY
;
3874 if (attlistDeclHandler
&& declAttributeType
) {
3875 if (*declAttributeType
== XML_T('(')
3876 || (*declAttributeType
== XML_T('N')
3877 && declAttributeType
[1] == XML_T('O'))) {
3878 /* Enumerated or Notation type */
3879 if (!poolAppendChar(&tempPool
, XML_T(')'))
3880 || !poolAppendChar(&tempPool
, XML_T('\0')))
3881 return XML_ERROR_NO_MEMORY
;
3882 declAttributeType
= tempPool
.start
;
3883 poolFinish(&tempPool
);
3886 attlistDeclHandler(handlerArg
, declElementType
->name
,
3887 declAttributeId
->name
, declAttributeType
,
3888 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3889 poolClear(&tempPool
);
3890 handleDefault
= XML_FALSE
;
3894 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3895 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3896 if (dtd
->keepProcessing
) {
3897 const XML_Char
*attVal
;
3898 enum XML_Error result
=
3899 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3900 s
+ enc
->minBytesPerChar
,
3901 next
- enc
->minBytesPerChar
,
3905 attVal
= poolStart(&dtd
->pool
);
3906 poolFinish(&dtd
->pool
);
3907 /* ID attributes aren't allowed to have a default */
3908 if (!defineAttribute(declElementType
, declAttributeId
,
3909 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3910 return XML_ERROR_NO_MEMORY
;
3911 if (attlistDeclHandler
&& declAttributeType
) {
3912 if (*declAttributeType
== XML_T('(')
3913 || (*declAttributeType
== XML_T('N')
3914 && declAttributeType
[1] == XML_T('O'))) {
3915 /* Enumerated or Notation type */
3916 if (!poolAppendChar(&tempPool
, XML_T(')'))
3917 || !poolAppendChar(&tempPool
, XML_T('\0')))
3918 return XML_ERROR_NO_MEMORY
;
3919 declAttributeType
= tempPool
.start
;
3920 poolFinish(&tempPool
);
3923 attlistDeclHandler(handlerArg
, declElementType
->name
,
3924 declAttributeId
->name
, declAttributeType
,
3926 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3927 poolClear(&tempPool
);
3928 handleDefault
= XML_FALSE
;
3932 case XML_ROLE_ENTITY_VALUE
:
3933 if (dtd
->keepProcessing
) {
3934 enum XML_Error result
= storeEntityValue(parser
, enc
,
3935 s
+ enc
->minBytesPerChar
,
3936 next
- enc
->minBytesPerChar
);
3938 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
3939 declEntity
->textLen
= poolLength(&dtd
->entityValuePool
);
3940 poolFinish(&dtd
->entityValuePool
);
3941 if (entityDeclHandler
) {
3943 entityDeclHandler(handlerArg
,
3945 declEntity
->is_param
,
3946 declEntity
->textPtr
,
3947 declEntity
->textLen
,
3949 handleDefault
= XML_FALSE
;
3953 poolDiscard(&dtd
->entityValuePool
);
3954 if (result
!= XML_ERROR_NONE
)
3958 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3960 useForeignDTD
= XML_FALSE
;
3961 #endif /* XML_DTD */
3962 dtd
->hasParamEntityRefs
= XML_TRUE
;
3963 if (startDoctypeDeclHandler
) {
3964 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3965 s
+ enc
->minBytesPerChar
,
3966 next
- enc
->minBytesPerChar
);
3967 if (doctypeSysid
== NULL
)
3968 return XML_ERROR_NO_MEMORY
;
3969 poolFinish(&tempPool
);
3970 handleDefault
= XML_FALSE
;
3974 /* use externalSubsetName to make doctypeSysid non-NULL
3975 for the case where no startDoctypeDeclHandler is set */
3976 doctypeSysid
= externalSubsetName
;
3977 #endif /* XML_DTD */
3978 if (!dtd
->standalone
3980 && !paramEntityParsing
3981 #endif /* XML_DTD */
3982 && notStandaloneHandler
3983 && !notStandaloneHandler(handlerArg
))
3984 return XML_ERROR_NOT_STANDALONE
;
3989 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3993 return XML_ERROR_NO_MEMORY
;
3994 declEntity
->publicId
= NULL
;
3997 #endif /* XML_DTD */
3998 case XML_ROLE_ENTITY_SYSTEM_ID
:
3999 if (dtd
->keepProcessing
&& declEntity
) {
4000 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4001 s
+ enc
->minBytesPerChar
,
4002 next
- enc
->minBytesPerChar
);
4003 if (!declEntity
->systemId
)
4004 return XML_ERROR_NO_MEMORY
;
4005 declEntity
->base
= curBase
;
4006 poolFinish(&dtd
->pool
);
4007 if (entityDeclHandler
)
4008 handleDefault
= XML_FALSE
;
4011 case XML_ROLE_ENTITY_COMPLETE
:
4012 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4014 entityDeclHandler(handlerArg
,
4016 declEntity
->is_param
,
4019 declEntity
->systemId
,
4020 declEntity
->publicId
,
4022 handleDefault
= XML_FALSE
;
4025 case XML_ROLE_ENTITY_NOTATION_NAME
:
4026 if (dtd
->keepProcessing
&& declEntity
) {
4027 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4028 if (!declEntity
->notation
)
4029 return XML_ERROR_NO_MEMORY
;
4030 poolFinish(&dtd
->pool
);
4031 if (unparsedEntityDeclHandler
) {
4033 unparsedEntityDeclHandler(handlerArg
,
4036 declEntity
->systemId
,
4037 declEntity
->publicId
,
4038 declEntity
->notation
);
4039 handleDefault
= XML_FALSE
;
4041 else if (entityDeclHandler
) {
4043 entityDeclHandler(handlerArg
,
4047 declEntity
->systemId
,
4048 declEntity
->publicId
,
4049 declEntity
->notation
);
4050 handleDefault
= XML_FALSE
;
4054 case XML_ROLE_GENERAL_ENTITY_NAME
:
4056 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4060 if (dtd
->keepProcessing
) {
4061 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4063 return XML_ERROR_NO_MEMORY
;
4064 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4067 return XML_ERROR_NO_MEMORY
;
4068 if (declEntity
->name
!= name
) {
4069 poolDiscard(&dtd
->pool
);
4073 poolFinish(&dtd
->pool
);
4074 declEntity
->publicId
= NULL
;
4075 declEntity
->is_param
= XML_FALSE
;
4076 /* if we have a parent parser or are reading an internal parameter
4077 entity, then the entity declaration is not considered "internal"
4079 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4080 if (entityDeclHandler
)
4081 handleDefault
= XML_FALSE
;
4085 poolDiscard(&dtd
->pool
);
4090 case XML_ROLE_PARAM_ENTITY_NAME
:
4092 if (dtd
->keepProcessing
) {
4093 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4095 return XML_ERROR_NO_MEMORY
;
4096 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4097 name
, sizeof(ENTITY
));
4099 return XML_ERROR_NO_MEMORY
;
4100 if (declEntity
->name
!= name
) {
4101 poolDiscard(&dtd
->pool
);
4105 poolFinish(&dtd
->pool
);
4106 declEntity
->publicId
= NULL
;
4107 declEntity
->is_param
= XML_TRUE
;
4108 /* if we have a parent parser or are reading an internal parameter
4109 entity, then the entity declaration is not considered "internal"
4111 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4112 if (entityDeclHandler
)
4113 handleDefault
= XML_FALSE
;
4117 poolDiscard(&dtd
->pool
);
4120 #else /* not XML_DTD */
4122 #endif /* XML_DTD */
4124 case XML_ROLE_NOTATION_NAME
:
4125 declNotationPublicId
= NULL
;
4126 declNotationName
= NULL
;
4127 if (notationDeclHandler
) {
4128 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4129 if (!declNotationName
)
4130 return XML_ERROR_NO_MEMORY
;
4131 poolFinish(&tempPool
);
4132 handleDefault
= XML_FALSE
;
4135 case XML_ROLE_NOTATION_PUBLIC_ID
:
4136 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4137 return XML_ERROR_PUBLICID
;
4138 if (declNotationName
) { /* means notationDeclHandler != NULL */
4139 XML_Char
*tem
= poolStoreString(&tempPool
,
4141 s
+ enc
->minBytesPerChar
,
4142 next
- enc
->minBytesPerChar
);
4144 return XML_ERROR_NO_MEMORY
;
4145 normalizePublicId(tem
);
4146 declNotationPublicId
= tem
;
4147 poolFinish(&tempPool
);
4148 handleDefault
= XML_FALSE
;
4151 case XML_ROLE_NOTATION_SYSTEM_ID
:
4152 if (declNotationName
&& notationDeclHandler
) {
4153 const XML_Char
*systemId
4154 = poolStoreString(&tempPool
, enc
,
4155 s
+ enc
->minBytesPerChar
,
4156 next
- enc
->minBytesPerChar
);
4158 return XML_ERROR_NO_MEMORY
;
4160 notationDeclHandler(handlerArg
,
4164 declNotationPublicId
);
4165 handleDefault
= XML_FALSE
;
4167 poolClear(&tempPool
);
4169 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4170 if (declNotationPublicId
&& notationDeclHandler
) {
4172 notationDeclHandler(handlerArg
,
4176 declNotationPublicId
);
4177 handleDefault
= XML_FALSE
;
4179 poolClear(&tempPool
);
4181 case XML_ROLE_ERROR
:
4183 case XML_TOK_PARAM_ENTITY_REF
:
4184 /* PE references in internal subset are
4185 not allowed within declarations. */
4186 return XML_ERROR_PARAM_ENTITY_REF
;
4187 case XML_TOK_XML_DECL
:
4188 return XML_ERROR_MISPLACED_XML_PI
;
4190 return XML_ERROR_SYNTAX
;
4193 case XML_ROLE_IGNORE_SECT
:
4195 enum XML_Error result
;
4197 reportDefault(parser
, enc
, s
, next
);
4198 handleDefault
= XML_FALSE
;
4199 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4200 if (result
!= XML_ERROR_NONE
)
4203 processor
= ignoreSectionProcessor
;
4208 #endif /* XML_DTD */
4209 case XML_ROLE_GROUP_OPEN
:
4210 if (prologState
.level
>= groupSize
) {
4212 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4214 return XML_ERROR_NO_MEMORY
;
4215 groupConnector
= temp
;
4216 if (dtd
->scaffIndex
) {
4217 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4218 groupSize
* sizeof(int));
4220 return XML_ERROR_NO_MEMORY
;
4221 dtd
->scaffIndex
= temp
;
4225 groupConnector
= (char *)MALLOC(groupSize
= 32);
4226 if (!groupConnector
)
4227 return XML_ERROR_NO_MEMORY
;
4230 groupConnector
[prologState
.level
] = 0;
4231 if (dtd
->in_eldecl
) {
4232 int myindex
= nextScaffoldPart(parser
);
4234 return XML_ERROR_NO_MEMORY
;
4235 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4237 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4238 if (elementDeclHandler
)
4239 handleDefault
= XML_FALSE
;
4242 case XML_ROLE_GROUP_SEQUENCE
:
4243 if (groupConnector
[prologState
.level
] == '|')
4244 return XML_ERROR_SYNTAX
;
4245 groupConnector
[prologState
.level
] = ',';
4246 if (dtd
->in_eldecl
&& elementDeclHandler
)
4247 handleDefault
= XML_FALSE
;
4249 case XML_ROLE_GROUP_CHOICE
:
4250 if (groupConnector
[prologState
.level
] == ',')
4251 return XML_ERROR_SYNTAX
;
4253 && !groupConnector
[prologState
.level
]
4254 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4257 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4259 if (elementDeclHandler
)
4260 handleDefault
= XML_FALSE
;
4262 groupConnector
[prologState
.level
] = '|';
4264 case XML_ROLE_PARAM_ENTITY_REF
:
4266 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4267 dtd
->hasParamEntityRefs
= XML_TRUE
;
4268 if (!paramEntityParsing
)
4269 dtd
->keepProcessing
= dtd
->standalone
;
4271 const XML_Char
*name
;
4273 name
= poolStoreString(&dtd
->pool
, enc
,
4274 s
+ enc
->minBytesPerChar
,
4275 next
- enc
->minBytesPerChar
);
4277 return XML_ERROR_NO_MEMORY
;
4278 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4279 poolDiscard(&dtd
->pool
);
4280 /* first, determine if a check for an existing declaration is needed;
4281 if yes, check that the entity exists, and that it is internal,
4282 otherwise call the skipped entity handler
4284 if (prologState
.documentEntity
&&
4286 ? !openInternalEntities
4287 : !dtd
->hasParamEntityRefs
)) {
4289 return XML_ERROR_UNDEFINED_ENTITY
;
4290 else if (!entity
->is_internal
)
4291 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4294 dtd
->keepProcessing
= dtd
->standalone
;
4295 /* cannot report skipped entities in declarations */
4296 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4297 skippedEntityHandler(handlerArg
, name
, 1);
4298 handleDefault
= XML_FALSE
;
4303 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4304 if (entity
->textPtr
) {
4305 enum XML_Error result
;
4306 XML_Bool betweenDecl
=
4307 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4308 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4309 if (result
!= XML_ERROR_NONE
)
4311 handleDefault
= XML_FALSE
;
4314 if (externalEntityRefHandler
) {
4315 dtd
->paramEntityRead
= XML_FALSE
;
4316 entity
->open
= XML_TRUE
;
4317 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4321 entity
->publicId
)) {
4322 entity
->open
= XML_FALSE
;
4323 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4325 entity
->open
= XML_FALSE
;
4326 handleDefault
= XML_FALSE
;
4327 if (!dtd
->paramEntityRead
) {
4328 dtd
->keepProcessing
= dtd
->standalone
;
4333 dtd
->keepProcessing
= dtd
->standalone
;
4337 #endif /* XML_DTD */
4338 if (!dtd
->standalone
&&
4339 notStandaloneHandler
&&
4340 !notStandaloneHandler(handlerArg
))
4341 return XML_ERROR_NOT_STANDALONE
;
4344 /* Element declaration stuff */
4346 case XML_ROLE_ELEMENT_NAME
:
4347 if (elementDeclHandler
) {
4348 declElementType
= getElementType(parser
, enc
, s
, next
);
4349 if (!declElementType
)
4350 return XML_ERROR_NO_MEMORY
;
4351 dtd
->scaffLevel
= 0;
4352 dtd
->scaffCount
= 0;
4353 dtd
->in_eldecl
= XML_TRUE
;
4354 handleDefault
= XML_FALSE
;
4358 case XML_ROLE_CONTENT_ANY
:
4359 case XML_ROLE_CONTENT_EMPTY
:
4360 if (dtd
->in_eldecl
) {
4361 if (elementDeclHandler
) {
4362 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4364 return XML_ERROR_NO_MEMORY
;
4365 content
->quant
= XML_CQUANT_NONE
;
4366 content
->name
= NULL
;
4367 content
->numchildren
= 0;
4368 content
->children
= NULL
;
4369 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4373 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4374 handleDefault
= XML_FALSE
;
4376 dtd
->in_eldecl
= XML_FALSE
;
4380 case XML_ROLE_CONTENT_PCDATA
:
4381 if (dtd
->in_eldecl
) {
4382 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4384 if (elementDeclHandler
)
4385 handleDefault
= XML_FALSE
;
4389 case XML_ROLE_CONTENT_ELEMENT
:
4390 quant
= XML_CQUANT_NONE
;
4391 goto elementContent
;
4392 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4393 quant
= XML_CQUANT_OPT
;
4394 goto elementContent
;
4395 case XML_ROLE_CONTENT_ELEMENT_REP
:
4396 quant
= XML_CQUANT_REP
;
4397 goto elementContent
;
4398 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4399 quant
= XML_CQUANT_PLUS
;
4401 if (dtd
->in_eldecl
) {
4403 const XML_Char
*name
;
4405 const char *nxt
= (quant
== XML_CQUANT_NONE
4407 : next
- enc
->minBytesPerChar
);
4408 int myindex
= nextScaffoldPart(parser
);
4410 return XML_ERROR_NO_MEMORY
;
4411 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4412 dtd
->scaffold
[myindex
].quant
= quant
;
4413 el
= getElementType(parser
, enc
, s
, nxt
);
4415 return XML_ERROR_NO_MEMORY
;
4417 dtd
->scaffold
[myindex
].name
= name
;
4419 for (; name
[nameLen
++]; );
4420 dtd
->contentStringLen
+= nameLen
;
4421 if (elementDeclHandler
)
4422 handleDefault
= XML_FALSE
;
4426 case XML_ROLE_GROUP_CLOSE
:
4427 quant
= XML_CQUANT_NONE
;
4429 case XML_ROLE_GROUP_CLOSE_OPT
:
4430 quant
= XML_CQUANT_OPT
;
4432 case XML_ROLE_GROUP_CLOSE_REP
:
4433 quant
= XML_CQUANT_REP
;
4435 case XML_ROLE_GROUP_CLOSE_PLUS
:
4436 quant
= XML_CQUANT_PLUS
;
4438 if (dtd
->in_eldecl
) {
4439 if (elementDeclHandler
)
4440 handleDefault
= XML_FALSE
;
4442 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4443 if (dtd
->scaffLevel
== 0) {
4444 if (!handleDefault
) {
4445 XML_Content
*model
= build_model(parser
);
4447 return XML_ERROR_NO_MEMORY
;
4449 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4451 dtd
->in_eldecl
= XML_FALSE
;
4452 dtd
->contentStringLen
= 0;
4456 /* End element declaration stuff */
4459 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4460 return XML_ERROR_NO_MEMORY
;
4461 handleDefault
= XML_FALSE
;
4463 case XML_ROLE_COMMENT
:
4464 if (!reportComment(parser
, enc
, s
, next
))
4465 return XML_ERROR_NO_MEMORY
;
4466 handleDefault
= XML_FALSE
;
4471 handleDefault
= XML_FALSE
;
4475 case XML_ROLE_DOCTYPE_NONE
:
4476 if (startDoctypeDeclHandler
)
4477 handleDefault
= XML_FALSE
;
4479 case XML_ROLE_ENTITY_NONE
:
4480 if (dtd
->keepProcessing
&& entityDeclHandler
)
4481 handleDefault
= XML_FALSE
;
4483 case XML_ROLE_NOTATION_NONE
:
4484 if (notationDeclHandler
)
4485 handleDefault
= XML_FALSE
;
4487 case XML_ROLE_ATTLIST_NONE
:
4488 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4489 handleDefault
= XML_FALSE
;
4491 case XML_ROLE_ELEMENT_NONE
:
4492 if (elementDeclHandler
)
4493 handleDefault
= XML_FALSE
;
4495 } /* end of big switch */
4497 if (handleDefault
&& defaultHandler
)
4498 reportDefault(parser
, enc
, s
, next
);
4503 return XML_ERROR_NONE
;
4505 return XML_ERROR_ABORTED
;
4508 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4514 static enum XML_Error PTRCALL
4515 epilogProcessor(XML_Parser parser
,
4518 const char **nextPtr
)
4520 processor
= epilogProcessor
;
4523 const char *next
= NULL
;
4524 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4527 /* report partial linebreak - it might be the last token */
4528 case -XML_TOK_PROLOG_S
:
4529 if (defaultHandler
) {
4530 reportDefault(parser
, encoding
, s
, next
);
4531 if (parsing
== XML_FINISHED
)
4532 return XML_ERROR_ABORTED
;
4535 return XML_ERROR_NONE
;
4538 return XML_ERROR_NONE
;
4539 case XML_TOK_PROLOG_S
:
4541 reportDefault(parser
, encoding
, s
, next
);
4544 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4545 return XML_ERROR_NO_MEMORY
;
4547 case XML_TOK_COMMENT
:
4548 if (!reportComment(parser
, encoding
, s
, next
))
4549 return XML_ERROR_NO_MEMORY
;
4551 case XML_TOK_INVALID
:
4553 return XML_ERROR_INVALID_TOKEN
;
4554 case XML_TOK_PARTIAL
:
4557 return XML_ERROR_NONE
;
4559 return XML_ERROR_UNCLOSED_TOKEN
;
4560 case XML_TOK_PARTIAL_CHAR
:
4563 return XML_ERROR_NONE
;
4565 return XML_ERROR_PARTIAL_CHAR
;
4567 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4569 eventPtr
= s
= next
;
4573 return XML_ERROR_NONE
;
4575 return XML_ERROR_ABORTED
;
4581 static enum XML_Error
4582 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4583 XML_Bool betweenDecl
)
4585 const char *textStart
, *textEnd
;
4587 enum XML_Error result
;
4588 OPEN_INTERNAL_ENTITY
*openEntity
;
4590 if (freeInternalEntities
) {
4591 openEntity
= freeInternalEntities
;
4592 freeInternalEntities
= openEntity
->next
;
4595 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4597 return XML_ERROR_NO_MEMORY
;
4599 entity
->open
= XML_TRUE
;
4600 entity
->processed
= 0;
4601 openEntity
->next
= openInternalEntities
;
4602 openInternalEntities
= openEntity
;
4603 openEntity
->entity
= entity
;
4604 openEntity
->startTagLevel
= tagLevel
;
4605 openEntity
->betweenDecl
= betweenDecl
;
4606 openEntity
->internalEventPtr
= NULL
;
4607 openEntity
->internalEventEndPtr
= NULL
;
4608 textStart
= (char *)entity
->textPtr
;
4609 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4612 if (entity
->is_param
) {
4613 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4614 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4615 next
, &next
, XML_FALSE
);
4618 #endif /* XML_DTD */
4619 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4620 textEnd
, &next
, XML_FALSE
);
4622 if (result
== XML_ERROR_NONE
) {
4623 if (textEnd
!= next
&& parsing
== XML_SUSPENDED
) {
4624 entity
->processed
= next
- textStart
;
4625 processor
= internalEntityProcessor
;
4628 entity
->open
= XML_FALSE
;
4629 openInternalEntities
= openEntity
->next
;
4630 /* put openEntity back in list of free instances */
4631 openEntity
->next
= freeInternalEntities
;
4632 freeInternalEntities
= openEntity
;
4638 static enum XML_Error PTRCALL
4639 internalEntityProcessor(XML_Parser parser
,
4642 const char **nextPtr
)
4645 const char *textStart
, *textEnd
;
4647 enum XML_Error result
;
4648 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4650 return XML_ERROR_UNEXPECTED_STATE
;
4652 entity
= openEntity
->entity
;
4653 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4654 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4657 if (entity
->is_param
) {
4658 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4659 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4660 next
, &next
, XML_FALSE
);
4663 #endif /* XML_DTD */
4664 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4665 textStart
, textEnd
, &next
, XML_FALSE
);
4667 if (result
!= XML_ERROR_NONE
)
4669 else if (textEnd
!= next
&& parsing
== XML_SUSPENDED
) {
4670 entity
->processed
= next
- (char *)entity
->textPtr
;
4674 entity
->open
= XML_FALSE
;
4675 openInternalEntities
= openEntity
->next
;
4676 /* put openEntity back in list of free instances */
4677 openEntity
->next
= freeInternalEntities
;
4678 freeInternalEntities
= openEntity
;
4682 if (entity
->is_param
) {
4684 processor
= prologProcessor
;
4685 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4686 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4687 (XML_Bool
)!finalBuffer
);
4690 #endif /* XML_DTD */
4692 processor
= contentProcessor
;
4693 /* see externalEntityContentProcessor vs contentProcessor */
4694 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4695 nextPtr
, (XML_Bool
)!finalBuffer
);
4699 static enum XML_Error PTRCALL
4700 errorProcessor(XML_Parser parser
,
4703 const char **nextPtr
)
4708 static enum XML_Error
4709 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4710 const char *ptr
, const char *end
,
4713 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4717 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4719 if (!poolAppendChar(pool
, XML_T('\0')))
4720 return XML_ERROR_NO_MEMORY
;
4721 return XML_ERROR_NONE
;
4724 static enum XML_Error
4725 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4726 const char *ptr
, const char *end
,
4729 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4732 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4735 return XML_ERROR_NONE
;
4736 case XML_TOK_INVALID
:
4737 if (enc
== encoding
)
4739 return XML_ERROR_INVALID_TOKEN
;
4740 case XML_TOK_PARTIAL
:
4741 if (enc
== encoding
)
4743 return XML_ERROR_INVALID_TOKEN
;
4744 case XML_TOK_CHAR_REF
:
4746 XML_Char buf
[XML_ENCODE_MAX
];
4748 int n
= XmlCharRefNumber(enc
, ptr
);
4750 if (enc
== encoding
)
4752 return XML_ERROR_BAD_CHAR_REF
;
4755 && n
== 0x20 /* space */
4756 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4758 n
= XmlEncode(n
, (ICHAR
*)buf
);
4760 if (enc
== encoding
)
4762 return XML_ERROR_BAD_CHAR_REF
;
4764 for (i
= 0; i
< n
; i
++) {
4765 if (!poolAppendChar(pool
, buf
[i
]))
4766 return XML_ERROR_NO_MEMORY
;
4770 case XML_TOK_DATA_CHARS
:
4771 if (!poolAppend(pool
, enc
, ptr
, next
))
4772 return XML_ERROR_NO_MEMORY
;
4774 case XML_TOK_TRAILING_CR
:
4775 next
= ptr
+ enc
->minBytesPerChar
;
4777 case XML_TOK_ATTRIBUTE_VALUE_S
:
4778 case XML_TOK_DATA_NEWLINE
:
4779 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4781 if (!poolAppendChar(pool
, 0x20))
4782 return XML_ERROR_NO_MEMORY
;
4784 case XML_TOK_ENTITY_REF
:
4786 const XML_Char
*name
;
4788 char checkEntityDecl
;
4789 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4790 ptr
+ enc
->minBytesPerChar
,
4791 next
- enc
->minBytesPerChar
);
4793 if (!poolAppendChar(pool
, ch
))
4794 return XML_ERROR_NO_MEMORY
;
4797 name
= poolStoreString(&temp2Pool
, enc
,
4798 ptr
+ enc
->minBytesPerChar
,
4799 next
- enc
->minBytesPerChar
);
4801 return XML_ERROR_NO_MEMORY
;
4802 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4803 poolDiscard(&temp2Pool
);
4804 /* first, determine if a check for an existing declaration is needed;
4805 if yes, check that the entity exists, and that it is internal,
4806 otherwise call the default handler (if called from content)
4808 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4811 prologState
.documentEntity
&&
4812 #endif /* XML_DTD */
4814 ? !openInternalEntities
4815 : !dtd
->hasParamEntityRefs
);
4816 else /* if (pool == &tempPool): we are called from content */
4817 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4818 if (checkEntityDecl
) {
4820 return XML_ERROR_UNDEFINED_ENTITY
;
4821 else if (!entity
->is_internal
)
4822 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4825 /* cannot report skipped entity here - see comments on
4826 skippedEntityHandler
4827 if (skippedEntityHandler)
4828 skippedEntityHandler(handlerArg, name, 0);
4830 if ((pool
== &tempPool
) && defaultHandler
)
4831 reportDefault(parser
, enc
, ptr
, next
);
4835 if (enc
== encoding
)
4837 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4839 if (entity
->notation
) {
4840 if (enc
== encoding
)
4842 return XML_ERROR_BINARY_ENTITY_REF
;
4844 if (!entity
->textPtr
) {
4845 if (enc
== encoding
)
4847 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4850 enum XML_Error result
;
4851 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4852 entity
->open
= XML_TRUE
;
4853 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4854 (char *)entity
->textPtr
,
4855 (char *)textEnd
, pool
);
4856 entity
->open
= XML_FALSE
;
4863 if (enc
== encoding
)
4865 return XML_ERROR_UNEXPECTED_STATE
;
4872 static enum XML_Error
4873 storeEntityValue(XML_Parser parser
,
4874 const ENCODING
*enc
,
4875 const char *entityTextPtr
,
4876 const char *entityTextEnd
)
4878 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4879 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4880 enum XML_Error result
= XML_ERROR_NONE
;
4882 int oldInEntityValue
= prologState
.inEntityValue
;
4883 prologState
.inEntityValue
= 1;
4884 #endif /* XML_DTD */
4885 /* never return Null for the value argument in EntityDeclHandler,
4886 since this would indicate an external entity; therefore we
4887 have to make sure that entityValuePool.start is not null */
4888 if (!pool
->blocks
) {
4889 if (!poolGrow(pool
))
4890 return XML_ERROR_NO_MEMORY
;
4895 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4897 case XML_TOK_PARAM_ENTITY_REF
:
4899 if (isParamEntity
|| enc
!= encoding
) {
4900 const XML_Char
*name
;
4902 name
= poolStoreString(&tempPool
, enc
,
4903 entityTextPtr
+ enc
->minBytesPerChar
,
4904 next
- enc
->minBytesPerChar
);
4906 result
= XML_ERROR_NO_MEMORY
;
4907 goto endEntityValue
;
4909 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4910 poolDiscard(&tempPool
);
4912 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4913 /* cannot report skipped entity here - see comments on
4914 skippedEntityHandler
4915 if (skippedEntityHandler)
4916 skippedEntityHandler(handlerArg, name, 0);
4918 dtd
->keepProcessing
= dtd
->standalone
;
4919 goto endEntityValue
;
4922 if (enc
== encoding
)
4923 eventPtr
= entityTextPtr
;
4924 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4925 goto endEntityValue
;
4927 if (entity
->systemId
) {
4928 if (externalEntityRefHandler
) {
4929 dtd
->paramEntityRead
= XML_FALSE
;
4930 entity
->open
= XML_TRUE
;
4931 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4935 entity
->publicId
)) {
4936 entity
->open
= XML_FALSE
;
4937 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4938 goto endEntityValue
;
4940 entity
->open
= XML_FALSE
;
4941 if (!dtd
->paramEntityRead
)
4942 dtd
->keepProcessing
= dtd
->standalone
;
4945 dtd
->keepProcessing
= dtd
->standalone
;
4948 entity
->open
= XML_TRUE
;
4949 result
= storeEntityValue(parser
,
4951 (char *)entity
->textPtr
,
4952 (char *)(entity
->textPtr
4953 + entity
->textLen
));
4954 entity
->open
= XML_FALSE
;
4956 goto endEntityValue
;
4960 #endif /* XML_DTD */
4961 /* In the internal subset, PE references are not legal
4962 within markup declarations, e.g entity values in this case. */
4963 eventPtr
= entityTextPtr
;
4964 result
= XML_ERROR_PARAM_ENTITY_REF
;
4965 goto endEntityValue
;
4967 result
= XML_ERROR_NONE
;
4968 goto endEntityValue
;
4969 case XML_TOK_ENTITY_REF
:
4970 case XML_TOK_DATA_CHARS
:
4971 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4972 result
= XML_ERROR_NO_MEMORY
;
4973 goto endEntityValue
;
4976 case XML_TOK_TRAILING_CR
:
4977 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4979 case XML_TOK_DATA_NEWLINE
:
4980 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4981 result
= XML_ERROR_NO_MEMORY
;
4982 goto endEntityValue
;
4984 *(pool
->ptr
)++ = 0xA;
4986 case XML_TOK_CHAR_REF
:
4988 XML_Char buf
[XML_ENCODE_MAX
];
4990 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4992 if (enc
== encoding
)
4993 eventPtr
= entityTextPtr
;
4994 result
= XML_ERROR_BAD_CHAR_REF
;
4995 goto endEntityValue
;
4997 n
= XmlEncode(n
, (ICHAR
*)buf
);
4999 if (enc
== encoding
)
5000 eventPtr
= entityTextPtr
;
5001 result
= XML_ERROR_BAD_CHAR_REF
;
5002 goto endEntityValue
;
5004 for (i
= 0; i
< n
; i
++) {
5005 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5006 result
= XML_ERROR_NO_MEMORY
;
5007 goto endEntityValue
;
5009 *(pool
->ptr
)++ = buf
[i
];
5013 case XML_TOK_PARTIAL
:
5014 if (enc
== encoding
)
5015 eventPtr
= entityTextPtr
;
5016 result
= XML_ERROR_INVALID_TOKEN
;
5017 goto endEntityValue
;
5018 case XML_TOK_INVALID
:
5019 if (enc
== encoding
)
5021 result
= XML_ERROR_INVALID_TOKEN
;
5022 goto endEntityValue
;
5024 if (enc
== encoding
)
5025 eventPtr
= entityTextPtr
;
5026 result
= XML_ERROR_UNEXPECTED_STATE
;
5027 goto endEntityValue
;
5029 entityTextPtr
= next
;
5033 prologState
.inEntityValue
= oldInEntityValue
;
5034 #endif /* XML_DTD */
5038 static void FASTCALL
5039 normalizeLines(XML_Char
*s
)
5043 if (*s
== XML_T('\0'))
5062 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5063 const char *start
, const char *end
)
5065 const XML_Char
*target
;
5068 if (!processingInstructionHandler
) {
5070 reportDefault(parser
, enc
, start
, end
);
5073 start
+= enc
->minBytesPerChar
* 2;
5074 tem
= start
+ XmlNameLength(enc
, start
);
5075 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5078 poolFinish(&tempPool
);
5079 data
= poolStoreString(&tempPool
, enc
,
5081 end
- enc
->minBytesPerChar
*2);
5084 normalizeLines(data
);
5085 processingInstructionHandler(handlerArg
, target
, data
);
5086 poolClear(&tempPool
);
5091 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5092 const char *start
, const char *end
)
5095 if (!commentHandler
) {
5097 reportDefault(parser
, enc
, start
, end
);
5100 data
= poolStoreString(&tempPool
,
5102 start
+ enc
->minBytesPerChar
* 4,
5103 end
- enc
->minBytesPerChar
* 3);
5106 normalizeLines(data
);
5107 commentHandler(handlerArg
, data
);
5108 poolClear(&tempPool
);
5113 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5114 const char *s
, const char *end
)
5116 if (MUST_CONVERT(enc
, s
)) {
5117 const char **eventPP
;
5118 const char **eventEndPP
;
5119 if (enc
== encoding
) {
5120 eventPP
= &eventPtr
;
5121 eventEndPP
= &eventEndPtr
;
5124 eventPP
= &(openInternalEntities
->internalEventPtr
);
5125 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5128 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5129 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5131 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
5136 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
5141 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5142 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5144 DEFAULT_ATTRIBUTE
*att
;
5145 if (value
|| isId
) {
5146 /* The handling of default attributes gets messed up if we have
5147 a default which duplicates a non-default. */
5149 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5150 if (attId
== type
->defaultAtts
[i
].id
)
5152 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5153 type
->idAtt
= attId
;
5155 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5156 if (type
->allocDefaultAtts
== 0) {
5157 type
->allocDefaultAtts
= 8;
5158 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5159 * sizeof(DEFAULT_ATTRIBUTE
));
5160 if (!type
->defaultAtts
)
5164 DEFAULT_ATTRIBUTE
*temp
;
5165 int count
= type
->allocDefaultAtts
* 2;
5166 temp
= (DEFAULT_ATTRIBUTE
*)
5167 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5170 type
->allocDefaultAtts
= count
;
5171 type
->defaultAtts
= temp
;
5174 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5177 att
->isCdata
= isCdata
;
5179 attId
->maybeTokenized
= XML_TRUE
;
5180 type
->nDefaultAtts
+= 1;
5185 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5187 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5188 const XML_Char
*name
;
5189 for (name
= elementType
->name
; *name
; name
++) {
5190 if (*name
== XML_T(':')) {
5193 for (s
= elementType
->name
; s
!= name
; s
++) {
5194 if (!poolAppendChar(&dtd
->pool
, *s
))
5197 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5199 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5203 if (prefix
->name
== poolStart(&dtd
->pool
))
5204 poolFinish(&dtd
->pool
);
5206 poolDiscard(&dtd
->pool
);
5207 elementType
->prefix
= prefix
;
5214 static ATTRIBUTE_ID
*
5215 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5216 const char *start
, const char *end
)
5218 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5220 const XML_Char
*name
;
5221 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5223 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5226 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5228 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5231 if (id
->name
!= name
)
5232 poolDiscard(&dtd
->pool
);
5234 poolFinish(&dtd
->pool
);
5237 else if (name
[0] == XML_T('x')
5238 && name
[1] == XML_T('m')
5239 && name
[2] == XML_T('l')
5240 && name
[3] == XML_T('n')
5241 && name
[4] == XML_T('s')
5242 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
5243 if (name
[5] == XML_T('\0'))
5244 id
->prefix
= &dtd
->defaultPrefix
;
5246 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5247 id
->xmlns
= XML_TRUE
;
5251 for (i
= 0; name
[i
]; i
++) {
5252 /* attributes without prefix are *not* in the default namespace */
5253 if (name
[i
] == XML_T(':')) {
5255 for (j
= 0; j
< i
; j
++) {
5256 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5259 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5261 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5263 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5264 poolFinish(&dtd
->pool
);
5266 poolDiscard(&dtd
->pool
);
5275 #define CONTEXT_SEP XML_T('\f')
5277 static const XML_Char
*
5278 getContext(XML_Parser parser
)
5280 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5281 HASH_TABLE_ITER iter
;
5282 XML_Bool needSep
= XML_FALSE
;
5284 if (dtd
->defaultPrefix
.binding
) {
5287 if (!poolAppendChar(&tempPool
, XML_T('=')))
5289 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5290 if (namespaceSeparator
)
5292 for (i
= 0; i
< len
; i
++)
5293 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5298 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5303 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5306 if (!prefix
->binding
)
5308 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5310 for (s
= prefix
->name
; *s
; s
++)
5311 if (!poolAppendChar(&tempPool
, *s
))
5313 if (!poolAppendChar(&tempPool
, XML_T('=')))
5315 len
= prefix
->binding
->uriLen
;
5316 if (namespaceSeparator
)
5318 for (i
= 0; i
< len
; i
++)
5319 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5325 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5328 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5333 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5335 for (s
= e
->name
; *s
; s
++)
5336 if (!poolAppendChar(&tempPool
, *s
))
5341 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5343 return tempPool
.start
;
5347 setContext(XML_Parser parser
, const XML_Char
*context
)
5349 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5350 const XML_Char
*s
= context
;
5352 while (*context
!= XML_T('\0')) {
5353 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5355 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5357 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5360 if (*s
!= XML_T('\0'))
5363 poolDiscard(&tempPool
);
5365 else if (*s
== XML_T('=')) {
5367 if (poolLength(&tempPool
) == 0)
5368 prefix
= &dtd
->defaultPrefix
;
5370 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5372 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5376 if (prefix
->name
== poolStart(&tempPool
)) {
5377 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5381 poolDiscard(&tempPool
);
5383 for (context
= s
+ 1;
5384 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5386 if (!poolAppendChar(&tempPool
, *context
))
5388 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5390 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5391 &inheritedBindings
) != XML_ERROR_NONE
)
5393 poolDiscard(&tempPool
);
5394 if (*context
!= XML_T('\0'))
5399 if (!poolAppendChar(&tempPool
, *s
))
5407 static void FASTCALL
5408 normalizePublicId(XML_Char
*publicId
)
5410 XML_Char
*p
= publicId
;
5412 for (s
= publicId
; *s
; s
++) {
5417 if (p
!= publicId
&& p
[-1] != 0x20)
5424 if (p
!= publicId
&& p
[-1] == 0x20)
5430 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5432 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5435 poolInit(&(p
->pool
), ms
);
5436 poolInit(&(p
->entityValuePool
), ms
);
5437 hashTableInit(&(p
->generalEntities
), ms
);
5438 hashTableInit(&(p
->elementTypes
), ms
);
5439 hashTableInit(&(p
->attributeIds
), ms
);
5440 hashTableInit(&(p
->prefixes
), ms
);
5442 p
->paramEntityRead
= XML_FALSE
;
5443 hashTableInit(&(p
->paramEntities
), ms
);
5444 #endif /* XML_DTD */
5445 p
->defaultPrefix
.name
= NULL
;
5446 p
->defaultPrefix
.binding
= NULL
;
5448 p
->in_eldecl
= XML_FALSE
;
5449 p
->scaffIndex
= NULL
;
5454 p
->contentStringLen
= 0;
5456 p
->keepProcessing
= XML_TRUE
;
5457 p
->hasParamEntityRefs
= XML_FALSE
;
5458 p
->standalone
= XML_FALSE
;
5463 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5465 HASH_TABLE_ITER iter
;
5466 hashTableIterInit(&iter
, &(p
->elementTypes
));
5468 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5471 if (e
->allocDefaultAtts
!= 0)
5472 ms
->free_fcn(e
->defaultAtts
);
5474 hashTableClear(&(p
->generalEntities
));
5476 p
->paramEntityRead
= XML_FALSE
;
5477 hashTableClear(&(p
->paramEntities
));
5478 #endif /* XML_DTD */
5479 hashTableClear(&(p
->elementTypes
));
5480 hashTableClear(&(p
->attributeIds
));
5481 hashTableClear(&(p
->prefixes
));
5482 poolClear(&(p
->pool
));
5483 poolClear(&(p
->entityValuePool
));
5484 p
->defaultPrefix
.name
= NULL
;
5485 p
->defaultPrefix
.binding
= NULL
;
5487 p
->in_eldecl
= XML_FALSE
;
5489 ms
->free_fcn(p
->scaffIndex
);
5490 p
->scaffIndex
= NULL
;
5491 ms
->free_fcn(p
->scaffold
);
5497 p
->contentStringLen
= 0;
5499 p
->keepProcessing
= XML_TRUE
;
5500 p
->hasParamEntityRefs
= XML_FALSE
;
5501 p
->standalone
= XML_FALSE
;
5505 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5507 HASH_TABLE_ITER iter
;
5508 hashTableIterInit(&iter
, &(p
->elementTypes
));
5510 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5513 if (e
->allocDefaultAtts
!= 0)
5514 ms
->free_fcn(e
->defaultAtts
);
5516 hashTableDestroy(&(p
->generalEntities
));
5518 hashTableDestroy(&(p
->paramEntities
));
5519 #endif /* XML_DTD */
5520 hashTableDestroy(&(p
->elementTypes
));
5521 hashTableDestroy(&(p
->attributeIds
));
5522 hashTableDestroy(&(p
->prefixes
));
5523 poolDestroy(&(p
->pool
));
5524 poolDestroy(&(p
->entityValuePool
));
5526 ms
->free_fcn(p
->scaffIndex
);
5527 ms
->free_fcn(p
->scaffold
);
5532 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5533 The new DTD has already been initialized.
5536 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5538 HASH_TABLE_ITER iter
;
5540 /* Copy the prefix table. */
5542 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5544 const XML_Char
*name
;
5545 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5548 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5551 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5555 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5557 /* Copy the attribute id table. */
5561 const XML_Char
*name
;
5562 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5566 /* Remember to allocate the scratch byte before the name. */
5567 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5569 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5573 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5574 sizeof(ATTRIBUTE_ID
));
5577 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5579 newA
->xmlns
= oldA
->xmlns
;
5580 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5581 newA
->prefix
= &newDtd
->defaultPrefix
;
5583 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5584 oldA
->prefix
->name
, 0);
5588 /* Copy the element type table. */
5590 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5595 const XML_Char
*name
;
5596 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5599 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5602 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5603 sizeof(ELEMENT_TYPE
));
5606 if (oldE
->nDefaultAtts
) {
5607 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5608 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5609 if (!newE
->defaultAtts
) {
5615 newE
->idAtt
= (ATTRIBUTE_ID
*)
5616 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5617 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5619 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5620 oldE
->prefix
->name
, 0);
5621 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5622 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5623 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5624 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5625 if (oldE
->defaultAtts
[i
].value
) {
5626 newE
->defaultAtts
[i
].value
5627 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5628 if (!newE
->defaultAtts
[i
].value
)
5632 newE
->defaultAtts
[i
].value
= NULL
;
5636 /* Copy the entity tables. */
5637 if (!copyEntityTable(&(newDtd
->generalEntities
),
5639 &(oldDtd
->generalEntities
)))
5643 if (!copyEntityTable(&(newDtd
->paramEntities
),
5645 &(oldDtd
->paramEntities
)))
5647 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5648 #endif /* XML_DTD */
5650 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5651 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5652 newDtd
->standalone
= oldDtd
->standalone
;
5654 /* Don't want deep copying for scaffolding */
5655 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5656 newDtd
->scaffold
= oldDtd
->scaffold
;
5657 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5658 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5659 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5660 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5666 copyEntityTable(HASH_TABLE
*newTable
,
5667 STRING_POOL
*newPool
,
5668 const HASH_TABLE
*oldTable
)
5670 HASH_TABLE_ITER iter
;
5671 const XML_Char
*cachedOldBase
= NULL
;
5672 const XML_Char
*cachedNewBase
= NULL
;
5674 hashTableIterInit(&iter
, oldTable
);
5678 const XML_Char
*name
;
5679 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5682 name
= poolCopyString(newPool
, oldE
->name
);
5685 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5688 if (oldE
->systemId
) {
5689 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5692 newE
->systemId
= tem
;
5694 if (oldE
->base
== cachedOldBase
)
5695 newE
->base
= cachedNewBase
;
5697 cachedOldBase
= oldE
->base
;
5698 tem
= poolCopyString(newPool
, cachedOldBase
);
5701 cachedNewBase
= newE
->base
= tem
;
5704 if (oldE
->publicId
) {
5705 tem
= poolCopyString(newPool
, oldE
->publicId
);
5708 newE
->publicId
= tem
;
5712 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5716 newE
->textPtr
= tem
;
5717 newE
->textLen
= oldE
->textLen
;
5719 if (oldE
->notation
) {
5720 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5723 newE
->notation
= tem
;
5725 newE
->is_param
= oldE
->is_param
;
5726 newE
->is_internal
= oldE
->is_internal
;
5731 #define INIT_POWER 6
5733 static XML_Bool FASTCALL
5734 keyeq(KEY s1
, KEY s2
)
5736 for (; *s1
== *s2
; s1
++, s2
++)
5742 static unsigned long FASTCALL
5745 unsigned long h
= 0;
5747 h
= CHAR_HASH(h
, *s
++);
5752 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5755 if (table
->size
== 0) {
5759 table
->power
= INIT_POWER
;
5760 /* table->size is a power of 2 */
5761 table
->size
= (size_t)1 << INIT_POWER
;
5762 tsize
= table
->size
* sizeof(NAMED
*);
5763 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5768 memset(table
->v
, 0, tsize
);
5769 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5772 unsigned long h
= hash(name
);
5773 unsigned long mask
= (unsigned long)table
->size
- 1;
5774 unsigned char step
= 0;
5776 while (table
->v
[i
]) {
5777 if (keyeq(name
, table
->v
[i
]->name
))
5780 step
= PROBE_STEP(h
, mask
, table
->power
);
5781 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5786 /* check for overflow (table is half full) */
5787 if (table
->used
>> (table
->power
- 1)) {
5788 unsigned char newPower
= table
->power
+ 1;
5789 size_t newSize
= (size_t)1 << newPower
;
5790 unsigned long newMask
= (unsigned long)newSize
- 1;
5791 size_t tsize
= newSize
* sizeof(NAMED
*);
5792 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5795 memset(newV
, 0, tsize
);
5796 for (i
= 0; i
< table
->size
; i
++)
5798 unsigned long newHash
= hash(table
->v
[i
]->name
);
5799 size_t j
= newHash
& newMask
;
5803 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5804 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5806 newV
[j
] = table
->v
[i
];
5808 table
->mem
->free_fcn(table
->v
);
5810 table
->power
= newPower
;
5811 table
->size
= newSize
;
5814 while (table
->v
[i
]) {
5816 step
= PROBE_STEP(h
, newMask
, newPower
);
5817 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5821 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5824 memset(table
->v
[i
], 0, createSize
);
5825 table
->v
[i
]->name
= name
;
5830 static void FASTCALL
5831 hashTableClear(HASH_TABLE
*table
)
5834 for (i
= 0; i
< table
->size
; i
++) {
5835 table
->mem
->free_fcn(table
->v
[i
]);
5841 static void FASTCALL
5842 hashTableDestroy(HASH_TABLE
*table
)
5845 for (i
= 0; i
< table
->size
; i
++)
5846 table
->mem
->free_fcn(table
->v
[i
]);
5847 table
->mem
->free_fcn(table
->v
);
5850 static void FASTCALL
5851 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5860 static void FASTCALL
5861 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5864 iter
->end
= iter
->p
+ table
->size
;
5867 static NAMED
* FASTCALL
5868 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5870 while (iter
->p
!= iter
->end
) {
5871 NAMED
*tem
= *(iter
->p
)++;
5878 static void FASTCALL
5879 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5881 pool
->blocks
= NULL
;
5882 pool
->freeBlocks
= NULL
;
5889 static void FASTCALL
5890 poolClear(STRING_POOL
*pool
)
5892 if (!pool
->freeBlocks
)
5893 pool
->freeBlocks
= pool
->blocks
;
5895 BLOCK
*p
= pool
->blocks
;
5897 BLOCK
*tem
= p
->next
;
5898 p
->next
= pool
->freeBlocks
;
5899 pool
->freeBlocks
= p
;
5903 pool
->blocks
= NULL
;
5909 static void FASTCALL
5910 poolDestroy(STRING_POOL
*pool
)
5912 BLOCK
*p
= pool
->blocks
;
5914 BLOCK
*tem
= p
->next
;
5915 pool
->mem
->free_fcn(p
);
5918 p
= pool
->freeBlocks
;
5920 BLOCK
*tem
= p
->next
;
5921 pool
->mem
->free_fcn(p
);
5927 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5928 const char *ptr
, const char *end
)
5930 if (!pool
->ptr
&& !poolGrow(pool
))
5933 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5936 if (!poolGrow(pool
))
5942 static const XML_Char
* FASTCALL
5943 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5946 if (!poolAppendChar(pool
, *s
))
5954 static const XML_Char
*
5955 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5957 if (!pool
->ptr
&& !poolGrow(pool
))
5959 for (; n
> 0; --n
, s
++) {
5960 if (!poolAppendChar(pool
, *s
))
5968 static const XML_Char
* FASTCALL
5969 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5972 if (!poolAppendChar(pool
, *s
))
5980 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5981 const char *ptr
, const char *end
)
5983 if (!poolAppend(pool
, enc
, ptr
, end
))
5985 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5991 static XML_Bool FASTCALL
5992 poolGrow(STRING_POOL
*pool
)
5994 if (pool
->freeBlocks
) {
5995 if (pool
->start
== 0) {
5996 pool
->blocks
= pool
->freeBlocks
;
5997 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5998 pool
->blocks
->next
= NULL
;
5999 pool
->start
= pool
->blocks
->s
;
6000 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6001 pool
->ptr
= pool
->start
;
6004 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6005 BLOCK
*tem
= pool
->freeBlocks
->next
;
6006 pool
->freeBlocks
->next
= pool
->blocks
;
6007 pool
->blocks
= pool
->freeBlocks
;
6008 pool
->freeBlocks
= tem
;
6009 memcpy(pool
->blocks
->s
, pool
->start
,
6010 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6011 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6012 pool
->start
= pool
->blocks
->s
;
6013 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6017 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6018 int blockSize
= (pool
->end
- pool
->start
)*2;
6019 pool
->blocks
= (BLOCK
*)
6020 pool
->mem
->realloc_fcn(pool
->blocks
,
6022 + blockSize
* sizeof(XML_Char
)));
6023 if (pool
->blocks
== NULL
)
6025 pool
->blocks
->size
= blockSize
;
6026 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6027 pool
->start
= pool
->blocks
->s
;
6028 pool
->end
= pool
->start
+ blockSize
;
6032 int blockSize
= pool
->end
- pool
->start
;
6033 if (blockSize
< INIT_BLOCK_SIZE
)
6034 blockSize
= INIT_BLOCK_SIZE
;
6037 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6038 + blockSize
* sizeof(XML_Char
));
6041 tem
->size
= blockSize
;
6042 tem
->next
= pool
->blocks
;
6044 if (pool
->ptr
!= pool
->start
)
6045 memcpy(tem
->s
, pool
->start
,
6046 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6047 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6048 pool
->start
= tem
->s
;
6049 pool
->end
= tem
->s
+ blockSize
;
6055 nextScaffoldPart(XML_Parser parser
)
6057 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6058 CONTENT_SCAFFOLD
* me
;
6061 if (!dtd
->scaffIndex
) {
6062 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6063 if (!dtd
->scaffIndex
)
6065 dtd
->scaffIndex
[0] = 0;
6068 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6069 CONTENT_SCAFFOLD
*temp
;
6070 if (dtd
->scaffold
) {
6071 temp
= (CONTENT_SCAFFOLD
*)
6072 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6075 dtd
->scaffSize
*= 2;
6078 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6079 * sizeof(CONTENT_SCAFFOLD
));
6082 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6084 dtd
->scaffold
= temp
;
6086 next
= dtd
->scaffCount
++;
6087 me
= &dtd
->scaffold
[next
];
6088 if (dtd
->scaffLevel
) {
6089 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6090 if (parent
->lastchild
) {
6091 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6093 if (!parent
->childcnt
)
6094 parent
->firstchild
= next
;
6095 parent
->lastchild
= next
;
6098 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6103 build_node(XML_Parser parser
,
6106 XML_Content
**contpos
,
6109 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6110 dest
->type
= dtd
->scaffold
[src_node
].type
;
6111 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6112 if (dest
->type
== XML_CTYPE_NAME
) {
6113 const XML_Char
*src
;
6114 dest
->name
= *strpos
;
6115 src
= dtd
->scaffold
[src_node
].name
;
6117 *(*strpos
)++ = *src
;
6122 dest
->numchildren
= 0;
6123 dest
->children
= NULL
;
6128 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6129 dest
->children
= *contpos
;
6130 *contpos
+= dest
->numchildren
;
6131 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6132 i
< dest
->numchildren
;
6133 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6134 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6140 static XML_Content
*
6141 build_model (XML_Parser parser
)
6143 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6147 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6148 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6150 ret
= (XML_Content
*)MALLOC(allocsize
);
6154 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6157 build_node(parser
, 0, ret
, &cpos
, &str
);
6161 static ELEMENT_TYPE
*
6162 getElementType(XML_Parser parser
,
6163 const ENCODING
*enc
,
6167 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6168 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6173 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6176 if (ret
->name
!= name
)
6177 poolDiscard(&dtd
->pool
);
6179 poolFinish(&dtd
->pool
);
6180 if (!setElementTypePrefix(parser
, ret
))