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() */
8 // Track memory leaks on Windows to the line that new'd the memory
11 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
14 static char THIS_FILE
[] = __FILE__
;
18 #ifdef COMPILED_FROM_DSP
20 #include "winconfig.h"
22 #define XMLPARSEAPI(type) type __cdecl
24 #define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
29 #elif defined(MACOS_CLASSIC)
31 #include "macconfig.h"
36 #include <expat_config.h>
39 #define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
47 #endif /* ndef COMPILED_FROM_DSP */
50 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
51 #define XmlConvert XmlUtf16Convert
52 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
53 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
54 #define XmlEncode XmlUtf16Encode
55 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
56 typedef unsigned short ICHAR
;
58 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
59 #define XmlConvert XmlUtf8Convert
60 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
61 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
62 #define XmlEncode XmlUtf8Encode
63 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
70 #define XmlInitEncodingNS XmlInitEncoding
71 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
72 #undef XmlGetInternalEncodingNS
73 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
74 #define XmlParseXmlDeclNS XmlParseXmlDecl
80 #ifdef XML_UNICODE_WCHAR_T
81 #define XML_T(x) (const wchar_t)x
82 #define XML_L(x) L ## x
84 #define XML_T(x) (const unsigned short)x
95 /* Round up n to be a multiple of sz, where sz is a power of 2. */
96 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
98 /* Handle the case where memmove() doesn't exist. */
101 #define memmove(d,s,l) bcopy((s),(d),(l))
103 #error memmove does not exist on this platform, nor is a substitute available
104 #endif /* HAVE_BCOPY */
105 #endif /* HAVE_MEMMOVE */
107 #include "internal.h"
111 typedef const XML_Char
*KEY
;
122 XML_Memory_Handling_Suite
*mem
;
130 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
131 #define INIT_DATA_BUF_SIZE 1024
132 #define INIT_ATTS_SIZE 16
133 #define INIT_BLOCK_SIZE 1024
134 #define INIT_BUFFER_SIZE 1024
136 #define EXPAND_SPARE 24
138 typedef struct binding
{
139 struct prefix
*prefix
;
140 struct binding
*nextTagBinding
;
141 struct binding
*prevPrefixBinding
;
142 const struct attribute_id
*attId
;
148 typedef struct prefix
{
149 const XML_Char
*name
;
155 const XML_Char
*localPart
;
156 const XML_Char
*prefix
;
162 /* TAG represents an open element.
163 The name of the element is stored in both the document and API
164 encodings. The memory buffer 'buf' is a separately-allocated
165 memory area which stores the name. During the XML_Parse()/
166 XMLParseBuffer() when the element is open, the memory for the 'raw'
167 version of the name (in the document encoding) is shared with the
168 document buffer. If the element is open across calls to
169 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
170 contain the 'raw' name as well.
172 A parser re-uses these structures, maintaining a list of allocated
173 TAG objects in a free list.
176 struct tag
*parent
; /* parent of this element */
177 const char *rawName
; /* tagName in the original encoding */
179 TAG_NAME name
; /* tagName in the API encoding */
180 char *buf
; /* buffer for name components */
181 char *bufEnd
; /* end of the buffer */
186 const XML_Char
*name
;
187 const XML_Char
*textPtr
;
189 const XML_Char
*systemId
;
190 const XML_Char
*base
;
191 const XML_Char
*publicId
;
192 const XML_Char
*notation
;
195 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
199 enum XML_Content_Type type
;
200 enum XML_Content_Quant quant
;
201 const XML_Char
* name
;
208 #define INIT_SCAFFOLD_ELEMENTS 32
210 typedef struct block
{
222 XML_Memory_Handling_Suite
*mem
;
225 /* The XML_Char before the name is used to determine whether
226 an attribute has been specified. */
227 typedef struct attribute_id
{
230 XML_Bool maybeTokenized
;
235 const ATTRIBUTE_ID
*id
;
237 const XML_Char
*value
;
241 const XML_Char
*name
;
243 const ATTRIBUTE_ID
*idAtt
;
245 int allocDefaultAtts
;
246 DEFAULT_ATTRIBUTE
*defaultAtts
;
250 HASH_TABLE generalEntities
;
251 HASH_TABLE elementTypes
;
252 HASH_TABLE attributeIds
;
255 STRING_POOL entityValuePool
;
256 /* false once a parameter entity reference has been skipped */
257 XML_Bool keepProcessing
;
258 /* true once an internal or external PE reference has been encountered;
259 any external subset is considered an external PE reference */
260 XML_Bool hasParamEntityRefs
;
263 /* indicates if external PE has been read */
264 XML_Bool paramEntityRead
;
265 HASH_TABLE paramEntities
;
267 PREFIX defaultPrefix
;
268 /* === scaffolding for building content model === */
270 CONTENT_SCAFFOLD
*scaffold
;
271 unsigned contentStringLen
;
278 typedef struct open_internal_entity
{
279 const char *internalEventPtr
;
280 const char *internalEventEndPtr
;
281 struct open_internal_entity
*next
;
283 } OPEN_INTERNAL_ENTITY
;
285 typedef enum XML_Error FASTCALL
Processor(XML_Parser parser
,
288 const char **endPtr
);
290 static Processor prologProcessor
;
291 static Processor prologInitProcessor
;
292 static Processor contentProcessor
;
293 static Processor cdataSectionProcessor
;
295 static Processor ignoreSectionProcessor
;
296 static Processor externalParEntProcessor
;
297 static Processor externalParEntInitProcessor
;
298 static Processor entityValueProcessor
;
299 static Processor entityValueInitProcessor
;
301 static Processor epilogProcessor
;
302 static Processor errorProcessor
;
303 static Processor externalEntityInitProcessor
;
304 static Processor externalEntityInitProcessor2
;
305 static Processor externalEntityInitProcessor3
;
306 static Processor externalEntityContentProcessor
;
308 static enum XML_Error FASTCALL
309 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
310 static enum XML_Error FASTCALL
311 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
312 const char *, const char *);
313 static enum XML_Error FASTCALL
314 initializeEncoding(XML_Parser parser
);
315 static enum XML_Error FASTCALL
316 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
317 const char *end
, int tok
, const char *next
, const char **nextPtr
);
318 static enum XML_Error FASTCALL
319 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
320 static enum XML_Error FASTCALL
321 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
322 const char *start
, const char *end
, const char **endPtr
);
323 static enum XML_Error FASTCALL
324 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
325 const char *end
, const char **nextPtr
);
327 static enum XML_Error FASTCALL
328 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
329 const char *end
, const char **nextPtr
);
331 static enum XML_Error FASTCALL
332 storeAtts(XML_Parser parser
, const ENCODING
*,
333 const char *s
, TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
335 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
336 const XML_Char
*uri
, BINDING
**bindingsPtr
);
339 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
340 XML_Bool isCdata
, XML_Bool isId
, const XML_Char
*dfltValue
,
343 static enum XML_Error FASTCALL
344 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
345 const char *, const char *, STRING_POOL
*);
346 static enum XML_Error FASTCALL
347 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
348 const char *, const char *, STRING_POOL
*);
349 static ATTRIBUTE_ID
* FASTCALL
350 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
353 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
354 static enum XML_Error FASTCALL
355 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
358 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
359 const char *start
, const char *end
);
361 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
364 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
367 static const XML_Char
* FASTCALL
getContext(XML_Parser parser
);
368 static XML_Bool FASTCALL
369 setContext(XML_Parser parser
, const XML_Char
*context
);
370 static void FASTCALL
normalizePublicId(XML_Char
*s
);
371 static void FASTCALL
dtdInit(DTD
*, XML_Parser parser
);
373 /* do not call if parentParser != NULL */
374 static void FASTCALL
dtdReset(DTD
*, XML_Parser parser
);
375 static void FASTCALL
dtdDestroy(DTD
*, XML_Parser parser
);
377 static int FASTCALL
dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, XML_Parser parser
);
379 static int FASTCALL
copyEntityTable(HASH_TABLE
*, STRING_POOL
*,
380 const HASH_TABLE
*, XML_Parser parser
);
383 static void FASTCALL
dtdSwap(DTD
*, DTD
*);
386 static NAMED
* FASTCALL
387 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
390 hashTableInit(HASH_TABLE
*, XML_Memory_Handling_Suite
*ms
);
392 static void FASTCALL
hashTableClear(HASH_TABLE
*);
393 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
394 static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
395 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
396 static void FASTCALL
poolInit(STRING_POOL
*, XML_Memory_Handling_Suite
*ms
);
397 static void FASTCALL
poolClear(STRING_POOL
*);
398 static void FASTCALL
poolDestroy(STRING_POOL
*);
399 static XML_Char
* FASTCALL
400 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
401 const char *ptr
, const char *end
);
402 static XML_Char
* FASTCALL
403 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
404 const char *ptr
, const char *end
);
406 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
408 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
409 static XML_Content
* FASTCALL
build_model(XML_Parser parser
);
411 static const XML_Char
* FASTCALL
412 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
413 static const XML_Char
* FASTCALL
414 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
415 static const XML_Char
* FASTCALL
416 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
417 static ELEMENT_TYPE
* FASTCALL
418 getElementType(XML_Parser Paraser
, const ENCODING
*enc
,
419 const char *ptr
, const char *end
);
422 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
424 #define poolStart(pool) ((pool)->start)
425 #define poolEnd(pool) ((pool)->ptr)
426 #define poolLength(pool) ((pool)->ptr - (pool)->start)
427 #define poolChop(pool) ((void)--(pool->ptr))
428 #define poolLastChar(pool) (((pool)->ptr)[-1])
429 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
430 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
431 #define poolAppendChar(pool, c) \
432 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
434 : ((*((pool)->ptr)++ = c), 1))
436 struct XML_ParserStruct
{
437 /* The first member must be userData so that the XML_GetUserData
442 XML_Memory_Handling_Suite m_mem
;
443 /* first character to be parsed */
444 const char *m_bufferPtr
;
445 /* past last character to be parsed */
447 /* allocated end of buffer */
448 const char *m_bufferLim
;
449 long m_parseEndByteIndex
;
450 const char *m_parseEndPtr
;
452 XML_Char
*m_dataBufEnd
;
453 XML_StartElementHandler m_startElementHandler
;
454 XML_EndElementHandler m_endElementHandler
;
455 XML_CharacterDataHandler m_characterDataHandler
;
456 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
457 XML_CommentHandler m_commentHandler
;
458 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
459 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
460 XML_DefaultHandler m_defaultHandler
;
461 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
462 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
463 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
464 XML_NotationDeclHandler m_notationDeclHandler
;
465 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
466 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
467 XML_NotStandaloneHandler m_notStandaloneHandler
;
468 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
469 void *m_externalEntityRefHandlerArg
;
470 XML_SkippedEntityHandler m_skippedEntityHandler
;
471 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
472 XML_ElementDeclHandler m_elementDeclHandler
;
473 XML_AttlistDeclHandler m_attlistDeclHandler
;
474 XML_EntityDeclHandler m_entityDeclHandler
;
475 XML_XmlDeclHandler m_xmlDeclHandler
;
476 const ENCODING
*m_encoding
;
477 INIT_ENCODING m_initEncoding
;
478 const ENCODING
*m_internalEncoding
;
479 const XML_Char
*m_protocolEncodingName
;
481 XML_Bool m_ns_triplets
;
482 void *m_unknownEncodingMem
;
483 void *m_unknownEncodingData
;
484 void *m_unknownEncodingHandlerData
;
485 void (*m_unknownEncodingRelease
)(void *);
486 PROLOG_STATE m_prologState
;
487 Processor
*m_processor
;
488 enum XML_Error m_errorCode
;
489 const char *m_eventPtr
;
490 const char *m_eventEndPtr
;
491 const char *m_positionPtr
;
492 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
493 XML_Bool m_defaultExpandInternalEntities
;
495 ENTITY
*m_declEntity
;
496 const XML_Char
*m_doctypeName
;
497 const XML_Char
*m_doctypeSysid
;
498 const XML_Char
*m_doctypePubid
;
499 const XML_Char
*m_declAttributeType
;
500 const XML_Char
*m_declNotationName
;
501 const XML_Char
*m_declNotationPublicId
;
502 ELEMENT_TYPE
*m_declElementType
;
503 ATTRIBUTE_ID
*m_declAttributeId
;
504 XML_Bool m_declAttributeIsCdata
;
505 XML_Bool m_declAttributeIsId
;
507 const XML_Char
*m_curBase
;
510 BINDING
*m_inheritedBindings
;
511 BINDING
*m_freeBindingList
;
513 int m_nSpecifiedAtts
;
517 STRING_POOL m_tempPool
;
518 STRING_POOL m_temp2Pool
;
519 char *m_groupConnector
;
520 unsigned m_groupSize
;
521 XML_Char m_namespaceSeparator
;
522 XML_Parser m_parentParser
;
524 XML_Bool m_isParamEntity
;
525 XML_Bool m_useForeignDTD
;
526 enum XML_ParamEntityParsing m_paramEntityParsing
;
530 #define MALLOC(s) ((parser)->m_mem.malloc_fcn((s)))
531 #define REALLOC(p,s) ((parser)->m_mem.realloc_fcn((p),(s)))
532 #define FREE(p) ((parser)->m_mem.free_fcn((p)))
534 #define userData (parser->m_userData)
535 #define handlerArg (parser->m_handlerArg)
536 #define startElementHandler (parser->m_startElementHandler)
537 #define endElementHandler (parser->m_endElementHandler)
538 #define characterDataHandler (parser->m_characterDataHandler)
539 #define processingInstructionHandler \
540 (parser->m_processingInstructionHandler)
541 #define commentHandler (parser->m_commentHandler)
542 #define startCdataSectionHandler \
543 (parser->m_startCdataSectionHandler)
544 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
545 #define defaultHandler (parser->m_defaultHandler)
546 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
547 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
548 #define unparsedEntityDeclHandler \
549 (parser->m_unparsedEntityDeclHandler)
550 #define notationDeclHandler (parser->m_notationDeclHandler)
551 #define startNamespaceDeclHandler \
552 (parser->m_startNamespaceDeclHandler)
553 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
554 #define notStandaloneHandler (parser->m_notStandaloneHandler)
555 #define externalEntityRefHandler \
556 (parser->m_externalEntityRefHandler)
557 #define externalEntityRefHandlerArg \
558 (parser->m_externalEntityRefHandlerArg)
559 #define internalEntityRefHandler \
560 (parser->m_internalEntityRefHandler)
561 #define skippedEntityHandler (parser->m_skippedEntityHandler)
562 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
563 #define elementDeclHandler (parser->m_elementDeclHandler)
564 #define attlistDeclHandler (parser->m_attlistDeclHandler)
565 #define entityDeclHandler (parser->m_entityDeclHandler)
566 #define xmlDeclHandler (parser->m_xmlDeclHandler)
567 #define encoding (parser->m_encoding)
568 #define initEncoding (parser->m_initEncoding)
569 #define internalEncoding (parser->m_internalEncoding)
570 #define unknownEncodingMem (parser->m_unknownEncodingMem)
571 #define unknownEncodingData (parser->m_unknownEncodingData)
572 #define unknownEncodingHandlerData \
573 (parser->m_unknownEncodingHandlerData)
574 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
575 #define protocolEncodingName (parser->m_protocolEncodingName)
576 #define ns (parser->m_ns)
577 #define ns_triplets (parser->m_ns_triplets)
578 #define prologState (parser->m_prologState)
579 #define processor (parser->m_processor)
580 #define errorCode (parser->m_errorCode)
581 #define eventPtr (parser->m_eventPtr)
582 #define eventEndPtr (parser->m_eventEndPtr)
583 #define positionPtr (parser->m_positionPtr)
584 #define position (parser->m_position)
585 #define openInternalEntities (parser->m_openInternalEntities)
586 #define defaultExpandInternalEntities \
587 (parser->m_defaultExpandInternalEntities)
588 #define tagLevel (parser->m_tagLevel)
589 #define buffer (parser->m_buffer)
590 #define bufferPtr (parser->m_bufferPtr)
591 #define bufferEnd (parser->m_bufferEnd)
592 #define parseEndByteIndex (parser->m_parseEndByteIndex)
593 #define parseEndPtr (parser->m_parseEndPtr)
594 #define bufferLim (parser->m_bufferLim)
595 #define dataBuf (parser->m_dataBuf)
596 #define dataBufEnd (parser->m_dataBufEnd)
597 #define dtd (parser->m_dtd)
598 #define curBase (parser->m_curBase)
599 #define declEntity (parser->m_declEntity)
600 #define doctypeName (parser->m_doctypeName)
601 #define doctypeSysid (parser->m_doctypeSysid)
602 #define doctypePubid (parser->m_doctypePubid)
603 #define declAttributeType (parser->m_declAttributeType)
604 #define declNotationName (parser->m_declNotationName)
605 #define declNotationPublicId (parser->m_declNotationPublicId)
606 #define declElementType (parser->m_declElementType)
607 #define declAttributeId (parser->m_declAttributeId)
608 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
609 #define declAttributeIsId (parser->m_declAttributeIsId)
610 #define freeTagList (parser->m_freeTagList)
611 #define freeBindingList (parser->m_freeBindingList)
612 #define inheritedBindings (parser->m_inheritedBindings)
613 #define tagStack (parser->m_tagStack)
614 #define atts (parser->m_atts)
615 #define attsSize (parser->m_attsSize)
616 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
617 #define idAttIndex (parser->m_idAttIndex)
618 #define tempPool (parser->m_tempPool)
619 #define temp2Pool (parser->m_temp2Pool)
620 #define groupConnector (parser->m_groupConnector)
621 #define groupSize (parser->m_groupSize)
622 #define namespaceSeparator (parser->m_namespaceSeparator)
623 #define parentParser (parser->m_parentParser)
625 #define isParamEntity (parser->m_isParamEntity)
626 #define useForeignDTD (parser->m_useForeignDTD)
627 #define paramEntityParsing (parser->m_paramEntityParsing)
630 #define parsing (processor != prologInitProcessor)
633 XML_ParserCreate(const XML_Char
*encodingName
)
635 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
639 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
643 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
647 XML_ParserCreate_MM(const XML_Char
*encodingName
,
648 const XML_Memory_Handling_Suite
*memsuite
,
649 const XML_Char
*nameSep
) {
651 static const XML_Char implicitContext
[] = {
652 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
653 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
654 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
655 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
660 XML_Memory_Handling_Suite
*mtemp
;
661 parser
= memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
662 if (parser
!= NULL
) {
663 mtemp
= &(parser
->m_mem
);
664 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
665 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
666 mtemp
->free_fcn
= memsuite
->free_fcn
;
670 XML_Memory_Handling_Suite
*mtemp
;
671 parser
= malloc(sizeof(struct XML_ParserStruct
));
672 if (parser
!= NULL
) {
673 mtemp
= &(parser
->m_mem
);
674 mtemp
->malloc_fcn
= malloc
;
675 mtemp
->realloc_fcn
= realloc
;
676 mtemp
->free_fcn
= free
;
686 attsSize
= INIT_ATTS_SIZE
;
687 atts
= MALLOC(attsSize
* sizeof(ATTRIBUTE
));
692 dataBuf
= MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
693 if (dataBuf
== NULL
) {
698 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
700 freeBindingList
= NULL
;
704 groupConnector
= NULL
;
706 unknownEncodingHandler
= NULL
;
707 unknownEncodingHandlerData
= NULL
;
709 namespaceSeparator
= '!';
711 ns_triplets
= XML_FALSE
;
713 poolInit(&tempPool
, &(parser
->m_mem
));
714 poolInit(&temp2Pool
, &(parser
->m_mem
));
715 parserInit(parser
, encodingName
);
716 dtdInit(&dtd
, parser
);
718 if (!atts
|| !dataBuf
|| (encodingName
&& !protocolEncodingName
)) {
719 XML_ParserFree(parser
);
725 internalEncoding
= XmlGetInternalEncodingNS();
726 namespaceSeparator
= *nameSep
;
728 if (!setContext(parser
, implicitContext
)) {
729 XML_ParserFree(parser
);
734 internalEncoding
= XmlGetInternalEncoding();
741 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
743 processor
= prologInitProcessor
;
744 XmlPrologStateInit(&prologState
);
745 protocolEncodingName
= (encodingName
!= NULL
746 ? poolCopyString(&tempPool
, encodingName
)
749 XmlInitEncoding(&initEncoding
, &encoding
, 0);
752 startElementHandler
= NULL
;
753 endElementHandler
= NULL
;
754 characterDataHandler
= NULL
;
755 processingInstructionHandler
= NULL
;
756 commentHandler
= NULL
;
757 startCdataSectionHandler
= NULL
;
758 endCdataSectionHandler
= NULL
;
759 defaultHandler
= NULL
;
760 startDoctypeDeclHandler
= NULL
;
761 endDoctypeDeclHandler
= NULL
;
762 unparsedEntityDeclHandler
= NULL
;
763 notationDeclHandler
= NULL
;
764 startNamespaceDeclHandler
= NULL
;
765 endNamespaceDeclHandler
= NULL
;
766 notStandaloneHandler
= NULL
;
767 externalEntityRefHandler
= NULL
;
768 externalEntityRefHandlerArg
= parser
;
769 skippedEntityHandler
= NULL
;
770 elementDeclHandler
= NULL
;
771 attlistDeclHandler
= NULL
;
772 entityDeclHandler
= NULL
;
773 xmlDeclHandler
= NULL
;
776 parseEndByteIndex
= 0;
778 declElementType
= NULL
;
779 declAttributeId
= NULL
;
784 declAttributeType
= NULL
;
785 declNotationName
= NULL
;
786 declNotationPublicId
= NULL
;
787 declAttributeIsCdata
= XML_FALSE
;
788 declAttributeIsId
= XML_FALSE
;
789 memset(&position
, 0, sizeof(POSITION
));
790 errorCode
= XML_ERROR_NONE
;
794 openInternalEntities
= 0;
795 defaultExpandInternalEntities
= XML_TRUE
;
798 inheritedBindings
= NULL
;
800 unknownEncodingMem
= NULL
;
801 unknownEncodingRelease
= NULL
;
802 unknownEncodingData
= NULL
;
805 isParamEntity
= XML_FALSE
;
806 useForeignDTD
= XML_FALSE
;
807 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
811 /* moves list of bindings to freeBindingList */
813 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
816 BINDING
*b
= bindings
;
817 bindings
= bindings
->nextTagBinding
;
818 b
->nextTagBinding
= freeBindingList
;
824 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
829 /* move tagStack to freeTagList */
834 tag
->parent
= freeTagList
;
835 moveToFreeBindingList(parser
, tag
->bindings
);
836 tag
->bindings
= NULL
;
839 moveToFreeBindingList(parser
, inheritedBindings
);
840 if (unknownEncodingMem
)
841 FREE(unknownEncodingMem
);
842 if (unknownEncodingRelease
)
843 unknownEncodingRelease(unknownEncodingData
);
844 poolClear(&tempPool
);
845 poolClear(&temp2Pool
);
846 parserInit(parser
, encodingName
);
847 dtdReset(&dtd
, parser
);
852 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
854 /* block after XML_Parse()/XML_ParseBuffer() has been called */
857 if (encodingName
== NULL
)
858 protocolEncodingName
= NULL
;
860 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
861 if (!protocolEncodingName
)
868 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
869 const XML_Char
*context
,
870 const XML_Char
*encodingName
)
872 XML_Parser parser
= oldParser
;
874 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
875 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
876 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
877 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
878 = processingInstructionHandler
;
879 XML_CommentHandler oldCommentHandler
= commentHandler
;
880 XML_StartCdataSectionHandler oldStartCdataSectionHandler
881 = startCdataSectionHandler
;
882 XML_EndCdataSectionHandler oldEndCdataSectionHandler
883 = endCdataSectionHandler
;
884 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
885 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
886 = unparsedEntityDeclHandler
;
887 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
888 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
889 = startNamespaceDeclHandler
;
890 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
891 = endNamespaceDeclHandler
;
892 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
893 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
894 = externalEntityRefHandler
;
895 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
896 XML_UnknownEncodingHandler oldUnknownEncodingHandler
897 = unknownEncodingHandler
;
898 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
899 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
900 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
901 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
902 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
904 void *oldUserData
= userData
;
905 void *oldHandlerArg
= handlerArg
;
906 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
907 void *oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
909 int oldParamEntityParsing
= paramEntityParsing
;
910 int oldInEntityValue
= prologState
.inEntityValue
;
912 XML_Bool oldns_triplets
= ns_triplets
;
914 /* Note that the magical uses of the pre-processor to make field
915 access look more like C++ require that `parser' be overwritten
916 here. This makes this function more painful to follow than it
922 *tmp
= namespaceSeparator
;
923 parser
= XML_ParserCreate_MM(encodingName
, &parser
->m_mem
,
927 parser
= XML_ParserCreate_MM(encodingName
, &parser
->m_mem
,
934 startElementHandler
= oldStartElementHandler
;
935 endElementHandler
= oldEndElementHandler
;
936 characterDataHandler
= oldCharacterDataHandler
;
937 processingInstructionHandler
= oldProcessingInstructionHandler
;
938 commentHandler
= oldCommentHandler
;
939 startCdataSectionHandler
= oldStartCdataSectionHandler
;
940 endCdataSectionHandler
= oldEndCdataSectionHandler
;
941 defaultHandler
= oldDefaultHandler
;
942 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
943 notationDeclHandler
= oldNotationDeclHandler
;
944 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
945 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
946 notStandaloneHandler
= oldNotStandaloneHandler
;
947 externalEntityRefHandler
= oldExternalEntityRefHandler
;
948 skippedEntityHandler
= oldSkippedEntityHandler
;
949 unknownEncodingHandler
= oldUnknownEncodingHandler
;
950 elementDeclHandler
= oldElementDeclHandler
;
951 attlistDeclHandler
= oldAttlistDeclHandler
;
952 entityDeclHandler
= oldEntityDeclHandler
;
953 xmlDeclHandler
= oldXmlDeclHandler
;
954 declElementType
= oldDeclElementType
;
955 userData
= oldUserData
;
956 if (oldUserData
== oldHandlerArg
)
957 handlerArg
= userData
;
960 if (oldExternalEntityRefHandlerArg
!= oldParser
)
961 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
962 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
963 ns_triplets
= oldns_triplets
;
964 parentParser
= oldParser
;
966 paramEntityParsing
= oldParamEntityParsing
;
967 prologState
.inEntityValue
= oldInEntityValue
;
970 if (!dtdCopy(&dtd
, oldDtd
, parser
) || !setContext(parser
, context
)) {
971 XML_ParserFree(parser
);
974 processor
= externalEntityInitProcessor
;
978 dtdSwap(&dtd
, oldDtd
);
979 isParamEntity
= XML_TRUE
;
980 XmlPrologStateInitExternalEntity(&prologState
);
981 processor
= externalParEntInitProcessor
;
988 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
991 BINDING
*b
= bindings
;
994 bindings
= b
->nextTagBinding
;
1001 XML_ParserFree(XML_Parser parser
)
1005 if (tagStack
== 0) {
1006 if (freeTagList
== NULL
)
1008 tagStack
= freeTagList
;
1012 tagStack
= tagStack
->parent
;
1014 destroyBindings(p
->bindings
, parser
);
1017 destroyBindings(freeBindingList
, parser
);
1018 destroyBindings(inheritedBindings
, parser
);
1019 poolDestroy(&tempPool
);
1020 poolDestroy(&temp2Pool
);
1023 dtdSwap(&dtd
, &parentParser
->m_dtd
);
1024 #endif /* XML_DTD */
1025 dtdDestroy(&dtd
, parser
);
1028 FREE(groupConnector
);
1032 if (unknownEncodingMem
)
1033 FREE(unknownEncodingMem
);
1034 if (unknownEncodingRelease
)
1035 unknownEncodingRelease(unknownEncodingData
);
1040 XML_UseParserAsHandlerArg(XML_Parser parser
)
1042 handlerArg
= parser
;
1046 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1049 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1051 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1052 useForeignDTD
= useDTD
;
1053 return XML_ERROR_NONE
;
1055 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1060 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1062 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1065 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1069 XML_SetUserData(XML_Parser parser
, void *p
)
1071 if (handlerArg
== userData
)
1072 handlerArg
= userData
= p
;
1078 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1081 p
= poolCopyString(&dtd
.pool
, p
);
1092 XML_GetBase(XML_Parser parser
)
1098 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1100 return nSpecifiedAtts
;
1104 XML_GetIdAttributeIndex(XML_Parser parser
)
1110 XML_SetElementHandler(XML_Parser parser
,
1111 XML_StartElementHandler start
,
1112 XML_EndElementHandler end
)
1114 startElementHandler
= start
;
1115 endElementHandler
= end
;
1119 XML_SetStartElementHandler(XML_Parser parser
,
1120 XML_StartElementHandler start
) {
1121 startElementHandler
= start
;
1125 XML_SetEndElementHandler(XML_Parser parser
,
1126 XML_EndElementHandler end
) {
1127 endElementHandler
= end
;
1131 XML_SetCharacterDataHandler(XML_Parser parser
,
1132 XML_CharacterDataHandler handler
)
1134 characterDataHandler
= handler
;
1138 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1139 XML_ProcessingInstructionHandler handler
)
1141 processingInstructionHandler
= handler
;
1145 XML_SetCommentHandler(XML_Parser parser
,
1146 XML_CommentHandler handler
)
1148 commentHandler
= handler
;
1152 XML_SetCdataSectionHandler(XML_Parser parser
,
1153 XML_StartCdataSectionHandler start
,
1154 XML_EndCdataSectionHandler end
)
1156 startCdataSectionHandler
= start
;
1157 endCdataSectionHandler
= end
;
1161 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1162 XML_StartCdataSectionHandler start
) {
1163 startCdataSectionHandler
= start
;
1167 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1168 XML_EndCdataSectionHandler end
) {
1169 endCdataSectionHandler
= end
;
1173 XML_SetDefaultHandler(XML_Parser parser
,
1174 XML_DefaultHandler handler
)
1176 defaultHandler
= handler
;
1177 defaultExpandInternalEntities
= XML_FALSE
;
1181 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1182 XML_DefaultHandler handler
)
1184 defaultHandler
= handler
;
1185 defaultExpandInternalEntities
= XML_TRUE
;
1189 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1190 XML_StartDoctypeDeclHandler start
,
1191 XML_EndDoctypeDeclHandler end
)
1193 startDoctypeDeclHandler
= start
;
1194 endDoctypeDeclHandler
= end
;
1198 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1199 XML_StartDoctypeDeclHandler start
) {
1200 startDoctypeDeclHandler
= start
;
1204 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1205 XML_EndDoctypeDeclHandler end
) {
1206 endDoctypeDeclHandler
= end
;
1210 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1211 XML_UnparsedEntityDeclHandler handler
)
1213 unparsedEntityDeclHandler
= handler
;
1217 XML_SetNotationDeclHandler(XML_Parser parser
,
1218 XML_NotationDeclHandler handler
)
1220 notationDeclHandler
= handler
;
1224 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1225 XML_StartNamespaceDeclHandler start
,
1226 XML_EndNamespaceDeclHandler end
)
1228 startNamespaceDeclHandler
= start
;
1229 endNamespaceDeclHandler
= end
;
1233 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1234 XML_StartNamespaceDeclHandler start
) {
1235 startNamespaceDeclHandler
= start
;
1239 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1240 XML_EndNamespaceDeclHandler end
) {
1241 endNamespaceDeclHandler
= end
;
1245 XML_SetNotStandaloneHandler(XML_Parser parser
,
1246 XML_NotStandaloneHandler handler
)
1248 notStandaloneHandler
= handler
;
1252 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1253 XML_ExternalEntityRefHandler handler
)
1255 externalEntityRefHandler
= handler
;
1259 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1262 externalEntityRefHandlerArg
= arg
;
1264 externalEntityRefHandlerArg
= parser
;
1268 XML_SetSkippedEntityHandler(XML_Parser parser
,
1269 XML_SkippedEntityHandler handler
)
1271 skippedEntityHandler
= handler
;
1275 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1276 XML_UnknownEncodingHandler handler
,
1279 unknownEncodingHandler
= handler
;
1280 unknownEncodingHandlerData
= data
;
1284 XML_SetElementDeclHandler(XML_Parser parser
,
1285 XML_ElementDeclHandler eldecl
)
1287 elementDeclHandler
= eldecl
;
1291 XML_SetAttlistDeclHandler(XML_Parser parser
,
1292 XML_AttlistDeclHandler attdecl
)
1294 attlistDeclHandler
= attdecl
;
1298 XML_SetEntityDeclHandler(XML_Parser parser
,
1299 XML_EntityDeclHandler handler
)
1301 entityDeclHandler
= handler
;
1305 XML_SetXmlDeclHandler(XML_Parser parser
,
1306 XML_XmlDeclHandler handler
) {
1307 xmlDeclHandler
= handler
;
1311 XML_SetParamEntityParsing(XML_Parser parser
,
1312 enum XML_ParamEntityParsing peParsing
)
1314 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1318 paramEntityParsing
= peParsing
;
1321 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1326 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1330 return XML_STATUS_OK
;
1331 positionPtr
= bufferPtr
;
1332 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1333 if (errorCode
== XML_ERROR_NONE
)
1334 return XML_STATUS_OK
;
1335 eventEndPtr
= eventPtr
;
1336 processor
= errorProcessor
;
1337 return XML_STATUS_ERROR
;
1339 #ifndef XML_CONTEXT_BYTES
1340 else if (bufferPtr
== bufferEnd
) {
1343 parseEndByteIndex
+= len
;
1346 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1347 if (errorCode
== XML_ERROR_NONE
)
1348 return XML_STATUS_OK
;
1349 eventEndPtr
= eventPtr
;
1350 processor
= errorProcessor
;
1351 return XML_STATUS_ERROR
;
1353 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1354 if (errorCode
!= XML_ERROR_NONE
) {
1355 eventEndPtr
= eventPtr
;
1356 processor
= errorProcessor
;
1357 return XML_STATUS_ERROR
;
1359 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1360 nLeftOver
= s
+ len
- end
;
1362 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1363 /* FIXME avoid integer overflow */
1365 temp
= buffer
== NULL
? MALLOC(len
* 2) : REALLOC(buffer
, len
* 2);
1367 errorCode
= XML_ERROR_NO_MEMORY
;
1368 return XML_STATUS_ERROR
;
1372 errorCode
= XML_ERROR_NO_MEMORY
;
1373 eventPtr
= eventEndPtr
= NULL
;
1374 processor
= errorProcessor
;
1375 return XML_STATUS_ERROR
;
1377 bufferLim
= buffer
+ len
* 2;
1379 memcpy(buffer
, end
, nLeftOver
);
1381 bufferEnd
= buffer
+ nLeftOver
;
1383 return XML_STATUS_OK
;
1385 #endif /* not defined XML_CONTEXT_BYTES */
1387 void *buff
= XML_GetBuffer(parser
, len
);
1389 return XML_STATUS_ERROR
;
1391 memcpy(buff
, s
, len
);
1392 return XML_ParseBuffer(parser
, len
, isFinal
);
1398 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1400 const char *start
= bufferPtr
;
1401 positionPtr
= start
;
1403 parseEndByteIndex
+= len
;
1404 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1405 isFinal
? (const char **)NULL
: &bufferPtr
);
1406 if (errorCode
== XML_ERROR_NONE
) {
1408 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1409 return XML_STATUS_OK
;
1412 eventEndPtr
= eventPtr
;
1413 processor
= errorProcessor
;
1414 return XML_STATUS_ERROR
;
1419 XML_GetBuffer(XML_Parser parser
, int len
)
1421 if (len
> bufferLim
- bufferEnd
) {
1422 /* FIXME avoid integer overflow */
1423 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1424 #ifdef XML_CONTEXT_BYTES
1425 int keep
= bufferPtr
- buffer
;
1427 if (keep
> XML_CONTEXT_BYTES
)
1428 keep
= XML_CONTEXT_BYTES
;
1430 #endif /* defined XML_CONTEXT_BYTES */
1431 if (neededSize
<= bufferLim
- buffer
) {
1432 #ifdef XML_CONTEXT_BYTES
1433 if (keep
< bufferPtr
- buffer
) {
1434 int offset
= (bufferPtr
- buffer
) - keep
;
1435 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1436 bufferEnd
-= offset
;
1437 bufferPtr
-= offset
;
1440 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1441 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1443 #endif /* not defined XML_CONTEXT_BYTES */
1447 int bufferSize
= bufferLim
- bufferPtr
;
1448 if (bufferSize
== 0)
1449 bufferSize
= INIT_BUFFER_SIZE
;
1452 } while (bufferSize
< neededSize
);
1453 newBuf
= MALLOC(bufferSize
);
1455 errorCode
= XML_ERROR_NO_MEMORY
;
1458 bufferLim
= newBuf
+ bufferSize
;
1459 #ifdef XML_CONTEXT_BYTES
1461 int keep
= bufferPtr
- buffer
;
1462 if (keep
> XML_CONTEXT_BYTES
)
1463 keep
= XML_CONTEXT_BYTES
;
1464 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1467 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1468 bufferPtr
= buffer
+ keep
;
1471 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1472 bufferPtr
= buffer
= newBuf
;
1476 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1479 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1480 bufferPtr
= buffer
= newBuf
;
1481 #endif /* not defined XML_CONTEXT_BYTES */
1488 XML_GetErrorCode(XML_Parser parser
)
1494 XML_GetCurrentByteIndex(XML_Parser parser
)
1497 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1502 XML_GetCurrentByteCount(XML_Parser parser
)
1504 if (eventEndPtr
&& eventPtr
)
1505 return eventEndPtr
- eventPtr
;
1510 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1512 #ifdef XML_CONTEXT_BYTES
1513 if (eventPtr
&& buffer
) {
1514 *offset
= eventPtr
- buffer
;
1515 *size
= bufferEnd
- buffer
;
1518 #endif /* defined XML_CONTEXT_BYTES */
1523 XML_GetCurrentLineNumber(XML_Parser parser
)
1526 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1527 positionPtr
= eventPtr
;
1529 return position
.lineNumber
+ 1;
1533 XML_GetCurrentColumnNumber(XML_Parser parser
)
1536 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1537 positionPtr
= eventPtr
;
1539 return position
.columnNumber
;
1543 XML_DefaultCurrent(XML_Parser parser
)
1545 if (defaultHandler
) {
1546 if (openInternalEntities
)
1547 reportDefault(parser
,
1549 openInternalEntities
->internalEventPtr
,
1550 openInternalEntities
->internalEventEndPtr
);
1552 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1557 XML_ErrorString(enum XML_Error code
)
1559 static const XML_LChar
*message
[] = {
1561 XML_L("out of memory"),
1562 XML_L("syntax error"),
1563 XML_L("no element found"),
1564 XML_L("not well-formed (invalid token)"),
1565 XML_L("unclosed token"),
1566 XML_L("partial character"),
1567 XML_L("mismatched tag"),
1568 XML_L("duplicate attribute"),
1569 XML_L("junk after document element"),
1570 XML_L("illegal parameter entity reference"),
1571 XML_L("undefined entity"),
1572 XML_L("recursive entity reference"),
1573 XML_L("asynchronous entity"),
1574 XML_L("reference to invalid character number"),
1575 XML_L("reference to binary entity"),
1576 XML_L("reference to external entity in attribute"),
1577 XML_L("xml declaration not at start of external entity"),
1578 XML_L("unknown encoding"),
1579 XML_L("encoding specified in XML declaration is incorrect"),
1580 XML_L("unclosed CDATA section"),
1581 XML_L("error in processing external entity reference"),
1582 XML_L("document is not standalone"),
1583 XML_L("unexpected parser state - please send a bug report"),
1584 XML_L("entity declared in parameter entity"),
1585 XML_L("requested feature requires XML_DTD support in Expat"),
1586 XML_L("cannot change setting once parsing has begun")
1588 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1589 return message
[code
];
1594 XML_ExpatVersion(void) {
1596 /* V1 is used to string-ize the version number. However, it would
1597 string-ize the actual version macro *names* unless we get them
1598 substituted before being passed to V1. CPP is defined to expand
1599 a macro, then rescan for more expansions. Thus, we use V2 to expand
1600 the version macros, then CPP will expand the resulting V1() macro
1601 with the correct numerals. */
1602 /* ### I'm assuming cpp is portable in this respect... */
1604 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1605 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1607 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1614 XML_ExpatVersionInfo(void)
1616 XML_Expat_Version version
;
1618 version
.major
= XML_MAJOR_VERSION
;
1619 version
.minor
= XML_MINOR_VERSION
;
1620 version
.micro
= XML_MICRO_VERSION
;
1626 XML_GetFeatureList(void)
1628 static XML_Feature features
[] = {
1629 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)")},
1630 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)")},
1632 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE")},
1634 #ifdef XML_UNICODE_WCHAR_T
1635 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T")},
1638 {XML_FEATURE_DTD
, XML_L("XML_DTD")},
1640 #ifdef XML_CONTEXT_BYTES
1641 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1645 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE")},
1647 {XML_FEATURE_END
, NULL
}
1650 features
[0].value
= sizeof(XML_Char
);
1651 features
[1].value
= sizeof(XML_LChar
);
1655 /* Initially tag->rawName always points into the parse buffer;
1656 for those TAG instances opened while the current parse buffer was
1657 processed, and not yet closed, we need to store tag->rawName in a more
1658 permanent location, since the parse buffer is about to be discarded.
1660 static XML_Bool FASTCALL
1661 storeRawNames(XML_Parser parser
)
1663 TAG
*tag
= tagStack
;
1666 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1667 char *rawNameBuf
= tag
->buf
+ nameLen
;
1668 /* Stop if already stored. Since tagStack is a stack, we can stop
1669 at the first entry that has already been copied; everything
1670 below it in the stack is already been accounted for in a
1671 previous call to this function.
1673 if (tag
->rawName
== rawNameBuf
)
1675 /* For re-use purposes we need to ensure that the
1676 size of tag->buf is a multiple of sizeof(XML_Char).
1678 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1679 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1680 char *temp
= REALLOC(tag
->buf
, bufSize
);
1684 tag
->name
.str
= (XML_Char
*)temp
;
1685 tag
->bufEnd
= temp
+ bufSize
;
1686 rawNameBuf
= temp
+ nameLen
;
1688 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
1689 tag
->rawName
= rawNameBuf
;
1695 static enum XML_Error FASTCALL
1696 contentProcessor(XML_Parser parser
,
1699 const char **endPtr
)
1701 enum XML_Error result
=
1702 doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1703 if (result
!= XML_ERROR_NONE
)
1705 if (!storeRawNames(parser
))
1706 return XML_ERROR_NO_MEMORY
;
1710 static enum XML_Error FASTCALL
1711 externalEntityInitProcessor(XML_Parser parser
,
1714 const char **endPtr
)
1716 enum XML_Error result
= initializeEncoding(parser
);
1717 if (result
!= XML_ERROR_NONE
)
1719 processor
= externalEntityInitProcessor2
;
1720 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1723 static enum XML_Error FASTCALL
1724 externalEntityInitProcessor2(XML_Parser parser
,
1727 const char **endPtr
)
1729 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1730 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1733 /* If we are at the end of the buffer, this would cause the next stage,
1734 i.e. externalEntityInitProcessor3, to pass control directly to
1735 doContent (by detecting XML_TOK_NONE) without processing any xml text
1736 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1738 if (next
== end
&& endPtr
) {
1740 return XML_ERROR_NONE
;
1744 case XML_TOK_PARTIAL
:
1747 return XML_ERROR_NONE
;
1750 return XML_ERROR_UNCLOSED_TOKEN
;
1751 case XML_TOK_PARTIAL_CHAR
:
1754 return XML_ERROR_NONE
;
1757 return XML_ERROR_PARTIAL_CHAR
;
1759 processor
= externalEntityInitProcessor3
;
1760 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1763 static enum XML_Error FASTCALL
1764 externalEntityInitProcessor3(XML_Parser parser
,
1767 const char **endPtr
)
1769 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
1770 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1772 case XML_TOK_XML_DECL
:
1774 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1775 if (result
!= XML_ERROR_NONE
)
1780 case XML_TOK_PARTIAL
:
1783 return XML_ERROR_NONE
;
1786 return XML_ERROR_UNCLOSED_TOKEN
;
1787 case XML_TOK_PARTIAL_CHAR
:
1790 return XML_ERROR_NONE
;
1793 return XML_ERROR_PARTIAL_CHAR
;
1795 processor
= externalEntityContentProcessor
;
1797 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
1800 static enum XML_Error FASTCALL
1801 externalEntityContentProcessor(XML_Parser parser
,
1804 const char **endPtr
)
1806 enum XML_Error result
=
1807 doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1808 if (result
!= XML_ERROR_NONE
)
1810 if (!storeRawNames(parser
))
1811 return XML_ERROR_NO_MEMORY
;
1815 static enum XML_Error FASTCALL
1816 doContent(XML_Parser parser
,
1818 const ENCODING
*enc
,
1821 const char **nextPtr
)
1823 const char **eventPP
;
1824 const char **eventEndPP
;
1825 if (enc
== encoding
) {
1826 eventPP
= &eventPtr
;
1827 eventEndPP
= &eventEndPtr
;
1830 eventPP
= &(openInternalEntities
->internalEventPtr
);
1831 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1835 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1836 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1839 case XML_TOK_TRAILING_CR
:
1842 return XML_ERROR_NONE
;
1845 if (characterDataHandler
) {
1847 characterDataHandler(handlerArg
, &c
, 1);
1849 else if (defaultHandler
)
1850 reportDefault(parser
, enc
, s
, end
);
1851 if (startTagLevel
== 0)
1852 return XML_ERROR_NO_ELEMENTS
;
1853 if (tagLevel
!= startTagLevel
)
1854 return XML_ERROR_ASYNC_ENTITY
;
1855 return XML_ERROR_NONE
;
1859 return XML_ERROR_NONE
;
1861 if (startTagLevel
> 0) {
1862 if (tagLevel
!= startTagLevel
)
1863 return XML_ERROR_ASYNC_ENTITY
;
1864 return XML_ERROR_NONE
;
1866 return XML_ERROR_NO_ELEMENTS
;
1867 case XML_TOK_INVALID
:
1869 return XML_ERROR_INVALID_TOKEN
;
1870 case XML_TOK_PARTIAL
:
1873 return XML_ERROR_NONE
;
1875 return XML_ERROR_UNCLOSED_TOKEN
;
1876 case XML_TOK_PARTIAL_CHAR
:
1879 return XML_ERROR_NONE
;
1881 return XML_ERROR_PARTIAL_CHAR
;
1882 case XML_TOK_ENTITY_REF
:
1884 const XML_Char
*name
;
1886 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
1887 s
+ enc
->minBytesPerChar
,
1888 next
- enc
->minBytesPerChar
);
1890 if (characterDataHandler
)
1891 characterDataHandler(handlerArg
, &ch
, 1);
1892 else if (defaultHandler
)
1893 reportDefault(parser
, enc
, s
, next
);
1896 name
= poolStoreString(&dtd
.pool
, enc
,
1897 s
+ enc
->minBytesPerChar
,
1898 next
- enc
->minBytesPerChar
);
1900 return XML_ERROR_NO_MEMORY
;
1901 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
1902 poolDiscard(&dtd
.pool
);
1903 /* First, determine if a check for an existing declaration is needed;
1904 if yes, check that the entity exists, and that it is internal,
1905 otherwise call the skipped entity or default handler.
1907 if (!dtd
.hasParamEntityRefs
|| dtd
.standalone
) {
1909 return XML_ERROR_UNDEFINED_ENTITY
;
1910 else if (!entity
->is_internal
)
1911 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
1914 if (skippedEntityHandler
)
1915 skippedEntityHandler(handlerArg
, name
, 0);
1916 else if (defaultHandler
)
1917 reportDefault(parser
, enc
, s
, next
);
1921 return XML_ERROR_RECURSIVE_ENTITY_REF
;
1922 if (entity
->notation
)
1923 return XML_ERROR_BINARY_ENTITY_REF
;
1924 if (entity
->textPtr
) {
1925 enum XML_Error result
;
1926 OPEN_INTERNAL_ENTITY openEntity
;
1927 if (!defaultExpandInternalEntities
) {
1928 if (skippedEntityHandler
)
1929 skippedEntityHandler(handlerArg
, entity
->name
, 0);
1930 else if (defaultHandler
)
1931 reportDefault(parser
, enc
, s
, next
);
1934 entity
->open
= XML_TRUE
;
1935 openEntity
.next
= openInternalEntities
;
1936 openInternalEntities
= &openEntity
;
1937 openEntity
.entity
= entity
;
1938 openEntity
.internalEventPtr
= NULL
;
1939 openEntity
.internalEventEndPtr
= NULL
;
1940 result
= doContent(parser
,
1943 (char *)entity
->textPtr
,
1944 (char *)(entity
->textPtr
+ entity
->textLen
),
1946 entity
->open
= XML_FALSE
;
1947 openInternalEntities
= openEntity
.next
;
1951 else if (externalEntityRefHandler
) {
1952 const XML_Char
*context
;
1953 entity
->open
= XML_TRUE
;
1954 context
= getContext(parser
);
1955 entity
->open
= XML_FALSE
;
1957 return XML_ERROR_NO_MEMORY
;
1958 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
1963 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
1964 poolDiscard(&tempPool
);
1966 else if (defaultHandler
)
1967 reportDefault(parser
, enc
, s
, next
);
1970 case XML_TOK_START_TAG_WITH_ATTS
:
1971 if (!startElementHandler
) {
1972 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
1977 case XML_TOK_START_TAG_NO_ATTS
:
1980 enum XML_Error result
;
1984 freeTagList
= freeTagList
->parent
;
1987 tag
= MALLOC(sizeof(TAG
));
1989 return XML_ERROR_NO_MEMORY
;
1990 tag
->buf
= MALLOC(INIT_TAG_BUF_SIZE
);
1993 return XML_ERROR_NO_MEMORY
;
1995 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
1997 tag
->bindings
= NULL
;
1998 tag
->parent
= tagStack
;
2000 tag
->name
.localPart
= NULL
;
2001 tag
->name
.prefix
= NULL
;
2002 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2003 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2006 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2007 const char *fromPtr
= tag
->rawName
;
2008 toPtr
= (XML_Char
*)tag
->buf
;
2013 &fromPtr
, rawNameEnd
,
2014 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2015 convLen
= toPtr
- (XML_Char
*)tag
->buf
;
2016 if (fromPtr
== rawNameEnd
) {
2017 tag
->name
.strLen
= convLen
;
2020 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
2022 char *temp
= REALLOC(tag
->buf
, bufSize
);
2024 return XML_ERROR_NO_MEMORY
;
2026 tag
->bufEnd
= temp
+ bufSize
;
2027 toPtr
= (XML_Char
*)temp
+ convLen
;
2031 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2032 *toPtr
= XML_T('\0');
2033 if (startElementHandler
) {
2034 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2037 startElementHandler(handlerArg
, tag
->name
.str
,
2038 (const XML_Char
**)atts
);
2040 else if (defaultHandler
)
2041 reportDefault(parser
, enc
, s
, next
);
2042 poolClear(&tempPool
);
2045 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2046 if (!startElementHandler
) {
2047 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
2052 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2053 if (startElementHandler
|| endElementHandler
) {
2054 const char *rawName
= s
+ enc
->minBytesPerChar
;
2055 enum XML_Error result
;
2056 BINDING
*bindings
= NULL
;
2058 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2059 rawName
+ XmlNameLength(enc
, rawName
));
2061 return XML_ERROR_NO_MEMORY
;
2062 poolFinish(&tempPool
);
2063 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2066 poolFinish(&tempPool
);
2067 if (startElementHandler
)
2068 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2069 if (endElementHandler
) {
2070 if (startElementHandler
)
2071 *eventPP
= *eventEndPP
;
2072 endElementHandler(handlerArg
, name
.str
);
2074 poolClear(&tempPool
);
2076 BINDING
*b
= bindings
;
2077 if (endNamespaceDeclHandler
)
2078 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2079 bindings
= bindings
->nextTagBinding
;
2080 b
->nextTagBinding
= freeBindingList
;
2081 freeBindingList
= b
;
2082 b
->prefix
->binding
= b
->prevPrefixBinding
;
2085 else if (defaultHandler
)
2086 reportDefault(parser
, enc
, s
, next
);
2088 return epilogProcessor(parser
, next
, end
, nextPtr
);
2090 case XML_TOK_END_TAG
:
2091 if (tagLevel
== startTagLevel
)
2092 return XML_ERROR_ASYNC_ENTITY
;
2095 const char *rawName
;
2096 TAG
*tag
= tagStack
;
2097 tagStack
= tag
->parent
;
2098 tag
->parent
= freeTagList
;
2100 rawName
= s
+ enc
->minBytesPerChar
*2;
2101 len
= XmlNameLength(enc
, rawName
);
2102 if (len
!= tag
->rawNameLength
2103 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2105 return XML_ERROR_TAG_MISMATCH
;
2108 if (endElementHandler
) {
2109 const XML_Char
*localPart
;
2110 const XML_Char
*prefix
;
2112 localPart
= tag
->name
.localPart
;
2113 if (ns
&& localPart
) {
2114 /* localPart and prefix may have been overwritten in
2115 tag->name.str, since this points to the binding->uri
2116 buffer which gets re-used; so we have to add them again
2118 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2119 /* don't need to check for space - already done in storeAtts() */
2120 while (*localPart
) *uri
++ = *localPart
++;
2121 prefix
= (XML_Char
*)tag
->name
.prefix
;
2122 if (ns_triplets
&& prefix
) {
2123 *uri
++ = namespaceSeparator
;
2124 while (*prefix
) *uri
++ = *prefix
++;
2128 endElementHandler(handlerArg
, tag
->name
.str
);
2130 else if (defaultHandler
)
2131 reportDefault(parser
, enc
, s
, next
);
2132 while (tag
->bindings
) {
2133 BINDING
*b
= tag
->bindings
;
2134 if (endNamespaceDeclHandler
)
2135 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2136 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2137 b
->nextTagBinding
= freeBindingList
;
2138 freeBindingList
= b
;
2139 b
->prefix
->binding
= b
->prevPrefixBinding
;
2142 return epilogProcessor(parser
, next
, end
, nextPtr
);
2145 case XML_TOK_CHAR_REF
:
2147 int n
= XmlCharRefNumber(enc
, s
);
2149 return XML_ERROR_BAD_CHAR_REF
;
2150 if (characterDataHandler
) {
2151 XML_Char buf
[XML_ENCODE_MAX
];
2152 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2154 else if (defaultHandler
)
2155 reportDefault(parser
, enc
, s
, next
);
2158 case XML_TOK_XML_DECL
:
2159 return XML_ERROR_MISPLACED_XML_PI
;
2160 case XML_TOK_DATA_NEWLINE
:
2161 if (characterDataHandler
) {
2163 characterDataHandler(handlerArg
, &c
, 1);
2165 else if (defaultHandler
)
2166 reportDefault(parser
, enc
, s
, next
);
2168 case XML_TOK_CDATA_SECT_OPEN
:
2170 enum XML_Error result
;
2171 if (startCdataSectionHandler
)
2172 startCdataSectionHandler(handlerArg
);
2174 /* Suppose you doing a transformation on a document that involves
2175 changing only the character data. You set up a defaultHandler
2176 and a characterDataHandler. The defaultHandler simply copies
2177 characters through. The characterDataHandler does the
2178 transformation and writes the characters out escaping them as
2179 necessary. This case will fail to work if we leave out the
2180 following two lines (because & and < inside CDATA sections will
2181 be incorrectly escaped).
2183 However, now we have a start/endCdataSectionHandler, so it seems
2184 easier to let the user deal with this.
2186 else if (characterDataHandler
)
2187 characterDataHandler(handlerArg
, dataBuf
, 0);
2189 else if (defaultHandler
)
2190 reportDefault(parser
, enc
, s
, next
);
2191 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
2193 processor
= cdataSectionProcessor
;
2198 case XML_TOK_TRAILING_RSQB
:
2201 return XML_ERROR_NONE
;
2203 if (characterDataHandler
) {
2204 if (MUST_CONVERT(enc
, s
)) {
2205 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2206 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2207 characterDataHandler(handlerArg
, dataBuf
,
2208 dataPtr
- (ICHAR
*)dataBuf
);
2211 characterDataHandler(handlerArg
,
2213 (XML_Char
*)end
- (XML_Char
*)s
);
2215 else if (defaultHandler
)
2216 reportDefault(parser
, enc
, s
, end
);
2217 if (startTagLevel
== 0) {
2219 return XML_ERROR_NO_ELEMENTS
;
2221 if (tagLevel
!= startTagLevel
) {
2223 return XML_ERROR_ASYNC_ENTITY
;
2225 return XML_ERROR_NONE
;
2226 case XML_TOK_DATA_CHARS
:
2227 if (characterDataHandler
) {
2228 if (MUST_CONVERT(enc
, s
)) {
2230 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2231 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2233 characterDataHandler(handlerArg
, dataBuf
,
2234 dataPtr
- (ICHAR
*)dataBuf
);
2241 characterDataHandler(handlerArg
,
2243 (XML_Char
*)next
- (XML_Char
*)s
);
2245 else if (defaultHandler
)
2246 reportDefault(parser
, enc
, s
, next
);
2249 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2250 return XML_ERROR_NO_MEMORY
;
2252 case XML_TOK_COMMENT
:
2253 if (!reportComment(parser
, enc
, s
, next
))
2254 return XML_ERROR_NO_MEMORY
;
2258 reportDefault(parser
, enc
, s
, next
);
2261 *eventPP
= s
= next
;
2266 /* If tagNamePtr is non-null, build a real list of attributes,
2267 otherwise just check the attributes for well-formedness.
2269 static enum XML_Error FASTCALL
2270 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2271 const char *attStr
, TAG_NAME
*tagNamePtr
,
2272 BINDING
**bindingsPtr
)
2274 ELEMENT_TYPE
*elementType
= NULL
;
2275 int nDefaultAtts
= 0;
2276 const XML_Char
**appAtts
; /* the attribute list for the application */
2284 const XML_Char
*localPart
;
2286 /* lookup the element type name */
2288 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
,0);
2290 tagNamePtr
->str
= poolCopyString(&dtd
.pool
, tagNamePtr
->str
);
2291 if (!tagNamePtr
->str
)
2292 return XML_ERROR_NO_MEMORY
;
2293 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
,
2294 sizeof(ELEMENT_TYPE
));
2296 return XML_ERROR_NO_MEMORY
;
2297 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2298 return XML_ERROR_NO_MEMORY
;
2300 nDefaultAtts
= elementType
->nDefaultAtts
;
2302 /* get the attributes from the tokenizer */
2303 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2304 if (n
+ nDefaultAtts
> attsSize
) {
2305 int oldAttsSize
= attsSize
;
2307 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2308 temp
= REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2310 return XML_ERROR_NO_MEMORY
;
2312 if (n
> oldAttsSize
)
2313 XmlGetAttributes(enc
, attStr
, n
, atts
);
2315 appAtts
= (const XML_Char
**)atts
;
2316 for (i
= 0; i
< n
; i
++) {
2317 /* add the name and value to the attribute list */
2318 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2320 + XmlNameLength(enc
, atts
[i
].name
));
2322 return XML_ERROR_NO_MEMORY
;
2323 /* detect duplicate attributes */
2324 if ((attId
->name
)[-1]) {
2325 if (enc
== encoding
)
2326 eventPtr
= atts
[i
].name
;
2327 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2329 (attId
->name
)[-1] = 1;
2330 appAtts
[attIndex
++] = attId
->name
;
2331 if (!atts
[i
].normalized
) {
2332 enum XML_Error result
;
2333 XML_Bool isCdata
= XML_TRUE
;
2335 /* figure out whether declared as other than CDATA */
2336 if (attId
->maybeTokenized
) {
2338 for (j
= 0; j
< nDefaultAtts
; j
++) {
2339 if (attId
== elementType
->defaultAtts
[j
].id
) {
2340 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2346 /* normalize the attribute value */
2347 result
= storeAttributeValue(parser
, enc
, isCdata
,
2348 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2353 appAtts
[attIndex
] = poolStart(&tempPool
);
2354 poolFinish(&tempPool
);
2357 poolDiscard(&tempPool
);
2359 else if (tagNamePtr
) {
2360 /* the value did not need normalizing */
2361 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2363 if (appAtts
[attIndex
] == 0)
2364 return XML_ERROR_NO_MEMORY
;
2365 poolFinish(&tempPool
);
2367 /* handle prefixed attribute names */
2368 if (attId
->prefix
&& tagNamePtr
) {
2370 /* deal with namespace declarations here */
2371 if (!addBinding(parser
, attId
->prefix
, attId
, appAtts
[attIndex
],
2373 return XML_ERROR_NO_MEMORY
;
2377 /* deal with other prefixed names later */
2380 (attId
->name
)[-1] = 2;
2388 nSpecifiedAtts
= attIndex
;
2389 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2390 for (i
= 0; i
< attIndex
; i
+= 2)
2391 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2398 /* do attribute defaulting */
2399 for (j
= 0; j
< nDefaultAtts
; j
++) {
2400 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ j
;
2401 if (!(da
->id
->name
)[-1] && da
->value
) {
2402 if (da
->id
->prefix
) {
2403 if (da
->id
->xmlns
) {
2404 if (!addBinding(parser
, da
->id
->prefix
, da
->id
, da
->value
,
2406 return XML_ERROR_NO_MEMORY
;
2409 (da
->id
->name
)[-1] = 2;
2411 appAtts
[attIndex
++] = da
->id
->name
;
2412 appAtts
[attIndex
++] = da
->value
;
2416 (da
->id
->name
)[-1] = 1;
2417 appAtts
[attIndex
++] = da
->id
->name
;
2418 appAtts
[attIndex
++] = da
->value
;
2422 appAtts
[attIndex
] = 0;
2426 /* expand prefixed attribute names */
2427 for (; i
< attIndex
; i
+= 2) {
2428 if (appAtts
[i
][-1] == 2) {
2430 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2431 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, appAtts
[i
], 0);
2432 if (id
->prefix
->binding
) {
2434 const BINDING
*b
= id
->prefix
->binding
;
2435 const XML_Char
*s
= appAtts
[i
];
2436 for (j
= 0; j
< b
->uriLen
; j
++) {
2437 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2438 return XML_ERROR_NO_MEMORY
;
2440 while (*s
++ != XML_T(':'))
2443 if (!poolAppendChar(&tempPool
, *s
))
2444 return XML_ERROR_NO_MEMORY
;
2447 tempPool
.ptr
[-1] = namespaceSeparator
;
2448 s
= b
->prefix
->name
;
2450 if (!poolAppendChar(&tempPool
, *s
))
2451 return XML_ERROR_NO_MEMORY
;
2455 appAtts
[i
] = poolStart(&tempPool
);
2456 poolFinish(&tempPool
);
2462 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2465 /* clear the flags that say whether attributes were specified */
2466 for (; i
< attIndex
; i
+= 2)
2467 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2469 return XML_ERROR_NONE
;
2470 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2471 binding
->attId
->name
[-1] = 0;
2472 /* expand the element type name */
2473 if (elementType
->prefix
) {
2474 binding
= elementType
->prefix
->binding
;
2476 return XML_ERROR_NONE
;
2477 localPart
= tagNamePtr
->str
;
2478 while (*localPart
++ != XML_T(':'))
2481 else if (dtd
.defaultPrefix
.binding
) {
2482 binding
= dtd
.defaultPrefix
.binding
;
2483 localPart
= tagNamePtr
->str
;
2486 return XML_ERROR_NONE
;
2488 if (ns
&& ns_triplets
&& binding
->prefix
->name
) {
2489 for (; binding
->prefix
->name
[prefixLen
++];)
2492 tagNamePtr
->localPart
= localPart
;
2493 tagNamePtr
->uriLen
= binding
->uriLen
;
2494 tagNamePtr
->prefix
= binding
->prefix
->name
;
2495 tagNamePtr
->prefixLen
= prefixLen
;
2496 for (i
= 0; localPart
[i
++];)
2498 n
= i
+ binding
->uriLen
+ prefixLen
;
2499 if (n
> binding
->uriAlloc
) {
2501 uri
= MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2503 return XML_ERROR_NO_MEMORY
;
2504 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2505 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2506 for (p
= tagStack
; p
; p
= p
->parent
)
2507 if (p
->name
.str
== binding
->uri
)
2512 uri
= binding
->uri
+ binding
->uriLen
;
2513 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2515 uri
= uri
+ (i
- 1);
2516 if (namespaceSeparator
) { *(uri
) = namespaceSeparator
; }
2517 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2519 tagNamePtr
->str
= binding
->uri
;
2520 return XML_ERROR_NONE
;
2524 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2525 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2529 for (len
= 0; uri
[len
]; len
++)
2531 if (namespaceSeparator
)
2533 if (freeBindingList
) {
2534 b
= freeBindingList
;
2535 if (len
> b
->uriAlloc
) {
2536 XML_Char
*temp
= REALLOC(b
->uri
,
2537 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2541 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2543 freeBindingList
= b
->nextTagBinding
;
2546 b
= MALLOC(sizeof(BINDING
));
2549 b
->uri
= MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2554 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2557 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2558 if (namespaceSeparator
)
2559 b
->uri
[len
- 1] = namespaceSeparator
;
2562 b
->prevPrefixBinding
= prefix
->binding
;
2563 if (*uri
== XML_T('\0') && prefix
== &dtd
.defaultPrefix
)
2564 prefix
->binding
= NULL
;
2566 prefix
->binding
= b
;
2567 b
->nextTagBinding
= *bindingsPtr
;
2569 if (startNamespaceDeclHandler
)
2570 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2571 prefix
->binding
? uri
: 0);
2575 /* The idea here is to avoid using stack for each CDATA section when
2576 the whole file is parsed with one call.
2578 static enum XML_Error FASTCALL
2579 cdataSectionProcessor(XML_Parser parser
,
2582 const char **endPtr
)
2584 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
,
2587 if (parentParser
) { /* we are parsing an external entity */
2588 processor
= externalEntityContentProcessor
;
2589 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2592 processor
= contentProcessor
;
2593 return contentProcessor(parser
, start
, end
, endPtr
);
2599 /* startPtr gets set to non-null is the section is closed, and to null if
2600 the section is not yet closed.
2602 static enum XML_Error FASTCALL
2603 doCdataSection(XML_Parser parser
,
2604 const ENCODING
*enc
,
2605 const char **startPtr
,
2607 const char **nextPtr
)
2609 const char *s
= *startPtr
;
2610 const char **eventPP
;
2611 const char **eventEndPP
;
2612 if (enc
== encoding
) {
2613 eventPP
= &eventPtr
;
2615 eventEndPP
= &eventEndPtr
;
2618 eventPP
= &(openInternalEntities
->internalEventPtr
);
2619 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2625 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2628 case XML_TOK_CDATA_SECT_CLOSE
:
2629 if (endCdataSectionHandler
)
2630 endCdataSectionHandler(handlerArg
);
2632 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2633 else if (characterDataHandler
)
2634 characterDataHandler(handlerArg
, dataBuf
, 0);
2636 else if (defaultHandler
)
2637 reportDefault(parser
, enc
, s
, next
);
2639 return XML_ERROR_NONE
;
2640 case XML_TOK_DATA_NEWLINE
:
2641 if (characterDataHandler
) {
2643 characterDataHandler(handlerArg
, &c
, 1);
2645 else if (defaultHandler
)
2646 reportDefault(parser
, enc
, s
, next
);
2648 case XML_TOK_DATA_CHARS
:
2649 if (characterDataHandler
) {
2650 if (MUST_CONVERT(enc
, s
)) {
2652 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2653 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2655 characterDataHandler(handlerArg
, dataBuf
,
2656 dataPtr
- (ICHAR
*)dataBuf
);
2663 characterDataHandler(handlerArg
,
2665 (XML_Char
*)next
- (XML_Char
*)s
);
2667 else if (defaultHandler
)
2668 reportDefault(parser
, enc
, s
, next
);
2670 case XML_TOK_INVALID
:
2672 return XML_ERROR_INVALID_TOKEN
;
2673 case XML_TOK_PARTIAL_CHAR
:
2676 return XML_ERROR_NONE
;
2678 return XML_ERROR_PARTIAL_CHAR
;
2679 case XML_TOK_PARTIAL
:
2683 return XML_ERROR_NONE
;
2685 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2688 return XML_ERROR_UNEXPECTED_STATE
;
2690 *eventPP
= s
= next
;
2697 /* The idea here is to avoid using stack for each IGNORE section when
2698 the whole file is parsed with one call.
2700 static enum XML_Error FASTCALL
2701 ignoreSectionProcessor(XML_Parser parser
,
2704 const char **endPtr
)
2706 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
,
2709 processor
= prologProcessor
;
2710 return prologProcessor(parser
, start
, end
, endPtr
);
2715 /* startPtr gets set to non-null is the section is closed, and to null
2716 if the section is not yet closed.
2718 static enum XML_Error FASTCALL
2719 doIgnoreSection(XML_Parser parser
,
2720 const ENCODING
*enc
,
2721 const char **startPtr
,
2723 const char **nextPtr
)
2727 const char *s
= *startPtr
;
2728 const char **eventPP
;
2729 const char **eventEndPP
;
2730 if (enc
== encoding
) {
2731 eventPP
= &eventPtr
;
2733 eventEndPP
= &eventEndPtr
;
2736 eventPP
= &(openInternalEntities
->internalEventPtr
);
2737 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2741 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2744 case XML_TOK_IGNORE_SECT
:
2746 reportDefault(parser
, enc
, s
, next
);
2748 return XML_ERROR_NONE
;
2749 case XML_TOK_INVALID
:
2751 return XML_ERROR_INVALID_TOKEN
;
2752 case XML_TOK_PARTIAL_CHAR
:
2755 return XML_ERROR_NONE
;
2757 return XML_ERROR_PARTIAL_CHAR
;
2758 case XML_TOK_PARTIAL
:
2762 return XML_ERROR_NONE
;
2764 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2767 return XML_ERROR_UNEXPECTED_STATE
;
2772 #endif /* XML_DTD */
2774 static enum XML_Error FASTCALL
2775 initializeEncoding(XML_Parser parser
)
2779 char encodingBuf
[128];
2780 if (!protocolEncodingName
)
2784 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2785 if (i
== sizeof(encodingBuf
) - 1
2786 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2787 encodingBuf
[0] = '\0';
2790 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2792 encodingBuf
[i
] = '\0';
2796 s
= protocolEncodingName
;
2798 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2799 return XML_ERROR_NONE
;
2800 return handleUnknownEncoding(parser
, protocolEncodingName
);
2803 static enum XML_Error FASTCALL
2804 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2805 const char *s
, const char *next
)
2807 const char *encodingName
= NULL
;
2808 const XML_Char
*storedEncName
= NULL
;
2809 const ENCODING
*newEncoding
= NULL
;
2810 const char *version
= NULL
;
2811 const char *versionend
;
2812 const XML_Char
*storedversion
= NULL
;
2813 int standalone
= -1;
2816 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2826 return XML_ERROR_SYNTAX
;
2827 if (!isGeneralTextEntity
&& standalone
== 1) {
2828 dtd
.standalone
= XML_TRUE
;
2830 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2831 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2832 #endif /* XML_DTD */
2834 if (xmlDeclHandler
) {
2835 if (encodingName
!= NULL
) {
2836 storedEncName
= poolStoreString(&temp2Pool
,
2840 + XmlNameLength(encoding
, encodingName
));
2842 return XML_ERROR_NO_MEMORY
;
2843 poolFinish(&temp2Pool
);
2846 storedversion
= poolStoreString(&temp2Pool
,
2849 versionend
- encoding
->minBytesPerChar
);
2851 return XML_ERROR_NO_MEMORY
;
2853 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2855 else if (defaultHandler
)
2856 reportDefault(parser
, encoding
, s
, next
);
2857 if (protocolEncodingName
== NULL
) {
2859 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2860 eventPtr
= encodingName
;
2861 return XML_ERROR_INCORRECT_ENCODING
;
2863 encoding
= newEncoding
;
2865 else if (encodingName
) {
2866 enum XML_Error result
;
2867 if (!storedEncName
) {
2868 storedEncName
= poolStoreString(
2869 &temp2Pool
, encoding
, encodingName
,
2870 encodingName
+ XmlNameLength(encoding
, encodingName
));
2872 return XML_ERROR_NO_MEMORY
;
2874 result
= handleUnknownEncoding(parser
, storedEncName
);
2875 poolClear(&temp2Pool
);
2876 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2877 eventPtr
= encodingName
;
2882 if (storedEncName
|| storedversion
)
2883 poolClear(&temp2Pool
);
2885 return XML_ERROR_NONE
;
2888 static enum XML_Error FASTCALL
2889 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2891 if (unknownEncodingHandler
) {
2894 for (i
= 0; i
< 256; i
++)
2896 info
.convert
= NULL
;
2898 info
.release
= NULL
;
2899 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
2902 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2903 if (!unknownEncodingMem
) {
2905 info
.release(info
.data
);
2906 return XML_ERROR_NO_MEMORY
;
2909 ? XmlInitUnknownEncodingNS
2910 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
2915 unknownEncodingData
= info
.data
;
2916 unknownEncodingRelease
= info
.release
;
2918 return XML_ERROR_NONE
;
2921 if (info
.release
!= NULL
)
2922 info
.release(info
.data
);
2924 return XML_ERROR_UNKNOWN_ENCODING
;
2927 static enum XML_Error FASTCALL
2928 prologInitProcessor(XML_Parser parser
,
2931 const char **nextPtr
)
2933 enum XML_Error result
= initializeEncoding(parser
);
2934 if (result
!= XML_ERROR_NONE
)
2936 processor
= prologProcessor
;
2937 return prologProcessor(parser
, s
, end
, nextPtr
);
2942 static enum XML_Error FASTCALL
2943 externalParEntInitProcessor(XML_Parser parser
,
2946 const char **nextPtr
)
2948 enum XML_Error result
= initializeEncoding(parser
);
2949 if (result
!= XML_ERROR_NONE
)
2952 /* we know now that XML_Parse(Buffer) has been called,
2953 so we consider the external parameter entity read */
2954 dtd
.paramEntityRead
= XML_TRUE
;
2956 if (prologState
.inEntityValue
) {
2957 processor
= entityValueInitProcessor
;
2958 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
2961 processor
= externalParEntProcessor
;
2962 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
2966 static enum XML_Error FASTCALL
2967 entityValueInitProcessor(XML_Parser parser
,
2970 const char **nextPtr
)
2972 const char *start
= s
;
2973 const char *next
= s
;
2977 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
2979 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
2981 return XML_ERROR_NONE
;
2984 case XML_TOK_INVALID
:
2985 return XML_ERROR_INVALID_TOKEN
;
2986 case XML_TOK_PARTIAL
:
2987 return XML_ERROR_UNCLOSED_TOKEN
;
2988 case XML_TOK_PARTIAL_CHAR
:
2989 return XML_ERROR_PARTIAL_CHAR
;
2990 case XML_TOK_NONE
: /* start == end */
2994 return storeEntityValue(parser
, encoding
, s
, end
);
2996 else if (tok
== XML_TOK_XML_DECL
) {
2997 enum XML_Error result
= processXmlDecl(parser
, 0, start
, next
);
2998 if (result
!= XML_ERROR_NONE
)
3000 if (nextPtr
) *nextPtr
= next
;
3001 /* stop scanning for text declaration - we found one */
3002 processor
= entityValueProcessor
;
3003 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3005 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3006 return XML_TOK_NONE on the next call, which would then cause the
3007 function to exit with *nextPtr set to s - that is what we want for other
3008 tokens, but not for the BOM - we would rather like to skip it;
3009 then, when this routine is entered the next time, XmlPrologTok will
3010 return XML_TOK_INVALID, since the BOM is still in the buffer
3012 else if (tok
== XML_TOK_BOM
&& next
== end
&& nextPtr
) {
3014 return XML_ERROR_NONE
;
3020 static enum XML_Error FASTCALL
3021 externalParEntProcessor(XML_Parser parser
,
3024 const char **nextPtr
)
3026 const char *start
= s
;
3027 const char *next
= s
;
3030 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3032 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3034 return XML_ERROR_NONE
;
3037 case XML_TOK_INVALID
:
3038 return XML_ERROR_INVALID_TOKEN
;
3039 case XML_TOK_PARTIAL
:
3040 return XML_ERROR_UNCLOSED_TOKEN
;
3041 case XML_TOK_PARTIAL_CHAR
:
3042 return XML_ERROR_PARTIAL_CHAR
;
3043 case XML_TOK_NONE
: /* start == end */
3048 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3049 However, when parsing an external subset, doProlog will not accept a BOM
3050 as valid, and report a syntax error, so we have to skip the BOM
3052 else if (tok
== XML_TOK_BOM
) {
3054 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3057 processor
= prologProcessor
;
3058 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3061 static enum XML_Error FASTCALL
3062 entityValueProcessor(XML_Parser parser
,
3065 const char **nextPtr
)
3067 const char *start
= s
;
3068 const char *next
= s
;
3069 const ENCODING
*enc
= encoding
;
3073 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3075 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3077 return XML_ERROR_NONE
;
3080 case XML_TOK_INVALID
:
3081 return XML_ERROR_INVALID_TOKEN
;
3082 case XML_TOK_PARTIAL
:
3083 return XML_ERROR_UNCLOSED_TOKEN
;
3084 case XML_TOK_PARTIAL_CHAR
:
3085 return XML_ERROR_PARTIAL_CHAR
;
3086 case XML_TOK_NONE
: /* start == end */
3090 return storeEntityValue(parser
, enc
, s
, end
);
3096 #endif /* XML_DTD */
3098 static enum XML_Error FASTCALL
3099 prologProcessor(XML_Parser parser
,
3102 const char **nextPtr
)
3104 const char *next
= s
;
3105 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3106 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
3109 static enum XML_Error FASTCALL
3110 doProlog(XML_Parser parser
,
3111 const ENCODING
*enc
,
3116 const char **nextPtr
)
3119 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
3120 #endif /* XML_DTD */
3121 static const XML_Char atypeCDATA
[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3122 static const XML_Char atypeID
[] = { 'I', 'D', '\0' };
3123 static const XML_Char atypeIDREF
[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3124 static const XML_Char atypeIDREFS
[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3125 static const XML_Char atypeENTITY
[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3126 static const XML_Char atypeENTITIES
[] =
3127 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3128 static const XML_Char atypeNMTOKEN
[] = {
3129 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3130 static const XML_Char atypeNMTOKENS
[] = {
3131 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3132 static const XML_Char notationPrefix
[] = {
3133 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3134 static const XML_Char enumValueSep
[] = { '|', '\0' };
3135 static const XML_Char enumValueStart
[] = { '(', '\0' };
3137 const char **eventPP
;
3138 const char **eventEndPP
;
3139 enum XML_Content_Quant quant
;
3141 if (enc
== encoding
) {
3142 eventPP
= &eventPtr
;
3143 eventEndPP
= &eventEndPtr
;
3146 eventPP
= &(openInternalEntities
->internalEventPtr
);
3147 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3151 XML_Bool handleDefault
= XML_TRUE
;
3155 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
3157 return XML_ERROR_NONE
;
3160 case XML_TOK_INVALID
:
3162 return XML_ERROR_INVALID_TOKEN
;
3163 case XML_TOK_PARTIAL
:
3164 return XML_ERROR_UNCLOSED_TOKEN
;
3165 case XML_TOK_PARTIAL_CHAR
:
3166 return XML_ERROR_PARTIAL_CHAR
;
3169 if (enc
!= encoding
)
3170 return XML_ERROR_NONE
;
3171 if (isParamEntity
) {
3172 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3174 return XML_ERROR_SYNTAX
;
3175 return XML_ERROR_NONE
;
3177 #endif /* XML_DTD */
3178 return XML_ERROR_NO_ELEMENTS
;
3185 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3187 case XML_ROLE_XML_DECL
:
3189 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3190 if (result
!= XML_ERROR_NONE
)
3193 handleDefault
= XML_FALSE
;
3196 case XML_ROLE_DOCTYPE_NAME
:
3197 if (startDoctypeDeclHandler
) {
3198 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3200 return XML_ERROR_NO_MEMORY
;
3201 poolFinish(&tempPool
);
3202 doctypePubid
= NULL
;
3203 handleDefault
= XML_FALSE
;
3205 doctypeSysid
= NULL
; /* always initialize to NULL */
3207 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3208 if (startDoctypeDeclHandler
) {
3209 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3212 poolClear(&tempPool
);
3213 handleDefault
= XML_FALSE
;
3217 case XML_ROLE_TEXT_DECL
:
3219 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3220 if (result
!= XML_ERROR_NONE
)
3223 handleDefault
= XML_FALSE
;
3226 #endif /* XML_DTD */
3227 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3229 useForeignDTD
= XML_FALSE
;
3230 #endif /* XML_DTD */
3231 dtd
.hasParamEntityRefs
= XML_TRUE
;
3232 if (startDoctypeDeclHandler
) {
3233 doctypePubid
= poolStoreString(&tempPool
, enc
,
3234 s
+ enc
->minBytesPerChar
,
3235 next
- enc
->minBytesPerChar
);
3237 return XML_ERROR_NO_MEMORY
;
3238 poolFinish(&tempPool
);
3239 handleDefault
= XML_FALSE
;
3242 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
3246 return XML_ERROR_NO_MEMORY
;
3247 #endif /* XML_DTD */
3249 case XML_ROLE_ENTITY_PUBLIC_ID
:
3250 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3251 return XML_ERROR_SYNTAX
;
3252 if (dtd
.keepProcessing
&& declEntity
) {
3253 XML_Char
*tem
= poolStoreString(&dtd
.pool
,
3255 s
+ enc
->minBytesPerChar
,
3256 next
- enc
->minBytesPerChar
);
3258 return XML_ERROR_NO_MEMORY
;
3259 normalizePublicId(tem
);
3260 declEntity
->publicId
= tem
;
3261 poolFinish(&dtd
.pool
);
3262 if (entityDeclHandler
)
3263 handleDefault
= XML_FALSE
;
3266 case XML_ROLE_DOCTYPE_CLOSE
:
3268 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3269 doctypeSysid
, doctypePubid
, 0);
3270 poolClear(&tempPool
);
3271 handleDefault
= XML_FALSE
;
3273 /* doctypeSysid will be non-NULL in the case of a previous
3274 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3275 was not set, indicating an external subset
3278 if (doctypeSysid
|| useForeignDTD
) {
3279 dtd
.hasParamEntityRefs
= XML_TRUE
; /* when docTypeSysid == NULL */
3280 if (paramEntityParsing
&& externalEntityRefHandler
) {
3281 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
3285 return XML_ERROR_NO_MEMORY
;
3287 entity
->base
= curBase
;
3288 dtd
.paramEntityRead
= XML_FALSE
;
3289 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3294 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3295 if (dtd
.paramEntityRead
&&
3297 notStandaloneHandler
&&
3298 !notStandaloneHandler(handlerArg
))
3299 return XML_ERROR_NOT_STANDALONE
;
3300 /* end of DTD - no need to update dtd.keepProcessing */
3302 useForeignDTD
= XML_FALSE
;
3304 #endif /* XML_DTD */
3305 if (endDoctypeDeclHandler
) {
3306 endDoctypeDeclHandler(handlerArg
);
3307 handleDefault
= XML_FALSE
;
3310 case XML_ROLE_INSTANCE_START
:
3312 /* if there is no DOCTYPE declaration then now is the
3313 last chance to read the foreign DTD
3315 if (useForeignDTD
) {
3316 dtd
.hasParamEntityRefs
= XML_TRUE
;
3317 if (paramEntityParsing
&& externalEntityRefHandler
) {
3318 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
3322 return XML_ERROR_NO_MEMORY
;
3323 entity
->base
= curBase
;
3324 dtd
.paramEntityRead
= XML_FALSE
;
3325 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3330 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3331 if (dtd
.paramEntityRead
&&
3333 notStandaloneHandler
&&
3334 !notStandaloneHandler(handlerArg
))
3335 return XML_ERROR_NOT_STANDALONE
;
3336 /* end of DTD - no need to update dtd.keepProcessing */
3339 #endif /* XML_DTD */
3340 processor
= contentProcessor
;
3341 return contentProcessor(parser
, s
, end
, nextPtr
);
3342 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3343 declElementType
= getElementType(parser
, enc
, s
, next
);
3344 if (!declElementType
)
3345 return XML_ERROR_NO_MEMORY
;
3346 goto checkAttListDeclHandler
;
3347 case XML_ROLE_ATTRIBUTE_NAME
:
3348 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3349 if (!declAttributeId
)
3350 return XML_ERROR_NO_MEMORY
;
3351 declAttributeIsCdata
= XML_FALSE
;
3352 declAttributeType
= NULL
;
3353 declAttributeIsId
= XML_FALSE
;
3354 goto checkAttListDeclHandler
;
3355 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3356 declAttributeIsCdata
= XML_TRUE
;
3357 declAttributeType
= atypeCDATA
;
3358 goto checkAttListDeclHandler
;
3359 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3360 declAttributeIsId
= XML_TRUE
;
3361 declAttributeType
= atypeID
;
3362 goto checkAttListDeclHandler
;
3363 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3364 declAttributeType
= atypeIDREF
;
3365 goto checkAttListDeclHandler
;
3366 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3367 declAttributeType
= atypeIDREFS
;
3368 goto checkAttListDeclHandler
;
3369 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3370 declAttributeType
= atypeENTITY
;
3371 goto checkAttListDeclHandler
;
3372 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3373 declAttributeType
= atypeENTITIES
;
3374 goto checkAttListDeclHandler
;
3375 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3376 declAttributeType
= atypeNMTOKEN
;
3377 goto checkAttListDeclHandler
;
3378 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3379 declAttributeType
= atypeNMTOKENS
;
3380 checkAttListDeclHandler
:
3381 if (dtd
.keepProcessing
&& attlistDeclHandler
)
3382 handleDefault
= XML_FALSE
;
3384 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3385 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3386 if (dtd
.keepProcessing
&& attlistDeclHandler
) {
3387 const XML_Char
*prefix
;
3388 if (declAttributeType
) {
3389 prefix
= enumValueSep
;
3392 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3396 if (!poolAppendString(&tempPool
, prefix
))
3397 return XML_ERROR_NO_MEMORY
;
3398 if (!poolAppend(&tempPool
, enc
, s
, next
))
3399 return XML_ERROR_NO_MEMORY
;
3400 declAttributeType
= tempPool
.start
;
3401 handleDefault
= XML_FALSE
;
3404 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3405 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3406 if (dtd
.keepProcessing
) {
3407 if (!defineAttribute(declElementType
, declAttributeId
,
3408 declAttributeIsCdata
, declAttributeIsId
, 0,
3410 return XML_ERROR_NO_MEMORY
;
3411 if (attlistDeclHandler
&& declAttributeType
) {
3412 if (*declAttributeType
== XML_T('(')
3413 || (*declAttributeType
== XML_T('N')
3414 && declAttributeType
[1] == XML_T('O'))) {
3415 /* Enumerated or Notation type */
3416 if (!poolAppendChar(&tempPool
, XML_T(')'))
3417 || !poolAppendChar(&tempPool
, XML_T('\0')))
3418 return XML_ERROR_NO_MEMORY
;
3419 declAttributeType
= tempPool
.start
;
3420 poolFinish(&tempPool
);
3423 attlistDeclHandler(handlerArg
, declElementType
->name
,
3424 declAttributeId
->name
, declAttributeType
,
3425 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3426 poolClear(&tempPool
);
3427 handleDefault
= XML_FALSE
;
3431 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3432 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
3433 if (dtd
.keepProcessing
) {
3434 const XML_Char
*attVal
;
3435 enum XML_Error result
3436 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
3437 s
+ enc
->minBytesPerChar
,
3438 next
- enc
->minBytesPerChar
,
3442 attVal
= poolStart(&dtd
.pool
);
3443 poolFinish(&dtd
.pool
);
3444 /* ID attributes aren't allowed to have a default */
3445 if (!defineAttribute(declElementType
, declAttributeId
,
3446 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
3447 return XML_ERROR_NO_MEMORY
;
3448 if (attlistDeclHandler
&& declAttributeType
) {
3449 if (*declAttributeType
== XML_T('(')
3450 || (*declAttributeType
== XML_T('N')
3451 && declAttributeType
[1] == XML_T('O'))) {
3452 /* Enumerated or Notation type */
3453 if (!poolAppendChar(&tempPool
, XML_T(')'))
3454 || !poolAppendChar(&tempPool
, XML_T('\0')))
3455 return XML_ERROR_NO_MEMORY
;
3456 declAttributeType
= tempPool
.start
;
3457 poolFinish(&tempPool
);
3460 attlistDeclHandler(handlerArg
, declElementType
->name
,
3461 declAttributeId
->name
, declAttributeType
,
3463 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
3464 poolClear(&tempPool
);
3465 handleDefault
= XML_FALSE
;
3469 case XML_ROLE_ENTITY_VALUE
:
3470 if (dtd
.keepProcessing
) {
3471 enum XML_Error result
= storeEntityValue(parser
, enc
,
3472 s
+ enc
->minBytesPerChar
,
3473 next
- enc
->minBytesPerChar
);
3475 declEntity
->textPtr
= poolStart(&dtd
.entityValuePool
);
3476 declEntity
->textLen
= poolLength(&dtd
.entityValuePool
);
3477 poolFinish(&dtd
.entityValuePool
);
3478 if (entityDeclHandler
) {
3480 entityDeclHandler(handlerArg
,
3482 declEntity
->is_param
,
3483 declEntity
->textPtr
,
3484 declEntity
->textLen
,
3486 handleDefault
= XML_FALSE
;
3490 poolDiscard(&dtd
.entityValuePool
);
3491 if (result
!= XML_ERROR_NONE
)
3495 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
3497 useForeignDTD
= XML_FALSE
;
3498 #endif /* XML_DTD */
3499 dtd
.hasParamEntityRefs
= XML_TRUE
;
3500 if (startDoctypeDeclHandler
) {
3501 doctypeSysid
= poolStoreString(&tempPool
, enc
,
3502 s
+ enc
->minBytesPerChar
,
3503 next
- enc
->minBytesPerChar
);
3504 if (doctypeSysid
== NULL
)
3505 return XML_ERROR_NO_MEMORY
;
3506 poolFinish(&tempPool
);
3507 handleDefault
= XML_FALSE
;
3511 /* use externalSubsetName to make doctypeSysid non-NULL
3512 for the case where no startDoctypeDeclHandler is set */
3513 doctypeSysid
= externalSubsetName
;
3514 #endif /* XML_DTD */
3517 && !paramEntityParsing
3518 #endif /* XML_DTD */
3519 && notStandaloneHandler
3520 && !notStandaloneHandler(handlerArg
))
3521 return XML_ERROR_NOT_STANDALONE
;
3526 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
3530 return XML_ERROR_NO_MEMORY
;
3531 declEntity
->publicId
= NULL
;
3534 #endif /* XML_DTD */
3535 case XML_ROLE_ENTITY_SYSTEM_ID
:
3536 if (dtd
.keepProcessing
&& declEntity
) {
3537 declEntity
->systemId
= poolStoreString(&dtd
.pool
, enc
,
3538 s
+ enc
->minBytesPerChar
,
3539 next
- enc
->minBytesPerChar
);
3540 if (!declEntity
->systemId
)
3541 return XML_ERROR_NO_MEMORY
;
3542 declEntity
->base
= curBase
;
3543 poolFinish(&dtd
.pool
);
3544 if (entityDeclHandler
)
3545 handleDefault
= XML_FALSE
;
3548 case XML_ROLE_ENTITY_COMPLETE
:
3549 if (dtd
.keepProcessing
&& declEntity
&& entityDeclHandler
) {
3551 entityDeclHandler(handlerArg
,
3553 declEntity
->is_param
,
3556 declEntity
->systemId
,
3557 declEntity
->publicId
,
3559 handleDefault
= XML_FALSE
;
3562 case XML_ROLE_ENTITY_NOTATION_NAME
:
3563 if (dtd
.keepProcessing
&& declEntity
) {
3564 declEntity
->notation
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
3565 if (!declEntity
->notation
)
3566 return XML_ERROR_NO_MEMORY
;
3567 poolFinish(&dtd
.pool
);
3568 if (unparsedEntityDeclHandler
) {
3570 unparsedEntityDeclHandler(handlerArg
,
3573 declEntity
->systemId
,
3574 declEntity
->publicId
,
3575 declEntity
->notation
);
3576 handleDefault
= XML_FALSE
;
3578 else if (entityDeclHandler
) {
3580 entityDeclHandler(handlerArg
,
3584 declEntity
->systemId
,
3585 declEntity
->publicId
,
3586 declEntity
->notation
);
3587 handleDefault
= XML_FALSE
;
3591 case XML_ROLE_GENERAL_ENTITY_NAME
:
3593 if (XmlPredefinedEntityName(enc
, s
, next
)) {
3597 if (dtd
.keepProcessing
) {
3598 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
3600 return XML_ERROR_NO_MEMORY
;
3601 declEntity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
,
3604 return XML_ERROR_NO_MEMORY
;
3605 if (declEntity
->name
!= name
) {
3606 poolDiscard(&dtd
.pool
);
3610 poolFinish(&dtd
.pool
);
3611 declEntity
->publicId
= NULL
;
3612 declEntity
->is_param
= XML_FALSE
;
3613 /* if we have a parent parser or are reading an internal parameter
3614 entity, then the entity declaration is not considered "internal"
3616 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3617 if (entityDeclHandler
)
3618 handleDefault
= XML_FALSE
;
3622 poolDiscard(&dtd
.pool
);
3627 case XML_ROLE_PARAM_ENTITY_NAME
:
3629 if (dtd
.keepProcessing
) {
3630 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
3632 return XML_ERROR_NO_MEMORY
;
3633 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
3634 name
, sizeof(ENTITY
));
3636 return XML_ERROR_NO_MEMORY
;
3637 if (declEntity
->name
!= name
) {
3638 poolDiscard(&dtd
.pool
);
3642 poolFinish(&dtd
.pool
);
3643 declEntity
->publicId
= NULL
;
3644 declEntity
->is_param
= XML_TRUE
;
3645 /* if we have a parent parser or are reading an internal parameter
3646 entity, then the entity declaration is not considered "internal"
3648 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
3649 if (entityDeclHandler
)
3650 handleDefault
= XML_FALSE
;
3654 poolDiscard(&dtd
.pool
);
3657 #else /* not XML_DTD */
3659 #endif /* XML_DTD */
3661 case XML_ROLE_NOTATION_NAME
:
3662 declNotationPublicId
= NULL
;
3663 declNotationName
= NULL
;
3664 if (notationDeclHandler
) {
3665 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
3666 if (!declNotationName
)
3667 return XML_ERROR_NO_MEMORY
;
3668 poolFinish(&tempPool
);
3669 handleDefault
= XML_FALSE
;
3672 case XML_ROLE_NOTATION_PUBLIC_ID
:
3673 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3674 return XML_ERROR_SYNTAX
;
3675 if (declNotationName
) { /* means notationDeclHandler != NULL */
3676 XML_Char
*tem
= poolStoreString(&tempPool
,
3678 s
+ enc
->minBytesPerChar
,
3679 next
- enc
->minBytesPerChar
);
3681 return XML_ERROR_NO_MEMORY
;
3682 normalizePublicId(tem
);
3683 declNotationPublicId
= tem
;
3684 poolFinish(&tempPool
);
3685 handleDefault
= XML_FALSE
;
3688 case XML_ROLE_NOTATION_SYSTEM_ID
:
3689 if (declNotationName
&& notationDeclHandler
) {
3690 const XML_Char
*systemId
3691 = poolStoreString(&tempPool
, enc
,
3692 s
+ enc
->minBytesPerChar
,
3693 next
- enc
->minBytesPerChar
);
3695 return XML_ERROR_NO_MEMORY
;
3697 notationDeclHandler(handlerArg
,
3701 declNotationPublicId
);
3702 handleDefault
= XML_FALSE
;
3704 poolClear(&tempPool
);
3706 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
3707 if (declNotationPublicId
&& notationDeclHandler
) {
3709 notationDeclHandler(handlerArg
,
3713 declNotationPublicId
);
3714 handleDefault
= XML_FALSE
;
3716 poolClear(&tempPool
);
3718 case XML_ROLE_ERROR
:
3720 case XML_TOK_PARAM_ENTITY_REF
:
3721 return XML_ERROR_PARAM_ENTITY_REF
;
3722 case XML_TOK_XML_DECL
:
3723 return XML_ERROR_MISPLACED_XML_PI
;
3725 return XML_ERROR_SYNTAX
;
3728 case XML_ROLE_IGNORE_SECT
:
3730 enum XML_Error result
;
3732 reportDefault(parser
, enc
, s
, next
);
3733 handleDefault
= XML_FALSE
;
3734 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3736 processor
= ignoreSectionProcessor
;
3741 #endif /* XML_DTD */
3742 case XML_ROLE_GROUP_OPEN
:
3743 if (prologState
.level
>= groupSize
) {
3745 char *temp
= REALLOC(groupConnector
, groupSize
*= 2);
3747 return XML_ERROR_NO_MEMORY
;
3748 groupConnector
= temp
;
3749 if (dtd
.scaffIndex
) {
3750 int *temp
= REALLOC(dtd
.scaffIndex
, groupSize
* sizeof(int));
3752 return XML_ERROR_NO_MEMORY
;
3753 dtd
.scaffIndex
= temp
;
3757 groupConnector
= MALLOC(groupSize
= 32);
3758 if (!groupConnector
)
3759 return XML_ERROR_NO_MEMORY
;
3762 groupConnector
[prologState
.level
] = 0;
3763 if (dtd
.in_eldecl
) {
3764 int myindex
= nextScaffoldPart(parser
);
3766 return XML_ERROR_NO_MEMORY
;
3767 dtd
.scaffIndex
[dtd
.scaffLevel
] = myindex
;
3769 dtd
.scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3770 if (elementDeclHandler
)
3771 handleDefault
= XML_FALSE
;
3774 case XML_ROLE_GROUP_SEQUENCE
:
3775 if (groupConnector
[prologState
.level
] == '|')
3776 return XML_ERROR_SYNTAX
;
3777 groupConnector
[prologState
.level
] = ',';
3778 if (dtd
.in_eldecl
&& elementDeclHandler
)
3779 handleDefault
= XML_FALSE
;
3781 case XML_ROLE_GROUP_CHOICE
:
3782 if (groupConnector
[prologState
.level
] == ',')
3783 return XML_ERROR_SYNTAX
;
3785 && !groupConnector
[prologState
.level
]
3786 && (dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
3789 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
3791 if (elementDeclHandler
)
3792 handleDefault
= XML_FALSE
;
3794 groupConnector
[prologState
.level
] = '|';
3796 case XML_ROLE_PARAM_ENTITY_REF
:
3798 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3799 /* PE references in internal subset are
3800 not allowed within declarations */
3801 if (prologState
.documentEntity
&&
3802 role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3803 return XML_ERROR_PARAM_ENTITY_REF
;
3804 dtd
.hasParamEntityRefs
= XML_TRUE
;
3805 if (!paramEntityParsing
)
3806 dtd
.keepProcessing
= dtd
.standalone
;
3808 const XML_Char
*name
;
3810 name
= poolStoreString(&dtd
.pool
, enc
,
3811 s
+ enc
->minBytesPerChar
,
3812 next
- enc
->minBytesPerChar
);
3814 return XML_ERROR_NO_MEMORY
;
3815 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
3816 poolDiscard(&dtd
.pool
);
3817 /* first, determine if a check for an existing declaration is needed;
3818 if yes, check that the entity exists, and that it is internal,
3819 otherwise call the skipped entity handler
3821 if (prologState
.documentEntity
&&
3823 ? !openInternalEntities
3824 : !dtd
.hasParamEntityRefs
)) {
3826 return XML_ERROR_UNDEFINED_ENTITY
;
3827 else if (!entity
->is_internal
)
3828 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
3831 dtd
.keepProcessing
= dtd
.standalone
;
3832 /* cannot report skipped entities in declarations */
3833 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
3834 skippedEntityHandler(handlerArg
, name
, 1);
3835 handleDefault
= XML_FALSE
;
3840 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3841 if (entity
->textPtr
) {
3842 enum XML_Error result
;
3843 result
= processInternalParamEntity(parser
, entity
);
3844 if (result
!= XML_ERROR_NONE
)
3846 handleDefault
= XML_FALSE
;
3849 if (externalEntityRefHandler
) {
3850 dtd
.paramEntityRead
= XML_FALSE
;
3851 entity
->open
= XML_TRUE
;
3852 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3856 entity
->publicId
)) {
3857 entity
->open
= XML_FALSE
;
3858 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3860 entity
->open
= XML_FALSE
;
3861 handleDefault
= XML_FALSE
;
3862 if (!dtd
.paramEntityRead
) {
3863 dtd
.keepProcessing
= dtd
.standalone
;
3868 dtd
.keepProcessing
= dtd
.standalone
;
3872 #endif /* XML_DTD */
3873 if (!dtd
.standalone
&&
3874 notStandaloneHandler
&&
3875 !notStandaloneHandler(handlerArg
))
3876 return XML_ERROR_NOT_STANDALONE
;
3879 /* Element declaration stuff */
3881 case XML_ROLE_ELEMENT_NAME
:
3882 if (elementDeclHandler
) {
3883 declElementType
= getElementType(parser
, enc
, s
, next
);
3884 if (!declElementType
)
3885 return XML_ERROR_NO_MEMORY
;
3888 dtd
.in_eldecl
= XML_TRUE
;
3889 handleDefault
= XML_FALSE
;
3893 case XML_ROLE_CONTENT_ANY
:
3894 case XML_ROLE_CONTENT_EMPTY
:
3895 if (dtd
.in_eldecl
) {
3896 if (elementDeclHandler
) {
3897 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3899 return XML_ERROR_NO_MEMORY
;
3900 content
->quant
= XML_CQUANT_NONE
;
3901 content
->name
= NULL
;
3902 content
->numchildren
= 0;
3903 content
->children
= NULL
;
3904 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
3908 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
3909 handleDefault
= XML_FALSE
;
3911 dtd
.in_eldecl
= XML_FALSE
;
3915 case XML_ROLE_CONTENT_PCDATA
:
3916 if (dtd
.in_eldecl
) {
3917 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
3919 if (elementDeclHandler
)
3920 handleDefault
= XML_FALSE
;
3924 case XML_ROLE_CONTENT_ELEMENT
:
3925 quant
= XML_CQUANT_NONE
;
3926 goto elementContent
;
3927 case XML_ROLE_CONTENT_ELEMENT_OPT
:
3928 quant
= XML_CQUANT_OPT
;
3929 goto elementContent
;
3930 case XML_ROLE_CONTENT_ELEMENT_REP
:
3931 quant
= XML_CQUANT_REP
;
3932 goto elementContent
;
3933 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
3934 quant
= XML_CQUANT_PLUS
;
3936 if (dtd
.in_eldecl
) {
3938 const XML_Char
*name
;
3940 const char *nxt
= (quant
== XML_CQUANT_NONE
3942 : next
- enc
->minBytesPerChar
);
3943 int myindex
= nextScaffoldPart(parser
);
3945 return XML_ERROR_NO_MEMORY
;
3946 dtd
.scaffold
[myindex
].type
= XML_CTYPE_NAME
;
3947 dtd
.scaffold
[myindex
].quant
= quant
;
3948 el
= getElementType(parser
, enc
, s
, nxt
);
3950 return XML_ERROR_NO_MEMORY
;
3952 dtd
.scaffold
[myindex
].name
= name
;
3954 for (; name
[nameLen
++]; );
3955 dtd
.contentStringLen
+= nameLen
;
3956 if (elementDeclHandler
)
3957 handleDefault
= XML_FALSE
;
3961 case XML_ROLE_GROUP_CLOSE
:
3962 quant
= XML_CQUANT_NONE
;
3964 case XML_ROLE_GROUP_CLOSE_OPT
:
3965 quant
= XML_CQUANT_OPT
;
3967 case XML_ROLE_GROUP_CLOSE_REP
:
3968 quant
= XML_CQUANT_REP
;
3970 case XML_ROLE_GROUP_CLOSE_PLUS
:
3971 quant
= XML_CQUANT_PLUS
;
3973 if (dtd
.in_eldecl
) {
3974 if (elementDeclHandler
)
3975 handleDefault
= XML_FALSE
;
3977 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
]].quant
= quant
;
3978 if (dtd
.scaffLevel
== 0) {
3979 if (!handleDefault
) {
3980 XML_Content
*model
= build_model(parser
);
3982 return XML_ERROR_NO_MEMORY
;
3984 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
3986 dtd
.in_eldecl
= XML_FALSE
;
3987 dtd
.contentStringLen
= 0;
3991 /* End element declaration stuff */
3994 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
3995 return XML_ERROR_NO_MEMORY
;
3996 handleDefault
= XML_FALSE
;
3998 case XML_ROLE_COMMENT
:
3999 if (!reportComment(parser
, enc
, s
, next
))
4000 return XML_ERROR_NO_MEMORY
;
4001 handleDefault
= XML_FALSE
;
4006 handleDefault
= XML_FALSE
;
4010 case XML_ROLE_DOCTYPE_NONE
:
4011 if (startDoctypeDeclHandler
)
4012 handleDefault
= XML_FALSE
;
4014 case XML_ROLE_ENTITY_NONE
:
4015 if (dtd
.keepProcessing
&& entityDeclHandler
)
4016 handleDefault
= XML_FALSE
;
4018 case XML_ROLE_NOTATION_NONE
:
4019 if (notationDeclHandler
)
4020 handleDefault
= XML_FALSE
;
4022 case XML_ROLE_ATTLIST_NONE
:
4023 if (dtd
.keepProcessing
&& attlistDeclHandler
)
4024 handleDefault
= XML_FALSE
;
4026 case XML_ROLE_ELEMENT_NONE
:
4027 if (elementDeclHandler
)
4028 handleDefault
= XML_FALSE
;
4030 } /* end of big switch */
4032 if (handleDefault
&& defaultHandler
)
4033 reportDefault(parser
, enc
, s
, next
);
4036 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4041 static enum XML_Error FASTCALL
4042 epilogProcessor(XML_Parser parser
,
4045 const char **nextPtr
)
4047 processor
= epilogProcessor
;
4050 const char *next
= NULL
;
4051 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4054 /* report partial linebreak - it might be the last token */
4055 case -XML_TOK_PROLOG_S
:
4056 if (defaultHandler
) {
4058 reportDefault(parser
, encoding
, s
, next
);
4062 return XML_ERROR_NONE
;
4066 return XML_ERROR_NONE
;
4067 case XML_TOK_PROLOG_S
:
4069 reportDefault(parser
, encoding
, s
, next
);
4072 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4073 return XML_ERROR_NO_MEMORY
;
4075 case XML_TOK_COMMENT
:
4076 if (!reportComment(parser
, encoding
, s
, next
))
4077 return XML_ERROR_NO_MEMORY
;
4079 case XML_TOK_INVALID
:
4081 return XML_ERROR_INVALID_TOKEN
;
4082 case XML_TOK_PARTIAL
:
4085 return XML_ERROR_NONE
;
4087 return XML_ERROR_UNCLOSED_TOKEN
;
4088 case XML_TOK_PARTIAL_CHAR
:
4091 return XML_ERROR_NONE
;
4093 return XML_ERROR_PARTIAL_CHAR
;
4095 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4097 eventPtr
= s
= next
;
4103 static enum XML_Error FASTCALL
4104 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
4106 const char *s
, *end
, *next
;
4108 enum XML_Error result
;
4109 OPEN_INTERNAL_ENTITY openEntity
;
4110 entity
->open
= XML_TRUE
;
4111 openEntity
.next
= openInternalEntities
;
4112 openInternalEntities
= &openEntity
;
4113 openEntity
.entity
= entity
;
4114 openEntity
.internalEventPtr
= NULL
;
4115 openEntity
.internalEventEndPtr
= NULL
;
4116 s
= (char *)entity
->textPtr
;
4117 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
4118 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
4119 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
4120 entity
->open
= XML_FALSE
;
4121 openInternalEntities
= openEntity
.next
;
4125 #endif /* XML_DTD */
4127 static enum XML_Error FASTCALL
4128 errorProcessor(XML_Parser parser
,
4131 const char **nextPtr
)
4136 static enum XML_Error FASTCALL
4137 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4138 const char *ptr
, const char *end
,
4141 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4145 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4147 if (!poolAppendChar(pool
, XML_T('\0')))
4148 return XML_ERROR_NO_MEMORY
;
4149 return XML_ERROR_NONE
;
4152 static enum XML_Error FASTCALL
4153 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4154 const char *ptr
, const char *end
,
4159 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4162 return XML_ERROR_NONE
;
4163 case XML_TOK_INVALID
:
4164 if (enc
== encoding
)
4166 return XML_ERROR_INVALID_TOKEN
;
4167 case XML_TOK_PARTIAL
:
4168 if (enc
== encoding
)
4170 return XML_ERROR_INVALID_TOKEN
;
4171 case XML_TOK_CHAR_REF
:
4173 XML_Char buf
[XML_ENCODE_MAX
];
4175 int n
= XmlCharRefNumber(enc
, ptr
);
4177 if (enc
== encoding
)
4179 return XML_ERROR_BAD_CHAR_REF
;
4182 && n
== 0x20 /* space */
4183 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4185 n
= XmlEncode(n
, (ICHAR
*)buf
);
4187 if (enc
== encoding
)
4189 return XML_ERROR_BAD_CHAR_REF
;
4191 for (i
= 0; i
< n
; i
++) {
4192 if (!poolAppendChar(pool
, buf
[i
]))
4193 return XML_ERROR_NO_MEMORY
;
4197 case XML_TOK_DATA_CHARS
:
4198 if (!poolAppend(pool
, enc
, ptr
, next
))
4199 return XML_ERROR_NO_MEMORY
;
4201 case XML_TOK_TRAILING_CR
:
4202 next
= ptr
+ enc
->minBytesPerChar
;
4204 case XML_TOK_ATTRIBUTE_VALUE_S
:
4205 case XML_TOK_DATA_NEWLINE
:
4206 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4208 if (!poolAppendChar(pool
, 0x20))
4209 return XML_ERROR_NO_MEMORY
;
4211 case XML_TOK_ENTITY_REF
:
4213 const XML_Char
*name
;
4215 char checkEntityDecl
;
4216 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4217 ptr
+ enc
->minBytesPerChar
,
4218 next
- enc
->minBytesPerChar
);
4220 if (!poolAppendChar(pool
, ch
))
4221 return XML_ERROR_NO_MEMORY
;
4224 name
= poolStoreString(&temp2Pool
, enc
,
4225 ptr
+ enc
->minBytesPerChar
,
4226 next
- enc
->minBytesPerChar
);
4228 return XML_ERROR_NO_MEMORY
;
4229 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
4230 poolDiscard(&temp2Pool
);
4231 /* first, determine if a check for an existing declaration is needed;
4232 if yes, check that the entity exists, and that it is internal,
4233 otherwise call the default handler (if called from content)
4235 if (pool
== &dtd
.pool
) /* are we called from prolog? */
4238 prologState
.documentEntity
&&
4239 #endif /* XML_DTD */
4241 ? !openInternalEntities
4242 : !dtd
.hasParamEntityRefs
);
4243 else /* if (pool == &tempPool): we are called from content */
4244 checkEntityDecl
= !dtd
.hasParamEntityRefs
|| dtd
.standalone
;
4245 if (checkEntityDecl
) {
4247 return XML_ERROR_UNDEFINED_ENTITY
;
4248 else if (!entity
->is_internal
)
4249 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4252 /* cannot report skipped entity here - see comments on
4253 skippedEntityHandler
4254 if (skippedEntityHandler)
4255 skippedEntityHandler(handlerArg, name, 0);
4257 if ((pool
== &tempPool
) && defaultHandler
)
4258 reportDefault(parser
, enc
, ptr
, next
);
4262 if (enc
== encoding
)
4264 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4266 if (entity
->notation
) {
4267 if (enc
== encoding
)
4269 return XML_ERROR_BINARY_ENTITY_REF
;
4271 if (!entity
->textPtr
) {
4272 if (enc
== encoding
)
4274 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4277 enum XML_Error result
;
4278 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4279 entity
->open
= XML_TRUE
;
4280 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4281 (char *)entity
->textPtr
,
4282 (char *)textEnd
, pool
);
4283 entity
->open
= XML_FALSE
;
4290 if (enc
== encoding
)
4292 return XML_ERROR_UNEXPECTED_STATE
;
4299 static enum XML_Error FASTCALL
4300 storeEntityValue(XML_Parser parser
,
4301 const ENCODING
*enc
,
4302 const char *entityTextPtr
,
4303 const char *entityTextEnd
)
4305 STRING_POOL
*pool
= &(dtd
.entityValuePool
);
4306 enum XML_Error result
= XML_ERROR_NONE
;
4308 int oldInEntityValue
= prologState
.inEntityValue
;
4309 prologState
.inEntityValue
= 1;
4310 #endif /* XML_DTD */
4311 /* never return Null for the value argument in EntityDeclHandler,
4312 since this would indicate an external entity; therefore we
4313 have to make sure that entityValuePool.start is not null */
4314 if (!pool
->blocks
) {
4315 if (!poolGrow(pool
))
4316 return XML_ERROR_NO_MEMORY
;
4321 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
4323 case XML_TOK_PARAM_ENTITY_REF
:
4325 if (isParamEntity
|| enc
!= encoding
) {
4326 const XML_Char
*name
;
4328 name
= poolStoreString(&tempPool
, enc
,
4329 entityTextPtr
+ enc
->minBytesPerChar
,
4330 next
- enc
->minBytesPerChar
);
4332 result
= XML_ERROR_NO_MEMORY
;
4333 goto endEntityValue
;
4335 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
4336 poolDiscard(&tempPool
);
4338 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4339 /* cannot report skipped entity here - see comments on
4340 skippedEntityHandler
4341 if (skippedEntityHandler)
4342 skippedEntityHandler(handlerArg, name, 0);
4344 dtd
.keepProcessing
= dtd
.standalone
;
4345 goto endEntityValue
;
4348 if (enc
== encoding
)
4349 eventPtr
= entityTextPtr
;
4350 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
4351 goto endEntityValue
;
4353 if (entity
->systemId
) {
4354 if (externalEntityRefHandler
) {
4355 dtd
.paramEntityRead
= XML_FALSE
;
4356 entity
->open
= XML_TRUE
;
4357 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4361 entity
->publicId
)) {
4362 entity
->open
= XML_FALSE
;
4363 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4364 goto endEntityValue
;
4366 entity
->open
= XML_FALSE
;
4367 if (!dtd
.paramEntityRead
)
4368 dtd
.keepProcessing
= dtd
.standalone
;
4371 dtd
.keepProcessing
= dtd
.standalone
;
4374 entity
->open
= XML_TRUE
;
4375 result
= storeEntityValue(parser
,
4377 (char *)entity
->textPtr
,
4378 (char *)(entity
->textPtr
4379 + entity
->textLen
));
4380 entity
->open
= XML_FALSE
;
4382 goto endEntityValue
;
4386 #endif /* XML_DTD */
4387 /* in the internal subset, PE references are not legal
4388 within markup declarations, e.g entity values in this case */
4389 eventPtr
= entityTextPtr
;
4390 result
= XML_ERROR_PARAM_ENTITY_REF
;
4391 goto endEntityValue
;
4393 result
= XML_ERROR_NONE
;
4394 goto endEntityValue
;
4395 case XML_TOK_ENTITY_REF
:
4396 case XML_TOK_DATA_CHARS
:
4397 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
4398 result
= XML_ERROR_NO_MEMORY
;
4399 goto endEntityValue
;
4402 case XML_TOK_TRAILING_CR
:
4403 next
= entityTextPtr
+ enc
->minBytesPerChar
;
4405 case XML_TOK_DATA_NEWLINE
:
4406 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4407 result
= XML_ERROR_NO_MEMORY
;
4408 goto endEntityValue
;
4410 *(pool
->ptr
)++ = 0xA;
4412 case XML_TOK_CHAR_REF
:
4414 XML_Char buf
[XML_ENCODE_MAX
];
4416 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
4418 if (enc
== encoding
)
4419 eventPtr
= entityTextPtr
;
4420 result
= XML_ERROR_BAD_CHAR_REF
;
4421 goto endEntityValue
;
4423 n
= XmlEncode(n
, (ICHAR
*)buf
);
4425 if (enc
== encoding
)
4426 eventPtr
= entityTextPtr
;
4427 result
= XML_ERROR_BAD_CHAR_REF
;
4428 goto endEntityValue
;
4430 for (i
= 0; i
< n
; i
++) {
4431 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
4432 result
= XML_ERROR_NO_MEMORY
;
4433 goto endEntityValue
;
4435 *(pool
->ptr
)++ = buf
[i
];
4439 case XML_TOK_PARTIAL
:
4440 if (enc
== encoding
)
4441 eventPtr
= entityTextPtr
;
4442 result
= XML_ERROR_INVALID_TOKEN
;
4443 goto endEntityValue
;
4444 case XML_TOK_INVALID
:
4445 if (enc
== encoding
)
4447 result
= XML_ERROR_INVALID_TOKEN
;
4448 goto endEntityValue
;
4450 if (enc
== encoding
)
4451 eventPtr
= entityTextPtr
;
4452 result
= XML_ERROR_UNEXPECTED_STATE
;
4453 goto endEntityValue
;
4455 entityTextPtr
= next
;
4459 prologState
.inEntityValue
= oldInEntityValue
;
4460 #endif /* XML_DTD */
4464 static void FASTCALL
4465 normalizeLines(XML_Char
*s
)
4469 if (*s
== XML_T('\0'))
4488 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
4489 const char *start
, const char *end
)
4491 const XML_Char
*target
;
4494 if (!processingInstructionHandler
) {
4496 reportDefault(parser
, enc
, start
, end
);
4499 start
+= enc
->minBytesPerChar
* 2;
4500 tem
= start
+ XmlNameLength(enc
, start
);
4501 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
4504 poolFinish(&tempPool
);
4505 data
= poolStoreString(&tempPool
, enc
,
4507 end
- enc
->minBytesPerChar
*2);
4510 normalizeLines(data
);
4511 processingInstructionHandler(handlerArg
, target
, data
);
4512 poolClear(&tempPool
);
4517 reportComment(XML_Parser parser
, const ENCODING
*enc
,
4518 const char *start
, const char *end
)
4521 if (!commentHandler
) {
4523 reportDefault(parser
, enc
, start
, end
);
4526 data
= poolStoreString(&tempPool
,
4528 start
+ enc
->minBytesPerChar
* 4,
4529 end
- enc
->minBytesPerChar
* 3);
4532 normalizeLines(data
);
4533 commentHandler(handlerArg
, data
);
4534 poolClear(&tempPool
);
4538 static void FASTCALL
4539 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
4540 const char *s
, const char *end
)
4542 if (MUST_CONVERT(enc
, s
)) {
4543 const char **eventPP
;
4544 const char **eventEndPP
;
4545 if (enc
== encoding
) {
4546 eventPP
= &eventPtr
;
4547 eventEndPP
= &eventEndPtr
;
4550 eventPP
= &(openInternalEntities
->internalEventPtr
);
4551 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
4554 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
4555 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
4557 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
4562 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
4567 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
4568 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
4570 DEFAULT_ATTRIBUTE
*att
;
4571 if (value
|| isId
) {
4572 /* The handling of default attributes gets messed up if we have
4573 a default which duplicates a non-default. */
4575 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
4576 if (attId
== type
->defaultAtts
[i
].id
)
4578 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
4579 type
->idAtt
= attId
;
4581 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
4582 if (type
->allocDefaultAtts
== 0) {
4583 type
->allocDefaultAtts
= 8;
4584 type
->defaultAtts
= MALLOC(type
->allocDefaultAtts
4585 * sizeof(DEFAULT_ATTRIBUTE
));
4586 if (!type
->defaultAtts
)
4590 DEFAULT_ATTRIBUTE
*temp
;
4591 int count
= type
->allocDefaultAtts
* 2;
4592 temp
= REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
4595 type
->allocDefaultAtts
= count
;
4596 type
->defaultAtts
= temp
;
4599 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
4602 att
->isCdata
= isCdata
;
4604 attId
->maybeTokenized
= XML_TRUE
;
4605 type
->nDefaultAtts
+= 1;
4610 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
4612 const XML_Char
*name
;
4613 for (name
= elementType
->name
; *name
; name
++) {
4614 if (*name
== XML_T(':')) {
4617 for (s
= elementType
->name
; s
!= name
; s
++) {
4618 if (!poolAppendChar(&dtd
.pool
, *s
))
4621 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
4623 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
),
4627 if (prefix
->name
== poolStart(&dtd
.pool
))
4628 poolFinish(&dtd
.pool
);
4630 poolDiscard(&dtd
.pool
);
4631 elementType
->prefix
= prefix
;
4638 static ATTRIBUTE_ID
* FASTCALL
4639 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
4640 const char *start
, const char *end
)
4643 const XML_Char
*name
;
4644 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
4646 name
= poolStoreString(&dtd
.pool
, enc
, start
, end
);
4650 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
4653 if (id
->name
!= name
)
4654 poolDiscard(&dtd
.pool
);
4656 poolFinish(&dtd
.pool
);
4659 else if (name
[0] == 'x'
4664 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
4665 if (name
[5] == '\0')
4666 id
->prefix
= &dtd
.defaultPrefix
;
4668 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, name
+ 6, sizeof(PREFIX
));
4669 id
->xmlns
= XML_TRUE
;
4673 for (i
= 0; name
[i
]; i
++) {
4674 if (name
[i
] == XML_T(':')) {
4676 for (j
= 0; j
< i
; j
++) {
4677 if (!poolAppendChar(&dtd
.pool
, name
[j
]))
4680 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
4682 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
),
4684 if (id
->prefix
->name
== poolStart(&dtd
.pool
))
4685 poolFinish(&dtd
.pool
);
4687 poolDiscard(&dtd
.pool
);
4696 #define CONTEXT_SEP XML_T('\f')
4698 static const XML_Char
* FASTCALL
4699 getContext(XML_Parser parser
)
4701 HASH_TABLE_ITER iter
;
4702 XML_Bool needSep
= XML_FALSE
;
4704 if (dtd
.defaultPrefix
.binding
) {
4707 if (!poolAppendChar(&tempPool
, XML_T('=')))
4709 len
= dtd
.defaultPrefix
.binding
->uriLen
;
4710 if (namespaceSeparator
!= XML_T('\0'))
4712 for (i
= 0; i
< len
; i
++)
4713 if (!poolAppendChar(&tempPool
, dtd
.defaultPrefix
.binding
->uri
[i
]))
4718 hashTableIterInit(&iter
, &(dtd
.prefixes
));
4723 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
4726 if (!prefix
->binding
)
4728 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4730 for (s
= prefix
->name
; *s
; s
++)
4731 if (!poolAppendChar(&tempPool
, *s
))
4733 if (!poolAppendChar(&tempPool
, XML_T('=')))
4735 len
= prefix
->binding
->uriLen
;
4736 if (namespaceSeparator
!= XML_T('\0'))
4738 for (i
= 0; i
< len
; i
++)
4739 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
4745 hashTableIterInit(&iter
, &(dtd
.generalEntities
));
4748 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
4753 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
4755 for (s
= e
->name
; *s
; s
++)
4756 if (!poolAppendChar(&tempPool
, *s
))
4761 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4763 return tempPool
.start
;
4766 static XML_Bool FASTCALL
4767 setContext(XML_Parser parser
, const XML_Char
*context
)
4769 const XML_Char
*s
= context
;
4771 while (*context
!= XML_T('\0')) {
4772 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
4774 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4776 e
= (ENTITY
*)lookup(&dtd
.generalEntities
, poolStart(&tempPool
), 0);
4779 if (*s
!= XML_T('\0'))
4782 poolDiscard(&tempPool
);
4784 else if (*s
== XML_T('=')) {
4786 if (poolLength(&tempPool
) == 0)
4787 prefix
= &dtd
.defaultPrefix
;
4789 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4791 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&tempPool
),
4795 if (prefix
->name
== poolStart(&tempPool
)) {
4796 prefix
->name
= poolCopyString(&dtd
.pool
, prefix
->name
);
4800 poolDiscard(&tempPool
);
4802 for (context
= s
+ 1;
4803 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
4805 if (!poolAppendChar(&tempPool
, *context
))
4807 if (!poolAppendChar(&tempPool
, XML_T('\0')))
4809 if (!addBinding(parser
, prefix
, 0, poolStart(&tempPool
),
4810 &inheritedBindings
))
4812 poolDiscard(&tempPool
);
4813 if (*context
!= XML_T('\0'))
4818 if (!poolAppendChar(&tempPool
, *s
))
4826 static void FASTCALL
4827 normalizePublicId(XML_Char
*publicId
)
4829 XML_Char
*p
= publicId
;
4831 for (s
= publicId
; *s
; s
++) {
4836 if (p
!= publicId
&& p
[-1] != 0x20)
4843 if (p
!= publicId
&& p
[-1] == 0x20)
4848 static void FASTCALL
4849 dtdInit(DTD
*p
, XML_Parser parser
)
4851 XML_Memory_Handling_Suite
*ms
= &parser
->m_mem
;
4852 poolInit(&(p
->pool
), ms
);
4854 poolInit(&(p
->entityValuePool
), ms
);
4855 #endif /* XML_DTD */
4856 hashTableInit(&(p
->generalEntities
), ms
);
4857 hashTableInit(&(p
->elementTypes
), ms
);
4858 hashTableInit(&(p
->attributeIds
), ms
);
4859 hashTableInit(&(p
->prefixes
), ms
);
4861 p
->paramEntityRead
= XML_FALSE
;
4862 hashTableInit(&(p
->paramEntities
), ms
);
4863 #endif /* XML_DTD */
4864 p
->defaultPrefix
.name
= NULL
;
4865 p
->defaultPrefix
.binding
= NULL
;
4867 p
->in_eldecl
= XML_FALSE
;
4868 p
->scaffIndex
= NULL
;
4873 p
->contentStringLen
= 0;
4875 p
->keepProcessing
= XML_TRUE
;
4876 p
->hasParamEntityRefs
= XML_FALSE
;
4877 p
->standalone
= XML_FALSE
;
4882 static void FASTCALL
4883 dtdSwap(DTD
*p1
, DTD
*p2
)
4886 memcpy(&tem
, p1
, sizeof(DTD
));
4887 memcpy(p1
, p2
, sizeof(DTD
));
4888 memcpy(p2
, &tem
, sizeof(DTD
));
4891 #endif /* XML_DTD */
4893 static void FASTCALL
4894 dtdReset(DTD
*p
, XML_Parser parser
)
4896 HASH_TABLE_ITER iter
;
4897 hashTableIterInit(&iter
, &(p
->elementTypes
));
4899 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4902 if (e
->allocDefaultAtts
!= 0)
4903 FREE(e
->defaultAtts
);
4905 hashTableClear(&(p
->generalEntities
));
4907 p
->paramEntityRead
= XML_FALSE
;
4908 hashTableClear(&(p
->paramEntities
));
4909 #endif /* XML_DTD */
4910 hashTableClear(&(p
->elementTypes
));
4911 hashTableClear(&(p
->attributeIds
));
4912 hashTableClear(&(p
->prefixes
));
4913 poolClear(&(p
->pool
));
4915 poolClear(&(p
->entityValuePool
));
4916 #endif /* XML_DTD */
4917 p
->defaultPrefix
.name
= NULL
;
4918 p
->defaultPrefix
.binding
= NULL
;
4920 p
->in_eldecl
= XML_FALSE
;
4921 if (p
->scaffIndex
) {
4922 FREE(p
->scaffIndex
);
4923 p
->scaffIndex
= NULL
;
4932 p
->contentStringLen
= 0;
4934 p
->keepProcessing
= XML_TRUE
;
4935 p
->hasParamEntityRefs
= XML_FALSE
;
4936 p
->standalone
= XML_FALSE
;
4939 static void FASTCALL
4940 dtdDestroy(DTD
*p
, XML_Parser parser
)
4942 HASH_TABLE_ITER iter
;
4943 hashTableIterInit(&iter
, &(p
->elementTypes
));
4945 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4948 if (e
->allocDefaultAtts
!= 0)
4949 FREE(e
->defaultAtts
);
4951 hashTableDestroy(&(p
->generalEntities
));
4953 hashTableDestroy(&(p
->paramEntities
));
4954 #endif /* XML_DTD */
4955 hashTableDestroy(&(p
->elementTypes
));
4956 hashTableDestroy(&(p
->attributeIds
));
4957 hashTableDestroy(&(p
->prefixes
));
4958 poolDestroy(&(p
->pool
));
4960 poolDestroy(&(p
->entityValuePool
));
4961 #endif /* XML_DTD */
4962 if (!parentParser
) {
4964 FREE(p
->scaffIndex
);
4970 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
4971 The new DTD has already been initialized.
4974 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, XML_Parser parser
)
4976 HASH_TABLE_ITER iter
;
4978 /* Copy the prefix table. */
4980 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
4982 const XML_Char
*name
;
4983 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
4986 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
4989 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
4993 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
4995 /* Copy the attribute id table. */
4999 const XML_Char
*name
;
5000 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5004 /* Remember to allocate the scratch byte before the name. */
5005 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5007 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5011 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5012 sizeof(ATTRIBUTE_ID
));
5015 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5017 newA
->xmlns
= oldA
->xmlns
;
5018 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5019 newA
->prefix
= &newDtd
->defaultPrefix
;
5021 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5022 oldA
->prefix
->name
, 0);
5026 /* Copy the element type table. */
5028 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5033 const XML_Char
*name
;
5034 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5037 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5040 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5041 sizeof(ELEMENT_TYPE
));
5044 if (oldE
->nDefaultAtts
) {
5045 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5046 MALLOC(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5047 if (!newE
->defaultAtts
) {
5053 newE
->idAtt
= (ATTRIBUTE_ID
*)
5054 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5055 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5057 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5058 oldE
->prefix
->name
, 0);
5059 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5060 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5061 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5062 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5063 if (oldE
->defaultAtts
[i
].value
) {
5064 newE
->defaultAtts
[i
].value
5065 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5066 if (!newE
->defaultAtts
[i
].value
)
5070 newE
->defaultAtts
[i
].value
= NULL
;
5074 /* Copy the entity tables. */
5075 if (!copyEntityTable(&(newDtd
->generalEntities
),
5077 &(oldDtd
->generalEntities
), parser
))
5081 if (!copyEntityTable(&(newDtd
->paramEntities
),
5083 &(oldDtd
->paramEntities
), parser
))
5085 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5086 #endif /* XML_DTD */
5088 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5089 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5090 newDtd
->standalone
= oldDtd
->standalone
;
5092 /* Don't want deep copying for scaffolding */
5093 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5094 newDtd
->scaffold
= oldDtd
->scaffold
;
5095 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5096 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5097 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5098 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5104 copyEntityTable(HASH_TABLE
*newTable
,
5105 STRING_POOL
*newPool
,
5106 const HASH_TABLE
*oldTable
,
5109 HASH_TABLE_ITER iter
;
5110 const XML_Char
*cachedOldBase
= NULL
;
5111 const XML_Char
*cachedNewBase
= NULL
;
5113 hashTableIterInit(&iter
, oldTable
);
5117 const XML_Char
*name
;
5118 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5121 name
= poolCopyString(newPool
, oldE
->name
);
5124 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5127 if (oldE
->systemId
) {
5128 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5131 newE
->systemId
= tem
;
5133 if (oldE
->base
== cachedOldBase
)
5134 newE
->base
= cachedNewBase
;
5136 cachedOldBase
= oldE
->base
;
5137 tem
= poolCopyString(newPool
, cachedOldBase
);
5140 cachedNewBase
= newE
->base
= tem
;
5143 if (oldE
->publicId
) {
5144 tem
= poolCopyString(newPool
, oldE
->publicId
);
5147 newE
->publicId
= tem
;
5151 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5155 newE
->textPtr
= tem
;
5156 newE
->textLen
= oldE
->textLen
;
5158 if (oldE
->notation
) {
5159 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5162 newE
->notation
= tem
;
5164 newE
->is_param
= oldE
->is_param
;
5165 newE
->is_internal
= oldE
->is_internal
;
5170 #define INIT_SIZE 64
5173 keyeq(KEY s1
, KEY s2
)
5175 for (; *s1
== *s2
; s1
++, s2
++)
5181 static unsigned long FASTCALL
5184 unsigned long h
= 0;
5186 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
5190 static NAMED
* FASTCALL
5191 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5194 if (table
->size
== 0) {
5199 tsize
= INIT_SIZE
* sizeof(NAMED
*);
5200 table
->v
= table
->mem
->malloc_fcn(tsize
);
5203 memset(table
->v
, 0, tsize
);
5204 table
->size
= INIT_SIZE
;
5205 table
->usedLim
= INIT_SIZE
/ 2;
5206 i
= hash(name
) & (table
->size
- 1);
5209 unsigned long h
= hash(name
);
5210 for (i
= h
& (table
->size
- 1);
5212 i
== 0 ? i
= table
->size
- 1 : --i
) {
5213 if (keyeq(name
, table
->v
[i
]->name
))
5218 if (table
->used
== table
->usedLim
) {
5219 /* check for overflow */
5220 size_t newSize
= table
->size
* 2;
5221 size_t tsize
= newSize
* sizeof(NAMED
*);
5222 NAMED
**newV
= table
->mem
->malloc_fcn(tsize
);
5225 memset(newV
, 0, tsize
);
5226 for (i
= 0; i
< table
->size
; i
++)
5229 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
5231 j
== 0 ? j
= newSize
- 1 : --j
)
5233 newV
[j
] = table
->v
[i
];
5235 table
->mem
->free_fcn(table
->v
);
5237 table
->size
= newSize
;
5238 table
->usedLim
= newSize
/2;
5239 for (i
= h
& (table
->size
- 1);
5241 i
== 0 ? i
= table
->size
- 1 : --i
)
5245 table
->v
[i
] = table
->mem
->malloc_fcn(createSize
);
5248 memset(table
->v
[i
], 0, createSize
);
5249 table
->v
[i
]->name
= name
;
5254 static void FASTCALL
5255 hashTableClear(HASH_TABLE
*table
)
5258 for (i
= 0; i
< table
->size
; i
++) {
5259 NAMED
*p
= table
->v
[i
];
5261 table
->mem
->free_fcn(p
);
5265 table
->usedLim
= table
->size
/ 2;
5269 static void FASTCALL
5270 hashTableDestroy(HASH_TABLE
*table
)
5273 for (i
= 0; i
< table
->size
; i
++) {
5274 NAMED
*p
= table
->v
[i
];
5276 table
->mem
->free_fcn(p
);
5279 table
->mem
->free_fcn(table
->v
);
5282 static void FASTCALL
5283 hashTableInit(HASH_TABLE
*p
, XML_Memory_Handling_Suite
*ms
)
5292 static void FASTCALL
5293 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5296 iter
->end
= iter
->p
+ table
->size
;
5299 static NAMED
* FASTCALL
5300 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5302 while (iter
->p
!= iter
->end
) {
5303 NAMED
*tem
= *(iter
->p
)++;
5310 static void FASTCALL
5311 poolInit(STRING_POOL
*pool
, XML_Memory_Handling_Suite
*ms
)
5313 pool
->blocks
= NULL
;
5314 pool
->freeBlocks
= NULL
;
5321 static void FASTCALL
5322 poolClear(STRING_POOL
*pool
)
5324 if (!pool
->freeBlocks
)
5325 pool
->freeBlocks
= pool
->blocks
;
5327 BLOCK
*p
= pool
->blocks
;
5329 BLOCK
*tem
= p
->next
;
5330 p
->next
= pool
->freeBlocks
;
5331 pool
->freeBlocks
= p
;
5335 pool
->blocks
= NULL
;
5341 static void FASTCALL
5342 poolDestroy(STRING_POOL
*pool
)
5344 BLOCK
*p
= pool
->blocks
;
5346 BLOCK
*tem
= p
->next
;
5347 pool
->mem
->free_fcn(p
);
5350 p
= pool
->freeBlocks
;
5352 BLOCK
*tem
= p
->next
;
5353 pool
->mem
->free_fcn(p
);
5358 static XML_Char
* FASTCALL
5359 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
5360 const char *ptr
, const char *end
)
5362 if (!pool
->ptr
&& !poolGrow(pool
))
5365 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
5368 if (!poolGrow(pool
))
5374 static const XML_Char
* FASTCALL
5375 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
5378 if (!poolAppendChar(pool
, *s
))
5386 static const XML_Char
* FASTCALL
5387 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
5389 if (!pool
->ptr
&& !poolGrow(pool
))
5391 for (; n
> 0; --n
, s
++) {
5392 if (!poolAppendChar(pool
, *s
))
5400 static const XML_Char
* FASTCALL
5401 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
5404 if (!poolAppendChar(pool
, *s
))
5411 static XML_Char
* FASTCALL
5412 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
5413 const char *ptr
, const char *end
)
5415 if (!poolAppend(pool
, enc
, ptr
, end
))
5417 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
5423 static XML_Bool FASTCALL
5424 poolGrow(STRING_POOL
*pool
)
5426 if (pool
->freeBlocks
) {
5427 if (pool
->start
== 0) {
5428 pool
->blocks
= pool
->freeBlocks
;
5429 pool
->freeBlocks
= pool
->freeBlocks
->next
;
5430 pool
->blocks
->next
= NULL
;
5431 pool
->start
= pool
->blocks
->s
;
5432 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5433 pool
->ptr
= pool
->start
;
5436 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
5437 BLOCK
*tem
= pool
->freeBlocks
->next
;
5438 pool
->freeBlocks
->next
= pool
->blocks
;
5439 pool
->blocks
= pool
->freeBlocks
;
5440 pool
->freeBlocks
= tem
;
5441 memcpy(pool
->blocks
->s
, pool
->start
,
5442 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
5443 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5444 pool
->start
= pool
->blocks
->s
;
5445 pool
->end
= pool
->start
+ pool
->blocks
->size
;
5449 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
5450 int blockSize
= (pool
->end
- pool
->start
)*2;
5451 pool
->blocks
= pool
->mem
->realloc_fcn(pool
->blocks
,
5453 + blockSize
* sizeof(XML_Char
));
5454 if (pool
->blocks
== NULL
)
5456 pool
->blocks
->size
= blockSize
;
5457 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
5458 pool
->start
= pool
->blocks
->s
;
5459 pool
->end
= pool
->start
+ blockSize
;
5463 int blockSize
= pool
->end
- pool
->start
;
5464 if (blockSize
< INIT_BLOCK_SIZE
)
5465 blockSize
= INIT_BLOCK_SIZE
;
5468 tem
= pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
5469 + blockSize
* sizeof(XML_Char
));
5472 tem
->size
= blockSize
;
5473 tem
->next
= pool
->blocks
;
5475 if (pool
->ptr
!= pool
->start
)
5476 memcpy(tem
->s
, pool
->start
,
5477 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
5478 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
5479 pool
->start
= tem
->s
;
5480 pool
->end
= tem
->s
+ blockSize
;
5486 nextScaffoldPart(XML_Parser parser
)
5488 CONTENT_SCAFFOLD
* me
;
5491 if (!dtd
.scaffIndex
) {
5492 dtd
.scaffIndex
= MALLOC(groupSize
* sizeof(int));
5493 if (!dtd
.scaffIndex
)
5495 dtd
.scaffIndex
[0] = 0;
5498 if (dtd
.scaffCount
>= dtd
.scaffSize
) {
5499 CONTENT_SCAFFOLD
*temp
;
5501 temp
= (CONTENT_SCAFFOLD
*)
5502 REALLOC(dtd
.scaffold
, dtd
.scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
5508 temp
= MALLOC(INIT_SCAFFOLD_ELEMENTS
* sizeof(CONTENT_SCAFFOLD
));
5511 dtd
.scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
5513 dtd
.scaffold
= temp
;
5515 next
= dtd
.scaffCount
++;
5516 me
= &dtd
.scaffold
[next
];
5517 if (dtd
.scaffLevel
) {
5518 CONTENT_SCAFFOLD
*parent
= &dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
-1]];
5519 if (parent
->lastchild
) {
5520 dtd
.scaffold
[parent
->lastchild
].nextsib
= next
;
5522 if (!parent
->childcnt
)
5523 parent
->firstchild
= next
;
5524 parent
->lastchild
= next
;
5527 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
5531 static void FASTCALL
5532 build_node(XML_Parser parser
,
5535 XML_Content
**contpos
,
5538 dest
->type
= dtd
.scaffold
[src_node
].type
;
5539 dest
->quant
= dtd
.scaffold
[src_node
].quant
;
5540 if (dest
->type
== XML_CTYPE_NAME
) {
5541 const XML_Char
*src
;
5542 dest
->name
= *strpos
;
5543 src
= dtd
.scaffold
[src_node
].name
;
5545 *(*strpos
)++ = *src
;
5550 dest
->numchildren
= 0;
5551 dest
->children
= NULL
;
5556 dest
->numchildren
= dtd
.scaffold
[src_node
].childcnt
;
5557 dest
->children
= *contpos
;
5558 *contpos
+= dest
->numchildren
;
5559 for (i
= 0, cn
= dtd
.scaffold
[src_node
].firstchild
;
5560 i
< dest
->numchildren
;
5561 i
++, cn
= dtd
.scaffold
[cn
].nextsib
) {
5562 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
5568 static XML_Content
* FASTCALL
5569 build_model (XML_Parser parser
)
5574 int allocsize
= (dtd
.scaffCount
* sizeof(XML_Content
)
5575 + (dtd
.contentStringLen
* sizeof(XML_Char
)));
5577 ret
= MALLOC(allocsize
);
5581 str
= (XML_Char
*) (&ret
[dtd
.scaffCount
]);
5584 build_node(parser
, 0, ret
, &cpos
, &str
);
5588 static ELEMENT_TYPE
* FASTCALL
5589 getElementType(XML_Parser parser
,
5590 const ENCODING
*enc
,
5594 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, ptr
, end
);
5599 ret
= (ELEMENT_TYPE
*) lookup(&dtd
.elementTypes
, name
, sizeof(ELEMENT_TYPE
));
5602 if (ret
->name
!= name
)
5603 poolDiscard(&dtd
.pool
);
5605 poolFinish(&dtd
.pool
);
5606 if (!setElementTypePrefix(parser
, ret
))