1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
9 #define XML_BUILDING_EXPAT 1
12 #ifdef COMPILED_FROM_DSP
13 #include "winconfig.h"
14 #elif defined(MACOS_CLASSIC)
15 #include "macconfig.h"
16 #elif defined(__amigaos4__)
17 #include "amigaconfig.h"
18 #elif defined(__WATCOMC__)
19 #include "watcomconfig.h"
20 #elif defined(HAVE_EXPAT_CONFIG_H)
21 #include <expat_config.h>
22 #endif /* ndef COMPILED_FROM_DSP */
28 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
29 #define XmlConvert XmlUtf16Convert
30 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
31 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
32 #define XmlEncode XmlUtf16Encode
33 /* Using pointer subtraction to convert to integer type. */
34 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
35 typedef unsigned short ICHAR;
37 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
38 #define XmlConvert XmlUtf8Convert
39 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
40 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
41 #define XmlEncode XmlUtf8Encode
42 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
49 #define XmlInitEncodingNS XmlInitEncoding
50 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
51 #undef XmlGetInternalEncodingNS
52 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
53 #define XmlParseXmlDeclNS XmlParseXmlDecl
59 #ifdef XML_UNICODE_WCHAR_T
60 #define XML_T(x) (const wchar_t)x
61 #define XML_L(x) L ## x
63 #define XML_T(x) (const unsigned short)x
74 /* Round up n to be a multiple of sz, where sz is a power of 2. */
75 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
77 /* Handle the case where memmove() doesn't exist. */
80 #define memmove(d,s,l) bcopy((s),(d),(l))
82 #error memmove does not exist on this platform, nor is a substitute available
83 #endif /* HAVE_BCOPY */
84 #endif /* HAVE_MEMMOVE */
90 typedef const XML_Char *KEY;
101 const XML_Memory_Handling_Suite *mem;
104 /* Basic character hash algorithm, taken from Python's string hash:
105 h = h * 1000003 ^ character, the constant being a prime number.
109 #define CHAR_HASH(h, c) \
110 (((h) * 0xF4243) ^ (unsigned short)(c))
112 #define CHAR_HASH(h, c) \
113 (((h) * 0xF4243) ^ (unsigned char)(c))
116 /* For probing (after a collision) we need a step size relative prime
117 to the hash table size, which is a power of 2. We use double-hashing,
118 since we can calculate a second hash value cheaply by taking those bits
119 of the first hash value that were discarded (masked out) when the table
120 index was calculated: index = hash & mask, where mask = table->size - 1.
121 We limit the maximum step size to table->size / 4 (mask >> 2) and make
122 it odd, since odd numbers are always relative prime to a power of 2.
124 #define SECOND_HASH(hash, mask, power) \
125 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
126 #define PROBE_STEP(hash, mask, power) \
127 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
134 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
135 #define INIT_DATA_BUF_SIZE 1024
136 #define INIT_ATTS_SIZE 16
137 #define INIT_ATTS_VERSION 0xFFFFFFFF
138 #define INIT_BLOCK_SIZE 1024
139 #define INIT_BUFFER_SIZE 1024
141 #define EXPAND_SPARE 24
143 typedef struct binding {
144 struct prefix *prefix;
145 struct binding *nextTagBinding;
146 struct binding *prevPrefixBinding;
147 const struct attribute_id *attId;
153 typedef struct prefix {
154 const XML_Char *name;
160 const XML_Char *localPart;
161 const XML_Char *prefix;
167 /* TAG represents an open element.
168 The name of the element is stored in both the document and API
169 encodings. The memory buffer 'buf' is a separately-allocated
170 memory area which stores the name. During the XML_Parse()/
171 XMLParseBuffer() when the element is open, the memory for the 'raw'
172 version of the name (in the document encoding) is shared with the
173 document buffer. If the element is open across calls to
174 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
175 contain the 'raw' name as well.
177 A parser re-uses these structures, maintaining a list of allocated
178 TAG objects in a free list.
181 struct tag *parent; /* parent of this element */
182 const char *rawName; /* tagName in the original encoding */
184 TAG_NAME name; /* tagName in the API encoding */
185 char *buf; /* buffer for name components */
186 char *bufEnd; /* end of the buffer */
191 const XML_Char *name;
192 const XML_Char *textPtr;
193 int textLen; /* length in XML_Chars */
194 int processed; /* # of processed bytes - when suspended */
195 const XML_Char *systemId;
196 const XML_Char *base;
197 const XML_Char *publicId;
198 const XML_Char *notation;
201 XML_Bool is_internal; /* true if declared in internal subset outside PE */
205 enum XML_Content_Type type;
206 enum XML_Content_Quant quant;
207 const XML_Char * name;
214 #define INIT_SCAFFOLD_ELEMENTS 32
216 typedef struct block {
228 const XML_Memory_Handling_Suite *mem;
231 /* The XML_Char before the name is used to determine whether
232 an attribute has been specified. */
233 typedef struct attribute_id {
236 XML_Bool maybeTokenized;
241 const ATTRIBUTE_ID *id;
243 const XML_Char *value;
247 unsigned long version;
249 const XML_Char *uriName;
253 const XML_Char *name;
255 const ATTRIBUTE_ID *idAtt;
257 int allocDefaultAtts;
258 DEFAULT_ATTRIBUTE *defaultAtts;
262 HASH_TABLE generalEntities;
263 HASH_TABLE elementTypes;
264 HASH_TABLE attributeIds;
267 STRING_POOL entityValuePool;
268 /* false once a parameter entity reference has been skipped */
269 XML_Bool keepProcessing;
270 /* true once an internal or external PE reference has been encountered;
271 this includes the reference to an external subset */
272 XML_Bool hasParamEntityRefs;
275 /* indicates if external PE has been read */
276 XML_Bool paramEntityRead;
277 HASH_TABLE paramEntities;
279 PREFIX defaultPrefix;
280 /* === scaffolding for building content model === */
282 CONTENT_SCAFFOLD *scaffold;
283 unsigned contentStringLen;
290 typedef struct open_internal_entity {
291 const char *internalEventPtr;
292 const char *internalEventEndPtr;
293 struct open_internal_entity *next;
296 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
297 } OPEN_INTERNAL_ENTITY;
299 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
302 const char **endPtr);
304 static Processor prologProcessor;
305 static Processor prologInitProcessor;
306 static Processor contentProcessor;
307 static Processor cdataSectionProcessor;
309 static Processor ignoreSectionProcessor;
310 static Processor externalParEntProcessor;
311 static Processor externalParEntInitProcessor;
312 static Processor entityValueProcessor;
313 static Processor entityValueInitProcessor;
315 static Processor epilogProcessor;
316 static Processor errorProcessor;
317 static Processor externalEntityInitProcessor;
318 static Processor externalEntityInitProcessor2;
319 static Processor externalEntityInitProcessor3;
320 static Processor externalEntityContentProcessor;
321 static Processor internalEntityProcessor;
323 static enum XML_Error
324 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
325 static enum XML_Error
326 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
327 const char *s, const char *next);
328 static enum XML_Error
329 initializeEncoding(XML_Parser parser);
330 static enum XML_Error
331 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
332 const char *end, int tok, const char *next, const char **nextPtr,
334 static enum XML_Error
335 processInternalEntity(XML_Parser parser, ENTITY *entity,
336 XML_Bool betweenDecl);
337 static enum XML_Error
338 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
339 const char *start, const char *end, const char **endPtr,
341 static enum XML_Error
342 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
343 const char *end, const char **nextPtr, XML_Bool haveMore);
345 static enum XML_Error
346 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
347 const char *end, const char **nextPtr, XML_Bool haveMore);
350 static enum XML_Error
351 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
352 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
353 static enum XML_Error
354 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
355 const XML_Char *uri, BINDING **bindingsPtr);
357 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
358 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
359 static enum XML_Error
360 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
361 const char *, const char *, STRING_POOL *);
362 static enum XML_Error
363 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
364 const char *, const char *, STRING_POOL *);
365 static ATTRIBUTE_ID *
366 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
369 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
370 static enum XML_Error
371 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
374 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
375 const char *start, const char *end);
377 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
380 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
383 static const XML_Char * getContext(XML_Parser parser);
385 setContext(XML_Parser parser, const XML_Char *context);
387 static void FASTCALL normalizePublicId(XML_Char *s);
389 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
390 /* do not call if parentParser != NULL */
391 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
393 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
395 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
397 copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
400 lookup(HASH_TABLE *table, KEY name, size_t createSize);
402 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
403 static void FASTCALL hashTableClear(HASH_TABLE *);
404 static void FASTCALL hashTableDestroy(HASH_TABLE *);
406 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
407 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
410 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
411 static void FASTCALL poolClear(STRING_POOL *);
412 static void FASTCALL poolDestroy(STRING_POOL *);
414 poolAppend(STRING_POOL *pool, const ENCODING *enc,
415 const char *ptr, const char *end);
417 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
418 const char *ptr, const char *end);
419 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
420 static const XML_Char * FASTCALL
421 poolCopyString(STRING_POOL *pool, const XML_Char *s);
422 static const XML_Char *
423 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
424 static const XML_Char * FASTCALL
425 poolAppendString(STRING_POOL *pool, const XML_Char *s);
427 static int FASTCALL nextScaffoldPart(XML_Parser parser);
428 static XML_Content * build_model(XML_Parser parser);
429 static ELEMENT_TYPE *
430 getElementType(XML_Parser parser, const ENCODING *enc,
431 const char *ptr, const char *end);
434 parserCreate(const XML_Char *encodingName,
435 const XML_Memory_Handling_Suite *memsuite,
436 const XML_Char *nameSep,
439 parserInit(XML_Parser parser, const XML_Char *encodingName);
441 #define poolStart(pool) ((pool)->start)
442 #define poolEnd(pool) ((pool)->ptr)
443 #define poolLength(pool) ((pool)->ptr - (pool)->start)
444 #define poolChop(pool) ((void)--(pool->ptr))
445 #define poolLastChar(pool) (((pool)->ptr)[-1])
446 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
447 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
448 #define poolAppendChar(pool, c) \
449 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
451 : ((*((pool)->ptr)++ = c), 1))
453 struct XML_ParserStruct {
454 /* The first member must be userData so that the XML_GetUserData
459 const XML_Memory_Handling_Suite m_mem;
460 /* first character to be parsed */
461 const char *m_bufferPtr;
462 /* past last character to be parsed */
464 /* allocated end of buffer */
465 const char *m_bufferLim;
466 XML_Index m_parseEndByteIndex;
467 const char *m_parseEndPtr;
469 XML_Char *m_dataBufEnd;
470 XML_StartElementHandler m_startElementHandler;
471 XML_EndElementHandler m_endElementHandler;
472 XML_CharacterDataHandler m_characterDataHandler;
473 XML_ProcessingInstructionHandler m_processingInstructionHandler;
474 XML_CommentHandler m_commentHandler;
475 XML_StartCdataSectionHandler m_startCdataSectionHandler;
476 XML_EndCdataSectionHandler m_endCdataSectionHandler;
477 XML_DefaultHandler m_defaultHandler;
478 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
479 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
480 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
481 XML_NotationDeclHandler m_notationDeclHandler;
482 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
483 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
484 XML_NotStandaloneHandler m_notStandaloneHandler;
485 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
486 XML_Parser m_externalEntityRefHandlerArg;
487 XML_SkippedEntityHandler m_skippedEntityHandler;
488 XML_UnknownEncodingHandler m_unknownEncodingHandler;
489 XML_ElementDeclHandler m_elementDeclHandler;
490 XML_AttlistDeclHandler m_attlistDeclHandler;
491 XML_EntityDeclHandler m_entityDeclHandler;
492 XML_XmlDeclHandler m_xmlDeclHandler;
493 const ENCODING *m_encoding;
494 INIT_ENCODING m_initEncoding;
495 const ENCODING *m_internalEncoding;
496 const XML_Char *m_protocolEncodingName;
498 XML_Bool m_ns_triplets;
499 void *m_unknownEncodingMem;
500 void *m_unknownEncodingData;
501 void *m_unknownEncodingHandlerData;
502 void (XMLCALL *m_unknownEncodingRelease)(void *);
503 PROLOG_STATE m_prologState;
504 Processor *m_processor;
505 enum XML_Error m_errorCode;
506 const char *m_eventPtr;
507 const char *m_eventEndPtr;
508 const char *m_positionPtr;
509 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
510 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
511 XML_Bool m_defaultExpandInternalEntities;
513 ENTITY *m_declEntity;
514 const XML_Char *m_doctypeName;
515 const XML_Char *m_doctypeSysid;
516 const XML_Char *m_doctypePubid;
517 const XML_Char *m_declAttributeType;
518 const XML_Char *m_declNotationName;
519 const XML_Char *m_declNotationPublicId;
520 ELEMENT_TYPE *m_declElementType;
521 ATTRIBUTE_ID *m_declAttributeId;
522 XML_Bool m_declAttributeIsCdata;
523 XML_Bool m_declAttributeIsId;
525 const XML_Char *m_curBase;
528 BINDING *m_inheritedBindings;
529 BINDING *m_freeBindingList;
531 int m_nSpecifiedAtts;
535 unsigned long m_nsAttsVersion;
536 unsigned char m_nsAttsPower;
538 STRING_POOL m_tempPool;
539 STRING_POOL m_temp2Pool;
540 char *m_groupConnector;
541 unsigned int m_groupSize;
542 XML_Char m_namespaceSeparator;
543 XML_Parser m_parentParser;
544 XML_ParsingStatus m_parsingStatus;
546 XML_Bool m_isParamEntity;
547 XML_Bool m_useForeignDTD;
548 enum XML_ParamEntityParsing m_paramEntityParsing;
552 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
553 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
554 #define FREE(p) (parser->m_mem.free_fcn((p)))
556 #define userData (parser->m_userData)
557 #define handlerArg (parser->m_handlerArg)
558 #define startElementHandler (parser->m_startElementHandler)
559 #define endElementHandler (parser->m_endElementHandler)
560 #define characterDataHandler (parser->m_characterDataHandler)
561 #define processingInstructionHandler \
562 (parser->m_processingInstructionHandler)
563 #define commentHandler (parser->m_commentHandler)
564 #define startCdataSectionHandler \
565 (parser->m_startCdataSectionHandler)
566 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
567 #define defaultHandler (parser->m_defaultHandler)
568 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
569 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
570 #define unparsedEntityDeclHandler \
571 (parser->m_unparsedEntityDeclHandler)
572 #define notationDeclHandler (parser->m_notationDeclHandler)
573 #define startNamespaceDeclHandler \
574 (parser->m_startNamespaceDeclHandler)
575 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
576 #define notStandaloneHandler (parser->m_notStandaloneHandler)
577 #define externalEntityRefHandler \
578 (parser->m_externalEntityRefHandler)
579 #define externalEntityRefHandlerArg \
580 (parser->m_externalEntityRefHandlerArg)
581 #define internalEntityRefHandler \
582 (parser->m_internalEntityRefHandler)
583 #define skippedEntityHandler (parser->m_skippedEntityHandler)
584 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
585 #define elementDeclHandler (parser->m_elementDeclHandler)
586 #define attlistDeclHandler (parser->m_attlistDeclHandler)
587 #define entityDeclHandler (parser->m_entityDeclHandler)
588 #define xmlDeclHandler (parser->m_xmlDeclHandler)
589 #define encoding (parser->m_encoding)
590 #define initEncoding (parser->m_initEncoding)
591 #define internalEncoding (parser->m_internalEncoding)
592 #define unknownEncodingMem (parser->m_unknownEncodingMem)
593 #define unknownEncodingData (parser->m_unknownEncodingData)
594 #define unknownEncodingHandlerData \
595 (parser->m_unknownEncodingHandlerData)
596 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
597 #define protocolEncodingName (parser->m_protocolEncodingName)
598 #define ns (parser->m_ns)
599 #define ns_triplets (parser->m_ns_triplets)
600 #define prologState (parser->m_prologState)
601 #define processor (parser->m_processor)
602 #define errorCode (parser->m_errorCode)
603 #define eventPtr (parser->m_eventPtr)
604 #define eventEndPtr (parser->m_eventEndPtr)
605 #define positionPtr (parser->m_positionPtr)
606 #define position (parser->m_position)
607 #define openInternalEntities (parser->m_openInternalEntities)
608 #define freeInternalEntities (parser->m_freeInternalEntities)
609 #define defaultExpandInternalEntities \
610 (parser->m_defaultExpandInternalEntities)
611 #define tagLevel (parser->m_tagLevel)
612 #define buffer (parser->m_buffer)
613 #define bufferPtr (parser->m_bufferPtr)
614 #define bufferEnd (parser->m_bufferEnd)
615 #define parseEndByteIndex (parser->m_parseEndByteIndex)
616 #define parseEndPtr (parser->m_parseEndPtr)
617 #define bufferLim (parser->m_bufferLim)
618 #define dataBuf (parser->m_dataBuf)
619 #define dataBufEnd (parser->m_dataBufEnd)
620 #define _dtd (parser->m_dtd)
621 #define curBase (parser->m_curBase)
622 #define declEntity (parser->m_declEntity)
623 #define doctypeName (parser->m_doctypeName)
624 #define doctypeSysid (parser->m_doctypeSysid)
625 #define doctypePubid (parser->m_doctypePubid)
626 #define declAttributeType (parser->m_declAttributeType)
627 #define declNotationName (parser->m_declNotationName)
628 #define declNotationPublicId (parser->m_declNotationPublicId)
629 #define declElementType (parser->m_declElementType)
630 #define declAttributeId (parser->m_declAttributeId)
631 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
632 #define declAttributeIsId (parser->m_declAttributeIsId)
633 #define freeTagList (parser->m_freeTagList)
634 #define freeBindingList (parser->m_freeBindingList)
635 #define inheritedBindings (parser->m_inheritedBindings)
636 #define tagStack (parser->m_tagStack)
637 #define atts (parser->m_atts)
638 #define attsSize (parser->m_attsSize)
639 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
640 #define idAttIndex (parser->m_idAttIndex)
641 #define nsAtts (parser->m_nsAtts)
642 #define nsAttsVersion (parser->m_nsAttsVersion)
643 #define nsAttsPower (parser->m_nsAttsPower)
644 #define tempPool (parser->m_tempPool)
645 #define temp2Pool (parser->m_temp2Pool)
646 #define groupConnector (parser->m_groupConnector)
647 #define groupSize (parser->m_groupSize)
648 #define namespaceSeparator (parser->m_namespaceSeparator)
649 #define parentParser (parser->m_parentParser)
650 #define ps_parsing (parser->m_parsingStatus.parsing)
651 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
653 #define isParamEntity (parser->m_isParamEntity)
654 #define useForeignDTD (parser->m_useForeignDTD)
655 #define paramEntityParsing (parser->m_paramEntityParsing)
659 XML_ParserCreate(const XML_Char *encodingName)
661 return XML_ParserCreate_MM(encodingName, NULL, NULL);
665 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
669 return XML_ParserCreate_MM(encodingName, NULL, tmp);
672 static const XML_Char implicitContext[] = {
673 ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
674 ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
675 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
676 ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
677 ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
678 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
682 XML_ParserCreate_MM(const XML_Char *encodingName,
683 const XML_Memory_Handling_Suite *memsuite,
684 const XML_Char *nameSep)
686 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
687 if (parser != NULL && ns) {
688 /* implicit context only set for root parser, since child
689 parsers (i.e. external entity parsers) will inherit it
691 if (!setContext(parser, implicitContext)) {
692 XML_ParserFree(parser);
700 parserCreate(const XML_Char *encodingName,
701 const XML_Memory_Handling_Suite *memsuite,
702 const XML_Char *nameSep,
708 XML_Memory_Handling_Suite *mtemp;
709 parser = (XML_Parser)
710 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
711 if (parser != NULL) {
712 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
713 mtemp->malloc_fcn = memsuite->malloc_fcn;
714 mtemp->realloc_fcn = memsuite->realloc_fcn;
715 mtemp->free_fcn = memsuite->free_fcn;
719 XML_Memory_Handling_Suite *mtemp;
720 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
721 if (parser != NULL) {
722 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
723 mtemp->malloc_fcn = malloc;
724 mtemp->realloc_fcn = realloc;
725 mtemp->free_fcn = free;
735 attsSize = INIT_ATTS_SIZE;
736 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
741 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
742 if (dataBuf == NULL) {
747 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
752 _dtd = dtdCreate(&parser->m_mem);
761 freeBindingList = NULL;
763 freeInternalEntities = NULL;
766 groupConnector = NULL;
768 unknownEncodingHandler = NULL;
769 unknownEncodingHandlerData = NULL;
771 namespaceSeparator = ASCII_EXCL;
773 ns_triplets = XML_FALSE;
779 poolInit(&tempPool, &(parser->m_mem));
780 poolInit(&temp2Pool, &(parser->m_mem));
781 parserInit(parser, encodingName);
783 if (encodingName && !protocolEncodingName) {
784 XML_ParserFree(parser);
790 internalEncoding = XmlGetInternalEncodingNS();
791 namespaceSeparator = *nameSep;
794 internalEncoding = XmlGetInternalEncoding();
801 parserInit(XML_Parser parser, const XML_Char *encodingName)
803 processor = prologInitProcessor;
804 XmlPrologStateInit(&prologState);
805 protocolEncodingName = (encodingName != NULL
806 ? poolCopyString(&tempPool, encodingName)
809 XmlInitEncoding(&initEncoding, &encoding, 0);
812 startElementHandler = NULL;
813 endElementHandler = NULL;
814 characterDataHandler = NULL;
815 processingInstructionHandler = NULL;
816 commentHandler = NULL;
817 startCdataSectionHandler = NULL;
818 endCdataSectionHandler = NULL;
819 defaultHandler = NULL;
820 startDoctypeDeclHandler = NULL;
821 endDoctypeDeclHandler = NULL;
822 unparsedEntityDeclHandler = NULL;
823 notationDeclHandler = NULL;
824 startNamespaceDeclHandler = NULL;
825 endNamespaceDeclHandler = NULL;
826 notStandaloneHandler = NULL;
827 externalEntityRefHandler = NULL;
828 externalEntityRefHandlerArg = parser;
829 skippedEntityHandler = NULL;
830 elementDeclHandler = NULL;
831 attlistDeclHandler = NULL;
832 entityDeclHandler = NULL;
833 xmlDeclHandler = NULL;
836 parseEndByteIndex = 0;
838 declElementType = NULL;
839 declAttributeId = NULL;
844 declAttributeType = NULL;
845 declNotationName = NULL;
846 declNotationPublicId = NULL;
847 declAttributeIsCdata = XML_FALSE;
848 declAttributeIsId = XML_FALSE;
849 memset(&position, 0, sizeof(POSITION));
850 errorCode = XML_ERROR_NONE;
854 openInternalEntities = NULL;
855 defaultExpandInternalEntities = XML_TRUE;
858 inheritedBindings = NULL;
860 unknownEncodingMem = NULL;
861 unknownEncodingRelease = NULL;
862 unknownEncodingData = NULL;
864 ps_parsing = XML_INITIALIZED;
866 isParamEntity = XML_FALSE;
867 useForeignDTD = XML_FALSE;
868 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
872 /* moves list of bindings to freeBindingList */
874 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
877 BINDING *b = bindings;
878 bindings = bindings->nextTagBinding;
879 b->nextTagBinding = freeBindingList;
885 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
888 OPEN_INTERNAL_ENTITY *openEntityList;
891 /* move tagStack to freeTagList */
896 tag->parent = freeTagList;
897 moveToFreeBindingList(parser, tag->bindings);
898 tag->bindings = NULL;
901 /* move openInternalEntities to freeInternalEntities */
902 openEntityList = openInternalEntities;
903 while (openEntityList) {
904 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
905 openEntityList = openEntity->next;
906 openEntity->next = freeInternalEntities;
907 freeInternalEntities = openEntity;
909 moveToFreeBindingList(parser, inheritedBindings);
910 FREE(unknownEncodingMem);
911 if (unknownEncodingRelease)
912 unknownEncodingRelease(unknownEncodingData);
913 poolClear(&tempPool);
914 poolClear(&temp2Pool);
915 parserInit(parser, encodingName);
916 dtdReset(_dtd, &parser->m_mem);
917 return setContext(parser, implicitContext);
920 enum XML_Status XMLCALL
921 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
923 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
924 XXX There's no way for the caller to determine which of the
925 XXX possible error cases caused the XML_STATUS_ERROR return.
927 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
928 return XML_STATUS_ERROR;
929 if (encodingName == NULL)
930 protocolEncodingName = NULL;
932 protocolEncodingName = poolCopyString(&tempPool, encodingName);
933 if (!protocolEncodingName)
934 return XML_STATUS_ERROR;
936 return XML_STATUS_OK;
940 XML_ExternalEntityParserCreate(XML_Parser oldParser,
941 const XML_Char *context,
942 const XML_Char *encodingName)
944 XML_Parser parser = oldParser;
947 XML_StartElementHandler oldStartElementHandler = startElementHandler;
948 XML_EndElementHandler oldEndElementHandler = endElementHandler;
949 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
950 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
951 = processingInstructionHandler;
952 XML_CommentHandler oldCommentHandler = commentHandler;
953 XML_StartCdataSectionHandler oldStartCdataSectionHandler
954 = startCdataSectionHandler;
955 XML_EndCdataSectionHandler oldEndCdataSectionHandler
956 = endCdataSectionHandler;
957 XML_DefaultHandler oldDefaultHandler = defaultHandler;
958 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
959 = unparsedEntityDeclHandler;
960 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
961 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
962 = startNamespaceDeclHandler;
963 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
964 = endNamespaceDeclHandler;
965 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
966 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
967 = externalEntityRefHandler;
968 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
969 XML_UnknownEncodingHandler oldUnknownEncodingHandler
970 = unknownEncodingHandler;
971 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
972 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
973 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
974 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
975 ELEMENT_TYPE * oldDeclElementType = declElementType;
977 void *oldUserData = userData;
978 void *oldHandlerArg = handlerArg;
979 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
980 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
982 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
983 int oldInEntityValue = prologState.inEntityValue;
985 XML_Bool oldns_triplets = ns_triplets;
992 /* Note that the magical uses of the pre-processor to make field
993 access look more like C++ require that `parser' be overwritten
994 here. This makes this function more painful to follow than it
999 *tmp = namespaceSeparator;
1000 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1003 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1009 startElementHandler = oldStartElementHandler;
1010 endElementHandler = oldEndElementHandler;
1011 characterDataHandler = oldCharacterDataHandler;
1012 processingInstructionHandler = oldProcessingInstructionHandler;
1013 commentHandler = oldCommentHandler;
1014 startCdataSectionHandler = oldStartCdataSectionHandler;
1015 endCdataSectionHandler = oldEndCdataSectionHandler;
1016 defaultHandler = oldDefaultHandler;
1017 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1018 notationDeclHandler = oldNotationDeclHandler;
1019 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1020 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1021 notStandaloneHandler = oldNotStandaloneHandler;
1022 externalEntityRefHandler = oldExternalEntityRefHandler;
1023 skippedEntityHandler = oldSkippedEntityHandler;
1024 unknownEncodingHandler = oldUnknownEncodingHandler;
1025 elementDeclHandler = oldElementDeclHandler;
1026 attlistDeclHandler = oldAttlistDeclHandler;
1027 entityDeclHandler = oldEntityDeclHandler;
1028 xmlDeclHandler = oldXmlDeclHandler;
1029 declElementType = oldDeclElementType;
1030 userData = oldUserData;
1031 if (oldUserData == oldHandlerArg)
1032 handlerArg = userData;
1034 handlerArg = parser;
1035 if (oldExternalEntityRefHandlerArg != oldParser)
1036 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1037 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1038 ns_triplets = oldns_triplets;
1039 parentParser = oldParser;
1041 paramEntityParsing = oldParamEntityParsing;
1042 prologState.inEntityValue = oldInEntityValue;
1044 #endif /* XML_DTD */
1045 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1046 || !setContext(parser, context)) {
1047 XML_ParserFree(parser);
1050 processor = externalEntityInitProcessor;
1054 /* The DTD instance referenced by _dtd is shared between the document's
1055 root parser and external PE parsers, therefore one does not need to
1056 call setContext. In addition, one also *must* not call setContext,
1057 because this would overwrite existing prefix->binding pointers in
1058 _dtd with ones that get destroyed with the external PE parser.
1059 This would leave those prefixes with dangling pointers.
1061 isParamEntity = XML_TRUE;
1062 XmlPrologStateInitExternalEntity(&prologState);
1063 processor = externalParEntInitProcessor;
1065 #endif /* XML_DTD */
1069 static void FASTCALL
1070 destroyBindings(BINDING *bindings, XML_Parser parser)
1073 BINDING *b = bindings;
1076 bindings = b->nextTagBinding;
1083 XML_ParserFree(XML_Parser parser)
1086 OPEN_INTERNAL_ENTITY *entityList;
1089 /* free tagStack and freeTagList */
1093 if (tagList == NULL) {
1094 if (freeTagList == NULL)
1096 tagList = freeTagList;
1100 tagList = tagList->parent;
1102 destroyBindings(p->bindings, parser);
1105 /* free openInternalEntities and freeInternalEntities */
1106 entityList = openInternalEntities;
1108 OPEN_INTERNAL_ENTITY *openEntity;
1109 if (entityList == NULL) {
1110 if (freeInternalEntities == NULL)
1112 entityList = freeInternalEntities;
1113 freeInternalEntities = NULL;
1116 openEntity = entityList;
1117 entityList = entityList->next;
1121 destroyBindings(freeBindingList, parser);
1122 destroyBindings(inheritedBindings, parser);
1123 poolDestroy(&tempPool);
1124 poolDestroy(&temp2Pool);
1126 /* external parameter entity parsers share the DTD structure
1127 parser->m_dtd with the root parser, so we must not destroy it
1129 if (!isParamEntity && _dtd)
1132 #endif /* XML_DTD */
1133 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1135 FREE(groupConnector);
1139 FREE(unknownEncodingMem);
1140 if (unknownEncodingRelease)
1141 unknownEncodingRelease(unknownEncodingData);
1146 XML_UseParserAsHandlerArg(XML_Parser parser)
1148 handlerArg = parser;
1151 enum XML_Error XMLCALL
1152 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1155 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1156 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1157 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1158 useForeignDTD = useDTD;
1159 return XML_ERROR_NONE;
1161 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1166 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1168 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1169 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1171 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1175 XML_SetUserData(XML_Parser parser, void *p)
1177 if (handlerArg == userData)
1178 handlerArg = userData = p;
1183 enum XML_Status XMLCALL
1184 XML_SetBase(XML_Parser parser, const XML_Char *p)
1187 p = poolCopyString(&_dtd->pool, p);
1189 return XML_STATUS_ERROR;
1194 return XML_STATUS_OK;
1197 const XML_Char * XMLCALL
1198 XML_GetBase(XML_Parser parser)
1204 XML_GetSpecifiedAttributeCount(XML_Parser parser)
1206 return nSpecifiedAtts;
1210 XML_GetIdAttributeIndex(XML_Parser parser)
1216 XML_SetElementHandler(XML_Parser parser,
1217 XML_StartElementHandler start,
1218 XML_EndElementHandler end)
1220 startElementHandler = start;
1221 endElementHandler = end;
1225 XML_SetStartElementHandler(XML_Parser parser,
1226 XML_StartElementHandler start) {
1227 startElementHandler = start;
1231 XML_SetEndElementHandler(XML_Parser parser,
1232 XML_EndElementHandler end) {
1233 endElementHandler = end;
1237 XML_SetCharacterDataHandler(XML_Parser parser,
1238 XML_CharacterDataHandler handler)
1240 characterDataHandler = handler;
1244 XML_SetProcessingInstructionHandler(XML_Parser parser,
1245 XML_ProcessingInstructionHandler handler)
1247 processingInstructionHandler = handler;
1251 XML_SetCommentHandler(XML_Parser parser,
1252 XML_CommentHandler handler)
1254 commentHandler = handler;
1258 XML_SetCdataSectionHandler(XML_Parser parser,
1259 XML_StartCdataSectionHandler start,
1260 XML_EndCdataSectionHandler end)
1262 startCdataSectionHandler = start;
1263 endCdataSectionHandler = end;
1267 XML_SetStartCdataSectionHandler(XML_Parser parser,
1268 XML_StartCdataSectionHandler start) {
1269 startCdataSectionHandler = start;
1273 XML_SetEndCdataSectionHandler(XML_Parser parser,
1274 XML_EndCdataSectionHandler end) {
1275 endCdataSectionHandler = end;
1279 XML_SetDefaultHandler(XML_Parser parser,
1280 XML_DefaultHandler handler)
1282 defaultHandler = handler;
1283 defaultExpandInternalEntities = XML_FALSE;
1287 XML_SetDefaultHandlerExpand(XML_Parser parser,
1288 XML_DefaultHandler handler)
1290 defaultHandler = handler;
1291 defaultExpandInternalEntities = XML_TRUE;
1295 XML_SetDoctypeDeclHandler(XML_Parser parser,
1296 XML_StartDoctypeDeclHandler start,
1297 XML_EndDoctypeDeclHandler end)
1299 startDoctypeDeclHandler = start;
1300 endDoctypeDeclHandler = end;
1304 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1305 XML_StartDoctypeDeclHandler start) {
1306 startDoctypeDeclHandler = start;
1310 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1311 XML_EndDoctypeDeclHandler end) {
1312 endDoctypeDeclHandler = end;
1316 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1317 XML_UnparsedEntityDeclHandler handler)
1319 unparsedEntityDeclHandler = handler;
1323 XML_SetNotationDeclHandler(XML_Parser parser,
1324 XML_NotationDeclHandler handler)
1326 notationDeclHandler = handler;
1330 XML_SetNamespaceDeclHandler(XML_Parser parser,
1331 XML_StartNamespaceDeclHandler start,
1332 XML_EndNamespaceDeclHandler end)
1334 startNamespaceDeclHandler = start;
1335 endNamespaceDeclHandler = end;
1339 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1340 XML_StartNamespaceDeclHandler start) {
1341 startNamespaceDeclHandler = start;
1345 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1346 XML_EndNamespaceDeclHandler end) {
1347 endNamespaceDeclHandler = end;
1351 XML_SetNotStandaloneHandler(XML_Parser parser,
1352 XML_NotStandaloneHandler handler)
1354 notStandaloneHandler = handler;
1358 XML_SetExternalEntityRefHandler(XML_Parser parser,
1359 XML_ExternalEntityRefHandler handler)
1361 externalEntityRefHandler = handler;
1365 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1368 externalEntityRefHandlerArg = (XML_Parser)arg;
1370 externalEntityRefHandlerArg = parser;
1374 XML_SetSkippedEntityHandler(XML_Parser parser,
1375 XML_SkippedEntityHandler handler)
1377 skippedEntityHandler = handler;
1381 XML_SetUnknownEncodingHandler(XML_Parser parser,
1382 XML_UnknownEncodingHandler handler,
1385 unknownEncodingHandler = handler;
1386 unknownEncodingHandlerData = data;
1390 XML_SetElementDeclHandler(XML_Parser parser,
1391 XML_ElementDeclHandler eldecl)
1393 elementDeclHandler = eldecl;
1397 XML_SetAttlistDeclHandler(XML_Parser parser,
1398 XML_AttlistDeclHandler attdecl)
1400 attlistDeclHandler = attdecl;
1404 XML_SetEntityDeclHandler(XML_Parser parser,
1405 XML_EntityDeclHandler handler)
1407 entityDeclHandler = handler;
1411 XML_SetXmlDeclHandler(XML_Parser parser,
1412 XML_XmlDeclHandler handler) {
1413 xmlDeclHandler = handler;
1417 XML_SetParamEntityParsing(XML_Parser parser,
1418 enum XML_ParamEntityParsing peParsing)
1420 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1421 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1424 paramEntityParsing = peParsing;
1427 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1431 enum XML_Status XMLCALL
1432 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1434 switch (ps_parsing) {
1436 errorCode = XML_ERROR_SUSPENDED;
1437 return XML_STATUS_ERROR;
1439 errorCode = XML_ERROR_FINISHED;
1440 return XML_STATUS_ERROR;
1442 ps_parsing = XML_PARSING;
1446 ps_finalBuffer = (XML_Bool)isFinal;
1448 return XML_STATUS_OK;
1449 positionPtr = bufferPtr;
1450 parseEndPtr = bufferEnd;
1452 /* If data are left over from last buffer, and we now know that these
1453 data are the final chunk of input, then we have to check them again
1454 to detect errors based on that fact.
1456 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1458 if (errorCode == XML_ERROR_NONE) {
1459 switch (ps_parsing) {
1461 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1462 positionPtr = bufferPtr;
1463 return XML_STATUS_SUSPENDED;
1464 case XML_INITIALIZED:
1466 ps_parsing = XML_FINISHED;
1469 return XML_STATUS_OK;
1472 eventEndPtr = eventPtr;
1473 processor = errorProcessor;
1474 return XML_STATUS_ERROR;
1476 #ifndef XML_CONTEXT_BYTES
1477 else if (bufferPtr == bufferEnd) {
1480 enum XML_Error result;
1481 parseEndByteIndex += len;
1483 ps_finalBuffer = (XML_Bool)isFinal;
1485 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1487 if (errorCode != XML_ERROR_NONE) {
1488 eventEndPtr = eventPtr;
1489 processor = errorProcessor;
1490 return XML_STATUS_ERROR;
1493 switch (ps_parsing) {
1495 result = XML_STATUS_SUSPENDED;
1497 case XML_INITIALIZED:
1499 result = XML_STATUS_OK;
1501 ps_parsing = XML_FINISHED;
1507 XmlUpdatePosition(encoding, positionPtr, end, &position);
1508 nLeftOver = s + len - end;
1510 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1511 /* FIXME avoid integer overflow */
1513 temp = (buffer == NULL
1514 ? (char *)MALLOC(len * 2)
1515 : (char *)REALLOC(buffer, len * 2));
1517 errorCode = XML_ERROR_NO_MEMORY;
1518 return XML_STATUS_ERROR;
1522 errorCode = XML_ERROR_NO_MEMORY;
1523 eventPtr = eventEndPtr = NULL;
1524 processor = errorProcessor;
1525 return XML_STATUS_ERROR;
1527 bufferLim = buffer + len * 2;
1529 memcpy(buffer, end, nLeftOver);
1532 bufferEnd = buffer + nLeftOver;
1533 positionPtr = bufferPtr;
1534 parseEndPtr = bufferEnd;
1535 eventPtr = bufferPtr;
1536 eventEndPtr = bufferPtr;
1539 #endif /* not defined XML_CONTEXT_BYTES */
1541 void *buff = XML_GetBuffer(parser, len);
1543 return XML_STATUS_ERROR;
1545 memcpy(buff, s, len);
1546 return XML_ParseBuffer(parser, len, isFinal);
1551 enum XML_Status XMLCALL
1552 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1555 enum XML_Status result = XML_STATUS_OK;
1557 switch (ps_parsing) {
1559 errorCode = XML_ERROR_SUSPENDED;
1560 return XML_STATUS_ERROR;
1562 errorCode = XML_ERROR_FINISHED;
1563 return XML_STATUS_ERROR;
1565 ps_parsing = XML_PARSING;
1569 positionPtr = start;
1571 parseEndPtr = bufferEnd;
1572 parseEndByteIndex += len;
1573 ps_finalBuffer = (XML_Bool)isFinal;
1575 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1577 if (errorCode != XML_ERROR_NONE) {
1578 eventEndPtr = eventPtr;
1579 processor = errorProcessor;
1580 return XML_STATUS_ERROR;
1583 switch (ps_parsing) {
1585 result = XML_STATUS_SUSPENDED;
1587 case XML_INITIALIZED:
1590 ps_parsing = XML_FINISHED;
1593 default: ; /* should not happen */
1597 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1598 positionPtr = bufferPtr;
1603 XML_GetBuffer(XML_Parser parser, int len)
1605 switch (ps_parsing) {
1607 errorCode = XML_ERROR_SUSPENDED;
1610 errorCode = XML_ERROR_FINISHED;
1615 if (len > bufferLim - bufferEnd) {
1616 /* FIXME avoid integer overflow */
1617 int neededSize = len + (int)(bufferEnd - bufferPtr);
1618 #ifdef XML_CONTEXT_BYTES
1619 int keep = (int)(bufferPtr - buffer);
1621 if (keep > XML_CONTEXT_BYTES)
1622 keep = XML_CONTEXT_BYTES;
1624 #endif /* defined XML_CONTEXT_BYTES */
1625 if (neededSize <= bufferLim - buffer) {
1626 #ifdef XML_CONTEXT_BYTES
1627 if (keep < bufferPtr - buffer) {
1628 int offset = (int)(bufferPtr - buffer) - keep;
1629 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1630 bufferEnd -= offset;
1631 bufferPtr -= offset;
1634 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1635 bufferEnd = buffer + (bufferEnd - bufferPtr);
1637 #endif /* not defined XML_CONTEXT_BYTES */
1641 int bufferSize = (int)(bufferLim - bufferPtr);
1642 if (bufferSize == 0)
1643 bufferSize = INIT_BUFFER_SIZE;
1646 } while (bufferSize < neededSize);
1647 newBuf = (char *)MALLOC(bufferSize);
1649 errorCode = XML_ERROR_NO_MEMORY;
1652 bufferLim = newBuf + bufferSize;
1653 #ifdef XML_CONTEXT_BYTES
1655 int keep = (int)(bufferPtr - buffer);
1656 if (keep > XML_CONTEXT_BYTES)
1657 keep = XML_CONTEXT_BYTES;
1658 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1661 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1662 bufferPtr = buffer + keep;
1665 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1666 bufferPtr = buffer = newBuf;
1670 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1673 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1674 bufferPtr = buffer = newBuf;
1675 #endif /* not defined XML_CONTEXT_BYTES */
1681 enum XML_Status XMLCALL
1682 XML_StopParser(XML_Parser parser, XML_Bool resumable)
1684 switch (ps_parsing) {
1687 errorCode = XML_ERROR_SUSPENDED;
1688 return XML_STATUS_ERROR;
1690 ps_parsing = XML_FINISHED;
1693 errorCode = XML_ERROR_FINISHED;
1694 return XML_STATUS_ERROR;
1698 if (isParamEntity) {
1699 errorCode = XML_ERROR_SUSPEND_PE;
1700 return XML_STATUS_ERROR;
1703 ps_parsing = XML_SUSPENDED;
1706 ps_parsing = XML_FINISHED;
1708 return XML_STATUS_OK;
1711 enum XML_Status XMLCALL
1712 XML_ResumeParser(XML_Parser parser)
1714 enum XML_Status result = XML_STATUS_OK;
1716 if (ps_parsing != XML_SUSPENDED) {
1717 errorCode = XML_ERROR_NOT_SUSPENDED;
1718 return XML_STATUS_ERROR;
1720 ps_parsing = XML_PARSING;
1722 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1724 if (errorCode != XML_ERROR_NONE) {
1725 eventEndPtr = eventPtr;
1726 processor = errorProcessor;
1727 return XML_STATUS_ERROR;
1730 switch (ps_parsing) {
1732 result = XML_STATUS_SUSPENDED;
1734 case XML_INITIALIZED:
1736 if (ps_finalBuffer) {
1737 ps_parsing = XML_FINISHED;
1744 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1745 positionPtr = bufferPtr;
1750 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1752 assert(status != NULL);
1753 *status = parser->m_parsingStatus;
1756 enum XML_Error XMLCALL
1757 XML_GetErrorCode(XML_Parser parser)
1763 XML_GetCurrentByteIndex(XML_Parser parser)
1766 return parseEndByteIndex - (parseEndPtr - eventPtr);
1771 XML_GetCurrentByteCount(XML_Parser parser)
1773 if (eventEndPtr && eventPtr)
1774 return (int)(eventEndPtr - eventPtr);
1778 const char * XMLCALL
1779 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1781 #ifdef XML_CONTEXT_BYTES
1782 if (eventPtr && buffer) {
1783 *offset = (int)(eventPtr - buffer);
1784 *size = (int)(bufferEnd - buffer);
1787 #endif /* defined XML_CONTEXT_BYTES */
1792 XML_GetCurrentLineNumber(XML_Parser parser)
1794 if (eventPtr && eventPtr >= positionPtr) {
1795 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1796 positionPtr = eventPtr;
1798 return position.lineNumber + 1;
1802 XML_GetCurrentColumnNumber(XML_Parser parser)
1804 if (eventPtr && eventPtr >= positionPtr) {
1805 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1806 positionPtr = eventPtr;
1808 return position.columnNumber;
1812 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1818 XML_MemMalloc(XML_Parser parser, size_t size)
1820 return MALLOC(size);
1824 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1826 return REALLOC(ptr, size);
1830 XML_MemFree(XML_Parser parser, void *ptr)
1836 XML_DefaultCurrent(XML_Parser parser)
1838 if (defaultHandler) {
1839 if (openInternalEntities)
1840 reportDefault(parser,
1842 openInternalEntities->internalEventPtr,
1843 openInternalEntities->internalEventEndPtr);
1845 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1849 const XML_LChar * XMLCALL
1850 XML_ErrorString(enum XML_Error code)
1852 static const XML_LChar* const message[] = {
1854 XML_L("out of memory"),
1855 XML_L("syntax error"),
1856 XML_L("no element found"),
1857 XML_L("not well-formed (invalid token)"),
1858 XML_L("unclosed token"),
1859 XML_L("partial character"),
1860 XML_L("mismatched tag"),
1861 XML_L("duplicate attribute"),
1862 XML_L("junk after document element"),
1863 XML_L("illegal parameter entity reference"),
1864 XML_L("undefined entity"),
1865 XML_L("recursive entity reference"),
1866 XML_L("asynchronous entity"),
1867 XML_L("reference to invalid character number"),
1868 XML_L("reference to binary entity"),
1869 XML_L("reference to external entity in attribute"),
1870 XML_L("XML or text declaration not at start of entity"),
1871 XML_L("unknown encoding"),
1872 XML_L("encoding specified in XML declaration is incorrect"),
1873 XML_L("unclosed CDATA section"),
1874 XML_L("error in processing external entity reference"),
1875 XML_L("document is not standalone"),
1876 XML_L("unexpected parser state - please send a bug report"),
1877 XML_L("entity declared in parameter entity"),
1878 XML_L("requested feature requires XML_DTD support in Expat"),
1879 XML_L("cannot change setting once parsing has begun"),
1880 XML_L("unbound prefix"),
1881 XML_L("must not undeclare prefix"),
1882 XML_L("incomplete markup in parameter entity"),
1883 XML_L("XML declaration not well-formed"),
1884 XML_L("text declaration not well-formed"),
1885 XML_L("illegal character(s) in public id"),
1886 XML_L("parser suspended"),
1887 XML_L("parser not suspended"),
1888 XML_L("parsing aborted"),
1889 XML_L("parsing finished"),
1890 XML_L("cannot suspend in external parameter entity"),
1891 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1892 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1893 XML_L("prefix must not be bound to one of the reserved namespace names")
1895 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1896 return message[code];
1900 const XML_LChar * XMLCALL
1901 XML_ExpatVersion(void) {
1903 /* V1 is used to string-ize the version number. However, it would
1904 string-ize the actual version macro *names* unless we get them
1905 substituted before being passed to V1. CPP is defined to expand
1906 a macro, then rescan for more expansions. Thus, we use V2 to expand
1907 the version macros, then CPP will expand the resulting V1() macro
1908 with the correct numerals. */
1909 /* ### I'm assuming cpp is portable in this respect... */
1911 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1912 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1914 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1920 XML_Expat_Version XMLCALL
1921 XML_ExpatVersionInfo(void)
1923 XML_Expat_Version version;
1925 version.major = XML_MAJOR_VERSION;
1926 version.minor = XML_MINOR_VERSION;
1927 version.micro = XML_MICRO_VERSION;
1932 const XML_Feature * XMLCALL
1933 XML_GetFeatureList(void)
1935 static const XML_Feature features[] = {
1936 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
1938 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
1941 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
1943 #ifdef XML_UNICODE_WCHAR_T
1944 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
1947 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
1949 #ifdef XML_CONTEXT_BYTES
1950 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1954 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
1957 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
1959 #ifdef XML_LARGE_SIZE
1960 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
1962 {XML_FEATURE_END, NULL, 0}
1968 /* Initially tag->rawName always points into the parse buffer;
1969 for those TAG instances opened while the current parse buffer was
1970 processed, and not yet closed, we need to store tag->rawName in a more
1971 permanent location, since the parse buffer is about to be discarded.
1974 storeRawNames(XML_Parser parser)
1976 TAG *tag = tagStack;
1979 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1980 char *rawNameBuf = tag->buf + nameLen;
1981 /* Stop if already stored. Since tagStack is a stack, we can stop
1982 at the first entry that has already been copied; everything
1983 below it in the stack is already been accounted for in a
1984 previous call to this function.
1986 if (tag->rawName == rawNameBuf)
1988 /* For re-use purposes we need to ensure that the
1989 size of tag->buf is a multiple of sizeof(XML_Char).
1991 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1992 if (bufSize > tag->bufEnd - tag->buf) {
1993 char *temp = (char *)REALLOC(tag->buf, bufSize);
1996 /* if tag->name.str points to tag->buf (only when namespace
1997 processing is off) then we have to update it
1999 if (tag->name.str == (XML_Char *)tag->buf)
2000 tag->name.str = (XML_Char *)temp;
2001 /* if tag->name.localPart is set (when namespace processing is on)
2002 then update it as well, since it will always point into tag->buf
2004 if (tag->name.localPart)
2005 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2006 (XML_Char *)tag->buf);
2008 tag->bufEnd = temp + bufSize;
2009 rawNameBuf = temp + nameLen;
2011 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2012 tag->rawName = rawNameBuf;
2018 static enum XML_Error PTRCALL
2019 contentProcessor(XML_Parser parser,
2022 const char **endPtr)
2024 enum XML_Error result = doContent(parser, 0, encoding, start, end,
2025 endPtr, (XML_Bool)!ps_finalBuffer);
2026 if (result == XML_ERROR_NONE) {
2027 if (!storeRawNames(parser))
2028 return XML_ERROR_NO_MEMORY;
2033 static enum XML_Error PTRCALL
2034 externalEntityInitProcessor(XML_Parser parser,
2037 const char **endPtr)
2039 enum XML_Error result = initializeEncoding(parser);
2040 if (result != XML_ERROR_NONE)
2042 processor = externalEntityInitProcessor2;
2043 return externalEntityInitProcessor2(parser, start, end, endPtr);
2046 static enum XML_Error PTRCALL
2047 externalEntityInitProcessor2(XML_Parser parser,
2050 const char **endPtr)
2052 const char *next = start; /* XmlContentTok doesn't always set the last arg */
2053 int tok = XmlContentTok(encoding, start, end, &next);
2056 /* If we are at the end of the buffer, this would cause the next stage,
2057 i.e. externalEntityInitProcessor3, to pass control directly to
2058 doContent (by detecting XML_TOK_NONE) without processing any xml text
2059 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2061 if (next == end && !ps_finalBuffer) {
2063 return XML_ERROR_NONE;
2067 case XML_TOK_PARTIAL:
2068 if (!ps_finalBuffer) {
2070 return XML_ERROR_NONE;
2073 return XML_ERROR_UNCLOSED_TOKEN;
2074 case XML_TOK_PARTIAL_CHAR:
2075 if (!ps_finalBuffer) {
2077 return XML_ERROR_NONE;
2080 return XML_ERROR_PARTIAL_CHAR;
2082 processor = externalEntityInitProcessor3;
2083 return externalEntityInitProcessor3(parser, start, end, endPtr);
2086 static enum XML_Error PTRCALL
2087 externalEntityInitProcessor3(XML_Parser parser,
2090 const char **endPtr)
2093 const char *next = start; /* XmlContentTok doesn't always set the last arg */
2095 tok = XmlContentTok(encoding, start, end, &next);
2099 case XML_TOK_XML_DECL:
2101 enum XML_Error result;
2102 result = processXmlDecl(parser, 1, start, next);
2103 if (result != XML_ERROR_NONE)
2105 switch (ps_parsing) {
2108 return XML_ERROR_NONE;
2110 return XML_ERROR_ABORTED;
2116 case XML_TOK_PARTIAL:
2117 if (!ps_finalBuffer) {
2119 return XML_ERROR_NONE;
2121 return XML_ERROR_UNCLOSED_TOKEN;
2122 case XML_TOK_PARTIAL_CHAR:
2123 if (!ps_finalBuffer) {
2125 return XML_ERROR_NONE;
2127 return XML_ERROR_PARTIAL_CHAR;
2129 processor = externalEntityContentProcessor;
2131 return externalEntityContentProcessor(parser, start, end, endPtr);
2134 static enum XML_Error PTRCALL
2135 externalEntityContentProcessor(XML_Parser parser,
2138 const char **endPtr)
2140 enum XML_Error result = doContent(parser, 1, encoding, start, end,
2141 endPtr, (XML_Bool)!ps_finalBuffer);
2142 if (result == XML_ERROR_NONE) {
2143 if (!storeRawNames(parser))
2144 return XML_ERROR_NO_MEMORY;
2149 static enum XML_Error
2150 doContent(XML_Parser parser,
2152 const ENCODING *enc,
2155 const char **nextPtr,
2158 /* save one level of indirection */
2159 DTD * const dtd = _dtd;
2161 const char **eventPP;
2162 const char **eventEndPP;
2163 if (enc == encoding) {
2164 eventPP = &eventPtr;
2165 eventEndPP = &eventEndPtr;
2168 eventPP = &(openInternalEntities->internalEventPtr);
2169 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2174 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2175 int tok = XmlContentTok(enc, s, end, &next);
2178 case XML_TOK_TRAILING_CR:
2181 return XML_ERROR_NONE;
2184 if (characterDataHandler) {
2186 characterDataHandler(handlerArg, &c, 1);
2188 else if (defaultHandler)
2189 reportDefault(parser, enc, s, end);
2190 /* We are at the end of the final buffer, should we check for
2191 XML_SUSPENDED, XML_FINISHED?
2193 if (startTagLevel == 0)
2194 return XML_ERROR_NO_ELEMENTS;
2195 if (tagLevel != startTagLevel)
2196 return XML_ERROR_ASYNC_ENTITY;
2198 return XML_ERROR_NONE;
2202 return XML_ERROR_NONE;
2204 if (startTagLevel > 0) {
2205 if (tagLevel != startTagLevel)
2206 return XML_ERROR_ASYNC_ENTITY;
2208 return XML_ERROR_NONE;
2210 return XML_ERROR_NO_ELEMENTS;
2211 case XML_TOK_INVALID:
2213 return XML_ERROR_INVALID_TOKEN;
2214 case XML_TOK_PARTIAL:
2217 return XML_ERROR_NONE;
2219 return XML_ERROR_UNCLOSED_TOKEN;
2220 case XML_TOK_PARTIAL_CHAR:
2223 return XML_ERROR_NONE;
2225 return XML_ERROR_PARTIAL_CHAR;
2226 case XML_TOK_ENTITY_REF:
2228 const XML_Char *name;
2230 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2231 s + enc->minBytesPerChar,
2232 next - enc->minBytesPerChar);
2234 if (characterDataHandler)
2235 characterDataHandler(handlerArg, &ch, 1);
2236 else if (defaultHandler)
2237 reportDefault(parser, enc, s, next);
2240 name = poolStoreString(&dtd->pool, enc,
2241 s + enc->minBytesPerChar,
2242 next - enc->minBytesPerChar);
2244 return XML_ERROR_NO_MEMORY;
2245 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2246 poolDiscard(&dtd->pool);
2247 /* First, determine if a check for an existing declaration is needed;
2248 if yes, check that the entity exists, and that it is internal,
2249 otherwise call the skipped entity or default handler.
2251 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2253 return XML_ERROR_UNDEFINED_ENTITY;
2254 else if (!entity->is_internal)
2255 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2258 if (skippedEntityHandler)
2259 skippedEntityHandler(handlerArg, name, 0);
2260 else if (defaultHandler)
2261 reportDefault(parser, enc, s, next);
2265 return XML_ERROR_RECURSIVE_ENTITY_REF;
2266 if (entity->notation)
2267 return XML_ERROR_BINARY_ENTITY_REF;
2268 if (entity->textPtr) {
2269 enum XML_Error result;
2270 if (!defaultExpandInternalEntities) {
2271 if (skippedEntityHandler)
2272 skippedEntityHandler(handlerArg, entity->name, 0);
2273 else if (defaultHandler)
2274 reportDefault(parser, enc, s, next);
2277 result = processInternalEntity(parser, entity, XML_FALSE);
2278 if (result != XML_ERROR_NONE)
2281 else if (externalEntityRefHandler) {
2282 const XML_Char *context;
2283 entity->open = XML_TRUE;
2284 context = getContext(parser);
2285 entity->open = XML_FALSE;
2287 return XML_ERROR_NO_MEMORY;
2288 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2293 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2294 poolDiscard(&tempPool);
2296 else if (defaultHandler)
2297 reportDefault(parser, enc, s, next);
2300 case XML_TOK_START_TAG_NO_ATTS:
2302 case XML_TOK_START_TAG_WITH_ATTS:
2305 enum XML_Error result;
2309 freeTagList = freeTagList->parent;
2312 tag = (TAG *)MALLOC(sizeof(TAG));
2314 return XML_ERROR_NO_MEMORY;
2315 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2318 return XML_ERROR_NO_MEMORY;
2320 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2322 tag->bindings = NULL;
2323 tag->parent = tagStack;
2325 tag->name.localPart = NULL;
2326 tag->name.prefix = NULL;
2327 tag->rawName = s + enc->minBytesPerChar;
2328 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2331 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2332 const char *fromPtr = tag->rawName;
2333 toPtr = (XML_Char *)tag->buf;
2338 &fromPtr, rawNameEnd,
2339 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2340 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2341 if (fromPtr == rawNameEnd) {
2342 tag->name.strLen = convLen;
2345 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2347 char *temp = (char *)REALLOC(tag->buf, bufSize);
2349 return XML_ERROR_NO_MEMORY;
2351 tag->bufEnd = temp + bufSize;
2352 toPtr = (XML_Char *)temp + convLen;
2356 tag->name.str = (XML_Char *)tag->buf;
2357 *toPtr = XML_T('\0');
2358 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2361 if (startElementHandler)
2362 startElementHandler(handlerArg, tag->name.str,
2363 (const XML_Char **)atts);
2364 else if (defaultHandler)
2365 reportDefault(parser, enc, s, next);
2366 poolClear(&tempPool);
2369 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2371 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2373 const char *rawName = s + enc->minBytesPerChar;
2374 enum XML_Error result;
2375 BINDING *bindings = NULL;
2376 XML_Bool noElmHandlers = XML_TRUE;
2378 name.str = poolStoreString(&tempPool, enc, rawName,
2379 rawName + XmlNameLength(enc, rawName));
2381 return XML_ERROR_NO_MEMORY;
2382 poolFinish(&tempPool);
2383 result = storeAtts(parser, enc, s, &name, &bindings);
2386 poolFinish(&tempPool);
2387 if (startElementHandler) {
2388 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2389 noElmHandlers = XML_FALSE;
2391 if (endElementHandler) {
2392 if (startElementHandler)
2393 *eventPP = *eventEndPP;
2394 endElementHandler(handlerArg, name.str);
2395 noElmHandlers = XML_FALSE;
2397 if (noElmHandlers && defaultHandler)
2398 reportDefault(parser, enc, s, next);
2399 poolClear(&tempPool);
2401 BINDING *b = bindings;
2402 if (endNamespaceDeclHandler)
2403 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2404 bindings = bindings->nextTagBinding;
2405 b->nextTagBinding = freeBindingList;
2406 freeBindingList = b;
2407 b->prefix->binding = b->prevPrefixBinding;
2411 return epilogProcessor(parser, next, end, nextPtr);
2413 case XML_TOK_END_TAG:
2414 if (tagLevel == startTagLevel)
2415 return XML_ERROR_ASYNC_ENTITY;
2418 const char *rawName;
2419 TAG *tag = tagStack;
2420 tagStack = tag->parent;
2421 tag->parent = freeTagList;
2423 rawName = s + enc->minBytesPerChar*2;
2424 len = XmlNameLength(enc, rawName);
2425 if (len != tag->rawNameLength
2426 || memcmp(tag->rawName, rawName, len) != 0) {
2428 return XML_ERROR_TAG_MISMATCH;
2431 if (endElementHandler) {
2432 const XML_Char *localPart;
2433 const XML_Char *prefix;
2435 localPart = tag->name.localPart;
2436 if (ns && localPart) {
2437 /* localPart and prefix may have been overwritten in
2438 tag->name.str, since this points to the binding->uri
2439 buffer which gets re-used; so we have to add them again
2441 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2442 /* don't need to check for space - already done in storeAtts() */
2443 while (*localPart) *uri++ = *localPart++;
2444 prefix = (XML_Char *)tag->name.prefix;
2445 if (ns_triplets && prefix) {
2446 *uri++ = namespaceSeparator;
2447 while (*prefix) *uri++ = *prefix++;
2451 endElementHandler(handlerArg, tag->name.str);
2453 else if (defaultHandler)
2454 reportDefault(parser, enc, s, next);
2455 while (tag->bindings) {
2456 BINDING *b = tag->bindings;
2457 if (endNamespaceDeclHandler)
2458 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2459 tag->bindings = tag->bindings->nextTagBinding;
2460 b->nextTagBinding = freeBindingList;
2461 freeBindingList = b;
2462 b->prefix->binding = b->prevPrefixBinding;
2465 return epilogProcessor(parser, next, end, nextPtr);
2468 case XML_TOK_CHAR_REF:
2470 int n = XmlCharRefNumber(enc, s);
2472 return XML_ERROR_BAD_CHAR_REF;
2473 if (characterDataHandler) {
2474 XML_Char buf[XML_ENCODE_MAX];
2475 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2477 else if (defaultHandler)
2478 reportDefault(parser, enc, s, next);
2481 case XML_TOK_XML_DECL:
2482 return XML_ERROR_MISPLACED_XML_PI;
2483 case XML_TOK_DATA_NEWLINE:
2484 if (characterDataHandler) {
2486 characterDataHandler(handlerArg, &c, 1);
2488 else if (defaultHandler)
2489 reportDefault(parser, enc, s, next);
2491 case XML_TOK_CDATA_SECT_OPEN:
2493 enum XML_Error result;
2494 if (startCdataSectionHandler)
2495 startCdataSectionHandler(handlerArg);
2497 /* Suppose you doing a transformation on a document that involves
2498 changing only the character data. You set up a defaultHandler
2499 and a characterDataHandler. The defaultHandler simply copies
2500 characters through. The characterDataHandler does the
2501 transformation and writes the characters out escaping them as
2502 necessary. This case will fail to work if we leave out the
2503 following two lines (because & and < inside CDATA sections will
2504 be incorrectly escaped).
2506 However, now we have a start/endCdataSectionHandler, so it seems
2507 easier to let the user deal with this.
2509 else if (characterDataHandler)
2510 characterDataHandler(handlerArg, dataBuf, 0);
2512 else if (defaultHandler)
2513 reportDefault(parser, enc, s, next);
2514 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2515 if (result != XML_ERROR_NONE)
2518 processor = cdataSectionProcessor;
2523 case XML_TOK_TRAILING_RSQB:
2526 return XML_ERROR_NONE;
2528 if (characterDataHandler) {
2529 if (MUST_CONVERT(enc, s)) {
2530 ICHAR *dataPtr = (ICHAR *)dataBuf;
2531 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2532 characterDataHandler(handlerArg, dataBuf,
2533 (int)(dataPtr - (ICHAR *)dataBuf));
2536 characterDataHandler(handlerArg,
2538 (int)((XML_Char *)end - (XML_Char *)s));
2540 else if (defaultHandler)
2541 reportDefault(parser, enc, s, end);
2542 /* We are at the end of the final buffer, should we check for
2543 XML_SUSPENDED, XML_FINISHED?
2545 if (startTagLevel == 0) {
2547 return XML_ERROR_NO_ELEMENTS;
2549 if (tagLevel != startTagLevel) {
2551 return XML_ERROR_ASYNC_ENTITY;
2554 return XML_ERROR_NONE;
2555 case XML_TOK_DATA_CHARS:
2557 XML_CharacterDataHandler charDataHandler = characterDataHandler;
2558 if (charDataHandler) {
2559 if (MUST_CONVERT(enc, s)) {
2561 ICHAR *dataPtr = (ICHAR *)dataBuf;
2562 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2564 charDataHandler(handlerArg, dataBuf,
2565 (int)(dataPtr - (ICHAR *)dataBuf));
2572 charDataHandler(handlerArg,
2574 (int)((XML_Char *)next - (XML_Char *)s));
2576 else if (defaultHandler)
2577 reportDefault(parser, enc, s, next);
2581 if (!reportProcessingInstruction(parser, enc, s, next))
2582 return XML_ERROR_NO_MEMORY;
2584 case XML_TOK_COMMENT:
2585 if (!reportComment(parser, enc, s, next))
2586 return XML_ERROR_NO_MEMORY;
2590 reportDefault(parser, enc, s, next);
2593 *eventPP = s = next;
2594 switch (ps_parsing) {
2597 return XML_ERROR_NONE;
2599 return XML_ERROR_ABORTED;
2606 /* Precondition: all arguments must be non-NULL;
2608 - normalize attributes
2609 - check attributes for well-formedness
2610 - generate namespace aware attribute names (URI, prefix)
2611 - build list of attributes for startElementHandler
2612 - default attributes
2613 - process namespace declarations (check and report them)
2614 - generate namespace aware element name (URI, prefix)
2616 static enum XML_Error
2617 storeAtts(XML_Parser parser, const ENCODING *enc,
2618 const char *attStr, TAG_NAME *tagNamePtr,
2619 BINDING **bindingsPtr)
2621 DTD * const dtd = _dtd; /* save one level of indirection */
2622 ELEMENT_TYPE *elementType;
2624 const XML_Char **appAtts; /* the attribute list for the application */
2632 const XML_Char *localPart;
2634 /* lookup the element type name */
2635 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2637 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2639 return XML_ERROR_NO_MEMORY;
2640 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2641 sizeof(ELEMENT_TYPE));
2643 return XML_ERROR_NO_MEMORY;
2644 if (ns && !setElementTypePrefix(parser, elementType))
2645 return XML_ERROR_NO_MEMORY;
2647 nDefaultAtts = elementType->nDefaultAtts;
2649 /* get the attributes from the tokenizer */
2650 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2651 if (n + nDefaultAtts > attsSize) {
2652 int oldAttsSize = attsSize;
2654 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2655 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2657 return XML_ERROR_NO_MEMORY;
2659 if (n > oldAttsSize)
2660 XmlGetAttributes(enc, attStr, n, atts);
2663 appAtts = (const XML_Char **)atts;
2664 for (i = 0; i < n; i++) {
2665 /* add the name and value to the attribute list */
2666 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
2668 + XmlNameLength(enc, atts[i].name));
2670 return XML_ERROR_NO_MEMORY;
2671 /* Detect duplicate attributes by their QNames. This does not work when
2672 namespace processing is turned on and different prefixes for the same
2673 namespace are used. For this case we have a check further down.
2675 if ((attId->name)[-1]) {
2676 if (enc == encoding)
2677 eventPtr = atts[i].name;
2678 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2680 (attId->name)[-1] = 1;
2681 appAtts[attIndex++] = attId->name;
2682 if (!atts[i].normalized) {
2683 enum XML_Error result;
2684 XML_Bool isCdata = XML_TRUE;
2686 /* figure out whether declared as other than CDATA */
2687 if (attId->maybeTokenized) {
2689 for (j = 0; j < nDefaultAtts; j++) {
2690 if (attId == elementType->defaultAtts[j].id) {
2691 isCdata = elementType->defaultAtts[j].isCdata;
2697 /* normalize the attribute value */
2698 result = storeAttributeValue(parser, enc, isCdata,
2699 atts[i].valuePtr, atts[i].valueEnd,
2703 appAtts[attIndex] = poolStart(&tempPool);
2704 poolFinish(&tempPool);
2707 /* the value did not need normalizing */
2708 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2710 if (appAtts[attIndex] == 0)
2711 return XML_ERROR_NO_MEMORY;
2712 poolFinish(&tempPool);
2714 /* handle prefixed attribute names */
2715 if (attId->prefix) {
2717 /* deal with namespace declarations here */
2718 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2719 appAtts[attIndex], bindingsPtr);
2725 /* deal with other prefixed names later */
2728 (attId->name)[-1] = 2;
2735 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2736 nSpecifiedAtts = attIndex;
2737 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2738 for (i = 0; i < attIndex; i += 2)
2739 if (appAtts[i] == elementType->idAtt->name) {
2747 /* do attribute defaulting */
2748 for (i = 0; i < nDefaultAtts; i++) {
2749 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2750 if (!(da->id->name)[-1] && da->value) {
2751 if (da->id->prefix) {
2752 if (da->id->xmlns) {
2753 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2754 da->value, bindingsPtr);
2759 (da->id->name)[-1] = 2;
2761 appAtts[attIndex++] = da->id->name;
2762 appAtts[attIndex++] = da->value;
2766 (da->id->name)[-1] = 1;
2767 appAtts[attIndex++] = da->id->name;
2768 appAtts[attIndex++] = da->value;
2772 appAtts[attIndex] = 0;
2774 /* expand prefixed attribute names, check for duplicates,
2775 and clear flags that say whether attributes were specified */
2778 int j; /* hash table index */
2779 unsigned long version = nsAttsVersion;
2780 int nsAttsSize = (int)1 << nsAttsPower;
2781 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2782 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2784 /* hash table size must also be a power of 2 and >= 8 */
2785 while (nPrefixes >> nsAttsPower++);
2786 if (nsAttsPower < 3)
2788 nsAttsSize = (int)1 << nsAttsPower;
2789 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2791 return XML_ERROR_NO_MEMORY;
2793 version = 0; /* force re-initialization of nsAtts hash table */
2795 /* using a version flag saves us from initializing nsAtts every time */
2796 if (!version) { /* initialize version flags when version wraps around */
2797 version = INIT_ATTS_VERSION;
2798 for (j = nsAttsSize; j != 0; )
2799 nsAtts[--j].version = version;
2801 nsAttsVersion = --version;
2803 /* expand prefixed names and check for duplicates */
2804 for (; i < attIndex; i += 2) {
2805 const XML_Char *s = appAtts[i];
2806 if (s[-1] == 2) { /* prefixed */
2809 unsigned long uriHash = 0;
2810 ((XML_Char *)s)[-1] = 0; /* clear flag */
2811 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2812 b = id->prefix->binding;
2814 return XML_ERROR_UNBOUND_PREFIX;
2816 /* as we expand the name we also calculate its hash value */
2817 for (j = 0; j < b->uriLen; j++) {
2818 const XML_Char c = b->uri[j];
2819 if (!poolAppendChar(&tempPool, c))
2820 return XML_ERROR_NO_MEMORY;
2821 uriHash = CHAR_HASH(uriHash, c);
2823 while (*s++ != XML_T(ASCII_COLON))
2825 do { /* copies null terminator */
2826 const XML_Char c = *s;
2827 if (!poolAppendChar(&tempPool, *s))
2828 return XML_ERROR_NO_MEMORY;
2829 uriHash = CHAR_HASH(uriHash, c);
2832 { /* Check hash table for duplicate of expanded name (uriName).
2833 Derived from code in lookup(HASH_TABLE *table, ...).
2835 unsigned char step = 0;
2836 unsigned long mask = nsAttsSize - 1;
2837 j = uriHash & mask; /* index into hash table */
2838 while (nsAtts[j].version == version) {
2839 /* for speed we compare stored hash values first */
2840 if (uriHash == nsAtts[j].hash) {
2841 const XML_Char *s1 = poolStart(&tempPool);
2842 const XML_Char *s2 = nsAtts[j].uriName;
2843 /* s1 is null terminated, but not s2 */
2844 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2846 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2849 step = PROBE_STEP(uriHash, mask, nsAttsPower);
2850 j < step ? (j += nsAttsSize - step) : (j -= step);
2854 if (ns_triplets) { /* append namespace separator and prefix */
2855 tempPool.ptr[-1] = namespaceSeparator;
2856 s = b->prefix->name;
2858 if (!poolAppendChar(&tempPool, *s))
2859 return XML_ERROR_NO_MEMORY;
2863 /* store expanded name in attribute list */
2864 s = poolStart(&tempPool);
2865 poolFinish(&tempPool);
2868 /* fill empty slot with new version, uriName and hash value */
2869 nsAtts[j].version = version;
2870 nsAtts[j].hash = uriHash;
2871 nsAtts[j].uriName = s;
2878 else /* not prefixed */
2879 ((XML_Char *)s)[-1] = 0; /* clear flag */
2882 /* clear flags for the remaining attributes */
2883 for (; i < attIndex; i += 2)
2884 ((XML_Char *)(appAtts[i]))[-1] = 0;
2885 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2886 binding->attId->name[-1] = 0;
2889 return XML_ERROR_NONE;
2891 /* expand the element type name */
2892 if (elementType->prefix) {
2893 binding = elementType->prefix->binding;
2895 return XML_ERROR_UNBOUND_PREFIX;
2896 localPart = tagNamePtr->str;
2897 while (*localPart++ != XML_T(ASCII_COLON))
2900 else if (dtd->defaultPrefix.binding) {
2901 binding = dtd->defaultPrefix.binding;
2902 localPart = tagNamePtr->str;
2905 return XML_ERROR_NONE;
2907 if (ns_triplets && binding->prefix->name) {
2908 for (; binding->prefix->name[prefixLen++];)
2909 ; /* prefixLen includes null terminator */
2911 tagNamePtr->localPart = localPart;
2912 tagNamePtr->uriLen = binding->uriLen;
2913 tagNamePtr->prefix = binding->prefix->name;
2914 tagNamePtr->prefixLen = prefixLen;
2915 for (i = 0; localPart[i++];)
2916 ; /* i includes null terminator */
2917 n = i + binding->uriLen + prefixLen;
2918 if (n > binding->uriAlloc) {
2920 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2922 return XML_ERROR_NO_MEMORY;
2923 binding->uriAlloc = n + EXPAND_SPARE;
2924 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2925 for (p = tagStack; p; p = p->parent)
2926 if (p->name.str == binding->uri)
2931 /* if namespaceSeparator != '\0' then uri includes it already */
2932 uri = binding->uri + binding->uriLen;
2933 memcpy(uri, localPart, i * sizeof(XML_Char));
2934 /* we always have a namespace separator between localPart and prefix */
2937 *uri = namespaceSeparator; /* replace null terminator */
2938 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2940 tagNamePtr->str = binding->uri;
2941 return XML_ERROR_NONE;
2944 /* addBinding() overwrites the value of prefix->binding without checking.
2945 Therefore one must keep track of the old value outside of addBinding().
2947 static enum XML_Error
2948 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2949 const XML_Char *uri, BINDING **bindingsPtr)
2951 static const XML_Char xmlNamespace[] = {
2952 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
2953 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
2954 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
2955 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
2956 ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
2959 static const int xmlLen =
2960 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
2961 static const XML_Char xmlnsNamespace[] = {
2962 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
2963 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
2964 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
2965 ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
2968 static const int xmlnsLen =
2969 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
2971 XML_Bool mustBeXML = XML_FALSE;
2972 XML_Bool isXML = XML_TRUE;
2973 XML_Bool isXMLNS = XML_TRUE;
2978 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2979 if (*uri == XML_T('\0') && prefix->name)
2980 return XML_ERROR_UNDECLARING_PREFIX;
2983 && prefix->name[0] == XML_T(ASCII_x)
2984 && prefix->name[1] == XML_T(ASCII_m)
2985 && prefix->name[2] == XML_T(ASCII_l)) {
2987 /* Not allowed to bind xmlns */
2988 if (prefix->name[3] == XML_T(ASCII_n)
2989 && prefix->name[4] == XML_T(ASCII_s)
2990 && prefix->name[5] == XML_T('\0'))
2991 return XML_ERROR_RESERVED_PREFIX_XMLNS;
2993 if (prefix->name[3] == XML_T('\0'))
2994 mustBeXML = XML_TRUE;
2997 for (len = 0; uri[len]; len++) {
2998 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3001 if (!mustBeXML && isXMLNS
3002 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3003 isXMLNS = XML_FALSE;
3005 isXML = isXML && len == xmlLen;
3006 isXMLNS = isXMLNS && len == xmlnsLen;
3008 if (mustBeXML != isXML)
3009 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3010 : XML_ERROR_RESERVED_NAMESPACE_URI;
3013 return XML_ERROR_RESERVED_NAMESPACE_URI;
3015 if (namespaceSeparator)
3017 if (freeBindingList) {
3018 b = freeBindingList;
3019 if (len > b->uriAlloc) {
3020 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3021 sizeof(XML_Char) * (len + EXPAND_SPARE));
3023 return XML_ERROR_NO_MEMORY;
3025 b->uriAlloc = len + EXPAND_SPARE;
3027 freeBindingList = b->nextTagBinding;
3030 b = (BINDING *)MALLOC(sizeof(BINDING));
3032 return XML_ERROR_NO_MEMORY;
3033 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3036 return XML_ERROR_NO_MEMORY;
3038 b->uriAlloc = len + EXPAND_SPARE;
3041 memcpy(b->uri, uri, len * sizeof(XML_Char));
3042 if (namespaceSeparator)
3043 b->uri[len - 1] = namespaceSeparator;
3046 b->prevPrefixBinding = prefix->binding;
3047 /* NULL binding when default namespace undeclared */
3048 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3049 prefix->binding = NULL;
3051 prefix->binding = b;
3052 b->nextTagBinding = *bindingsPtr;
3054 /* if attId == NULL then we are not starting a namespace scope */
3055 if (attId && startNamespaceDeclHandler)
3056 startNamespaceDeclHandler(handlerArg, prefix->name,
3057 prefix->binding ? uri : 0);
3058 return XML_ERROR_NONE;
3061 /* The idea here is to avoid using stack for each CDATA section when
3062 the whole file is parsed with one call.
3064 static enum XML_Error PTRCALL
3065 cdataSectionProcessor(XML_Parser parser,
3068 const char **endPtr)
3070 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3071 endPtr, (XML_Bool)!ps_finalBuffer);
3072 if (result != XML_ERROR_NONE)
3075 if (parentParser) { /* we are parsing an external entity */
3076 processor = externalEntityContentProcessor;
3077 return externalEntityContentProcessor(parser, start, end, endPtr);
3080 processor = contentProcessor;
3081 return contentProcessor(parser, start, end, endPtr);
3087 /* startPtr gets set to non-null if the section is closed, and to null if
3088 the section is not yet closed.
3090 static enum XML_Error
3091 doCdataSection(XML_Parser parser,
3092 const ENCODING *enc,
3093 const char **startPtr,
3095 const char **nextPtr,
3098 const char *s = *startPtr;
3099 const char **eventPP;
3100 const char **eventEndPP;
3101 if (enc == encoding) {
3102 eventPP = &eventPtr;
3104 eventEndPP = &eventEndPtr;
3107 eventPP = &(openInternalEntities->internalEventPtr);
3108 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3115 int tok = XmlCdataSectionTok(enc, s, end, &next);
3118 case XML_TOK_CDATA_SECT_CLOSE:
3119 if (endCdataSectionHandler)
3120 endCdataSectionHandler(handlerArg);
3122 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3123 else if (characterDataHandler)
3124 characterDataHandler(handlerArg, dataBuf, 0);
3126 else if (defaultHandler)
3127 reportDefault(parser, enc, s, next);
3130 if (ps_parsing == XML_FINISHED)
3131 return XML_ERROR_ABORTED;
3133 return XML_ERROR_NONE;
3134 case XML_TOK_DATA_NEWLINE:
3135 if (characterDataHandler) {
3137 characterDataHandler(handlerArg, &c, 1);
3139 else if (defaultHandler)
3140 reportDefault(parser, enc, s, next);
3142 case XML_TOK_DATA_CHARS:
3144 XML_CharacterDataHandler charDataHandler = characterDataHandler;
3145 if (charDataHandler) {
3146 if (MUST_CONVERT(enc, s)) {
3148 ICHAR *dataPtr = (ICHAR *)dataBuf;
3149 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3151 charDataHandler(handlerArg, dataBuf,
3152 (int)(dataPtr - (ICHAR *)dataBuf));
3159 charDataHandler(handlerArg,
3161 (int)((XML_Char *)next - (XML_Char *)s));
3163 else if (defaultHandler)
3164 reportDefault(parser, enc, s, next);
3167 case XML_TOK_INVALID:
3169 return XML_ERROR_INVALID_TOKEN;
3170 case XML_TOK_PARTIAL_CHAR:
3173 return XML_ERROR_NONE;
3175 return XML_ERROR_PARTIAL_CHAR;
3176 case XML_TOK_PARTIAL:
3180 return XML_ERROR_NONE;
3182 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3185 return XML_ERROR_UNEXPECTED_STATE;
3188 *eventPP = s = next;
3189 switch (ps_parsing) {
3192 return XML_ERROR_NONE;
3194 return XML_ERROR_ABORTED;
3203 /* The idea here is to avoid using stack for each IGNORE section when
3204 the whole file is parsed with one call.
3206 static enum XML_Error PTRCALL
3207 ignoreSectionProcessor(XML_Parser parser,
3210 const char **endPtr)
3212 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3213 endPtr, (XML_Bool)!ps_finalBuffer);
3214 if (result != XML_ERROR_NONE)
3217 processor = prologProcessor;
3218 return prologProcessor(parser, start, end, endPtr);
3223 /* startPtr gets set to non-null is the section is closed, and to null
3224 if the section is not yet closed.
3226 static enum XML_Error
3227 doIgnoreSection(XML_Parser parser,
3228 const ENCODING *enc,
3229 const char **startPtr,
3231 const char **nextPtr,
3236 const char *s = *startPtr;
3237 const char **eventPP;
3238 const char **eventEndPP;
3239 if (enc == encoding) {
3240 eventPP = &eventPtr;
3242 eventEndPP = &eventEndPtr;
3245 eventPP = &(openInternalEntities->internalEventPtr);
3246 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3250 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3253 case XML_TOK_IGNORE_SECT:
3255 reportDefault(parser, enc, s, next);
3258 if (ps_parsing == XML_FINISHED)
3259 return XML_ERROR_ABORTED;
3261 return XML_ERROR_NONE;
3262 case XML_TOK_INVALID:
3264 return XML_ERROR_INVALID_TOKEN;
3265 case XML_TOK_PARTIAL_CHAR:
3268 return XML_ERROR_NONE;
3270 return XML_ERROR_PARTIAL_CHAR;
3271 case XML_TOK_PARTIAL:
3275 return XML_ERROR_NONE;
3277 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3280 return XML_ERROR_UNEXPECTED_STATE;
3285 #endif /* XML_DTD */
3287 static enum XML_Error
3288 initializeEncoding(XML_Parser parser)
3292 char encodingBuf[128];
3293 if (!protocolEncodingName)
3297 for (i = 0; protocolEncodingName[i]; i++) {
3298 if (i == sizeof(encodingBuf) - 1
3299 || (protocolEncodingName[i] & ~0x7f) != 0) {
3300 encodingBuf[0] = '\0';
3303 encodingBuf[i] = (char)protocolEncodingName[i];
3305 encodingBuf[i] = '\0';
3309 s = protocolEncodingName;
3311 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3312 return XML_ERROR_NONE;
3313 return handleUnknownEncoding(parser, protocolEncodingName);
3316 static enum XML_Error
3317 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3318 const char *s, const char *next)
3320 const char *encodingName = NULL;
3321 const XML_Char *storedEncName = NULL;
3322 const ENCODING *newEncoding = NULL;
3323 const char *version = NULL;
3324 const char *versionend;
3325 const XML_Char *storedversion = NULL;
3326 int standalone = -1;
3329 : XmlParseXmlDecl)(isGeneralTextEntity,
3339 if (isGeneralTextEntity)
3340 return XML_ERROR_TEXT_DECL;
3342 return XML_ERROR_XML_DECL;
3344 if (!isGeneralTextEntity && standalone == 1) {
3345 _dtd->standalone = XML_TRUE;
3347 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3348 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3349 #endif /* XML_DTD */
3351 if (xmlDeclHandler) {
3352 if (encodingName != NULL) {
3353 storedEncName = poolStoreString(&temp2Pool,
3357 + XmlNameLength(encoding, encodingName));
3359 return XML_ERROR_NO_MEMORY;
3360 poolFinish(&temp2Pool);
3363 storedversion = poolStoreString(&temp2Pool,
3366 versionend - encoding->minBytesPerChar);
3368 return XML_ERROR_NO_MEMORY;
3370 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3372 else if (defaultHandler)
3373 reportDefault(parser, encoding, s, next);
3374 if (protocolEncodingName == NULL) {
3376 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3377 eventPtr = encodingName;
3378 return XML_ERROR_INCORRECT_ENCODING;
3380 encoding = newEncoding;
3382 else if (encodingName) {
3383 enum XML_Error result;
3384 if (!storedEncName) {
3385 storedEncName = poolStoreString(
3386 &temp2Pool, encoding, encodingName,
3387 encodingName + XmlNameLength(encoding, encodingName));
3389 return XML_ERROR_NO_MEMORY;
3391 result = handleUnknownEncoding(parser, storedEncName);
3392 poolClear(&temp2Pool);
3393 if (result == XML_ERROR_UNKNOWN_ENCODING)
3394 eventPtr = encodingName;
3399 if (storedEncName || storedversion)
3400 poolClear(&temp2Pool);
3402 return XML_ERROR_NONE;
3405 static enum XML_Error
3406 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3408 if (unknownEncodingHandler) {
3411 for (i = 0; i < 256; i++)
3413 info.convert = NULL;
3415 info.release = NULL;
3416 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3419 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3420 if (!unknownEncodingMem) {
3422 info.release(info.data);
3423 return XML_ERROR_NO_MEMORY;
3426 ? XmlInitUnknownEncodingNS
3427 : XmlInitUnknownEncoding)(unknownEncodingMem,
3432 unknownEncodingData = info.data;
3433 unknownEncodingRelease = info.release;
3435 return XML_ERROR_NONE;
3438 if (info.release != NULL)
3439 info.release(info.data);
3441 return XML_ERROR_UNKNOWN_ENCODING;
3444 static enum XML_Error PTRCALL
3445 prologInitProcessor(XML_Parser parser,
3448 const char **nextPtr)
3450 enum XML_Error result = initializeEncoding(parser);
3451 if (result != XML_ERROR_NONE)
3453 processor = prologProcessor;
3454 return prologProcessor(parser, s, end, nextPtr);
3459 static enum XML_Error PTRCALL
3460 externalParEntInitProcessor(XML_Parser parser,
3463 const char **nextPtr)
3465 enum XML_Error result = initializeEncoding(parser);
3466 if (result != XML_ERROR_NONE)
3469 /* we know now that XML_Parse(Buffer) has been called,
3470 so we consider the external parameter entity read */
3471 _dtd->paramEntityRead = XML_TRUE;
3473 if (prologState.inEntityValue) {
3474 processor = entityValueInitProcessor;
3475 return entityValueInitProcessor(parser, s, end, nextPtr);
3478 processor = externalParEntProcessor;
3479 return externalParEntProcessor(parser, s, end, nextPtr);
3483 static enum XML_Error PTRCALL
3484 entityValueInitProcessor(XML_Parser parser,
3487 const char **nextPtr)
3490 const char *start = s;
3491 const char *next = start;
3495 tok = XmlPrologTok(encoding, start, end, &next);
3498 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3500 return XML_ERROR_NONE;
3503 case XML_TOK_INVALID:
3504 return XML_ERROR_INVALID_TOKEN;
3505 case XML_TOK_PARTIAL:
3506 return XML_ERROR_UNCLOSED_TOKEN;
3507 case XML_TOK_PARTIAL_CHAR:
3508 return XML_ERROR_PARTIAL_CHAR;
3509 case XML_TOK_NONE: /* start == end */
3513 /* found end of entity value - can store it now */
3514 return storeEntityValue(parser, encoding, s, end);
3516 else if (tok == XML_TOK_XML_DECL) {
3517 enum XML_Error result;
3518 result = processXmlDecl(parser, 0, start, next);
3519 if (result != XML_ERROR_NONE)
3521 switch (ps_parsing) {
3524 return XML_ERROR_NONE;
3526 return XML_ERROR_ABORTED;
3530 /* stop scanning for text declaration - we found one */
3531 processor = entityValueProcessor;
3532 return entityValueProcessor(parser, next, end, nextPtr);
3534 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3535 return XML_TOK_NONE on the next call, which would then cause the
3536 function to exit with *nextPtr set to s - that is what we want for other
3537 tokens, but not for the BOM - we would rather like to skip it;
3538 then, when this routine is entered the next time, XmlPrologTok will
3539 return XML_TOK_INVALID, since the BOM is still in the buffer
3541 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3543 return XML_ERROR_NONE;
3550 static enum XML_Error PTRCALL
3551 externalParEntProcessor(XML_Parser parser,
3554 const char **nextPtr)
3556 const char *next = s;
3559 tok = XmlPrologTok(encoding, s, end, &next);
3561 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3563 return XML_ERROR_NONE;
3566 case XML_TOK_INVALID:
3567 return XML_ERROR_INVALID_TOKEN;
3568 case XML_TOK_PARTIAL:
3569 return XML_ERROR_UNCLOSED_TOKEN;
3570 case XML_TOK_PARTIAL_CHAR:
3571 return XML_ERROR_PARTIAL_CHAR;
3572 case XML_TOK_NONE: /* start == end */
3577 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3578 However, when parsing an external subset, doProlog will not accept a BOM
3579 as valid, and report a syntax error, so we have to skip the BOM
3581 else if (tok == XML_TOK_BOM) {
3583 tok = XmlPrologTok(encoding, s, end, &next);
3586 processor = prologProcessor;
3587 return doProlog(parser, encoding, s, end, tok, next,
3588 nextPtr, (XML_Bool)!ps_finalBuffer);
3591 static enum XML_Error PTRCALL
3592 entityValueProcessor(XML_Parser parser,
3595 const char **nextPtr)
3597 const char *start = s;
3598 const char *next = s;
3599 const ENCODING *enc = encoding;
3603 tok = XmlPrologTok(enc, start, end, &next);
3605 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3607 return XML_ERROR_NONE;
3610 case XML_TOK_INVALID:
3611 return XML_ERROR_INVALID_TOKEN;
3612 case XML_TOK_PARTIAL:
3613 return XML_ERROR_UNCLOSED_TOKEN;
3614 case XML_TOK_PARTIAL_CHAR:
3615 return XML_ERROR_PARTIAL_CHAR;
3616 case XML_TOK_NONE: /* start == end */
3620 /* found end of entity value - can store it now */
3621 return storeEntityValue(parser, enc, s, end);
3627 #endif /* XML_DTD */
3629 static enum XML_Error PTRCALL
3630 prologProcessor(XML_Parser parser,
3633 const char **nextPtr)
3635 const char *next = s;
3636 int tok = XmlPrologTok(encoding, s, end, &next);
3637 return doProlog(parser, encoding, s, end, tok, next,
3638 nextPtr, (XML_Bool)!ps_finalBuffer);
3641 static enum XML_Error
3642 doProlog(XML_Parser parser,
3643 const ENCODING *enc,
3648 const char **nextPtr,
3652 static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3653 #endif /* XML_DTD */
3654 static const XML_Char atypeCDATA[] =
3655 { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3656 static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3657 static const XML_Char atypeIDREF[] =
3658 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3659 static const XML_Char atypeIDREFS[] =
3660 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3661 static const XML_Char atypeENTITY[] =
3662 { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3663 static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3664 ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3665 static const XML_Char atypeNMTOKEN[] = {
3666 ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3667 static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3668 ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3669 static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3670 ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3671 static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3672 static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3674 /* save one level of indirection */
3675 DTD * const dtd = _dtd;
3677 const char **eventPP;
3678 const char **eventEndPP;
3679 enum XML_Content_Quant quant;
3681 if (enc == encoding) {
3682 eventPP = &eventPtr;
3683 eventEndPP = &eventEndPtr;
3686 eventPP = &(openInternalEntities->internalEventPtr);
3687 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3692 XML_Bool handleDefault = XML_TRUE;
3696 if (haveMore && tok != XML_TOK_INVALID) {
3698 return XML_ERROR_NONE;
3701 case XML_TOK_INVALID:
3703 return XML_ERROR_INVALID_TOKEN;
3704 case XML_TOK_PARTIAL:
3705 return XML_ERROR_UNCLOSED_TOKEN;
3706 case XML_TOK_PARTIAL_CHAR:
3707 return XML_ERROR_PARTIAL_CHAR;
3710 /* for internal PE NOT referenced between declarations */
3711 if (enc != encoding && !openInternalEntities->betweenDecl) {
3713 return XML_ERROR_NONE;
3715 /* WFC: PE Between Declarations - must check that PE contains
3716 complete markup, not only for external PEs, but also for
3717 internal PEs if the reference occurs between declarations.
3719 if (isParamEntity || enc != encoding) {
3720 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3722 return XML_ERROR_INCOMPLETE_PE;
3724 return XML_ERROR_NONE;
3726 #endif /* XML_DTD */
3727 return XML_ERROR_NO_ELEMENTS;
3734 role = XmlTokenRole(&prologState, tok, s, next, enc);
3736 case XML_ROLE_XML_DECL:
3738 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3739 if (result != XML_ERROR_NONE)
3742 handleDefault = XML_FALSE;
3745 case XML_ROLE_DOCTYPE_NAME:
3746 if (startDoctypeDeclHandler) {
3747 doctypeName = poolStoreString(&tempPool, enc, s, next);
3749 return XML_ERROR_NO_MEMORY;
3750 poolFinish(&tempPool);
3751 doctypePubid = NULL;
3752 handleDefault = XML_FALSE;
3754 doctypeSysid = NULL; /* always initialize to NULL */
3756 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3757 if (startDoctypeDeclHandler) {
3758 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3761 poolClear(&tempPool);
3762 handleDefault = XML_FALSE;
3766 case XML_ROLE_TEXT_DECL:
3768 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3769 if (result != XML_ERROR_NONE)
3772 handleDefault = XML_FALSE;
3775 #endif /* XML_DTD */
3776 case XML_ROLE_DOCTYPE_PUBLIC_ID:
3778 useForeignDTD = XML_FALSE;
3779 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3783 return XML_ERROR_NO_MEMORY;
3784 #endif /* XML_DTD */
3785 dtd->hasParamEntityRefs = XML_TRUE;
3786 if (startDoctypeDeclHandler) {
3787 if (!XmlIsPublicId(enc, s, next, eventPP))
3788 return XML_ERROR_PUBLICID;
3789 doctypePubid = poolStoreString(&tempPool, enc,
3790 s + enc->minBytesPerChar,
3791 next - enc->minBytesPerChar);
3793 return XML_ERROR_NO_MEMORY;
3794 normalizePublicId((XML_Char *)doctypePubid);
3795 poolFinish(&tempPool);
3796 handleDefault = XML_FALSE;
3797 goto alreadyChecked;
3800 case XML_ROLE_ENTITY_PUBLIC_ID:
3801 if (!XmlIsPublicId(enc, s, next, eventPP))
3802 return XML_ERROR_PUBLICID;
3804 if (dtd->keepProcessing && declEntity) {
3805 XML_Char *tem = poolStoreString(&dtd->pool,
3807 s + enc->minBytesPerChar,
3808 next - enc->minBytesPerChar);
3810 return XML_ERROR_NO_MEMORY;
3811 normalizePublicId(tem);
3812 declEntity->publicId = tem;
3813 poolFinish(&dtd->pool);
3814 if (entityDeclHandler)
3815 handleDefault = XML_FALSE;
3818 case XML_ROLE_DOCTYPE_CLOSE:
3820 startDoctypeDeclHandler(handlerArg, doctypeName,
3821 doctypeSysid, doctypePubid, 0);
3822 poolClear(&tempPool);
3823 handleDefault = XML_FALSE;
3825 /* doctypeSysid will be non-NULL in the case of a previous
3826 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3827 was not set, indicating an external subset
3830 if (doctypeSysid || useForeignDTD) {
3831 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3832 dtd->hasParamEntityRefs = XML_TRUE;
3833 if (paramEntityParsing && externalEntityRefHandler) {
3834 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3838 return XML_ERROR_NO_MEMORY;
3840 entity->base = curBase;
3841 dtd->paramEntityRead = XML_FALSE;
3842 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3847 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3848 if (dtd->paramEntityRead) {
3849 if (!dtd->standalone &&
3850 notStandaloneHandler &&
3851 !notStandaloneHandler(handlerArg))
3852 return XML_ERROR_NOT_STANDALONE;
3854 /* if we didn't read the foreign DTD then this means that there
3855 is no external subset and we must reset dtd->hasParamEntityRefs
3857 else if (!doctypeSysid)
3858 dtd->hasParamEntityRefs = hadParamEntityRefs;
3859 /* end of DTD - no need to update dtd->keepProcessing */
3861 useForeignDTD = XML_FALSE;
3863 #endif /* XML_DTD */
3864 if (endDoctypeDeclHandler) {
3865 endDoctypeDeclHandler(handlerArg);
3866 handleDefault = XML_FALSE;
3869 case XML_ROLE_INSTANCE_START:
3871 /* if there is no DOCTYPE declaration then now is the
3872 last chance to read the foreign DTD
3874 if (useForeignDTD) {
3875 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3876 dtd->hasParamEntityRefs = XML_TRUE;
3877 if (paramEntityParsing && externalEntityRefHandler) {
3878 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3882 return XML_ERROR_NO_MEMORY;
3883 entity->base = curBase;
3884 dtd->paramEntityRead = XML_FALSE;
3885 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3890 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3891 if (dtd->paramEntityRead) {
3892 if (!dtd->standalone &&
3893 notStandaloneHandler &&
3894 !notStandaloneHandler(handlerArg))
3895 return XML_ERROR_NOT_STANDALONE;
3897 /* if we didn't read the foreign DTD then this means that there
3898 is no external subset and we must reset dtd->hasParamEntityRefs
3901 dtd->hasParamEntityRefs = hadParamEntityRefs;
3902 /* end of DTD - no need to update dtd->keepProcessing */
3905 #endif /* XML_DTD */
3906 processor = contentProcessor;
3907 return contentProcessor(parser, s, end, nextPtr);
3908 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3909 declElementType = getElementType(parser, enc, s, next);
3910 if (!declElementType)
3911 return XML_ERROR_NO_MEMORY;
3912 goto checkAttListDeclHandler;
3913 case XML_ROLE_ATTRIBUTE_NAME:
3914 declAttributeId = getAttributeId(parser, enc, s, next);
3915 if (!declAttributeId)
3916 return XML_ERROR_NO_MEMORY;
3917 declAttributeIsCdata = XML_FALSE;
3918 declAttributeType = NULL;
3919 declAttributeIsId = XML_FALSE;
3920 goto checkAttListDeclHandler;
3921 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
3922 declAttributeIsCdata = XML_TRUE;
3923 declAttributeType = atypeCDATA;
3924 goto checkAttListDeclHandler;
3925 case XML_ROLE_ATTRIBUTE_TYPE_ID:
3926 declAttributeIsId = XML_TRUE;
3927 declAttributeType = atypeID;
3928 goto checkAttListDeclHandler;
3929 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
3930 declAttributeType = atypeIDREF;
3931 goto checkAttListDeclHandler;
3932 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
3933 declAttributeType = atypeIDREFS;
3934 goto checkAttListDeclHandler;
3935 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
3936 declAttributeType = atypeENTITY;
3937 goto checkAttListDeclHandler;
3938 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
3939 declAttributeType = atypeENTITIES;
3940 goto checkAttListDeclHandler;
3941 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
3942 declAttributeType = atypeNMTOKEN;
3943 goto checkAttListDeclHandler;
3944 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
3945 declAttributeType = atypeNMTOKENS;
3946 checkAttListDeclHandler:
3947 if (dtd->keepProcessing && attlistDeclHandler)
3948 handleDefault = XML_FALSE;
3950 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3951 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
3952 if (dtd->keepProcessing && attlistDeclHandler) {
3953 const XML_Char *prefix;
3954 if (declAttributeType) {
3955 prefix = enumValueSep;
3958 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3962 if (!poolAppendString(&tempPool, prefix))
3963 return XML_ERROR_NO_MEMORY;
3964 if (!poolAppend(&tempPool, enc, s, next))
3965 return XML_ERROR_NO_MEMORY;
3966 declAttributeType = tempPool.start;
3967 handleDefault = XML_FALSE;
3970 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3971 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
3972 if (dtd->keepProcessing) {
3973 if (!defineAttribute(declElementType, declAttributeId,
3974 declAttributeIsCdata, declAttributeIsId,
3976 return XML_ERROR_NO_MEMORY;
3977 if (attlistDeclHandler && declAttributeType) {
3978 if (*declAttributeType == XML_T(ASCII_LPAREN)
3979 || (*declAttributeType == XML_T(ASCII_N)
3980 && declAttributeType[1] == XML_T(ASCII_O))) {
3981 /* Enumerated or Notation type */
3982 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
3983 || !poolAppendChar(&tempPool, XML_T('\0')))
3984 return XML_ERROR_NO_MEMORY;
3985 declAttributeType = tempPool.start;
3986 poolFinish(&tempPool);
3989 attlistDeclHandler(handlerArg, declElementType->name,
3990 declAttributeId->name, declAttributeType,
3991 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3992 poolClear(&tempPool);
3993 handleDefault = XML_FALSE;
3997 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3998 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
3999 if (dtd->keepProcessing) {
4000 const XML_Char *attVal;
4001 enum XML_Error result =
4002 storeAttributeValue(parser, enc, declAttributeIsCdata,
4003 s + enc->minBytesPerChar,
4004 next - enc->minBytesPerChar,
4008 attVal = poolStart(&dtd->pool);
4009 poolFinish(&dtd->pool);
4010 /* ID attributes aren't allowed to have a default */
4011 if (!defineAttribute(declElementType, declAttributeId,
4012 declAttributeIsCdata, XML_FALSE, attVal, parser))
4013 return XML_ERROR_NO_MEMORY;
4014 if (attlistDeclHandler && declAttributeType) {
4015 if (*declAttributeType == XML_T(ASCII_LPAREN)
4016 || (*declAttributeType == XML_T(ASCII_N)
4017 && declAttributeType[1] == XML_T(ASCII_O))) {
4018 /* Enumerated or Notation type */
4019 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4020 || !poolAppendChar(&tempPool, XML_T('\0')))
4021 return XML_ERROR_NO_MEMORY;
4022 declAttributeType = tempPool.start;
4023 poolFinish(&tempPool);
4026 attlistDeclHandler(handlerArg, declElementType->name,
4027 declAttributeId->name, declAttributeType,
4029 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4030 poolClear(&tempPool);
4031 handleDefault = XML_FALSE;
4035 case XML_ROLE_ENTITY_VALUE:
4036 if (dtd->keepProcessing) {
4037 enum XML_Error result = storeEntityValue(parser, enc,
4038 s + enc->minBytesPerChar,
4039 next - enc->minBytesPerChar);
4041 declEntity->textPtr = poolStart(&dtd->entityValuePool);
4042 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4043 poolFinish(&dtd->entityValuePool);
4044 if (entityDeclHandler) {
4046 entityDeclHandler(handlerArg,
4048 declEntity->is_param,
4049 declEntity->textPtr,
4050 declEntity->textLen,
4052 handleDefault = XML_FALSE;
4056 poolDiscard(&dtd->entityValuePool);
4057 if (result != XML_ERROR_NONE)
4061 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4063 useForeignDTD = XML_FALSE;
4064 #endif /* XML_DTD */
4065 dtd->hasParamEntityRefs = XML_TRUE;
4066 if (startDoctypeDeclHandler) {
4067 doctypeSysid = poolStoreString(&tempPool, enc,
4068 s + enc->minBytesPerChar,
4069 next - enc->minBytesPerChar);
4070 if (doctypeSysid == NULL)
4071 return XML_ERROR_NO_MEMORY;
4072 poolFinish(&tempPool);
4073 handleDefault = XML_FALSE;
4077 /* use externalSubsetName to make doctypeSysid non-NULL
4078 for the case where no startDoctypeDeclHandler is set */
4079 doctypeSysid = externalSubsetName;
4080 #endif /* XML_DTD */
4081 if (!dtd->standalone
4083 && !paramEntityParsing
4084 #endif /* XML_DTD */
4085 && notStandaloneHandler
4086 && !notStandaloneHandler(handlerArg))
4087 return XML_ERROR_NOT_STANDALONE;
4092 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4096 return XML_ERROR_NO_MEMORY;
4097 declEntity->publicId = NULL;
4100 #endif /* XML_DTD */
4101 case XML_ROLE_ENTITY_SYSTEM_ID:
4102 if (dtd->keepProcessing && declEntity) {
4103 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4104 s + enc->minBytesPerChar,
4105 next - enc->minBytesPerChar);
4106 if (!declEntity->systemId)
4107 return XML_ERROR_NO_MEMORY;
4108 declEntity->base = curBase;
4109 poolFinish(&dtd->pool);
4110 if (entityDeclHandler)
4111 handleDefault = XML_FALSE;
4114 case XML_ROLE_ENTITY_COMPLETE:
4115 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4117 entityDeclHandler(handlerArg,
4119 declEntity->is_param,
4122 declEntity->systemId,
4123 declEntity->publicId,
4125 handleDefault = XML_FALSE;
4128 case XML_ROLE_ENTITY_NOTATION_NAME:
4129 if (dtd->keepProcessing && declEntity) {
4130 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4131 if (!declEntity->notation)
4132 return XML_ERROR_NO_MEMORY;
4133 poolFinish(&dtd->pool);
4134 if (unparsedEntityDeclHandler) {
4136 unparsedEntityDeclHandler(handlerArg,
4139 declEntity->systemId,
4140 declEntity->publicId,
4141 declEntity->notation);
4142 handleDefault = XML_FALSE;
4144 else if (entityDeclHandler) {
4146 entityDeclHandler(handlerArg,
4150 declEntity->systemId,
4151 declEntity->publicId,
4152 declEntity->notation);
4153 handleDefault = XML_FALSE;
4157 case XML_ROLE_GENERAL_ENTITY_NAME:
4159 if (XmlPredefinedEntityName(enc, s, next)) {
4163 if (dtd->keepProcessing) {
4164 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4166 return XML_ERROR_NO_MEMORY;
4167 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
4170 return XML_ERROR_NO_MEMORY;
4171 if (declEntity->name != name) {
4172 poolDiscard(&dtd->pool);
4176 poolFinish(&dtd->pool);
4177 declEntity->publicId = NULL;
4178 declEntity->is_param = XML_FALSE;
4179 /* if we have a parent parser or are reading an internal parameter
4180 entity, then the entity declaration is not considered "internal"
4182 declEntity->is_internal = !(parentParser || openInternalEntities);
4183 if (entityDeclHandler)
4184 handleDefault = XML_FALSE;
4188 poolDiscard(&dtd->pool);
4193 case XML_ROLE_PARAM_ENTITY_NAME:
4195 if (dtd->keepProcessing) {
4196 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4198 return XML_ERROR_NO_MEMORY;
4199 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4200 name, sizeof(ENTITY));
4202 return XML_ERROR_NO_MEMORY;
4203 if (declEntity->name != name) {
4204 poolDiscard(&dtd->pool);
4208 poolFinish(&dtd->pool);
4209 declEntity->publicId = NULL;
4210 declEntity->is_param = XML_TRUE;
4211 /* if we have a parent parser or are reading an internal parameter
4212 entity, then the entity declaration is not considered "internal"
4214 declEntity->is_internal = !(parentParser || openInternalEntities);
4215 if (entityDeclHandler)
4216 handleDefault = XML_FALSE;
4220 poolDiscard(&dtd->pool);
4223 #else /* not XML_DTD */
4225 #endif /* XML_DTD */
4227 case XML_ROLE_NOTATION_NAME:
4228 declNotationPublicId = NULL;
4229 declNotationName = NULL;
4230 if (notationDeclHandler) {
4231 declNotationName = poolStoreString(&tempPool, enc, s, next);
4232 if (!declNotationName)
4233 return XML_ERROR_NO_MEMORY;
4234 poolFinish(&tempPool);
4235 handleDefault = XML_FALSE;
4238 case XML_ROLE_NOTATION_PUBLIC_ID:
4239 if (!XmlIsPublicId(enc, s, next, eventPP))
4240 return XML_ERROR_PUBLICID;
4241 if (declNotationName) { /* means notationDeclHandler != NULL */
4242 XML_Char *tem = poolStoreString(&tempPool,
4244 s + enc->minBytesPerChar,
4245 next - enc->minBytesPerChar);
4247 return XML_ERROR_NO_MEMORY;
4248 normalizePublicId(tem);
4249 declNotationPublicId = tem;
4250 poolFinish(&tempPool);
4251 handleDefault = XML_FALSE;
4254 case XML_ROLE_NOTATION_SYSTEM_ID:
4255 if (declNotationName && notationDeclHandler) {
4256 const XML_Char *systemId
4257 = poolStoreString(&tempPool, enc,
4258 s + enc->minBytesPerChar,
4259 next - enc->minBytesPerChar);
4261 return XML_ERROR_NO_MEMORY;
4263 notationDeclHandler(handlerArg,
4267 declNotationPublicId);
4268 handleDefault = XML_FALSE;
4270 poolClear(&tempPool);
4272 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4273 if (declNotationPublicId && notationDeclHandler) {
4275 notationDeclHandler(handlerArg,
4279 declNotationPublicId);
4280 handleDefault = XML_FALSE;
4282 poolClear(&tempPool);
4284 case XML_ROLE_ERROR:
4286 case XML_TOK_PARAM_ENTITY_REF:
4287 /* PE references in internal subset are
4288 not allowed within declarations. */
4289 return XML_ERROR_PARAM_ENTITY_REF;
4290 case XML_TOK_XML_DECL:
4291 return XML_ERROR_MISPLACED_XML_PI;
4293 return XML_ERROR_SYNTAX;
4296 case XML_ROLE_IGNORE_SECT:
4298 enum XML_Error result;
4300 reportDefault(parser, enc, s, next);
4301 handleDefault = XML_FALSE;
4302 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4303 if (result != XML_ERROR_NONE)
4306 processor = ignoreSectionProcessor;
4311 #endif /* XML_DTD */
4312 case XML_ROLE_GROUP_OPEN:
4313 if (prologState.level >= groupSize) {
4315 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4317 return XML_ERROR_NO_MEMORY;
4318 groupConnector = temp;
4319 if (dtd->scaffIndex) {
4320 int *temp = (int *)REALLOC(dtd->scaffIndex,
4321 groupSize * sizeof(int));
4323 return XML_ERROR_NO_MEMORY;
4324 dtd->scaffIndex = temp;
4328 groupConnector = (char *)MALLOC(groupSize = 32);
4329 if (!groupConnector)
4330 return XML_ERROR_NO_MEMORY;
4333 groupConnector[prologState.level] = 0;
4334 if (dtd->in_eldecl) {
4335 int myindex = nextScaffoldPart(parser);
4337 return XML_ERROR_NO_MEMORY;
4338 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4340 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4341 if (elementDeclHandler)
4342 handleDefault = XML_FALSE;
4345 case XML_ROLE_GROUP_SEQUENCE:
4346 if (groupConnector[prologState.level] == ASCII_PIPE)
4347 return XML_ERROR_SYNTAX;
4348 groupConnector[prologState.level] = ASCII_COMMA;
4349 if (dtd->in_eldecl && elementDeclHandler)
4350 handleDefault = XML_FALSE;
4352 case XML_ROLE_GROUP_CHOICE:
4353 if (groupConnector[prologState.level] == ASCII_COMMA)
4354 return XML_ERROR_SYNTAX;
4356 && !groupConnector[prologState.level]
4357 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4360 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4362 if (elementDeclHandler)
4363 handleDefault = XML_FALSE;
4365 groupConnector[prologState.level] = ASCII_PIPE;
4367 case XML_ROLE_PARAM_ENTITY_REF:
4369 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4370 dtd->hasParamEntityRefs = XML_TRUE;
4371 if (!paramEntityParsing)
4372 dtd->keepProcessing = dtd->standalone;
4374 const XML_Char *name;
4376 name = poolStoreString(&dtd->pool, enc,
4377 s + enc->minBytesPerChar,
4378 next - enc->minBytesPerChar);
4380 return XML_ERROR_NO_MEMORY;
4381 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4382 poolDiscard(&dtd->pool);
4383 /* first, determine if a check for an existing declaration is needed;
4384 if yes, check that the entity exists, and that it is internal,
4385 otherwise call the skipped entity handler
4387 if (prologState.documentEntity &&
4389 ? !openInternalEntities
4390 : !dtd->hasParamEntityRefs)) {
4392 return XML_ERROR_UNDEFINED_ENTITY;
4393 else if (!entity->is_internal)
4394 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4397 dtd->keepProcessing = dtd->standalone;
4398 /* cannot report skipped entities in declarations */
4399 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4400 skippedEntityHandler(handlerArg, name, 1);
4401 handleDefault = XML_FALSE;
4406 return XML_ERROR_RECURSIVE_ENTITY_REF;
4407 if (entity->textPtr) {
4408 enum XML_Error result;
4409 XML_Bool betweenDecl =
4410 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4411 result = processInternalEntity(parser, entity, betweenDecl);
4412 if (result != XML_ERROR_NONE)
4414 handleDefault = XML_FALSE;
4417 if (externalEntityRefHandler) {
4418 dtd->paramEntityRead = XML_FALSE;
4419 entity->open = XML_TRUE;
4420 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4424 entity->publicId)) {
4425 entity->open = XML_FALSE;
4426 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4428 entity->open = XML_FALSE;
4429 handleDefault = XML_FALSE;
4430 if (!dtd->paramEntityRead) {
4431 dtd->keepProcessing = dtd->standalone;
4436 dtd->keepProcessing = dtd->standalone;
4440 #endif /* XML_DTD */
4441 if (!dtd->standalone &&
4442 notStandaloneHandler &&
4443 !notStandaloneHandler(handlerArg))
4444 return XML_ERROR_NOT_STANDALONE;
4447 /* Element declaration stuff */
4449 case XML_ROLE_ELEMENT_NAME:
4450 if (elementDeclHandler) {
4451 declElementType = getElementType(parser, enc, s, next);
4452 if (!declElementType)
4453 return XML_ERROR_NO_MEMORY;
4454 dtd->scaffLevel = 0;
4455 dtd->scaffCount = 0;
4456 dtd->in_eldecl = XML_TRUE;
4457 handleDefault = XML_FALSE;
4461 case XML_ROLE_CONTENT_ANY:
4462 case XML_ROLE_CONTENT_EMPTY:
4463 if (dtd->in_eldecl) {
4464 if (elementDeclHandler) {
4465 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4467 return XML_ERROR_NO_MEMORY;
4468 content->quant = XML_CQUANT_NONE;
4469 content->name = NULL;
4470 content->numchildren = 0;
4471 content->children = NULL;
4472 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4476 elementDeclHandler(handlerArg, declElementType->name, content);
4477 handleDefault = XML_FALSE;
4479 dtd->in_eldecl = XML_FALSE;
4483 case XML_ROLE_CONTENT_PCDATA:
4484 if (dtd->in_eldecl) {
4485 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4487 if (elementDeclHandler)
4488 handleDefault = XML_FALSE;
4492 case XML_ROLE_CONTENT_ELEMENT:
4493 quant = XML_CQUANT_NONE;
4494 goto elementContent;
4495 case XML_ROLE_CONTENT_ELEMENT_OPT:
4496 quant = XML_CQUANT_OPT;
4497 goto elementContent;
4498 case XML_ROLE_CONTENT_ELEMENT_REP:
4499 quant = XML_CQUANT_REP;
4500 goto elementContent;
4501 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4502 quant = XML_CQUANT_PLUS;
4504 if (dtd->in_eldecl) {
4506 const XML_Char *name;
4508 const char *nxt = (quant == XML_CQUANT_NONE
4510 : next - enc->minBytesPerChar);
4511 int myindex = nextScaffoldPart(parser);
4513 return XML_ERROR_NO_MEMORY;
4514 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4515 dtd->scaffold[myindex].quant = quant;
4516 el = getElementType(parser, enc, s, nxt);
4518 return XML_ERROR_NO_MEMORY;
4520 dtd->scaffold[myindex].name = name;
4522 for (; name[nameLen++]; );
4523 dtd->contentStringLen += nameLen;
4524 if (elementDeclHandler)
4525 handleDefault = XML_FALSE;
4529 case XML_ROLE_GROUP_CLOSE:
4530 quant = XML_CQUANT_NONE;
4532 case XML_ROLE_GROUP_CLOSE_OPT:
4533 quant = XML_CQUANT_OPT;
4535 case XML_ROLE_GROUP_CLOSE_REP:
4536 quant = XML_CQUANT_REP;
4538 case XML_ROLE_GROUP_CLOSE_PLUS:
4539 quant = XML_CQUANT_PLUS;
4541 if (dtd->in_eldecl) {
4542 if (elementDeclHandler)
4543 handleDefault = XML_FALSE;
4545 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4546 if (dtd->scaffLevel == 0) {
4547 if (!handleDefault) {
4548 XML_Content *model = build_model(parser);
4550 return XML_ERROR_NO_MEMORY;
4552 elementDeclHandler(handlerArg, declElementType->name, model);
4554 dtd->in_eldecl = XML_FALSE;
4555 dtd->contentStringLen = 0;
4559 /* End element declaration stuff */
4562 if (!reportProcessingInstruction(parser, enc, s, next))
4563 return XML_ERROR_NO_MEMORY;
4564 handleDefault = XML_FALSE;
4566 case XML_ROLE_COMMENT:
4567 if (!reportComment(parser, enc, s, next))
4568 return XML_ERROR_NO_MEMORY;
4569 handleDefault = XML_FALSE;
4574 handleDefault = XML_FALSE;
4578 case XML_ROLE_DOCTYPE_NONE:
4579 if (startDoctypeDeclHandler)
4580 handleDefault = XML_FALSE;
4582 case XML_ROLE_ENTITY_NONE:
4583 if (dtd->keepProcessing && entityDeclHandler)
4584 handleDefault = XML_FALSE;
4586 case XML_ROLE_NOTATION_NONE:
4587 if (notationDeclHandler)
4588 handleDefault = XML_FALSE;
4590 case XML_ROLE_ATTLIST_NONE:
4591 if (dtd->keepProcessing && attlistDeclHandler)
4592 handleDefault = XML_FALSE;
4594 case XML_ROLE_ELEMENT_NONE:
4595 if (elementDeclHandler)
4596 handleDefault = XML_FALSE;
4598 } /* end of big switch */
4600 if (handleDefault && defaultHandler)
4601 reportDefault(parser, enc, s, next);
4603 switch (ps_parsing) {
4606 return XML_ERROR_NONE;
4608 return XML_ERROR_ABORTED;
4611 tok = XmlPrologTok(enc, s, end, &next);
4617 static enum XML_Error PTRCALL
4618 epilogProcessor(XML_Parser parser,
4621 const char **nextPtr)
4623 processor = epilogProcessor;
4626 const char *next = NULL;
4627 int tok = XmlPrologTok(encoding, s, end, &next);
4630 /* report partial linebreak - it might be the last token */
4631 case -XML_TOK_PROLOG_S:
4632 if (defaultHandler) {
4633 reportDefault(parser, encoding, s, next);
4634 if (ps_parsing == XML_FINISHED)
4635 return XML_ERROR_ABORTED;
4638 return XML_ERROR_NONE;
4641 return XML_ERROR_NONE;
4642 case XML_TOK_PROLOG_S:
4644 reportDefault(parser, encoding, s, next);
4647 if (!reportProcessingInstruction(parser, encoding, s, next))
4648 return XML_ERROR_NO_MEMORY;
4650 case XML_TOK_COMMENT:
4651 if (!reportComment(parser, encoding, s, next))
4652 return XML_ERROR_NO_MEMORY;
4654 case XML_TOK_INVALID:
4656 return XML_ERROR_INVALID_TOKEN;
4657 case XML_TOK_PARTIAL:
4658 if (!ps_finalBuffer) {
4660 return XML_ERROR_NONE;
4662 return XML_ERROR_UNCLOSED_TOKEN;
4663 case XML_TOK_PARTIAL_CHAR:
4664 if (!ps_finalBuffer) {
4666 return XML_ERROR_NONE;
4668 return XML_ERROR_PARTIAL_CHAR;
4670 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4672 eventPtr = s = next;
4673 switch (ps_parsing) {
4676 return XML_ERROR_NONE;
4678 return XML_ERROR_ABORTED;
4684 static enum XML_Error
4685 processInternalEntity(XML_Parser parser, ENTITY *entity,
4686 XML_Bool betweenDecl)
4688 const char *textStart, *textEnd;
4690 enum XML_Error result;
4691 OPEN_INTERNAL_ENTITY *openEntity;
4693 if (freeInternalEntities) {
4694 openEntity = freeInternalEntities;
4695 freeInternalEntities = openEntity->next;
4698 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4700 return XML_ERROR_NO_MEMORY;
4702 entity->open = XML_TRUE;
4703 entity->processed = 0;
4704 openEntity->next = openInternalEntities;
4705 openInternalEntities = openEntity;
4706 openEntity->entity = entity;
4707 openEntity->startTagLevel = tagLevel;
4708 openEntity->betweenDecl = betweenDecl;
4709 openEntity->internalEventPtr = NULL;
4710 openEntity->internalEventEndPtr = NULL;
4711 textStart = (char *)entity->textPtr;
4712 textEnd = (char *)(entity->textPtr + entity->textLen);
4715 if (entity->is_param) {
4716 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4717 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4718 next, &next, XML_FALSE);
4721 #endif /* XML_DTD */
4722 result = doContent(parser, tagLevel, internalEncoding, textStart,
4723 textEnd, &next, XML_FALSE);
4725 if (result == XML_ERROR_NONE) {
4726 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4727 entity->processed = (int)(next - textStart);
4728 processor = internalEntityProcessor;
4731 entity->open = XML_FALSE;
4732 openInternalEntities = openEntity->next;
4733 /* put openEntity back in list of free instances */
4734 openEntity->next = freeInternalEntities;
4735 freeInternalEntities = openEntity;
4741 static enum XML_Error PTRCALL
4742 internalEntityProcessor(XML_Parser parser,
4745 const char **nextPtr)
4748 const char *textStart, *textEnd;
4750 enum XML_Error result;
4751 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4753 return XML_ERROR_UNEXPECTED_STATE;
4755 entity = openEntity->entity;
4756 textStart = ((char *)entity->textPtr) + entity->processed;
4757 textEnd = (char *)(entity->textPtr + entity->textLen);
4760 if (entity->is_param) {
4761 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4762 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4763 next, &next, XML_FALSE);
4766 #endif /* XML_DTD */
4767 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4768 textStart, textEnd, &next, XML_FALSE);
4770 if (result != XML_ERROR_NONE)
4772 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4773 entity->processed = (int)(next - (char *)entity->textPtr);
4777 entity->open = XML_FALSE;
4778 openInternalEntities = openEntity->next;
4779 /* put openEntity back in list of free instances */
4780 openEntity->next = freeInternalEntities;
4781 freeInternalEntities = openEntity;
4785 if (entity->is_param) {
4787 processor = prologProcessor;
4788 tok = XmlPrologTok(encoding, s, end, &next);
4789 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
4790 (XML_Bool)!ps_finalBuffer);
4793 #endif /* XML_DTD */
4795 processor = contentProcessor;
4796 /* see externalEntityContentProcessor vs contentProcessor */
4797 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4798 nextPtr, (XML_Bool)!ps_finalBuffer);
4802 static enum XML_Error PTRCALL
4803 errorProcessor(XML_Parser parser,
4806 const char **nextPtr)
4811 static enum XML_Error
4812 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4813 const char *ptr, const char *end,
4816 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4820 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4822 if (!poolAppendChar(pool, XML_T('\0')))
4823 return XML_ERROR_NO_MEMORY;
4824 return XML_ERROR_NONE;
4827 static enum XML_Error
4828 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4829 const char *ptr, const char *end,
4832 DTD * const dtd = _dtd; /* save one level of indirection */
4835 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4838 return XML_ERROR_NONE;
4839 case XML_TOK_INVALID:
4840 if (enc == encoding)
4842 return XML_ERROR_INVALID_TOKEN;
4843 case XML_TOK_PARTIAL:
4844 if (enc == encoding)
4846 return XML_ERROR_INVALID_TOKEN;
4847 case XML_TOK_CHAR_REF:
4849 XML_Char buf[XML_ENCODE_MAX];
4851 int n = XmlCharRefNumber(enc, ptr);
4853 if (enc == encoding)
4855 return XML_ERROR_BAD_CHAR_REF;
4858 && n == 0x20 /* space */
4859 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4861 n = XmlEncode(n, (ICHAR *)buf);
4863 if (enc == encoding)
4865 return XML_ERROR_BAD_CHAR_REF;
4867 for (i = 0; i < n; i++) {
4868 if (!poolAppendChar(pool, buf[i]))
4869 return XML_ERROR_NO_MEMORY;
4873 case XML_TOK_DATA_CHARS:
4874 if (!poolAppend(pool, enc, ptr, next))
4875 return XML_ERROR_NO_MEMORY;
4877 case XML_TOK_TRAILING_CR:
4878 next = ptr + enc->minBytesPerChar;
4880 case XML_TOK_ATTRIBUTE_VALUE_S:
4881 case XML_TOK_DATA_NEWLINE:
4882 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4884 if (!poolAppendChar(pool, 0x20))
4885 return XML_ERROR_NO_MEMORY;
4887 case XML_TOK_ENTITY_REF:
4889 const XML_Char *name;
4891 char checkEntityDecl;
4892 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4893 ptr + enc->minBytesPerChar,
4894 next - enc->minBytesPerChar);
4896 if (!poolAppendChar(pool, ch))
4897 return XML_ERROR_NO_MEMORY;
4900 name = poolStoreString(&temp2Pool, enc,
4901 ptr + enc->minBytesPerChar,
4902 next - enc->minBytesPerChar);
4904 return XML_ERROR_NO_MEMORY;
4905 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4906 poolDiscard(&temp2Pool);
4907 /* First, determine if a check for an existing declaration is needed;
4908 if yes, check that the entity exists, and that it is internal.
4910 if (pool == &dtd->pool) /* are we called from prolog? */
4913 prologState.documentEntity &&
4914 #endif /* XML_DTD */
4916 ? !openInternalEntities
4917 : !dtd->hasParamEntityRefs);
4918 else /* if (pool == &tempPool): we are called from content */
4919 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4920 if (checkEntityDecl) {
4922 return XML_ERROR_UNDEFINED_ENTITY;
4923 else if (!entity->is_internal)
4924 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4927 /* Cannot report skipped entity here - see comments on
4928 skippedEntityHandler.
4929 if (skippedEntityHandler)
4930 skippedEntityHandler(handlerArg, name, 0);
4932 /* Cannot call the default handler because this would be
4933 out of sync with the call to the startElementHandler.
4934 if ((pool == &tempPool) && defaultHandler)
4935 reportDefault(parser, enc, ptr, next);
4940 if (enc == encoding)
4942 return XML_ERROR_RECURSIVE_ENTITY_REF;
4944 if (entity->notation) {
4945 if (enc == encoding)
4947 return XML_ERROR_BINARY_ENTITY_REF;
4949 if (!entity->textPtr) {
4950 if (enc == encoding)
4952 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4955 enum XML_Error result;
4956 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4957 entity->open = XML_TRUE;
4958 result = appendAttributeValue(parser, internalEncoding, isCdata,
4959 (char *)entity->textPtr,
4960 (char *)textEnd, pool);
4961 entity->open = XML_FALSE;
4968 if (enc == encoding)
4970 return XML_ERROR_UNEXPECTED_STATE;
4977 static enum XML_Error
4978 storeEntityValue(XML_Parser parser,
4979 const ENCODING *enc,
4980 const char *entityTextPtr,
4981 const char *entityTextEnd)
4983 DTD * const dtd = _dtd; /* save one level of indirection */
4984 STRING_POOL *pool = &(dtd->entityValuePool);
4985 enum XML_Error result = XML_ERROR_NONE;
4987 int oldInEntityValue = prologState.inEntityValue;
4988 prologState.inEntityValue = 1;
4989 #endif /* XML_DTD */
4990 /* never return Null for the value argument in EntityDeclHandler,
4991 since this would indicate an external entity; therefore we
4992 have to make sure that entityValuePool.start is not null */
4993 if (!pool->blocks) {
4994 if (!poolGrow(pool))
4995 return XML_ERROR_NO_MEMORY;
5000 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5002 case XML_TOK_PARAM_ENTITY_REF:
5004 if (isParamEntity || enc != encoding) {
5005 const XML_Char *name;
5007 name = poolStoreString(&tempPool, enc,
5008 entityTextPtr + enc->minBytesPerChar,
5009 next - enc->minBytesPerChar);
5011 result = XML_ERROR_NO_MEMORY;
5012 goto endEntityValue;
5014 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
5015 poolDiscard(&tempPool);
5017 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5018 /* cannot report skipped entity here - see comments on
5019 skippedEntityHandler
5020 if (skippedEntityHandler)
5021 skippedEntityHandler(handlerArg, name, 0);
5023 dtd->keepProcessing = dtd->standalone;
5024 goto endEntityValue;
5027 if (enc == encoding)
5028 eventPtr = entityTextPtr;
5029 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5030 goto endEntityValue;
5032 if (entity->systemId) {
5033 if (externalEntityRefHandler) {
5034 dtd->paramEntityRead = XML_FALSE;
5035 entity->open = XML_TRUE;
5036 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5040 entity->publicId)) {
5041 entity->open = XML_FALSE;
5042 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5043 goto endEntityValue;
5045 entity->open = XML_FALSE;
5046 if (!dtd->paramEntityRead)
5047 dtd->keepProcessing = dtd->standalone;
5050 dtd->keepProcessing = dtd->standalone;
5053 entity->open = XML_TRUE;
5054 result = storeEntityValue(parser,
5056 (char *)entity->textPtr,
5057 (char *)(entity->textPtr
5058 + entity->textLen));
5059 entity->open = XML_FALSE;
5061 goto endEntityValue;
5065 #endif /* XML_DTD */
5066 /* In the internal subset, PE references are not legal
5067 within markup declarations, e.g entity values in this case. */
5068 eventPtr = entityTextPtr;
5069 result = XML_ERROR_PARAM_ENTITY_REF;
5070 goto endEntityValue;
5072 result = XML_ERROR_NONE;
5073 goto endEntityValue;
5074 case XML_TOK_ENTITY_REF:
5075 case XML_TOK_DATA_CHARS:
5076 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5077 result = XML_ERROR_NO_MEMORY;
5078 goto endEntityValue;
5081 case XML_TOK_TRAILING_CR:
5082 next = entityTextPtr + enc->minBytesPerChar;
5084 case XML_TOK_DATA_NEWLINE:
5085 if (pool->end == pool->ptr && !poolGrow(pool)) {
5086 result = XML_ERROR_NO_MEMORY;
5087 goto endEntityValue;
5089 *(pool->ptr)++ = 0xA;
5091 case XML_TOK_CHAR_REF:
5093 XML_Char buf[XML_ENCODE_MAX];
5095 int n = XmlCharRefNumber(enc, entityTextPtr);
5097 if (enc == encoding)
5098 eventPtr = entityTextPtr;
5099 result = XML_ERROR_BAD_CHAR_REF;
5100 goto endEntityValue;
5102 n = XmlEncode(n, (ICHAR *)buf);
5104 if (enc == encoding)
5105 eventPtr = entityTextPtr;
5106 result = XML_ERROR_BAD_CHAR_REF;
5107 goto endEntityValue;
5109 for (i = 0; i < n; i++) {
5110 if (pool->end == pool->ptr && !poolGrow(pool)) {
5111 result = XML_ERROR_NO_MEMORY;
5112 goto endEntityValue;
5114 *(pool->ptr)++ = buf[i];
5118 case XML_TOK_PARTIAL:
5119 if (enc == encoding)
5120 eventPtr = entityTextPtr;
5121 result = XML_ERROR_INVALID_TOKEN;
5122 goto endEntityValue;
5123 case XML_TOK_INVALID:
5124 if (enc == encoding)
5126 result = XML_ERROR_INVALID_TOKEN;
5127 goto endEntityValue;
5129 if (enc == encoding)
5130 eventPtr = entityTextPtr;
5131 result = XML_ERROR_UNEXPECTED_STATE;
5132 goto endEntityValue;
5134 entityTextPtr = next;
5138 prologState.inEntityValue = oldInEntityValue;
5139 #endif /* XML_DTD */
5143 static void FASTCALL
5144 normalizeLines(XML_Char *s)
5148 if (*s == XML_T('\0'))
5167 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5168 const char *start, const char *end)
5170 const XML_Char *target;
5173 if (!processingInstructionHandler) {
5175 reportDefault(parser, enc, start, end);
5178 start += enc->minBytesPerChar * 2;
5179 tem = start + XmlNameLength(enc, start);
5180 target = poolStoreString(&tempPool, enc, start, tem);
5183 poolFinish(&tempPool);
5184 data = poolStoreString(&tempPool, enc,
5186 end - enc->minBytesPerChar*2);
5189 normalizeLines(data);
5190 processingInstructionHandler(handlerArg, target, data);
5191 poolClear(&tempPool);
5196 reportComment(XML_Parser parser, const ENCODING *enc,
5197 const char *start, const char *end)
5200 if (!commentHandler) {
5202 reportDefault(parser, enc, start, end);
5205 data = poolStoreString(&tempPool,
5207 start + enc->minBytesPerChar * 4,
5208 end - enc->minBytesPerChar * 3);
5211 normalizeLines(data);
5212 commentHandler(handlerArg, data);
5213 poolClear(&tempPool);
5218 reportDefault(XML_Parser parser, const ENCODING *enc,
5219 const char *s, const char *end)
5221 if (MUST_CONVERT(enc, s)) {
5222 const char **eventPP;
5223 const char **eventEndPP;
5224 if (enc == encoding) {
5225 eventPP = &eventPtr;
5226 eventEndPP = &eventEndPtr;
5229 eventPP = &(openInternalEntities->internalEventPtr);
5230 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5233 ICHAR *dataPtr = (ICHAR *)dataBuf;
5234 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5236 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5241 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5246 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5247 XML_Bool isId, const XML_Char *value, XML_Parser parser)
5249 DEFAULT_ATTRIBUTE *att;
5250 if (value || isId) {
5251 /* The handling of default attributes gets messed up if we have
5252 a default which duplicates a non-default. */
5254 for (i = 0; i < type->nDefaultAtts; i++)
5255 if (attId == type->defaultAtts[i].id)
5257 if (isId && !type->idAtt && !attId->xmlns)
5258 type->idAtt = attId;
5260 if (type->nDefaultAtts == type->allocDefaultAtts) {
5261 if (type->allocDefaultAtts == 0) {
5262 type->allocDefaultAtts = 8;
5263 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5264 * sizeof(DEFAULT_ATTRIBUTE));
5265 if (!type->defaultAtts)
5269 DEFAULT_ATTRIBUTE *temp;
5270 int count = type->allocDefaultAtts * 2;
5271 temp = (DEFAULT_ATTRIBUTE *)
5272 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5275 type->allocDefaultAtts = count;
5276 type->defaultAtts = temp;
5279 att = type->defaultAtts + type->nDefaultAtts;
5282 att->isCdata = isCdata;
5284 attId->maybeTokenized = XML_TRUE;
5285 type->nDefaultAtts += 1;
5290 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5292 DTD * const dtd = _dtd; /* save one level of indirection */
5293 const XML_Char *name;
5294 for (name = elementType->name; *name; name++) {
5295 if (*name == XML_T(ASCII_COLON)) {
5298 for (s = elementType->name; s != name; s++) {
5299 if (!poolAppendChar(&dtd->pool, *s))
5302 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5304 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5308 if (prefix->name == poolStart(&dtd->pool))
5309 poolFinish(&dtd->pool);
5311 poolDiscard(&dtd->pool);
5312 elementType->prefix = prefix;
5319 static ATTRIBUTE_ID *
5320 getAttributeId(XML_Parser parser, const ENCODING *enc,
5321 const char *start, const char *end)
5323 DTD * const dtd = _dtd; /* save one level of indirection */
5325 const XML_Char *name;
5326 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5328 name = poolStoreString(&dtd->pool, enc, start, end);
5331 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5333 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5336 if (id->name != name)
5337 poolDiscard(&dtd->pool);
5339 poolFinish(&dtd->pool);
5342 else if (name[0] == XML_T(ASCII_x)
5343 && name[1] == XML_T(ASCII_m)
5344 && name[2] == XML_T(ASCII_l)
5345 && name[3] == XML_T(ASCII_n)
5346 && name[4] == XML_T(ASCII_s)
5347 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5348 if (name[5] == XML_T('\0'))
5349 id->prefix = &dtd->defaultPrefix;
5351 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
5352 id->xmlns = XML_TRUE;
5356 for (i = 0; name[i]; i++) {
5357 /* attributes without prefix are *not* in the default namespace */
5358 if (name[i] == XML_T(ASCII_COLON)) {
5360 for (j = 0; j < i; j++) {
5361 if (!poolAppendChar(&dtd->pool, name[j]))
5364 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5366 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5368 if (id->prefix->name == poolStart(&dtd->pool))
5369 poolFinish(&dtd->pool);
5371 poolDiscard(&dtd->pool);
5380 #define CONTEXT_SEP XML_T(ASCII_FF)
5382 static const XML_Char *
5383 getContext(XML_Parser parser)
5385 DTD * const dtd = _dtd; /* save one level of indirection */
5386 HASH_TABLE_ITER iter;
5387 XML_Bool needSep = XML_FALSE;
5389 if (dtd->defaultPrefix.binding) {
5392 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5394 len = dtd->defaultPrefix.binding->uriLen;
5395 if (namespaceSeparator)
5397 for (i = 0; i < len; i++)
5398 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5403 hashTableIterInit(&iter, &(dtd->prefixes));
5408 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5411 if (!prefix->binding)
5413 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5415 for (s = prefix->name; *s; s++)
5416 if (!poolAppendChar(&tempPool, *s))
5418 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5420 len = prefix->binding->uriLen;
5421 if (namespaceSeparator)
5423 for (i = 0; i < len; i++)
5424 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5430 hashTableIterInit(&iter, &(dtd->generalEntities));
5433 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5438 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5440 for (s = e->name; *s; s++)
5441 if (!poolAppendChar(&tempPool, *s))
5446 if (!poolAppendChar(&tempPool, XML_T('\0')))
5448 return tempPool.start;
5452 setContext(XML_Parser parser, const XML_Char *context)
5454 DTD * const dtd = _dtd; /* save one level of indirection */
5455 const XML_Char *s = context;
5457 while (*context != XML_T('\0')) {
5458 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5460 if (!poolAppendChar(&tempPool, XML_T('\0')))
5462 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
5465 if (*s != XML_T('\0'))
5468 poolDiscard(&tempPool);
5470 else if (*s == XML_T(ASCII_EQUALS)) {
5472 if (poolLength(&tempPool) == 0)
5473 prefix = &dtd->defaultPrefix;
5475 if (!poolAppendChar(&tempPool, XML_T('\0')))
5477 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5481 if (prefix->name == poolStart(&tempPool)) {
5482 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5486 poolDiscard(&tempPool);
5488 for (context = s + 1;
5489 *context != CONTEXT_SEP && *context != XML_T('\0');
5491 if (!poolAppendChar(&tempPool, *context))
5493 if (!poolAppendChar(&tempPool, XML_T('\0')))
5495 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5496 &inheritedBindings) != XML_ERROR_NONE)
5498 poolDiscard(&tempPool);
5499 if (*context != XML_T('\0'))
5504 if (!poolAppendChar(&tempPool, *s))
5512 static void FASTCALL
5513 normalizePublicId(XML_Char *publicId)
5515 XML_Char *p = publicId;
5517 for (s = publicId; *s; s++) {
5522 if (p != publicId && p[-1] != 0x20)
5529 if (p != publicId && p[-1] == 0x20)
5535 dtdCreate(const XML_Memory_Handling_Suite *ms)
5537 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5540 poolInit(&(p->pool), ms);
5541 poolInit(&(p->entityValuePool), ms);
5542 hashTableInit(&(p->generalEntities), ms);
5543 hashTableInit(&(p->elementTypes), ms);
5544 hashTableInit(&(p->attributeIds), ms);
5545 hashTableInit(&(p->prefixes), ms);
5547 p->paramEntityRead = XML_FALSE;
5548 hashTableInit(&(p->paramEntities), ms);
5549 #endif /* XML_DTD */
5550 p->defaultPrefix.name = NULL;
5551 p->defaultPrefix.binding = NULL;
5553 p->in_eldecl = XML_FALSE;
5554 p->scaffIndex = NULL;
5559 p->contentStringLen = 0;
5561 p->keepProcessing = XML_TRUE;
5562 p->hasParamEntityRefs = XML_FALSE;
5563 p->standalone = XML_FALSE;
5568 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5570 HASH_TABLE_ITER iter;
5571 hashTableIterInit(&iter, &(p->elementTypes));
5573 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5576 if (e->allocDefaultAtts != 0)
5577 ms->free_fcn(e->defaultAtts);
5579 hashTableClear(&(p->generalEntities));
5581 p->paramEntityRead = XML_FALSE;
5582 hashTableClear(&(p->paramEntities));
5583 #endif /* XML_DTD */
5584 hashTableClear(&(p->elementTypes));
5585 hashTableClear(&(p->attributeIds));
5586 hashTableClear(&(p->prefixes));
5587 poolClear(&(p->pool));
5588 poolClear(&(p->entityValuePool));
5589 p->defaultPrefix.name = NULL;
5590 p->defaultPrefix.binding = NULL;
5592 p->in_eldecl = XML_FALSE;
5594 ms->free_fcn(p->scaffIndex);
5595 p->scaffIndex = NULL;
5596 ms->free_fcn(p->scaffold);
5602 p->contentStringLen = 0;
5604 p->keepProcessing = XML_TRUE;
5605 p->hasParamEntityRefs = XML_FALSE;
5606 p->standalone = XML_FALSE;
5610 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5612 HASH_TABLE_ITER iter;
5613 hashTableIterInit(&iter, &(p->elementTypes));
5615 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5618 if (e->allocDefaultAtts != 0)
5619 ms->free_fcn(e->defaultAtts);
5621 hashTableDestroy(&(p->generalEntities));
5623 hashTableDestroy(&(p->paramEntities));
5624 #endif /* XML_DTD */
5625 hashTableDestroy(&(p->elementTypes));
5626 hashTableDestroy(&(p->attributeIds));
5627 hashTableDestroy(&(p->prefixes));
5628 poolDestroy(&(p->pool));
5629 poolDestroy(&(p->entityValuePool));
5631 ms->free_fcn(p->scaffIndex);
5632 ms->free_fcn(p->scaffold);
5637 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5638 The new DTD has already been initialized.
5641 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5643 HASH_TABLE_ITER iter;
5645 /* Copy the prefix table. */
5647 hashTableIterInit(&iter, &(oldDtd->prefixes));
5649 const XML_Char *name;
5650 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5653 name = poolCopyString(&(newDtd->pool), oldP->name);
5656 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5660 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5662 /* Copy the attribute id table. */
5666 const XML_Char *name;
5667 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5671 /* Remember to allocate the scratch byte before the name. */
5672 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5674 name = poolCopyString(&(newDtd->pool), oldA->name);
5678 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5679 sizeof(ATTRIBUTE_ID));
5682 newA->maybeTokenized = oldA->maybeTokenized;
5684 newA->xmlns = oldA->xmlns;
5685 if (oldA->prefix == &oldDtd->defaultPrefix)
5686 newA->prefix = &newDtd->defaultPrefix;
5688 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5689 oldA->prefix->name, 0);
5693 /* Copy the element type table. */
5695 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5700 const XML_Char *name;
5701 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5704 name = poolCopyString(&(newDtd->pool), oldE->name);
5707 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5708 sizeof(ELEMENT_TYPE));
5711 if (oldE->nDefaultAtts) {
5712 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5713 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5714 if (!newE->defaultAtts) {
5720 newE->idAtt = (ATTRIBUTE_ID *)
5721 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5722 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5724 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5725 oldE->prefix->name, 0);
5726 for (i = 0; i < newE->nDefaultAtts; i++) {
5727 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5728 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5729 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5730 if (oldE->defaultAtts[i].value) {
5731 newE->defaultAtts[i].value
5732 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5733 if (!newE->defaultAtts[i].value)
5737 newE->defaultAtts[i].value = NULL;
5741 /* Copy the entity tables. */
5742 if (!copyEntityTable(&(newDtd->generalEntities),
5744 &(oldDtd->generalEntities)))
5748 if (!copyEntityTable(&(newDtd->paramEntities),
5750 &(oldDtd->paramEntities)))
5752 newDtd->paramEntityRead = oldDtd->paramEntityRead;
5753 #endif /* XML_DTD */
5755 newDtd->keepProcessing = oldDtd->keepProcessing;
5756 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5757 newDtd->standalone = oldDtd->standalone;
5759 /* Don't want deep copying for scaffolding */
5760 newDtd->in_eldecl = oldDtd->in_eldecl;
5761 newDtd->scaffold = oldDtd->scaffold;
5762 newDtd->contentStringLen = oldDtd->contentStringLen;
5763 newDtd->scaffSize = oldDtd->scaffSize;
5764 newDtd->scaffLevel = oldDtd->scaffLevel;
5765 newDtd->scaffIndex = oldDtd->scaffIndex;
5771 copyEntityTable(HASH_TABLE *newTable,
5772 STRING_POOL *newPool,
5773 const HASH_TABLE *oldTable)
5775 HASH_TABLE_ITER iter;
5776 const XML_Char *cachedOldBase = NULL;
5777 const XML_Char *cachedNewBase = NULL;
5779 hashTableIterInit(&iter, oldTable);
5783 const XML_Char *name;
5784 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5787 name = poolCopyString(newPool, oldE->name);
5790 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5793 if (oldE->systemId) {
5794 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5797 newE->systemId = tem;
5799 if (oldE->base == cachedOldBase)
5800 newE->base = cachedNewBase;
5802 cachedOldBase = oldE->base;
5803 tem = poolCopyString(newPool, cachedOldBase);
5806 cachedNewBase = newE->base = tem;
5809 if (oldE->publicId) {
5810 tem = poolCopyString(newPool, oldE->publicId);
5813 newE->publicId = tem;
5817 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5821 newE->textPtr = tem;
5822 newE->textLen = oldE->textLen;
5824 if (oldE->notation) {
5825 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5828 newE->notation = tem;
5830 newE->is_param = oldE->is_param;
5831 newE->is_internal = oldE->is_internal;
5836 #define INIT_POWER 6
5838 static XML_Bool FASTCALL
5839 keyeq(KEY s1, KEY s2)
5841 for (; *s1 == *s2; s1++, s2++)
5847 static unsigned long FASTCALL
5850 unsigned long h = 0;
5852 h = CHAR_HASH(h, *s++);
5857 lookup(HASH_TABLE *table, KEY name, size_t createSize)
5860 if (table->size == 0) {
5864 table->power = INIT_POWER;
5865 /* table->size is a power of 2 */
5866 table->size = (size_t)1 << INIT_POWER;
5867 tsize = table->size * sizeof(NAMED *);
5868 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5873 memset(table->v, 0, tsize);
5874 i = hash(name) & ((unsigned long)table->size - 1);
5877 unsigned long h = hash(name);
5878 unsigned long mask = (unsigned long)table->size - 1;
5879 unsigned char step = 0;
5881 while (table->v[i]) {
5882 if (keyeq(name, table->v[i]->name))
5885 step = PROBE_STEP(h, mask, table->power);
5886 i < step ? (i += table->size - step) : (i -= step);
5891 /* check for overflow (table is half full) */
5892 if (table->used >> (table->power - 1)) {
5893 unsigned char newPower = table->power + 1;
5894 size_t newSize = (size_t)1 << newPower;
5895 unsigned long newMask = (unsigned long)newSize - 1;
5896 size_t tsize = newSize * sizeof(NAMED *);
5897 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
5900 memset(newV, 0, tsize);
5901 for (i = 0; i < table->size; i++)
5903 unsigned long newHash = hash(table->v[i]->name);
5904 size_t j = newHash & newMask;
5908 step = PROBE_STEP(newHash, newMask, newPower);
5909 j < step ? (j += newSize - step) : (j -= step);
5911 newV[j] = table->v[i];
5913 table->mem->free_fcn(table->v);
5915 table->power = newPower;
5916 table->size = newSize;
5919 while (table->v[i]) {
5921 step = PROBE_STEP(h, newMask, newPower);
5922 i < step ? (i += newSize - step) : (i -= step);
5926 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
5929 memset(table->v[i], 0, createSize);
5930 table->v[i]->name = name;
5935 static void FASTCALL
5936 hashTableClear(HASH_TABLE *table)
5939 for (i = 0; i < table->size; i++) {
5940 table->mem->free_fcn(table->v[i]);
5946 static void FASTCALL
5947 hashTableDestroy(HASH_TABLE *table)
5950 for (i = 0; i < table->size; i++)
5951 table->mem->free_fcn(table->v[i]);
5952 table->mem->free_fcn(table->v);
5955 static void FASTCALL
5956 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
5965 static void FASTCALL
5966 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
5969 iter->end = iter->p + table->size;
5972 static NAMED * FASTCALL
5973 hashTableIterNext(HASH_TABLE_ITER *iter)
5975 while (iter->p != iter->end) {
5976 NAMED *tem = *(iter->p)++;
5983 static void FASTCALL
5984 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
5986 pool->blocks = NULL;
5987 pool->freeBlocks = NULL;
5994 static void FASTCALL
5995 poolClear(STRING_POOL *pool)
5997 if (!pool->freeBlocks)
5998 pool->freeBlocks = pool->blocks;
6000 BLOCK *p = pool->blocks;
6002 BLOCK *tem = p->next;
6003 p->next = pool->freeBlocks;
6004 pool->freeBlocks = p;
6008 pool->blocks = NULL;
6014 static void FASTCALL
6015 poolDestroy(STRING_POOL *pool)
6017 BLOCK *p = pool->blocks;
6019 BLOCK *tem = p->next;
6020 pool->mem->free_fcn(p);
6023 p = pool->freeBlocks;
6025 BLOCK *tem = p->next;
6026 pool->mem->free_fcn(p);
6032 poolAppend(STRING_POOL *pool, const ENCODING *enc,
6033 const char *ptr, const char *end)
6035 if (!pool->ptr && !poolGrow(pool))
6038 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6041 if (!poolGrow(pool))
6047 static const XML_Char * FASTCALL
6048 poolCopyString(STRING_POOL *pool, const XML_Char *s)
6051 if (!poolAppendChar(pool, *s))
6059 static const XML_Char *
6060 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6062 if (!pool->ptr && !poolGrow(pool))
6064 for (; n > 0; --n, s++) {
6065 if (!poolAppendChar(pool, *s))
6073 static const XML_Char * FASTCALL
6074 poolAppendString(STRING_POOL *pool, const XML_Char *s)
6077 if (!poolAppendChar(pool, *s))
6085 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6086 const char *ptr, const char *end)
6088 if (!poolAppend(pool, enc, ptr, end))
6090 if (pool->ptr == pool->end && !poolGrow(pool))
6096 static XML_Bool FASTCALL
6097 poolGrow(STRING_POOL *pool)
6099 if (pool->freeBlocks) {
6100 if (pool->start == 0) {
6101 pool->blocks = pool->freeBlocks;
6102 pool->freeBlocks = pool->freeBlocks->next;
6103 pool->blocks->next = NULL;
6104 pool->start = pool->blocks->s;
6105 pool->end = pool->start + pool->blocks->size;
6106 pool->ptr = pool->start;
6109 if (pool->end - pool->start < pool->freeBlocks->size) {
6110 BLOCK *tem = pool->freeBlocks->next;
6111 pool->freeBlocks->next = pool->blocks;
6112 pool->blocks = pool->freeBlocks;
6113 pool->freeBlocks = tem;
6114 memcpy(pool->blocks->s, pool->start,
6115 (pool->end - pool->start) * sizeof(XML_Char));
6116 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6117 pool->start = pool->blocks->s;
6118 pool->end = pool->start + pool->blocks->size;
6122 if (pool->blocks && pool->start == pool->blocks->s) {
6123 int blockSize = (int)(pool->end - pool->start)*2;
6124 pool->blocks = (BLOCK *)
6125 pool->mem->realloc_fcn(pool->blocks,
6127 + blockSize * sizeof(XML_Char)));
6128 if (pool->blocks == NULL)
6130 pool->blocks->size = blockSize;
6131 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6132 pool->start = pool->blocks->s;
6133 pool->end = pool->start + blockSize;
6137 int blockSize = (int)(pool->end - pool->start);
6138 if (blockSize < INIT_BLOCK_SIZE)
6139 blockSize = INIT_BLOCK_SIZE;
6142 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6143 + blockSize * sizeof(XML_Char));
6146 tem->size = blockSize;
6147 tem->next = pool->blocks;
6149 if (pool->ptr != pool->start)
6150 memcpy(tem->s, pool->start,
6151 (pool->ptr - pool->start) * sizeof(XML_Char));
6152 pool->ptr = tem->s + (pool->ptr - pool->start);
6153 pool->start = tem->s;
6154 pool->end = tem->s + blockSize;
6160 nextScaffoldPart(XML_Parser parser)
6162 DTD * const dtd = _dtd; /* save one level of indirection */
6163 CONTENT_SCAFFOLD * me;
6166 if (!dtd->scaffIndex) {
6167 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6168 if (!dtd->scaffIndex)
6170 dtd->scaffIndex[0] = 0;
6173 if (dtd->scaffCount >= dtd->scaffSize) {
6174 CONTENT_SCAFFOLD *temp;
6175 if (dtd->scaffold) {
6176 temp = (CONTENT_SCAFFOLD *)
6177 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6180 dtd->scaffSize *= 2;
6183 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6184 * sizeof(CONTENT_SCAFFOLD));
6187 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6189 dtd->scaffold = temp;
6191 next = dtd->scaffCount++;
6192 me = &dtd->scaffold[next];
6193 if (dtd->scaffLevel) {
6194 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6195 if (parent->lastchild) {
6196 dtd->scaffold[parent->lastchild].nextsib = next;
6198 if (!parent->childcnt)
6199 parent->firstchild = next;
6200 parent->lastchild = next;
6203 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6208 build_node(XML_Parser parser,
6211 XML_Content **contpos,
6214 DTD * const dtd = _dtd; /* save one level of indirection */
6215 dest->type = dtd->scaffold[src_node].type;
6216 dest->quant = dtd->scaffold[src_node].quant;
6217 if (dest->type == XML_CTYPE_NAME) {
6218 const XML_Char *src;
6219 dest->name = *strpos;
6220 src = dtd->scaffold[src_node].name;
6222 *(*strpos)++ = *src;
6227 dest->numchildren = 0;
6228 dest->children = NULL;
6233 dest->numchildren = dtd->scaffold[src_node].childcnt;
6234 dest->children = *contpos;
6235 *contpos += dest->numchildren;
6236 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6237 i < dest->numchildren;
6238 i++, cn = dtd->scaffold[cn].nextsib) {
6239 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6245 static XML_Content *
6246 build_model (XML_Parser parser)
6248 DTD * const dtd = _dtd; /* save one level of indirection */
6252 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6253 + (dtd->contentStringLen * sizeof(XML_Char)));
6255 ret = (XML_Content *)MALLOC(allocsize);
6259 str = (XML_Char *) (&ret[dtd->scaffCount]);
6262 build_node(parser, 0, ret, &cpos, &str);
6266 static ELEMENT_TYPE *
6267 getElementType(XML_Parser parser,
6268 const ENCODING *enc,
6272 DTD * const dtd = _dtd; /* save one level of indirection */
6273 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6278 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6281 if (ret->name != name)
6282 poolDiscard(&dtd->pool);
6284 poolFinish(&dtd->pool);
6285 if (!setElementTypePrefix(parser, ret))