xmlparse.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:189k
- /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
- */
- #include <stddef.h>
- #include <string.h> /* memset(), memcpy() */
- #include <assert.h>
- #define XML_BUILDING_EXPAT 1
- #ifdef COMPILED_FROM_DSP
- #include "winconfig.h"
- #elif defined(MACOS_CLASSIC)
- #include "macconfig.h"
- #elif defined(__amigaos4__)
- #include "amigaconfig.h"
- #elif defined(__WATCOMC__)
- #include "watcomconfig.h"
- #elif defined(HAVE_EXPAT_CONFIG_H)
- #include <expat_config.h>
- #endif /* ndef COMPILED_FROM_DSP */
- #include "ascii.h"
- #include "expat.h"
- #ifdef XML_UNICODE
- #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
- #define XmlConvert XmlUtf16Convert
- #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
- #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
- #define XmlEncode XmlUtf16Encode
- /* Using pointer subtraction to convert to integer type. */
- #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
- typedef unsigned short ICHAR;
- #else
- #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
- #define XmlConvert XmlUtf8Convert
- #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
- #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
- #define XmlEncode XmlUtf8Encode
- #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
- typedef char ICHAR;
- #endif
- #ifndef XML_NS
- #define XmlInitEncodingNS XmlInitEncoding
- #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
- #undef XmlGetInternalEncodingNS
- #define XmlGetInternalEncodingNS XmlGetInternalEncoding
- #define XmlParseXmlDeclNS XmlParseXmlDecl
- #endif
- #ifdef XML_UNICODE
- #ifdef XML_UNICODE_WCHAR_T
- #define XML_T(x) (const wchar_t)x
- #define XML_L(x) L ## x
- #else
- #define XML_T(x) (const unsigned short)x
- #define XML_L(x) x
- #endif
- #else
- #define XML_T(x) x
- #define XML_L(x) x
- #endif
- /* Round up n to be a multiple of sz, where sz is a power of 2. */
- #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
- /* Handle the case where memmove() doesn't exist. */
- #ifndef HAVE_MEMMOVE
- #ifdef HAVE_BCOPY
- #define memmove(d,s,l) bcopy((s),(d),(l))
- #else
- #error memmove does not exist on this platform, nor is a substitute available
- #endif /* HAVE_BCOPY */
- #endif /* HAVE_MEMMOVE */
- #include "internal.h"
- #include "xmltok.h"
- #include "xmlrole.h"
- typedef const XML_Char *KEY;
- typedef struct {
- KEY name;
- } NAMED;
- typedef struct {
- NAMED **v;
- unsigned char power;
- size_t size;
- size_t used;
- const XML_Memory_Handling_Suite *mem;
- } HASH_TABLE;
- /* Basic character hash algorithm, taken from Python's string hash:
- h = h * 1000003 ^ character, the constant being a prime number.
- */
- #ifdef XML_UNICODE
- #define CHAR_HASH(h, c)
- (((h) * 0xF4243) ^ (unsigned short)(c))
- #else
- #define CHAR_HASH(h, c)
- (((h) * 0xF4243) ^ (unsigned char)(c))
- #endif
- /* For probing (after a collision) we need a step size relative prime
- to the hash table size, which is a power of 2. We use double-hashing,
- since we can calculate a second hash value cheaply by taking those bits
- of the first hash value that were discarded (masked out) when the table
- index was calculated: index = hash & mask, where mask = table->size - 1.
- We limit the maximum step size to table->size / 4 (mask >> 2) and make
- it odd, since odd numbers are always relative prime to a power of 2.
- */
- #define SECOND_HASH(hash, mask, power)
- ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
- #define PROBE_STEP(hash, mask, power)
- ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
- typedef struct {
- NAMED **p;
- NAMED **end;
- } HASH_TABLE_ITER;
- #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
- #define INIT_DATA_BUF_SIZE 1024
- #define INIT_ATTS_SIZE 16
- #define INIT_ATTS_VERSION 0xFFFFFFFF
- #define INIT_BLOCK_SIZE 1024
- #define INIT_BUFFER_SIZE 1024
- #define EXPAND_SPARE 24
- typedef struct binding {
- struct prefix *prefix;
- struct binding *nextTagBinding;
- struct binding *prevPrefixBinding;
- const struct attribute_id *attId;
- XML_Char *uri;
- int uriLen;
- int uriAlloc;
- } BINDING;
- typedef struct prefix {
- const XML_Char *name;
- BINDING *binding;
- } PREFIX;
- typedef struct {
- const XML_Char *str;
- const XML_Char *localPart;
- const XML_Char *prefix;
- int strLen;
- int uriLen;
- int prefixLen;
- } TAG_NAME;
- /* TAG represents an open element.
- The name of the element is stored in both the document and API
- encodings. The memory buffer 'buf' is a separately-allocated
- memory area which stores the name. During the XML_Parse()/
- XMLParseBuffer() when the element is open, the memory for the 'raw'
- version of the name (in the document encoding) is shared with the
- document buffer. If the element is open across calls to
- XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
- contain the 'raw' name as well.
- A parser re-uses these structures, maintaining a list of allocated
- TAG objects in a free list.
- */
- typedef struct tag {
- struct tag *parent; /* parent of this element */
- const char *rawName; /* tagName in the original encoding */
- int rawNameLength;
- TAG_NAME name; /* tagName in the API encoding */
- char *buf; /* buffer for name components */
- char *bufEnd; /* end of the buffer */
- BINDING *bindings;
- } TAG;
- typedef struct {
- const XML_Char *name;
- const XML_Char *textPtr;
- int textLen; /* length in XML_Chars */
- int processed; /* # of processed bytes - when suspended */
- const XML_Char *systemId;
- const XML_Char *base;
- const XML_Char *publicId;
- const XML_Char *notation;
- XML_Bool open;
- XML_Bool is_param;
- XML_Bool is_internal; /* true if declared in internal subset outside PE */
- } ENTITY;
- typedef struct {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- const XML_Char * name;
- int firstchild;
- int lastchild;
- int childcnt;
- int nextsib;
- } CONTENT_SCAFFOLD;
- #define INIT_SCAFFOLD_ELEMENTS 32
- typedef struct block {
- struct block *next;
- int size;
- XML_Char s[1];
- } BLOCK;
- typedef struct {
- BLOCK *blocks;
- BLOCK *freeBlocks;
- const XML_Char *end;
- XML_Char *ptr;
- XML_Char *start;
- const XML_Memory_Handling_Suite *mem;
- } STRING_POOL;
- /* The XML_Char before the name is used to determine whether
- an attribute has been specified. */
- typedef struct attribute_id {
- XML_Char *name;
- PREFIX *prefix;
- XML_Bool maybeTokenized;
- XML_Bool xmlns;
- } ATTRIBUTE_ID;
- typedef struct {
- const ATTRIBUTE_ID *id;
- XML_Bool isCdata;
- const XML_Char *value;
- } DEFAULT_ATTRIBUTE;
- typedef struct {
- unsigned long version;
- unsigned long hash;
- const XML_Char *uriName;
- } NS_ATT;
- typedef struct {
- const XML_Char *name;
- PREFIX *prefix;
- const ATTRIBUTE_ID *idAtt;
- int nDefaultAtts;
- int allocDefaultAtts;
- DEFAULT_ATTRIBUTE *defaultAtts;
- } ELEMENT_TYPE;
- typedef struct {
- HASH_TABLE generalEntities;
- HASH_TABLE elementTypes;
- HASH_TABLE attributeIds;
- HASH_TABLE prefixes;
- STRING_POOL pool;
- STRING_POOL entityValuePool;
- /* false once a parameter entity reference has been skipped */
- XML_Bool keepProcessing;
- /* true once an internal or external PE reference has been encountered;
- this includes the reference to an external subset */
- XML_Bool hasParamEntityRefs;
- XML_Bool standalone;
- #ifdef XML_DTD
- /* indicates if external PE has been read */
- XML_Bool paramEntityRead;
- HASH_TABLE paramEntities;
- #endif /* XML_DTD */
- PREFIX defaultPrefix;
- /* === scaffolding for building content model === */
- XML_Bool in_eldecl;
- CONTENT_SCAFFOLD *scaffold;
- unsigned contentStringLen;
- unsigned scaffSize;
- unsigned scaffCount;
- int scaffLevel;
- int *scaffIndex;
- } DTD;
- typedef struct open_internal_entity {
- const char *internalEventPtr;
- const char *internalEventEndPtr;
- struct open_internal_entity *next;
- ENTITY *entity;
- int startTagLevel;
- XML_Bool betweenDecl; /* WFC: PE Between Declarations */
- } OPEN_INTERNAL_ENTITY;
- typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr);
- static Processor prologProcessor;
- static Processor prologInitProcessor;
- static Processor contentProcessor;
- static Processor cdataSectionProcessor;
- #ifdef XML_DTD
- static Processor ignoreSectionProcessor;
- static Processor externalParEntProcessor;
- static Processor externalParEntInitProcessor;
- static Processor entityValueProcessor;
- static Processor entityValueInitProcessor;
- #endif /* XML_DTD */
- static Processor epilogProcessor;
- static Processor errorProcessor;
- static Processor externalEntityInitProcessor;
- static Processor externalEntityInitProcessor2;
- static Processor externalEntityInitProcessor3;
- static Processor externalEntityContentProcessor;
- static Processor internalEntityProcessor;
- static enum XML_Error
- handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
- static enum XML_Error
- processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next);
- static enum XML_Error
- initializeEncoding(XML_Parser parser);
- static enum XML_Error
- doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
- const char *end, int tok, const char *next, const char **nextPtr,
- XML_Bool haveMore);
- static enum XML_Error
- processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
- static enum XML_Error
- doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
- const char *start, const char *end, const char **endPtr,
- XML_Bool haveMore);
- static enum XML_Error
- doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
- #ifdef XML_DTD
- static enum XML_Error
- doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
- #endif /* XML_DTD */
- static enum XML_Error
- storeAtts(XML_Parser parser, const ENCODING *, const char *s,
- TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
- static enum XML_Error
- addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr);
- static int
- defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
- static enum XML_Error
- storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
- static enum XML_Error
- appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
- static ATTRIBUTE_ID *
- getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
- static int
- setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
- static enum XML_Error
- storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
- static int
- reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
- static int
- reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
- static void
- reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
- static const XML_Char * getContext(XML_Parser parser);
- static XML_Bool
- setContext(XML_Parser parser, const XML_Char *context);
- static void FASTCALL normalizePublicId(XML_Char *s);
- static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
- /* do not call if parentParser != NULL */
- static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
- static void
- dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
- static int
- dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
- static int
- copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
- static NAMED *
- lookup(HASH_TABLE *table, KEY name, size_t createSize);
- static void FASTCALL
- hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
- static void FASTCALL hashTableClear(HASH_TABLE *);
- static void FASTCALL hashTableDestroy(HASH_TABLE *);
- static void FASTCALL
- hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
- static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
- static void FASTCALL
- poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
- static void FASTCALL poolClear(STRING_POOL *);
- static void FASTCALL poolDestroy(STRING_POOL *);
- static XML_Char *
- poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
- static XML_Char *
- poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
- static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
- static const XML_Char * FASTCALL
- poolCopyString(STRING_POOL *pool, const XML_Char *s);
- static const XML_Char *
- poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
- static const XML_Char * FASTCALL
- poolAppendString(STRING_POOL *pool, const XML_Char *s);
- static int FASTCALL nextScaffoldPart(XML_Parser parser);
- static XML_Content * build_model(XML_Parser parser);
- static ELEMENT_TYPE *
- getElementType(XML_Parser parser, const ENCODING *enc,
- const char *ptr, const char *end);
- static XML_Parser
- parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd);
- static void
- parserInit(XML_Parser parser, const XML_Char *encodingName);
- #define poolStart(pool) ((pool)->start)
- #define poolEnd(pool) ((pool)->ptr)
- #define poolLength(pool) ((pool)->ptr - (pool)->start)
- #define poolChop(pool) ((void)--(pool->ptr))
- #define poolLastChar(pool) (((pool)->ptr)[-1])
- #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
- #define poolFinish(pool) ((pool)->start = (pool)->ptr)
- #define poolAppendChar(pool, c)
- (((pool)->ptr == (pool)->end && !poolGrow(pool))
- ? 0
- : ((*((pool)->ptr)++ = c), 1))
- struct XML_ParserStruct {
- /* The first member must be userData so that the XML_GetUserData
- macro works. */
- void *m_userData;
- void *m_handlerArg;
- char *m_buffer;
- const XML_Memory_Handling_Suite m_mem;
- /* first character to be parsed */
- const char *m_bufferPtr;
- /* past last character to be parsed */
- char *m_bufferEnd;
- /* allocated end of buffer */
- const char *m_bufferLim;
- XML_Index m_parseEndByteIndex;
- const char *m_parseEndPtr;
- XML_Char *m_dataBuf;
- XML_Char *m_dataBufEnd;
- XML_StartElementHandler m_startElementHandler;
- XML_EndElementHandler m_endElementHandler;
- XML_CharacterDataHandler m_characterDataHandler;
- XML_ProcessingInstructionHandler m_processingInstructionHandler;
- XML_CommentHandler m_commentHandler;
- XML_StartCdataSectionHandler m_startCdataSectionHandler;
- XML_EndCdataSectionHandler m_endCdataSectionHandler;
- XML_DefaultHandler m_defaultHandler;
- XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
- XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
- XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
- XML_NotationDeclHandler m_notationDeclHandler;
- XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
- XML_NotStandaloneHandler m_notStandaloneHandler;
- XML_ExternalEntityRefHandler m_externalEntityRefHandler;
- XML_Parser m_externalEntityRefHandlerArg;
- XML_SkippedEntityHandler m_skippedEntityHandler;
- XML_UnknownEncodingHandler m_unknownEncodingHandler;
- XML_ElementDeclHandler m_elementDeclHandler;
- XML_AttlistDeclHandler m_attlistDeclHandler;
- XML_EntityDeclHandler m_entityDeclHandler;
- XML_XmlDeclHandler m_xmlDeclHandler;
- const ENCODING *m_encoding;
- INIT_ENCODING m_initEncoding;
- const ENCODING *m_internalEncoding;
- const XML_Char *m_protocolEncodingName;
- XML_Bool m_ns;
- XML_Bool m_ns_triplets;
- void *m_unknownEncodingMem;
- void *m_unknownEncodingData;
- void *m_unknownEncodingHandlerData;
- void (XMLCALL *m_unknownEncodingRelease)(void *);
- PROLOG_STATE m_prologState;
- Processor *m_processor;
- enum XML_Error m_errorCode;
- const char *m_eventPtr;
- const char *m_eventEndPtr;
- const char *m_positionPtr;
- OPEN_INTERNAL_ENTITY *m_openInternalEntities;
- OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
- XML_Bool m_defaultExpandInternalEntities;
- int m_tagLevel;
- ENTITY *m_declEntity;
- const XML_Char *m_doctypeName;
- const XML_Char *m_doctypeSysid;
- const XML_Char *m_doctypePubid;
- const XML_Char *m_declAttributeType;
- const XML_Char *m_declNotationName;
- const XML_Char *m_declNotationPublicId;
- ELEMENT_TYPE *m_declElementType;
- ATTRIBUTE_ID *m_declAttributeId;
- XML_Bool m_declAttributeIsCdata;
- XML_Bool m_declAttributeIsId;
- DTD *m_dtd;
- const XML_Char *m_curBase;
- TAG *m_tagStack;
- TAG *m_freeTagList;
- BINDING *m_inheritedBindings;
- BINDING *m_freeBindingList;
- int m_attsSize;
- int m_nSpecifiedAtts;
- int m_idAttIndex;
- ATTRIBUTE *m_atts;
- NS_ATT *m_nsAtts;
- unsigned long m_nsAttsVersion;
- unsigned char m_nsAttsPower;
- POSITION m_position;
- STRING_POOL m_tempPool;
- STRING_POOL m_temp2Pool;
- char *m_groupConnector;
- unsigned int m_groupSize;
- XML_Char m_namespaceSeparator;
- XML_Parser m_parentParser;
- XML_ParsingStatus m_parsingStatus;
- #ifdef XML_DTD
- XML_Bool m_isParamEntity;
- XML_Bool m_useForeignDTD;
- enum XML_ParamEntityParsing m_paramEntityParsing;
- #endif
- };
- #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
- #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
- #define FREE(p) (parser->m_mem.free_fcn((p)))
- #define userData (parser->m_userData)
- #define handlerArg (parser->m_handlerArg)
- #define startElementHandler (parser->m_startElementHandler)
- #define endElementHandler (parser->m_endElementHandler)
- #define characterDataHandler (parser->m_characterDataHandler)
- #define processingInstructionHandler
- (parser->m_processingInstructionHandler)
- #define commentHandler (parser->m_commentHandler)
- #define startCdataSectionHandler
- (parser->m_startCdataSectionHandler)
- #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
- #define defaultHandler (parser->m_defaultHandler)
- #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
- #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
- #define unparsedEntityDeclHandler
- (parser->m_unparsedEntityDeclHandler)
- #define notationDeclHandler (parser->m_notationDeclHandler)
- #define startNamespaceDeclHandler
- (parser->m_startNamespaceDeclHandler)
- #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
- #define notStandaloneHandler (parser->m_notStandaloneHandler)
- #define externalEntityRefHandler
- (parser->m_externalEntityRefHandler)
- #define externalEntityRefHandlerArg
- (parser->m_externalEntityRefHandlerArg)
- #define internalEntityRefHandler
- (parser->m_internalEntityRefHandler)
- #define skippedEntityHandler (parser->m_skippedEntityHandler)
- #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
- #define elementDeclHandler (parser->m_elementDeclHandler)
- #define attlistDeclHandler (parser->m_attlistDeclHandler)
- #define entityDeclHandler (parser->m_entityDeclHandler)
- #define xmlDeclHandler (parser->m_xmlDeclHandler)
- #define encoding (parser->m_encoding)
- #define initEncoding (parser->m_initEncoding)
- #define internalEncoding (parser->m_internalEncoding)
- #define unknownEncodingMem (parser->m_unknownEncodingMem)
- #define unknownEncodingData (parser->m_unknownEncodingData)
- #define unknownEncodingHandlerData
- (parser->m_unknownEncodingHandlerData)
- #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
- #define protocolEncodingName (parser->m_protocolEncodingName)
- #define ns (parser->m_ns)
- #define ns_triplets (parser->m_ns_triplets)
- #define prologState (parser->m_prologState)
- #define processor (parser->m_processor)
- #define errorCode (parser->m_errorCode)
- #define eventPtr (parser->m_eventPtr)
- #define eventEndPtr (parser->m_eventEndPtr)
- #define positionPtr (parser->m_positionPtr)
- #define position (parser->m_position)
- #define openInternalEntities (parser->m_openInternalEntities)
- #define freeInternalEntities (parser->m_freeInternalEntities)
- #define defaultExpandInternalEntities
- (parser->m_defaultExpandInternalEntities)
- #define tagLevel (parser->m_tagLevel)
- #define buffer (parser->m_buffer)
- #define bufferPtr (parser->m_bufferPtr)
- #define bufferEnd (parser->m_bufferEnd)
- #define parseEndByteIndex (parser->m_parseEndByteIndex)
- #define parseEndPtr (parser->m_parseEndPtr)
- #define bufferLim (parser->m_bufferLim)
- #define dataBuf (parser->m_dataBuf)
- #define dataBufEnd (parser->m_dataBufEnd)
- #define _dtd (parser->m_dtd)
- #define curBase (parser->m_curBase)
- #define declEntity (parser->m_declEntity)
- #define doctypeName (parser->m_doctypeName)
- #define doctypeSysid (parser->m_doctypeSysid)
- #define doctypePubid (parser->m_doctypePubid)
- #define declAttributeType (parser->m_declAttributeType)
- #define declNotationName (parser->m_declNotationName)
- #define declNotationPublicId (parser->m_declNotationPublicId)
- #define declElementType (parser->m_declElementType)
- #define declAttributeId (parser->m_declAttributeId)
- #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
- #define declAttributeIsId (parser->m_declAttributeIsId)
- #define freeTagList (parser->m_freeTagList)
- #define freeBindingList (parser->m_freeBindingList)
- #define inheritedBindings (parser->m_inheritedBindings)
- #define tagStack (parser->m_tagStack)
- #define atts (parser->m_atts)
- #define attsSize (parser->m_attsSize)
- #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
- #define idAttIndex (parser->m_idAttIndex)
- #define nsAtts (parser->m_nsAtts)
- #define nsAttsVersion (parser->m_nsAttsVersion)
- #define nsAttsPower (parser->m_nsAttsPower)
- #define tempPool (parser->m_tempPool)
- #define temp2Pool (parser->m_temp2Pool)
- #define groupConnector (parser->m_groupConnector)
- #define groupSize (parser->m_groupSize)
- #define namespaceSeparator (parser->m_namespaceSeparator)
- #define parentParser (parser->m_parentParser)
- #define ps_parsing (parser->m_parsingStatus.parsing)
- #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
- #ifdef XML_DTD
- #define isParamEntity (parser->m_isParamEntity)
- #define useForeignDTD (parser->m_useForeignDTD)
- #define paramEntityParsing (parser->m_paramEntityParsing)
- #endif /* XML_DTD */
- XML_Parser XMLCALL
- XML_ParserCreate(const XML_Char *encodingName)
- {
- return XML_ParserCreate_MM(encodingName, NULL, NULL);
- }
- XML_Parser XMLCALL
- XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
- {
- XML_Char tmp[2];
- *tmp = nsSep;
- return XML_ParserCreate_MM(encodingName, NULL, tmp);
- }
- static const XML_Char implicitContext[] = {
- ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
- ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
- ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
- ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
- ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
- ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, ' '
- };
- XML_Parser XMLCALL
- XML_ParserCreate_MM(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep)
- {
- XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
- if (parser != NULL && ns) {
- /* implicit context only set for root parser, since child
- parsers (i.e. external entity parsers) will inherit it
- */
- if (!setContext(parser, implicitContext)) {
- XML_ParserFree(parser);
- return NULL;
- }
- }
- return parser;
- }
- static XML_Parser
- parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd)
- {
- XML_Parser parser;
- if (memsuite) {
- XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)
- memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
- mtemp->malloc_fcn = memsuite->malloc_fcn;
- mtemp->realloc_fcn = memsuite->realloc_fcn;
- mtemp->free_fcn = memsuite->free_fcn;
- }
- }
- else {
- XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
- mtemp->malloc_fcn = malloc;
- mtemp->realloc_fcn = realloc;
- mtemp->free_fcn = free;
- }
- }
- if (!parser)
- return parser;
- buffer = NULL;
- bufferLim = NULL;
- attsSize = INIT_ATTS_SIZE;
- atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
- if (atts == NULL) {
- FREE(parser);
- return NULL;
- }
- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
- if (dataBuf == NULL) {
- FREE(atts);
- FREE(parser);
- return NULL;
- }
- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
- if (dtd)
- _dtd = dtd;
- else {
- _dtd = dtdCreate(&parser->m_mem);
- if (_dtd == NULL) {
- FREE(dataBuf);
- FREE(atts);
- FREE(parser);
- return NULL;
- }
- }
- freeBindingList = NULL;
- freeTagList = NULL;
- freeInternalEntities = NULL;
- groupSize = 0;
- groupConnector = NULL;
- unknownEncodingHandler = NULL;
- unknownEncodingHandlerData = NULL;
- namespaceSeparator = ASCII_EXCL;
- ns = XML_FALSE;
- ns_triplets = XML_FALSE;
- nsAtts = NULL;
- nsAttsVersion = 0;
- nsAttsPower = 0;
- poolInit(&tempPool, &(parser->m_mem));
- poolInit(&temp2Pool, &(parser->m_mem));
- parserInit(parser, encodingName);
- if (encodingName && !protocolEncodingName) {
- XML_ParserFree(parser);
- return NULL;
- }
- if (nameSep) {
- ns = XML_TRUE;
- internalEncoding = XmlGetInternalEncodingNS();
- namespaceSeparator = *nameSep;
- }
- else {
- internalEncoding = XmlGetInternalEncoding();
- }
- return parser;
- }
- static void
- parserInit(XML_Parser parser, const XML_Char *encodingName)
- {
- processor = prologInitProcessor;
- XmlPrologStateInit(&prologState);
- protocolEncodingName = (encodingName != NULL
- ? poolCopyString(&tempPool, encodingName)
- : NULL);
- curBase = NULL;
- XmlInitEncoding(&initEncoding, &encoding, 0);
- userData = NULL;
- handlerArg = NULL;
- startElementHandler = NULL;
- endElementHandler = NULL;
- characterDataHandler = NULL;
- processingInstructionHandler = NULL;
- commentHandler = NULL;
- startCdataSectionHandler = NULL;
- endCdataSectionHandler = NULL;
- defaultHandler = NULL;
- startDoctypeDeclHandler = NULL;
- endDoctypeDeclHandler = NULL;
- unparsedEntityDeclHandler = NULL;
- notationDeclHandler = NULL;
- startNamespaceDeclHandler = NULL;
- endNamespaceDeclHandler = NULL;
- notStandaloneHandler = NULL;
- externalEntityRefHandler = NULL;
- externalEntityRefHandlerArg = parser;
- skippedEntityHandler = NULL;
- elementDeclHandler = NULL;
- attlistDeclHandler = NULL;
- entityDeclHandler = NULL;
- xmlDeclHandler = NULL;
- bufferPtr = buffer;
- bufferEnd = buffer;
- parseEndByteIndex = 0;
- parseEndPtr = NULL;
- declElementType = NULL;
- declAttributeId = NULL;
- declEntity = NULL;
- doctypeName = NULL;
- doctypeSysid = NULL;
- doctypePubid = NULL;
- declAttributeType = NULL;
- declNotationName = NULL;
- declNotationPublicId = NULL;
- declAttributeIsCdata = XML_FALSE;
- declAttributeIsId = XML_FALSE;
- memset(&position, 0, sizeof(POSITION));
- errorCode = XML_ERROR_NONE;
- eventPtr = NULL;
- eventEndPtr = NULL;
- positionPtr = NULL;
- openInternalEntities = NULL;
- defaultExpandInternalEntities = XML_TRUE;
- tagLevel = 0;
- tagStack = NULL;
- inheritedBindings = NULL;
- nSpecifiedAtts = 0;
- unknownEncodingMem = NULL;
- unknownEncodingRelease = NULL;
- unknownEncodingData = NULL;
- parentParser = NULL;
- ps_parsing = XML_INITIALIZED;
- #ifdef XML_DTD
- isParamEntity = XML_FALSE;
- useForeignDTD = XML_FALSE;
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
- #endif
- }
- /* moves list of bindings to freeBindingList */
- static void FASTCALL
- moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
- {
- while (bindings) {
- BINDING *b = bindings;
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- }
- }
- XML_Bool XMLCALL
- XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
- {
- TAG *tStk;
- OPEN_INTERNAL_ENTITY *openEntityList;
- if (parentParser)
- return XML_FALSE;
- /* move tagStack to freeTagList */
- tStk = tagStack;
- while (tStk) {
- TAG *tag = tStk;
- tStk = tStk->parent;
- tag->parent = freeTagList;
- moveToFreeBindingList(parser, tag->bindings);
- tag->bindings = NULL;
- freeTagList = tag;
- }
- /* move openInternalEntities to freeInternalEntities */
- openEntityList = openInternalEntities;
- while (openEntityList) {
- OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
- openEntityList = openEntity->next;
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
- }
- moveToFreeBindingList(parser, inheritedBindings);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- poolClear(&tempPool);
- poolClear(&temp2Pool);
- parserInit(parser, encodingName);
- dtdReset(_dtd, &parser->m_mem);
- return setContext(parser, implicitContext);
- }
- enum XML_Status XMLCALL
- XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
- {
- /* Block after XML_Parse()/XML_ParseBuffer() has been called.
- XXX There's no way for the caller to determine which of the
- XXX possible error cases caused the XML_STATUS_ERROR return.
- */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return XML_STATUS_ERROR;
- if (encodingName == NULL)
- protocolEncodingName = NULL;
- else {
- protocolEncodingName = poolCopyString(&tempPool, encodingName);
- if (!protocolEncodingName)
- return XML_STATUS_ERROR;
- }
- return XML_STATUS_OK;
- }
- XML_Parser XMLCALL
- XML_ExternalEntityParserCreate(XML_Parser oldParser,
- const XML_Char *context,
- const XML_Char *encodingName)
- {
- XML_Parser parser = oldParser;
- DTD *newDtd = NULL;
- DTD *oldDtd = _dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
- #ifdef XML_DTD
- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
- #endif
- XML_Bool oldns_triplets = ns_triplets;
- #ifdef XML_DTD
- if (!context)
- newDtd = oldDtd;
- #endif /* XML_DTD */
- /* Note that the magical uses of the pre-processor to make field
- access look more like C++ require that `parser' be overwritten
- here. This makes this function more painful to follow than it
- would be otherwise.
- */
- if (ns) {
- XML_Char tmp[2];
- *tmp = namespaceSeparator;
- parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
- }
- else {
- parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
- }
- if (!parser)
- return NULL;
- startElementHandler = oldStartElementHandler;
- endElementHandler = oldEndElementHandler;
- characterDataHandler = oldCharacterDataHandler;
- processingInstructionHandler = oldProcessingInstructionHandler;
- commentHandler = oldCommentHandler;
- startCdataSectionHandler = oldStartCdataSectionHandler;
- endCdataSectionHandler = oldEndCdataSectionHandler;
- defaultHandler = oldDefaultHandler;
- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
- notationDeclHandler = oldNotationDeclHandler;
- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
- notStandaloneHandler = oldNotStandaloneHandler;
- externalEntityRefHandler = oldExternalEntityRefHandler;
- skippedEntityHandler = oldSkippedEntityHandler;
- unknownEncodingHandler = oldUnknownEncodingHandler;
- elementDeclHandler = oldElementDeclHandler;
- attlistDeclHandler = oldAttlistDeclHandler;
- entityDeclHandler = oldEntityDeclHandler;
- xmlDeclHandler = oldXmlDeclHandler;
- declElementType = oldDeclElementType;
- userData = oldUserData;
- if (oldUserData == oldHandlerArg)
- handlerArg = userData;
- else
- handlerArg = parser;
- if (oldExternalEntityRefHandlerArg != oldParser)
- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
- ns_triplets = oldns_triplets;
- parentParser = oldParser;
- #ifdef XML_DTD
- paramEntityParsing = oldParamEntityParsing;
- prologState.inEntityValue = oldInEntityValue;
- if (context) {
- #endif /* XML_DTD */
- if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
- || !setContext(parser, context)) {
- XML_ParserFree(parser);
- return NULL;
- }
- processor = externalEntityInitProcessor;
- #ifdef XML_DTD
- }
- else {
- /* The DTD instance referenced by _dtd is shared between the document's
- root parser and external PE parsers, therefore one does not need to
- call setContext. In addition, one also *must* not call setContext,
- because this would overwrite existing prefix->binding pointers in
- _dtd with ones that get destroyed with the external PE parser.
- This would leave those prefixes with dangling pointers.
- */
- isParamEntity = XML_TRUE;
- XmlPrologStateInitExternalEntity(&prologState);
- processor = externalParEntInitProcessor;
- }
- #endif /* XML_DTD */
- return parser;
- }
- static void FASTCALL
- destroyBindings(BINDING *bindings, XML_Parser parser)
- {
- for (;;) {
- BINDING *b = bindings;
- if (!b)
- break;
- bindings = b->nextTagBinding;
- FREE(b->uri);
- FREE(b);
- }
- }
- void XMLCALL
- XML_ParserFree(XML_Parser parser)
- {
- TAG *tagList;
- OPEN_INTERNAL_ENTITY *entityList;
- if (parser == NULL)
- return;
- /* free tagStack and freeTagList */
- tagList = tagStack;
- for (;;) {
- TAG *p;
- if (tagList == NULL) {
- if (freeTagList == NULL)
- break;
- tagList = freeTagList;
- freeTagList = NULL;
- }
- p = tagList;
- tagList = tagList->parent;
- FREE(p->buf);
- destroyBindings(p->bindings, parser);
- FREE(p);
- }
- /* free openInternalEntities and freeInternalEntities */
- entityList = openInternalEntities;
- for (;;) {
- OPEN_INTERNAL_ENTITY *openEntity;
- if (entityList == NULL) {
- if (freeInternalEntities == NULL)
- break;
- entityList = freeInternalEntities;
- freeInternalEntities = NULL;
- }
- openEntity = entityList;
- entityList = entityList->next;
- FREE(openEntity);
- }
- destroyBindings(freeBindingList, parser);
- destroyBindings(inheritedBindings, parser);
- poolDestroy(&tempPool);
- poolDestroy(&temp2Pool);
- #ifdef XML_DTD
- /* external parameter entity parsers share the DTD structure
- parser->m_dtd with the root parser, so we must not destroy it
- */
- if (!isParamEntity && _dtd)
- #else
- if (_dtd)
- #endif /* XML_DTD */
- dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
- FREE((void *)atts);
- FREE(groupConnector);
- FREE(buffer);
- FREE(dataBuf);
- FREE(nsAtts);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- FREE(parser);
- }
- void XMLCALL
- XML_UseParserAsHandlerArg(XML_Parser parser)
- {
- handlerArg = parser;
- }
- enum XML_Error XMLCALL
- XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
- {
- #ifdef XML_DTD
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
- useForeignDTD = useDTD;
- return XML_ERROR_NONE;
- #else
- return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
- #endif
- }
- void XMLCALL
- XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
- {
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return;
- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
- }
- void XMLCALL
- XML_SetUserData(XML_Parser parser, void *p)
- {
- if (handlerArg == userData)
- handlerArg = userData = p;
- else
- userData = p;
- }
- enum XML_Status XMLCALL
- XML_SetBase(XML_Parser parser, const XML_Char *p)
- {
- if (p) {
- p = poolCopyString(&_dtd->pool, p);
- if (!p)
- return XML_STATUS_ERROR;
- curBase = p;
- }
- else
- curBase = NULL;
- return XML_STATUS_OK;
- }
- const XML_Char * XMLCALL
- XML_GetBase(XML_Parser parser)
- {
- return curBase;
- }
- int XMLCALL
- XML_GetSpecifiedAttributeCount(XML_Parser parser)
- {
- return nSpecifiedAtts;
- }
- int XMLCALL
- XML_GetIdAttributeIndex(XML_Parser parser)
- {
- return idAttIndex;
- }
- void XMLCALL
- XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end)
- {
- startElementHandler = start;
- endElementHandler = end;
- }
- void XMLCALL
- XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler start) {
- startElementHandler = start;
- }
- void XMLCALL
- XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler end) {
- endElementHandler = end;
- }
- void XMLCALL
- XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler)
- {
- characterDataHandler = handler;
- }
- void XMLCALL
- XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler)
- {
- processingInstructionHandler = handler;
- }
- void XMLCALL
- XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler)
- {
- commentHandler = handler;
- }
- void XMLCALL
- XML_SetCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end)
- {
- startCdataSectionHandler = start;
- endCdataSectionHandler = end;
- }
- void XMLCALL
- XML_SetStartCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
- }
- void XMLCALL
- XML_SetEndCdataSectionHandler(XML_Parser parser,
- XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
- }
- void XMLCALL
- XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler)
- {
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_FALSE;
- }
- void XMLCALL
- XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler)
- {
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_TRUE;
- }
- void XMLCALL
- XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end)
- {
- startDoctypeDeclHandler = start;
- endDoctypeDeclHandler = end;
- }
- void XMLCALL
- XML_SetStartDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
- }
- void XMLCALL
- XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
- }
- void XMLCALL
- XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler)
- {
- unparsedEntityDeclHandler = handler;
- }
- void XMLCALL
- XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler)
- {
- notationDeclHandler = handler;
- }
- void XMLCALL
- XML_SetNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end)
- {
- startNamespaceDeclHandler = start;
- endNamespaceDeclHandler = end;
- }
- void XMLCALL
- XML_SetStartNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
- }
- void XMLCALL
- XML_SetEndNamespaceDeclHandler(XML_Parser parser,
- XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
- }
- void XMLCALL
- XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler)
- {
- notStandaloneHandler = handler;
- }
- void XMLCALL
- XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler)
- {
- externalEntityRefHandler = handler;
- }
- void XMLCALL
- XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
- {
- if (arg)
- externalEntityRefHandlerArg = (XML_Parser)arg;
- else
- externalEntityRefHandlerArg = parser;
- }
- void XMLCALL
- XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler)
- {
- skippedEntityHandler = handler;
- }
- void XMLCALL
- XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *data)
- {
- unknownEncodingHandler = handler;
- unknownEncodingHandlerData = data;
- }
- void XMLCALL
- XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl)
- {
- elementDeclHandler = eldecl;
- }
- void XMLCALL
- XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl)
- {
- attlistDeclHandler = attdecl;
- }
- void XMLCALL
- XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler)
- {
- entityDeclHandler = handler;
- }
- void XMLCALL
- XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
- }
- int XMLCALL
- XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing peParsing)
- {
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return 0;
- #ifdef XML_DTD
- paramEntityParsing = peParsing;
- return 1;
- #else
- return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
- #endif
- }
- enum XML_Status XMLCALL
- XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
- {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- default:
- ps_parsing = XML_PARSING;
- }
- if (len == 0) {
- ps_finalBuffer = (XML_Bool)isFinal;
- if (!isFinal)
- return XML_STATUS_OK;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
- /* If data are left over from last buffer, and we now know that these
- data are the final chunk of input, then we have to check them again
- to detect errors based on that fact.
- */
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
- if (errorCode == XML_ERROR_NONE) {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return XML_STATUS_SUSPENDED;
- case XML_INITIALIZED:
- case XML_PARSING:
- ps_parsing = XML_FINISHED;
- /* fall through */
- default:
- return XML_STATUS_OK;
- }
- }
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- #ifndef XML_CONTEXT_BYTES
- else if (bufferPtr == bufferEnd) {
- const char *end;
- int nLeftOver;
- enum XML_Error result;
- parseEndByteIndex += len;
- positionPtr = s;
- ps_finalBuffer = (XML_Bool)isFinal;
- errorCode = processor(parser, s, parseEndPtr = s + len, &end);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- result = XML_STATUS_OK;
- if (isFinal) {
- ps_parsing = XML_FINISHED;
- return result;
- }
- }
- }
- XmlUpdatePosition(encoding, positionPtr, end, &position);
- nLeftOver = s + len - end;
- if (nLeftOver) {
- if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = (buffer == NULL
- ? (char *)MALLOC(len * 2)
- : (char *)REALLOC(buffer, len * 2));
- if (temp == NULL) {
- errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
- }
- buffer = temp;
- if (!buffer) {
- errorCode = XML_ERROR_NO_MEMORY;
- eventPtr = eventEndPtr = NULL;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- bufferLim = buffer + len * 2;
- }
- memcpy(buffer, end, nLeftOver);
- }
- bufferPtr = buffer;
- bufferEnd = buffer + nLeftOver;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
- eventPtr = bufferPtr;
- eventEndPtr = bufferPtr;
- return result;
- }
- #endif /* not defined XML_CONTEXT_BYTES */
- else {
- void *buff = XML_GetBuffer(parser, len);
- if (buff == NULL)
- return XML_STATUS_ERROR;
- else {
- memcpy(buff, s, len);
- return XML_ParseBuffer(parser, len, isFinal);
- }
- }
- }
- enum XML_Status XMLCALL
- XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
- {
- const char *start;
- enum XML_Status result = XML_STATUS_OK;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- default:
- ps_parsing = XML_PARSING;
- }
- start = bufferPtr;
- positionPtr = start;
- bufferEnd += len;
- parseEndPtr = bufferEnd;
- parseEndByteIndex += len;
- ps_finalBuffer = (XML_Bool)isFinal;
- errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- if (isFinal) {
- ps_parsing = XML_FINISHED;
- return result;
- }
- default: ; /* should not happen */
- }
- }
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return result;
- }
- void * XMLCALL
- XML_GetBuffer(XML_Parser parser, int len)
- {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return NULL;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return NULL;
- default: ;
- }
- if (len > bufferLim - bufferEnd) {
- /* FIXME avoid integer overflow */
- int neededSize = len + (int)(bufferEnd - bufferPtr);
- #ifdef XML_CONTEXT_BYTES
- int keep = (int)(bufferPtr - buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- neededSize += keep;
- #endif /* defined XML_CONTEXT_BYTES */
- if (neededSize <= bufferLim - buffer) {
- #ifdef XML_CONTEXT_BYTES
- if (keep < bufferPtr - buffer) {
- int offset = (int)(bufferPtr - buffer) - keep;
- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
- bufferEnd -= offset;
- bufferPtr -= offset;
- }
- #else
- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
- bufferEnd = buffer + (bufferEnd - bufferPtr);
- bufferPtr = buffer;
- #endif /* not defined XML_CONTEXT_BYTES */
- }
- else {
- char *newBuf;
- int bufferSize = (int)(bufferLim - bufferPtr);
- if (bufferSize == 0)
- bufferSize = INIT_BUFFER_SIZE;
- do {
- bufferSize *= 2;
- } while (bufferSize < neededSize);
- newBuf = (char *)MALLOC(bufferSize);
- if (newBuf == 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- bufferLim = newBuf + bufferSize;
- #ifdef XML_CONTEXT_BYTES
- if (bufferPtr) {
- int keep = (int)(bufferPtr - buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
- FREE(buffer);
- buffer = newBuf;
- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
- bufferPtr = buffer + keep;
- }
- else {
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
- }
- #else
- if (bufferPtr) {
- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
- FREE(buffer);
- }
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
- #endif /* not defined XML_CONTEXT_BYTES */
- }
- }
- return bufferEnd;
- }
- enum XML_Status XMLCALL
- XML_StopParser(XML_Parser parser, XML_Bool resumable)
- {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- if (resumable) {
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- }
- ps_parsing = XML_FINISHED;
- break;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- default:
- if (resumable) {
- #ifdef XML_DTD
- if (isParamEntity) {
- errorCode = XML_ERROR_SUSPEND_PE;
- return XML_STATUS_ERROR;
- }
- #endif
- ps_parsing = XML_SUSPENDED;
- }
- else
- ps_parsing = XML_FINISHED;
- }
- return XML_STATUS_OK;
- }
- enum XML_Status XMLCALL
- XML_ResumeParser(XML_Parser parser)
- {
- enum XML_Status result = XML_STATUS_OK;
- if (ps_parsing != XML_SUSPENDED) {
- errorCode = XML_ERROR_NOT_SUSPENDED;
- return XML_STATUS_ERROR;
- }
- ps_parsing = XML_PARSING;
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- if (ps_finalBuffer) {
- ps_parsing = XML_FINISHED;
- return result;
- }
- default: ;
- }
- }
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return result;
- }
- void XMLCALL
- XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
- {
- assert(status != NULL);
- *status = parser->m_parsingStatus;
- }
- enum XML_Error XMLCALL
- XML_GetErrorCode(XML_Parser parser)
- {
- return errorCode;
- }
- XML_Index XMLCALL
- XML_GetCurrentByteIndex(XML_Parser parser)
- {
- if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
- return -1;
- }
- int XMLCALL
- XML_GetCurrentByteCount(XML_Parser parser)
- {
- if (eventEndPtr && eventPtr)
- return (int)(eventEndPtr - eventPtr);
- return 0;
- }
- const char * XMLCALL
- XML_GetInputContext(XML_Parser parser, int *offset, int *size)
- {
- #ifdef XML_CONTEXT_BYTES
- if (eventPtr && buffer) {
- *offset = (int)(eventPtr - buffer);
- *size = (int)(bufferEnd - buffer);
- return buffer;
- }
- #endif /* defined XML_CONTEXT_BYTES */
- return (char *) 0;
- }
- XML_Size XMLCALL
- XML_GetCurrentLineNumber(XML_Parser parser)
- {
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.lineNumber + 1;
- }
- XML_Size XMLCALL
- XML_GetCurrentColumnNumber(XML_Parser parser)
- {
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.columnNumber;
- }
- void XMLCALL
- XML_FreeContentModel(XML_Parser parser, XML_Content *model)
- {
- FREE(model);
- }
- void * XMLCALL
- XML_MemMalloc(XML_Parser parser, size_t size)
- {
- return MALLOC(size);
- }
- void * XMLCALL
- XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
- {
- return REALLOC(ptr, size);
- }
- void XMLCALL
- XML_MemFree(XML_Parser parser, void *ptr)
- {
- FREE(ptr);
- }
- void XMLCALL
- XML_DefaultCurrent(XML_Parser parser)
- {
- if (defaultHandler) {
- if (openInternalEntities)
- reportDefault(parser,
- internalEncoding,
- openInternalEntities->internalEventPtr,
- openInternalEntities->internalEventEndPtr);
- else
- reportDefault(parser, encoding, eventPtr, eventEndPtr);
- }
- }
- const XML_LChar * XMLCALL
- XML_ErrorString(enum XML_Error code)
- {
- static const XML_LChar* const message[] = {
- 0,
- XML_L("out of memory"),
- XML_L("syntax error"),
- XML_L("no element found"),
- XML_L("not well-formed (invalid token)"),
- XML_L("unclosed token"),
- XML_L("partial character"),
- XML_L("mismatched tag"),
- XML_L("duplicate attribute"),
- XML_L("junk after document element"),
- XML_L("illegal parameter entity reference"),
- XML_L("undefined entity"),
- XML_L("recursive entity reference"),
- XML_L("asynchronous entity"),
- XML_L("reference to invalid character number"),
- XML_L("reference to binary entity"),
- XML_L("reference to external entity in attribute"),
- XML_L("XML or text declaration not at start of entity"),
- XML_L("unknown encoding"),
- XML_L("encoding specified in XML declaration is incorrect"),
- XML_L("unclosed CDATA section"),
- XML_L("error in processing external entity reference"),
- XML_L("document is not standalone"),
- XML_L("unexpected parser state - please send a bug report"),
- XML_L("entity declared in parameter entity"),
- XML_L("requested feature requires XML_DTD support in Expat"),
- XML_L("cannot change setting once parsing has begun"),
- XML_L("unbound prefix"),
- XML_L("must not undeclare prefix"),
- XML_L("incomplete markup in parameter entity"),
- XML_L("XML declaration not well-formed"),
- XML_L("text declaration not well-formed"),
- XML_L("illegal character(s) in public id"),
- XML_L("parser suspended"),
- XML_L("parser not suspended"),
- XML_L("parsing aborted"),
- XML_L("parsing finished"),
- XML_L("cannot suspend in external parameter entity"),
- XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
- XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
- XML_L("prefix must not be bound to one of the reserved namespace names")
- };
- if (code > 0 && code < sizeof(message)/sizeof(message[0]))
- return message[code];
- return NULL;
- }
- const XML_LChar * XMLCALL
- XML_ExpatVersion(void) {
- /* V1 is used to string-ize the version number. However, it would
- string-ize the actual version macro *names* unless we get them
- substituted before being passed to V1. CPP is defined to expand
- a macro, then rescan for more expansions. Thus, we use V2 to expand
- the version macros, then CPP will expand the resulting V1() macro
- with the correct numerals. */
- /* ### I'm assuming cpp is portable in this respect... */
- #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
- #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
- return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
- #undef V1
- #undef V2
- }
- XML_Expat_Version XMLCALL
- XML_ExpatVersionInfo(void)
- {
- XML_Expat_Version version;
- version.major = XML_MAJOR_VERSION;
- version.minor = XML_MINOR_VERSION;
- version.micro = XML_MICRO_VERSION;
- return version;
- }
- const XML_Feature * XMLCALL
- XML_GetFeatureList(void)
- {
- static const XML_Feature features[] = {
- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
- sizeof(XML_Char)},
- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
- sizeof(XML_LChar)},
- #ifdef XML_UNICODE
- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
- #endif
- #ifdef XML_UNICODE_WCHAR_T
- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
- #endif
- #ifdef XML_DTD
- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
- #endif
- #ifdef XML_CONTEXT_BYTES
- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
- XML_CONTEXT_BYTES},
- #endif
- #ifdef XML_MIN_SIZE
- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
- #endif
- #ifdef XML_NS
- {XML_FEATURE_NS, XML_L("XML_NS"), 0},
- #endif
- #ifdef XML_LARGE_SIZE
- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
- #endif
- {XML_FEATURE_END, NULL, 0}
- };
- return features;
- }
- /* Initially tag->rawName always points into the parse buffer;
- for those TAG instances opened while the current parse buffer was
- processed, and not yet closed, we need to store tag->rawName in a more
- permanent location, since the parse buffer is about to be discarded.
- */
- static XML_Bool
- storeRawNames(XML_Parser parser)
- {
- TAG *tag = tagStack;
- while (tag) {
- int bufSize;
- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
- char *rawNameBuf = tag->buf + nameLen;
- /* Stop if already stored. Since tagStack is a stack, we can stop
- at the first entry that has already been copied; everything
- below it in the stack is already been accounted for in a
- previous call to this function.
- */
- if (tag->rawName == rawNameBuf)
- break;
- /* For re-use purposes we need to ensure that the
- size of tag->buf is a multiple of sizeof(XML_Char).
- */
- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
- if (bufSize > tag->bufEnd - tag->buf) {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_FALSE;
- /* if tag->name.str points to tag->buf (only when namespace
- processing is off) then we have to update it
- */
- if (tag->name.str == (XML_Char *)tag->buf)
- tag->name.str = (XML_Char *)temp;
- /* if tag->name.localPart is set (when namespace processing is on)
- then update it as well, since it will always point into tag->buf
- */
- if (tag->name.localPart)
- tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
- (XML_Char *)tag->buf);
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- rawNameBuf = temp + nameLen;
- }
- memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
- tag->rawName = rawNameBuf;
- tag = tag->parent;
- }
- return XML_TRUE;
- }
- static enum XML_Error PTRCALL
- contentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- enum XML_Error result = doContent(parser, 0, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- }
- return result;
- }
- static enum XML_Error PTRCALL
- externalEntityInitProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
- processor = externalEntityInitProcessor2;
- return externalEntityInitProcessor2(parser, start, end, endPtr);
- }
- static enum XML_Error PTRCALL
- externalEntityInitProcessor2(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_BOM:
- /* If we are at the end of the buffer, this would cause the next stage,
- i.e. externalEntityInitProcessor3, to pass control directly to
- doContent (by detecting XML_TOK_NONE) without processing any xml text
- declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
- */
- if (next == end && !ps_finalBuffer) {
- *endPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- break;
- case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityInitProcessor3;
- return externalEntityInitProcessor3(parser, start, end, endPtr);
- }
- static enum XML_Error PTRCALL
- externalEntityInitProcessor3(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- int tok;
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- eventPtr = start;
- tok = XmlContentTok(encoding, start, end, &next);
- eventEndPtr = next;
- switch (tok) {
- case XML_TOK_XML_DECL:
- {
- enum XML_Error result;
- result = processXmlDecl(parser, 1, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *endPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default:
- start = next;
- }
- }
- break;
- case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityContentProcessor;
- tagLevel = 1;
- return externalEntityContentProcessor(parser, start, end, endPtr);
- }
- static enum XML_Error PTRCALL
- externalEntityContentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- enum XML_Error result = doContent(parser, 1, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- }
- return result;
- }
- static enum XML_Error
- doContent(XML_Parser parser,
- int startTagLevel,
- const ENCODING *enc,
- const char *s,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
- {
- /* save one level of indirection */
- DTD * const dtd = _dtd;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- for (;;) {
- const char *next = s; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_TRAILING_CR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- *eventEndPP = end;
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- /* We are at the end of the final buffer, should we check for
- XML_SUSPENDED, XML_FINISHED?
- */
- if (startTagLevel == 0)
- return XML_ERROR_NO_ELEMENTS;
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- *nextPtr = end;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (startTagLevel > 0) {
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_NO_ELEMENTS;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (characterDataHandler)
- characterDataHandler(handlerArg, &ch, 1);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
- poolDiscard(&dtd->pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity or default handler.
- */
- if (!dtd->hasParamEntityRefs || dtd->standalone) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->notation)
- return XML_ERROR_BINARY_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- if (!defaultExpandInternalEntities) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, entity->name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- result = processInternalEntity(parser, entity, XML_FALSE);
- if (result != XML_ERROR_NONE)
- return result;
- }
- else if (externalEntityRefHandler) {
- const XML_Char *context;
- entity->open = XML_TRUE;
- context = getContext(parser);
- entity->open = XML_FALSE;
- if (!context)
- return XML_ERROR_NO_MEMORY;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- context,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- poolDiscard(&tempPool);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- case XML_TOK_START_TAG_NO_ATTS:
- /* fall through */
- case XML_TOK_START_TAG_WITH_ATTS:
- {
- TAG *tag;
- enum XML_Error result;
- XML_Char *toPtr;
- if (freeTagList) {
- tag = freeTagList;
- freeTagList = freeTagList->parent;
- }
- else {
- tag = (TAG *)MALLOC(sizeof(TAG));
- if (!tag)
- return XML_ERROR_NO_MEMORY;
- tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
- if (!tag->buf) {
- FREE(tag);
- return XML_ERROR_NO_MEMORY;
- }
- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
- }
- tag->bindings = NULL;
- tag->parent = tagStack;
- tagStack = tag;
- tag->name.localPart = NULL;
- tag->name.prefix = NULL;
- tag->rawName = s + enc->minBytesPerChar;
- tag->rawNameLength = XmlNameLength(enc, tag->rawName);
- ++tagLevel;
- {
- const char *rawNameEnd = tag->rawName + tag->rawNameLength;
- const char *fromPtr = tag->rawName;
- toPtr = (XML_Char *)tag->buf;
- for (;;) {
- int bufSize;
- int convLen;
- XmlConvert(enc,
- &fromPtr, rawNameEnd,
- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
- convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if (fromPtr == rawNameEnd) {
- tag->name.strLen = convLen;
- break;
- }
- bufSize = (int)(tag->bufEnd - tag->buf) << 1;
- {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- toPtr = (XML_Char *)temp + convLen;
- }
- }
- }
- tag->name.str = (XML_Char *)tag->buf;
- *toPtr = XML_T(' ');
- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
- if (result)
- return result;
- if (startElementHandler)
- startElementHandler(handlerArg, tag->name.str,
- (const XML_Char **)atts);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- break;
- }
- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
- /* fall through */
- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
- {
- const char *rawName = s + enc->minBytesPerChar;
- enum XML_Error result;
- BINDING *bindings = NULL;
- XML_Bool noElmHandlers = XML_TRUE;
- TAG_NAME name;
- name.str = poolStoreString(&tempPool, enc, rawName,
- rawName + XmlNameLength(enc, rawName));
- if (!name.str)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
- return result;
- poolFinish(&tempPool);
- if (startElementHandler) {
- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
- noElmHandlers = XML_FALSE;
- }
- if (endElementHandler) {
- if (startElementHandler)
- *eventPP = *eventEndPP;
- endElementHandler(handlerArg, name.str);
- noElmHandlers = XML_FALSE;
- }
- if (noElmHandlers && defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- }
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- break;
- case XML_TOK_END_TAG:
- if (tagLevel == startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- else {
- int len;
- const char *rawName;
- TAG *tag = tagStack;
- tagStack = tag->parent;
- tag->parent = freeTagList;
- freeTagList = tag;
- rawName = s + enc->minBytesPerChar*2;
- len = XmlNameLength(enc, rawName);
- if (len != tag->rawNameLength
- || memcmp(tag->rawName, rawName, len) != 0) {
- *eventPP = rawName;
- return XML_ERROR_TAG_MISMATCH;
- }
- --tagLevel;
- if (endElementHandler) {
- const XML_Char *localPart;
- const XML_Char *prefix;
- XML_Char *uri;
- localPart = tag->name.localPart;
- if (ns && localPart) {
- /* localPart and prefix may have been overwritten in
- tag->name.str, since this points to the binding->uri
- buffer which gets re-used; so we have to add them again
- */
- uri = (XML_Char *)tag->name.str + tag->name.uriLen;
- /* don't need to check for space - already done in storeAtts() */
- while (*localPart) *uri++ = *localPart++;
- prefix = (XML_Char *)tag->name.prefix;
- if (ns_triplets && prefix) {
- *uri++ = namespaceSeparator;
- while (*prefix) *uri++ = *prefix++;
- }
- *uri = XML_T(' ');
- }
- endElementHandler(handlerArg, tag->name.str);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- while (tag->bindings) {
- BINDING *b = tag->bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- tag->bindings = tag->bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- }
- break;
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(enc, s);
- if (n < 0)
- return XML_ERROR_BAD_CHAR_REF;
- if (characterDataHandler) {
- XML_Char buf[XML_ENCODE_MAX];
- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_XML_DECL:
- return XML_ERROR_MISPLACED_XML_PI;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_CDATA_SECT_OPEN:
- {
- enum XML_Error result;
- if (startCdataSectionHandler)
- startCdataSectionHandler(handlerArg);
- #if 0
- /* Suppose you doing a transformation on a document that involves
- changing only the character data. You set up a defaultHandler
- and a characterDataHandler. The defaultHandler simply copies
- characters through. The characterDataHandler does the
- transformation and writes the characters out escaping them as
- necessary. This case will fail to work if we leave out the
- following two lines (because & and < inside CDATA sections will
- be incorrectly escaped).
- However, now we have a start/endCdataSectionHandler, so it seems
- easier to let the user deal with this.
- */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
- #endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
- if (result != XML_ERROR_NONE)
- return result;
- else if (!next) {
- processor = cdataSectionProcessor;
- return result;
- }
- }
- break;
- case XML_TOK_TRAILING_RSQB:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- characterDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)end - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- /* We are at the end of the final buffer, should we check for
- XML_SUSPENDED, XML_FINISHED?
- */
- if (startTagLevel == 0) {
- *eventPP = end;
- return XML_ERROR_NO_ELEMENTS;
- }
- if (tagLevel != startTagLevel) {
- *eventPP = end;
- return XML_ERROR_ASYNC_ENTITY;
- }
- *nextPtr = end;
- return XML_ERROR_NONE;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- charDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
- break;
- *eventPP = s;
- }
- }
- else
- charDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)next - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- default:
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- *eventPP = s = next;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default: ;
- }
- }
- /* not reached */
- }
- /* Precondition: all arguments must be non-NULL;
- Purpose:
- - normalize attributes
- - check attributes for well-formedness
- - generate namespace aware attribute names (URI, prefix)
- - build list of attributes for startElementHandler
- - default attributes
- - process namespace declarations (check and report them)
- - generate namespace aware element name (URI, prefix)
- */
- static enum XML_Error
- storeAtts(XML_Parser parser, const ENCODING *enc,
- const char *attStr, TAG_NAME *tagNamePtr,
- BINDING **bindingsPtr)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- ELEMENT_TYPE *elementType;
- int nDefaultAtts;
- const XML_Char **appAtts; /* the attribute list for the application */
- int attIndex = 0;
- int prefixLen;
- int i;
- int n;
- XML_Char *uri;
- int nPrefixes = 0;
- BINDING *binding;
- const XML_Char *localPart;
- /* lookup the element type name */
- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
- if (!elementType) {
- const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
- sizeof(ELEMENT_TYPE));
- if (!elementType)
- return XML_ERROR_NO_MEMORY;
- if (ns && !setElementTypePrefix(parser, elementType))
- return XML_ERROR_NO_MEMORY;
- }
- nDefaultAtts = elementType->nDefaultAtts;
- /* get the attributes from the tokenizer */
- n = XmlGetAttributes(enc, attStr, attsSize, atts);
- if (n + nDefaultAtts > attsSize) {
- int oldAttsSize = attsSize;
- ATTRIBUTE *temp;
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- atts = temp;
- if (n > oldAttsSize)
- XmlGetAttributes(enc, attStr, n, atts);
- }
- appAtts = (const XML_Char **)atts;
- for (i = 0; i < n; i++) {
- /* add the name and value to the attribute list */
- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
- atts[i].name
- + XmlNameLength(enc, atts[i].name));
- if (!attId)
- return XML_ERROR_NO_MEMORY;
- /* Detect duplicate attributes by their QNames. This does not work when
- namespace processing is turned on and different prefixes for the same
- namespace are used. For this case we have a check further down.
- */
- if ((attId->name)[-1]) {
- if (enc == encoding)
- eventPtr = atts[i].name;
- return XML_ERROR_DUPLICATE_ATTRIBUTE;
- }
- (attId->name)[-1] = 1;
- appAtts[attIndex++] = attId->name;
- if (!atts[i].normalized) {
- enum XML_Error result;
- XML_Bool isCdata = XML_TRUE;
- /* figure out whether declared as other than CDATA */
- if (attId->maybeTokenized) {
- int j;
- for (j = 0; j < nDefaultAtts; j++) {
- if (attId == elementType->defaultAtts[j].id) {
- isCdata = elementType->defaultAtts[j].isCdata;
- break;
- }
- }
- }
- /* normalize the attribute value */
- result = storeAttributeValue(parser, enc, isCdata,
- atts[i].valuePtr, atts[i].valueEnd,
- &tempPool);
- if (result)
- return result;
- appAtts[attIndex] = poolStart(&tempPool);
- poolFinish(&tempPool);
- }
- else {
- /* the value did not need normalizing */
- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
- atts[i].valueEnd);
- if (appAtts[attIndex] == 0)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- }
- /* handle prefixed attribute names */
- if (attId->prefix) {
- if (attId->xmlns) {
- /* deal with namespace declarations here */
- enum XML_Error result = addBinding(parser, attId->prefix, attId,
- appAtts[attIndex], bindingsPtr);
- if (result)
- return result;
- --attIndex;
- }
- else {
- /* deal with other prefixed names later */
- attIndex++;
- nPrefixes++;
- (attId->name)[-1] = 2;
- }
- }
- else
- attIndex++;
- }
- /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
- nSpecifiedAtts = attIndex;
- if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
- for (i = 0; i < attIndex; i += 2)
- if (appAtts[i] == elementType->idAtt->name) {
- idAttIndex = i;
- break;
- }
- }
- else
- idAttIndex = -1;
- /* do attribute defaulting */
- for (i = 0; i < nDefaultAtts; i++) {
- const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
- if (!(da->id->name)[-1] && da->value) {
- if (da->id->prefix) {
- if (da->id->xmlns) {
- enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
- da->value, bindingsPtr);
- if (result)
- return result;
- }
- else {
- (da->id->name)[-1] = 2;
- nPrefixes++;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- else {
- (da->id->name)[-1] = 1;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- }
- appAtts[attIndex] = 0;
- /* expand prefixed attribute names, check for duplicates,
- and clear flags that say whether attributes were specified */
- i = 0;
- if (nPrefixes) {
- int j; /* hash table index */
- unsigned long version = nsAttsVersion;
- int nsAttsSize = (int)1 << nsAttsPower;
- /* size of hash table must be at least 2 * (# of prefixed attributes) */
- if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
- NS_ATT *temp;
- /* hash table size must also be a power of 2 and >= 8 */
- while (nPrefixes >> nsAttsPower++);
- if (nsAttsPower < 3)
- nsAttsPower = 3;
- nsAttsSize = (int)1 << nsAttsPower;
- temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
- if (!temp)
- return XML_ERROR_NO_MEMORY;
- nsAtts = temp;
- version = 0; /* force re-initialization of nsAtts hash table */
- }
- /* using a version flag saves us from initializing nsAtts every time */
- if (!version) { /* initialize version flags when version wraps around */
- version = INIT_ATTS_VERSION;
- for (j = nsAttsSize; j != 0; )
- nsAtts[--j].version = version;
- }
- nsAttsVersion = --version;
- /* expand prefixed names and check for duplicates */
- for (; i < attIndex; i += 2) {
- const XML_Char *s = appAtts[i];
- if (s[-1] == 2) { /* prefixed */
- ATTRIBUTE_ID *id;
- const BINDING *b;
- unsigned long uriHash = 0;
- ((XML_Char *)s)[-1] = 0; /* clear flag */
- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
- b = id->prefix->binding;
- if (!b)
- return XML_ERROR_UNBOUND_PREFIX;
- /* as we expand the name we also calculate its hash value */
- for (j = 0; j < b->uriLen; j++) {
- const XML_Char c = b->uri[j];
- if (!poolAppendChar(&tempPool, c))
- return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
- }
- while (*s++ != XML_T(ASCII_COLON))
- ;
- do { /* copies null terminator */
- const XML_Char c = *s;
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
- } while (*s++);
- { /* Check hash table for duplicate of expanded name (uriName).
- Derived from code in lookup(HASH_TABLE *table, ...).
- */
- unsigned char step = 0;
- unsigned long mask = nsAttsSize - 1;
- j = uriHash & mask; /* index into hash table */
- while (nsAtts[j].version == version) {
- /* for speed we compare stored hash values first */
- if (uriHash == nsAtts[j].hash) {
- const XML_Char *s1 = poolStart(&tempPool);
- const XML_Char *s2 = nsAtts[j].uriName;
- /* s1 is null terminated, but not s2 */
- for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
- if (*s1 == 0)
- return XML_ERROR_DUPLICATE_ATTRIBUTE;
- }
- if (!step)
- step = PROBE_STEP(uriHash, mask, nsAttsPower);
- j < step ? (j += nsAttsSize - step) : (j -= step);
- }
- }
- if (ns_triplets) { /* append namespace separator and prefix */
- tempPool.ptr[-1] = namespaceSeparator;
- s = b->prefix->name;
- do {
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- } while (*s++);
- }
- /* store expanded name in attribute list */
- s = poolStart(&tempPool);
- poolFinish(&tempPool);
- appAtts[i] = s;
- /* fill empty slot with new version, uriName and hash value */
- nsAtts[j].version = version;
- nsAtts[j].hash = uriHash;
- nsAtts[j].uriName = s;
- if (!--nPrefixes) {
- i += 2;
- break;
- }
- }
- else /* not prefixed */
- ((XML_Char *)s)[-1] = 0; /* clear flag */
- }
- }
- /* clear flags for the remaining attributes */
- for (; i < attIndex; i += 2)
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
- binding->attId->name[-1] = 0;
- if (!ns)
- return XML_ERROR_NONE;
- /* expand the element type name */
- if (elementType->prefix) {
- binding = elementType->prefix->binding;
- if (!binding)
- return XML_ERROR_UNBOUND_PREFIX;
- localPart = tagNamePtr->str;
- while (*localPart++ != XML_T(ASCII_COLON))
- ;
- }
- else if (dtd->defaultPrefix.binding) {
- binding = dtd->defaultPrefix.binding;
- localPart = tagNamePtr->str;
- }
- else
- return XML_ERROR_NONE;
- prefixLen = 0;
- if (ns_triplets && binding->prefix->name) {
- for (; binding->prefix->name[prefixLen++];)
- ; /* prefixLen includes null terminator */
- }
- tagNamePtr->localPart = localPart;
- tagNamePtr->uriLen = binding->uriLen;
- tagNamePtr->prefix = binding->prefix->name;
- tagNamePtr->prefixLen = prefixLen;
- for (i = 0; localPart[i++];)
- ; /* i includes null terminator */
- n = i + binding->uriLen + prefixLen;
- if (n > binding->uriAlloc) {
- TAG *p;
- uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
- if (!uri)
- return XML_ERROR_NO_MEMORY;
- binding->uriAlloc = n + EXPAND_SPARE;
- memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
- for (p = tagStack; p; p = p->parent)
- if (p->name.str == binding->uri)
- p->name.str = uri;
- FREE(binding->uri);
- binding->uri = uri;
- }
- /* if namespaceSeparator != ' ' then uri includes it already */
- uri = binding->uri + binding->uriLen;
- memcpy(uri, localPart, i * sizeof(XML_Char));
- /* we always have a namespace separator between localPart and prefix */
- if (prefixLen) {
- uri += i - 1;
- *uri = namespaceSeparator; /* replace null terminator */
- memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
- }
- tagNamePtr->str = binding->uri;
- return XML_ERROR_NONE;
- }
- /* addBinding() overwrites the value of prefix->binding without checking.
- Therefore one must keep track of the old value outside of addBinding().
- */
- static enum XML_Error
- addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr)
- {
- static const XML_Char xmlNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
- ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
- ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
- ASCII_e, ' '
- };
- static const int xmlLen =
- (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
- static const XML_Char xmlnsNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
- ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
- ASCII_SLASH, ' '
- };
- static const int xmlnsLen =
- (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
- XML_Bool mustBeXML = XML_FALSE;
- XML_Bool isXML = XML_TRUE;
- XML_Bool isXMLNS = XML_TRUE;
-
- BINDING *b;
- int len;
- /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
- if (*uri == XML_T(' ') && prefix->name)
- return XML_ERROR_UNDECLARING_PREFIX;
- if (prefix->name
- && prefix->name[0] == XML_T(ASCII_x)
- && prefix->name[1] == XML_T(ASCII_m)
- && prefix->name[2] == XML_T(ASCII_l)) {
- /* Not allowed to bind xmlns */
- if (prefix->name[3] == XML_T(ASCII_n)
- && prefix->name[4] == XML_T(ASCII_s)
- && prefix->name[5] == XML_T(' '))
- return XML_ERROR_RESERVED_PREFIX_XMLNS;
- if (prefix->name[3] == XML_T(' '))
- mustBeXML = XML_TRUE;
- }
- for (len = 0; uri[len]; len++) {
- if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
- isXML = XML_FALSE;
- if (!mustBeXML && isXMLNS
- && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
- isXMLNS = XML_FALSE;
- }
- isXML = isXML && len == xmlLen;
- isXMLNS = isXMLNS && len == xmlnsLen;
- if (mustBeXML != isXML)
- return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
- : XML_ERROR_RESERVED_NAMESPACE_URI;
- if (isXMLNS)
- return XML_ERROR_RESERVED_NAMESPACE_URI;
- if (namespaceSeparator)
- len++;
- if (freeBindingList) {
- b = freeBindingList;
- if (len > b->uriAlloc) {
- XML_Char *temp = (XML_Char *)REALLOC(b->uri,
- sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- b->uri = temp;
- b->uriAlloc = len + EXPAND_SPARE;
- }
- freeBindingList = b->nextTagBinding;
- }
- else {
- b = (BINDING *)MALLOC(sizeof(BINDING));
- if (!b)
- return XML_ERROR_NO_MEMORY;
- b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri) {
- FREE(b);
- return XML_ERROR_NO_MEMORY;
- }
- b->uriAlloc = len + EXPAND_SPARE;
- }
- b->uriLen = len;
- memcpy(b->uri, uri, len * sizeof(XML_Char));
- if (namespaceSeparator)
- b->uri[len - 1] = namespaceSeparator;
- b->prefix = prefix;
- b->attId = attId;
- b->prevPrefixBinding = prefix->binding;
- /* NULL binding when default namespace undeclared */
- if (*uri == XML_T(' ') && prefix == &_dtd->defaultPrefix)
- prefix->binding = NULL;
- else
- prefix->binding = b;
- b->nextTagBinding = *bindingsPtr;
- *bindingsPtr = b;
- /* if attId == NULL then we are not starting a namespace scope */
- if (attId && startNamespaceDeclHandler)
- startNamespaceDeclHandler(handlerArg, prefix->name,
- prefix->binding ? uri : 0);
- return XML_ERROR_NONE;
- }
- /* The idea here is to avoid using stack for each CDATA section when
- the whole file is parsed with one call.
- */
- static enum XML_Error PTRCALL
- cdataSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
- {
- enum XML_Error result = doCdataSection(parser, encoding, &start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result != XML_ERROR_NONE)
- return result;
- if (start) {
- if (parentParser) { /* we are parsing an external entity */
- processor = externalEntityContentProcessor;
- return externalEntityContentProcessor(parser, start, end, endPtr);
- }
- else {
- processor = contentProcessor;
- return contentProcessor(parser, start, end, endPtr);
- }
- }
- return result;
- }
- /* startPtr gets set to non-null if the section is closed, and to null if
- the section is not yet closed.
- */
- static enum XML_Error
- doCdataSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
- {
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- *eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- *startPtr = NULL;
- for (;;) {
- const char *next;
- int tok = XmlCdataSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_CDATA_SECT_CLOSE:
- if (endCdataSectionHandler)
- endCdataSectionHandler(handlerArg);
- #if 0
- /* see comment under XML_TOK_CDATA_SECT_OPEN */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
- #endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- *startPtr = next;
- *nextPtr = next;
- if (ps_parsing == XML_FINISHED)
- return XML_ERROR_ABORTED;
- else
- return XML_ERROR_NONE;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {