Index: third_party/expat/files/lib/xmlparse.c.original |
diff --git a/third_party/expat/files/lib/xmlparse.c.original b/third_party/expat/files/lib/xmlparse.c.original |
deleted file mode 100644 |
index f35aa36ba8a7fce3bae90f31b20354435b15d2f2..0000000000000000000000000000000000000000 |
--- a/third_party/expat/files/lib/xmlparse.c.original |
+++ /dev/null |
@@ -1,6403 +0,0 @@ |
-/* 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> |
-#include <limits.h> /* UINT_MAX */ |
-#include <time.h> /* time() */ |
- |
-#define XML_BUILDING_EXPAT 1 |
- |
-#ifdef COMPILED_FROM_DSP |
-#include "winconfig.h" |
-#elif defined(MACOS_CLASSIC) |
-#include "macconfig.h" |
-#elif defined(__amigaos__) |
-#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(XML_Parser oldParser, |
- DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); |
-static int |
-copyEntityTable(XML_Parser oldParser, |
- HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); |
-static NAMED * |
-lookup(XML_Parser parser, 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 unsigned long generate_hash_secret_salt(void); |
-static XML_Bool startParsing(XML_Parser parser); |
- |
-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; |
-#ifdef XML_ATTR_INFO |
- XML_AttrInfo *m_attInfo; |
-#endif |
- 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 |
- unsigned long m_hash_secret_salt; |
-}; |
- |
-#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 attInfo (parser->m_attInfo) |
-#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 */ |
-#define hash_secret_salt (parser->m_hash_secret_salt) |
- |
-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, '\0' |
-}; |
- |
-static unsigned long |
-generate_hash_secret_salt(void) |
-{ |
- unsigned int seed = time(NULL) % UINT_MAX; |
- srand(seed); |
- return rand(); |
-} |
- |
-static XML_Bool /* only valid for root parser */ |
-startParsing(XML_Parser parser) |
-{ |
- /* hash functions must be initialized before setContext() is called */ |
- if (hash_secret_salt == 0) |
- hash_secret_salt = generate_hash_secret_salt(); |
- if (ns) { |
- /* implicit context only set for root parser, since child |
- parsers (i.e. external entity parsers) will inherit it |
- */ |
- return setContext(parser, implicitContext); |
- } |
- return XML_TRUE; |
-} |
- |
-XML_Parser XMLCALL |
-XML_ParserCreate_MM(const XML_Char *encodingName, |
- const XML_Memory_Handling_Suite *memsuite, |
- const XML_Char *nameSep) |
-{ |
- return parserCreate(encodingName, memsuite, nameSep, NULL); |
-} |
- |
-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; |
- } |
-#ifdef XML_ATTR_INFO |
- attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo)); |
- if (attInfo == NULL) { |
- FREE(atts); |
- FREE(parser); |
- return NULL; |
- } |
-#endif |
- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); |
- if (dataBuf == NULL) { |
- FREE(atts); |
-#ifdef XML_ATTR_INFO |
- FREE(attInfo); |
-#endif |
- 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); |
-#ifdef XML_ATTR_INFO |
- FREE(attInfo); |
-#endif |
- 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 |
- hash_secret_salt = 0; |
-} |
- |
-/* 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 XML_TRUE; |
-} |
- |
-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; |
- /* Note that the new parser shares the same hash secret as the old |
- parser, so that dtdCopy and copyEntityTable can lookup values |
- from hash tables associated with either parser without us having |
- to worry which hash secrets each table has. |
- */ |
- unsigned long oldhash_secret_salt = hash_secret_salt; |
- |
-#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; |
- hash_secret_salt = oldhash_secret_salt; |
- parentParser = oldParser; |
-#ifdef XML_DTD |
- paramEntityParsing = oldParamEntityParsing; |
- prologState.inEntityValue = oldInEntityValue; |
- if (context) { |
-#endif /* XML_DTD */ |
- if (!dtdCopy(oldParser, _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); |
-#ifdef XML_ATTR_INFO |
- FREE((void *)attInfo); |
-#endif |
- 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; |
-} |
- |
-#ifdef XML_ATTR_INFO |
-const XML_AttrInfo * XMLCALL |
-XML_GetAttributeInfo(XML_Parser parser) |
-{ |
- return attInfo; |
-} |
-#endif |
- |
-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 |
-} |
- |
-int XMLCALL |
-XML_SetHashSalt(XML_Parser parser, |
- unsigned long hash_salt) |
-{ |
- /* block after XML_Parse()/XML_ParseBuffer() has been called */ |
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) |
- return 0; |
- hash_secret_salt = hash_salt; |
- return 1; |
-} |
- |
-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; |
- case XML_INITIALIZED: |
- if (parentParser == NULL && !startParsing(parser)) { |
- errorCode = XML_ERROR_NO_MEMORY; |
- 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: |
- if (isFinal) { |
- ps_parsing = XML_FINISHED; |
- return XML_STATUS_OK; |
- } |
- /* fall through */ |
- default: |
- result = XML_STATUS_OK; |
- } |
- } |
- |
- 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; |
- eventPtr = eventEndPtr = NULL; |
- processor = errorProcessor; |
- return XML_STATUS_ERROR; |
- } |
- buffer = temp; |
- 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; |
- case XML_INITIALIZED: |
- if (parentParser == NULL && !startParsing(parser)) { |
- errorCode = XML_ERROR_NO_MEMORY; |
- 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 */ |
- } |
- eventPtr = eventEndPtr = NULL; |
- positionPtr = NULL; |
- } |
- 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 |
-#ifdef XML_ATTR_INFO |
- {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 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(parser, &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('\0'); |
- 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('\0'); |
- } |
- 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(parser, &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(parser, &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; |
-#ifdef XML_ATTR_INFO |
- XML_AttrInfo *temp2; |
-#endif |
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; |
- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); |
- if (temp == NULL) |
- return XML_ERROR_NO_MEMORY; |
- atts = temp; |
-#ifdef XML_ATTR_INFO |
- temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo)); |
- if (temp2 == NULL) |
- return XML_ERROR_NO_MEMORY; |
- attInfo = temp2; |
-#endif |
- if (n > oldAttsSize) |
- XmlGetAttributes(enc, attStr, n, atts); |
- } |
- |
- appAtts = (const XML_Char **)atts; |
- for (i = 0; i < n; i++) { |
- ATTRIBUTE *currAtt = &atts[i]; |
-#ifdef XML_ATTR_INFO |
- XML_AttrInfo *currAttInfo = &attInfo[i]; |
-#endif |
- /* add the name and value to the attribute list */ |
- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, |
- currAtt->name |
- + XmlNameLength(enc, currAtt->name)); |
- if (!attId) |
- return XML_ERROR_NO_MEMORY; |
-#ifdef XML_ATTR_INFO |
- currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name); |
- currAttInfo->nameEnd = currAttInfo->nameStart + |
- XmlNameLength(enc, currAtt->name); |
- currAttInfo->valueStart = parseEndByteIndex - |
- (parseEndPtr - currAtt->valuePtr); |
- currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd); |
-#endif |
- /* 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 = hash_secret_salt; |
- ((XML_Char *)s)[-1] = 0; /* clear flag */ |
- id = (ATTRIBUTE_ID *)lookup(parser, &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(parser, 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 != '\0' 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, '\0' |
- }; |
- 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, '\0' |
- }; |
- 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('\0') && 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('\0')) |
- return XML_ERROR_RESERVED_PREFIX_XMLNS; |
- |
- if (prefix->name[3] == XML_T('\0')) |
- 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('\0') && 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)) { |
- for (;;) { |
- ICHAR *dataPtr = (ICHAR *)dataBuf; |
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); |
- *eventEndPP = next; |
- 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_INVALID: |
- *eventPP = next; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- if (haveMore) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_PARTIAL_CHAR; |
- case XML_TOK_PARTIAL: |
- case XML_TOK_NONE: |
- if (haveMore) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_UNCLOSED_CDATA_SECTION; |
- default: |
- *eventPP = next; |
- return XML_ERROR_UNEXPECTED_STATE; |
- } |
- |
- *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 */ |
-} |
- |
-#ifdef XML_DTD |
- |
-/* The idea here is to avoid using stack for each IGNORE section when |
- the whole file is parsed with one call. |
-*/ |
-static enum XML_Error PTRCALL |
-ignoreSectionProcessor(XML_Parser parser, |
- const char *start, |
- const char *end, |
- const char **endPtr) |
-{ |
- enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, |
- endPtr, (XML_Bool)!ps_finalBuffer); |
- if (result != XML_ERROR_NONE) |
- return result; |
- if (start) { |
- processor = prologProcessor; |
- return prologProcessor(parser, start, end, endPtr); |
- } |
- return result; |
-} |
- |
-/* startPtr gets set to non-null is the section is closed, and to null |
- if the section is not yet closed. |
-*/ |
-static enum XML_Error |
-doIgnoreSection(XML_Parser parser, |
- const ENCODING *enc, |
- const char **startPtr, |
- const char *end, |
- const char **nextPtr, |
- XML_Bool haveMore) |
-{ |
- const char *next; |
- int tok; |
- 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; |
- tok = XmlIgnoreSectionTok(enc, s, end, &next); |
- *eventEndPP = next; |
- switch (tok) { |
- case XML_TOK_IGNORE_SECT: |
- 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_INVALID: |
- *eventPP = next; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- if (haveMore) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_PARTIAL_CHAR; |
- case XML_TOK_PARTIAL: |
- case XML_TOK_NONE: |
- if (haveMore) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ |
- default: |
- *eventPP = next; |
- return XML_ERROR_UNEXPECTED_STATE; |
- } |
- /* not reached */ |
-} |
- |
-#endif /* XML_DTD */ |
- |
-static enum XML_Error |
-initializeEncoding(XML_Parser parser) |
-{ |
- const char *s; |
-#ifdef XML_UNICODE |
- char encodingBuf[128]; |
- if (!protocolEncodingName) |
- s = NULL; |
- else { |
- int i; |
- for (i = 0; protocolEncodingName[i]; i++) { |
- if (i == sizeof(encodingBuf) - 1 |
- || (protocolEncodingName[i] & ~0x7f) != 0) { |
- encodingBuf[0] = '\0'; |
- break; |
- } |
- encodingBuf[i] = (char)protocolEncodingName[i]; |
- } |
- encodingBuf[i] = '\0'; |
- s = encodingBuf; |
- } |
-#else |
- s = protocolEncodingName; |
-#endif |
- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) |
- return XML_ERROR_NONE; |
- return handleUnknownEncoding(parser, protocolEncodingName); |
-} |
- |
-static enum XML_Error |
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity, |
- const char *s, const char *next) |
-{ |
- const char *encodingName = NULL; |
- const XML_Char *storedEncName = NULL; |
- const ENCODING *newEncoding = NULL; |
- const char *version = NULL; |
- const char *versionend; |
- const XML_Char *storedversion = NULL; |
- int standalone = -1; |
- if (!(ns |
- ? XmlParseXmlDeclNS |
- : XmlParseXmlDecl)(isGeneralTextEntity, |
- encoding, |
- s, |
- next, |
- &eventPtr, |
- &version, |
- &versionend, |
- &encodingName, |
- &newEncoding, |
- &standalone)) { |
- if (isGeneralTextEntity) |
- return XML_ERROR_TEXT_DECL; |
- else |
- return XML_ERROR_XML_DECL; |
- } |
- if (!isGeneralTextEntity && standalone == 1) { |
- _dtd->standalone = XML_TRUE; |
-#ifdef XML_DTD |
- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) |
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; |
-#endif /* XML_DTD */ |
- } |
- if (xmlDeclHandler) { |
- if (encodingName != NULL) { |
- storedEncName = poolStoreString(&temp2Pool, |
- encoding, |
- encodingName, |
- encodingName |
- + XmlNameLength(encoding, encodingName)); |
- if (!storedEncName) |
- return XML_ERROR_NO_MEMORY; |
- poolFinish(&temp2Pool); |
- } |
- if (version) { |
- storedversion = poolStoreString(&temp2Pool, |
- encoding, |
- version, |
- versionend - encoding->minBytesPerChar); |
- if (!storedversion) |
- return XML_ERROR_NO_MEMORY; |
- } |
- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); |
- } |
- else if (defaultHandler) |
- reportDefault(parser, encoding, s, next); |
- if (protocolEncodingName == NULL) { |
- if (newEncoding) { |
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { |
- eventPtr = encodingName; |
- return XML_ERROR_INCORRECT_ENCODING; |
- } |
- encoding = newEncoding; |
- } |
- else if (encodingName) { |
- enum XML_Error result; |
- if (!storedEncName) { |
- storedEncName = poolStoreString( |
- &temp2Pool, encoding, encodingName, |
- encodingName + XmlNameLength(encoding, encodingName)); |
- if (!storedEncName) |
- return XML_ERROR_NO_MEMORY; |
- } |
- result = handleUnknownEncoding(parser, storedEncName); |
- poolClear(&temp2Pool); |
- if (result == XML_ERROR_UNKNOWN_ENCODING) |
- eventPtr = encodingName; |
- return result; |
- } |
- } |
- |
- if (storedEncName || storedversion) |
- poolClear(&temp2Pool); |
- |
- return XML_ERROR_NONE; |
-} |
- |
-static enum XML_Error |
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) |
-{ |
- if (unknownEncodingHandler) { |
- XML_Encoding info; |
- int i; |
- for (i = 0; i < 256; i++) |
- info.map[i] = -1; |
- info.convert = NULL; |
- info.data = NULL; |
- info.release = NULL; |
- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, |
- &info)) { |
- ENCODING *enc; |
- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); |
- if (!unknownEncodingMem) { |
- if (info.release) |
- info.release(info.data); |
- return XML_ERROR_NO_MEMORY; |
- } |
- enc = (ns |
- ? XmlInitUnknownEncodingNS |
- : XmlInitUnknownEncoding)(unknownEncodingMem, |
- info.map, |
- info.convert, |
- info.data); |
- if (enc) { |
- unknownEncodingData = info.data; |
- unknownEncodingRelease = info.release; |
- encoding = enc; |
- return XML_ERROR_NONE; |
- } |
- } |
- if (info.release != NULL) |
- info.release(info.data); |
- } |
- return XML_ERROR_UNKNOWN_ENCODING; |
-} |
- |
-static enum XML_Error PTRCALL |
-prologInitProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- enum XML_Error result = initializeEncoding(parser); |
- if (result != XML_ERROR_NONE) |
- return result; |
- processor = prologProcessor; |
- return prologProcessor(parser, s, end, nextPtr); |
-} |
- |
-#ifdef XML_DTD |
- |
-static enum XML_Error PTRCALL |
-externalParEntInitProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- enum XML_Error result = initializeEncoding(parser); |
- if (result != XML_ERROR_NONE) |
- return result; |
- |
- /* we know now that XML_Parse(Buffer) has been called, |
- so we consider the external parameter entity read */ |
- _dtd->paramEntityRead = XML_TRUE; |
- |
- if (prologState.inEntityValue) { |
- processor = entityValueInitProcessor; |
- return entityValueInitProcessor(parser, s, end, nextPtr); |
- } |
- else { |
- processor = externalParEntProcessor; |
- return externalParEntProcessor(parser, s, end, nextPtr); |
- } |
-} |
- |
-static enum XML_Error PTRCALL |
-entityValueInitProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- int tok; |
- const char *start = s; |
- const char *next = start; |
- eventPtr = start; |
- |
- for (;;) { |
- tok = XmlPrologTok(encoding, start, end, &next); |
- eventEndPtr = next; |
- if (tok <= 0) { |
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- switch (tok) { |
- case XML_TOK_INVALID: |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- return XML_ERROR_UNCLOSED_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- return XML_ERROR_PARTIAL_CHAR; |
- case XML_TOK_NONE: /* start == end */ |
- default: |
- break; |
- } |
- /* found end of entity value - can store it now */ |
- return storeEntityValue(parser, encoding, s, end); |
- } |
- else if (tok == XML_TOK_XML_DECL) { |
- enum XML_Error result; |
- result = processXmlDecl(parser, 0, start, next); |
- if (result != XML_ERROR_NONE) |
- return result; |
- switch (ps_parsing) { |
- case XML_SUSPENDED: |
- *nextPtr = next; |
- return XML_ERROR_NONE; |
- case XML_FINISHED: |
- return XML_ERROR_ABORTED; |
- default: |
- *nextPtr = next; |
- } |
- /* stop scanning for text declaration - we found one */ |
- processor = entityValueProcessor; |
- return entityValueProcessor(parser, next, end, nextPtr); |
- } |
- /* If we are at the end of the buffer, this would cause XmlPrologTok to |
- return XML_TOK_NONE on the next call, which would then cause the |
- function to exit with *nextPtr set to s - that is what we want for other |
- tokens, but not for the BOM - we would rather like to skip it; |
- then, when this routine is entered the next time, XmlPrologTok will |
- return XML_TOK_INVALID, since the BOM is still in the buffer |
- */ |
- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { |
- *nextPtr = next; |
- return XML_ERROR_NONE; |
- } |
- start = next; |
- eventPtr = start; |
- } |
-} |
- |
-static enum XML_Error PTRCALL |
-externalParEntProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- const char *next = s; |
- int tok; |
- |
- tok = XmlPrologTok(encoding, s, end, &next); |
- if (tok <= 0) { |
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- switch (tok) { |
- case XML_TOK_INVALID: |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- return XML_ERROR_UNCLOSED_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- return XML_ERROR_PARTIAL_CHAR; |
- case XML_TOK_NONE: /* start == end */ |
- default: |
- break; |
- } |
- } |
- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. |
- However, when parsing an external subset, doProlog will not accept a BOM |
- as valid, and report a syntax error, so we have to skip the BOM |
- */ |
- else if (tok == XML_TOK_BOM) { |
- s = next; |
- tok = XmlPrologTok(encoding, s, end, &next); |
- } |
- |
- processor = prologProcessor; |
- return doProlog(parser, encoding, s, end, tok, next, |
- nextPtr, (XML_Bool)!ps_finalBuffer); |
-} |
- |
-static enum XML_Error PTRCALL |
-entityValueProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- const char *start = s; |
- const char *next = s; |
- const ENCODING *enc = encoding; |
- int tok; |
- |
- for (;;) { |
- tok = XmlPrologTok(enc, start, end, &next); |
- if (tok <= 0) { |
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- switch (tok) { |
- case XML_TOK_INVALID: |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- return XML_ERROR_UNCLOSED_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- return XML_ERROR_PARTIAL_CHAR; |
- case XML_TOK_NONE: /* start == end */ |
- default: |
- break; |
- } |
- /* found end of entity value - can store it now */ |
- return storeEntityValue(parser, enc, s, end); |
- } |
- start = next; |
- } |
-} |
- |
-#endif /* XML_DTD */ |
- |
-static enum XML_Error PTRCALL |
-prologProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- const char *next = s; |
- int tok = XmlPrologTok(encoding, s, end, &next); |
- return doProlog(parser, encoding, s, end, tok, next, |
- nextPtr, (XML_Bool)!ps_finalBuffer); |
-} |
- |
-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) |
-{ |
-#ifdef XML_DTD |
- static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; |
-#endif /* XML_DTD */ |
- static const XML_Char atypeCDATA[] = |
- { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; |
- static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; |
- static const XML_Char atypeIDREF[] = |
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; |
- static const XML_Char atypeIDREFS[] = |
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; |
- static const XML_Char atypeENTITY[] = |
- { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; |
- static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, |
- ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; |
- static const XML_Char atypeNMTOKEN[] = { |
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; |
- static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, |
- ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; |
- static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, |
- ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; |
- static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; |
- static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; |
- |
- /* save one level of indirection */ |
- DTD * const dtd = _dtd; |
- |
- const char **eventPP; |
- const char **eventEndPP; |
- enum XML_Content_Quant quant; |
- |
- if (enc == encoding) { |
- eventPP = &eventPtr; |
- eventEndPP = &eventEndPtr; |
- } |
- else { |
- eventPP = &(openInternalEntities->internalEventPtr); |
- eventEndPP = &(openInternalEntities->internalEventEndPtr); |
- } |
- |
- for (;;) { |
- int role; |
- XML_Bool handleDefault = XML_TRUE; |
- *eventPP = s; |
- *eventEndPP = next; |
- if (tok <= 0) { |
- if (haveMore && tok != XML_TOK_INVALID) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- switch (tok) { |
- case XML_TOK_INVALID: |
- *eventPP = next; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- return XML_ERROR_UNCLOSED_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- return XML_ERROR_PARTIAL_CHAR; |
- case -XML_TOK_PROLOG_S: |
- tok = -tok; |
- break; |
- case XML_TOK_NONE: |
-#ifdef XML_DTD |
- /* for internal PE NOT referenced between declarations */ |
- if (enc != encoding && !openInternalEntities->betweenDecl) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- /* WFC: PE Between Declarations - must check that PE contains |
- complete markup, not only for external PEs, but also for |
- internal PEs if the reference occurs between declarations. |
- */ |
- if (isParamEntity || enc != encoding) { |
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) |
- == XML_ROLE_ERROR) |
- return XML_ERROR_INCOMPLETE_PE; |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
-#endif /* XML_DTD */ |
- return XML_ERROR_NO_ELEMENTS; |
- default: |
- tok = -tok; |
- next = end; |
- break; |
- } |
- } |
- role = XmlTokenRole(&prologState, tok, s, next, enc); |
- switch (role) { |
- case XML_ROLE_XML_DECL: |
- { |
- enum XML_Error result = processXmlDecl(parser, 0, s, next); |
- if (result != XML_ERROR_NONE) |
- return result; |
- enc = encoding; |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_DOCTYPE_NAME: |
- if (startDoctypeDeclHandler) { |
- doctypeName = poolStoreString(&tempPool, enc, s, next); |
- if (!doctypeName) |
- return XML_ERROR_NO_MEMORY; |
- poolFinish(&tempPool); |
- doctypePubid = NULL; |
- handleDefault = XML_FALSE; |
- } |
- doctypeSysid = NULL; /* always initialize to NULL */ |
- break; |
- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: |
- if (startDoctypeDeclHandler) { |
- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, |
- doctypePubid, 1); |
- doctypeName = NULL; |
- poolClear(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- break; |
-#ifdef XML_DTD |
- case XML_ROLE_TEXT_DECL: |
- { |
- enum XML_Error result = processXmlDecl(parser, 1, s, next); |
- if (result != XML_ERROR_NONE) |
- return result; |
- enc = encoding; |
- handleDefault = XML_FALSE; |
- } |
- break; |
-#endif /* XML_DTD */ |
- case XML_ROLE_DOCTYPE_PUBLIC_ID: |
-#ifdef XML_DTD |
- useForeignDTD = XML_FALSE; |
- declEntity = (ENTITY *)lookup(parser, |
- &dtd->paramEntities, |
- externalSubsetName, |
- sizeof(ENTITY)); |
- if (!declEntity) |
- return XML_ERROR_NO_MEMORY; |
-#endif /* XML_DTD */ |
- dtd->hasParamEntityRefs = XML_TRUE; |
- if (startDoctypeDeclHandler) { |
- XML_Char *pubId; |
- if (!XmlIsPublicId(enc, s, next, eventPP)) |
- return XML_ERROR_PUBLICID; |
- pubId = poolStoreString(&tempPool, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!pubId) |
- return XML_ERROR_NO_MEMORY; |
- normalizePublicId(pubId); |
- poolFinish(&tempPool); |
- doctypePubid = pubId; |
- handleDefault = XML_FALSE; |
- goto alreadyChecked; |
- } |
- /* fall through */ |
- case XML_ROLE_ENTITY_PUBLIC_ID: |
- if (!XmlIsPublicId(enc, s, next, eventPP)) |
- return XML_ERROR_PUBLICID; |
- alreadyChecked: |
- if (dtd->keepProcessing && declEntity) { |
- XML_Char *tem = poolStoreString(&dtd->pool, |
- enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!tem) |
- return XML_ERROR_NO_MEMORY; |
- normalizePublicId(tem); |
- declEntity->publicId = tem; |
- poolFinish(&dtd->pool); |
- if (entityDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_DOCTYPE_CLOSE: |
- if (doctypeName) { |
- startDoctypeDeclHandler(handlerArg, doctypeName, |
- doctypeSysid, doctypePubid, 0); |
- poolClear(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- /* doctypeSysid will be non-NULL in the case of a previous |
- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler |
- was not set, indicating an external subset |
- */ |
-#ifdef XML_DTD |
- if (doctypeSysid || useForeignDTD) { |
- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; |
- dtd->hasParamEntityRefs = XML_TRUE; |
- if (paramEntityParsing && externalEntityRefHandler) { |
- ENTITY *entity = (ENTITY *)lookup(parser, |
- &dtd->paramEntities, |
- externalSubsetName, |
- sizeof(ENTITY)); |
- if (!entity) |
- return XML_ERROR_NO_MEMORY; |
- if (useForeignDTD) |
- entity->base = curBase; |
- dtd->paramEntityRead = XML_FALSE; |
- if (!externalEntityRefHandler(externalEntityRefHandlerArg, |
- 0, |
- entity->base, |
- entity->systemId, |
- entity->publicId)) |
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
- if (dtd->paramEntityRead) { |
- if (!dtd->standalone && |
- notStandaloneHandler && |
- !notStandaloneHandler(handlerArg)) |
- return XML_ERROR_NOT_STANDALONE; |
- } |
- /* if we didn't read the foreign DTD then this means that there |
- is no external subset and we must reset dtd->hasParamEntityRefs |
- */ |
- else if (!doctypeSysid) |
- dtd->hasParamEntityRefs = hadParamEntityRefs; |
- /* end of DTD - no need to update dtd->keepProcessing */ |
- } |
- useForeignDTD = XML_FALSE; |
- } |
-#endif /* XML_DTD */ |
- if (endDoctypeDeclHandler) { |
- endDoctypeDeclHandler(handlerArg); |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_INSTANCE_START: |
-#ifdef XML_DTD |
- /* if there is no DOCTYPE declaration then now is the |
- last chance to read the foreign DTD |
- */ |
- if (useForeignDTD) { |
- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; |
- dtd->hasParamEntityRefs = XML_TRUE; |
- if (paramEntityParsing && externalEntityRefHandler) { |
- ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, |
- externalSubsetName, |
- sizeof(ENTITY)); |
- if (!entity) |
- return XML_ERROR_NO_MEMORY; |
- entity->base = curBase; |
- dtd->paramEntityRead = XML_FALSE; |
- if (!externalEntityRefHandler(externalEntityRefHandlerArg, |
- 0, |
- entity->base, |
- entity->systemId, |
- entity->publicId)) |
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
- if (dtd->paramEntityRead) { |
- if (!dtd->standalone && |
- notStandaloneHandler && |
- !notStandaloneHandler(handlerArg)) |
- return XML_ERROR_NOT_STANDALONE; |
- } |
- /* if we didn't read the foreign DTD then this means that there |
- is no external subset and we must reset dtd->hasParamEntityRefs |
- */ |
- else |
- dtd->hasParamEntityRefs = hadParamEntityRefs; |
- /* end of DTD - no need to update dtd->keepProcessing */ |
- } |
- } |
-#endif /* XML_DTD */ |
- processor = contentProcessor; |
- return contentProcessor(parser, s, end, nextPtr); |
- case XML_ROLE_ATTLIST_ELEMENT_NAME: |
- declElementType = getElementType(parser, enc, s, next); |
- if (!declElementType) |
- return XML_ERROR_NO_MEMORY; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_NAME: |
- declAttributeId = getAttributeId(parser, enc, s, next); |
- if (!declAttributeId) |
- return XML_ERROR_NO_MEMORY; |
- declAttributeIsCdata = XML_FALSE; |
- declAttributeType = NULL; |
- declAttributeIsId = XML_FALSE; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_CDATA: |
- declAttributeIsCdata = XML_TRUE; |
- declAttributeType = atypeCDATA; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_ID: |
- declAttributeIsId = XML_TRUE; |
- declAttributeType = atypeID; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_IDREF: |
- declAttributeType = atypeIDREF; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: |
- declAttributeType = atypeIDREFS; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: |
- declAttributeType = atypeENTITY; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: |
- declAttributeType = atypeENTITIES; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: |
- declAttributeType = atypeNMTOKEN; |
- goto checkAttListDeclHandler; |
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: |
- declAttributeType = atypeNMTOKENS; |
- checkAttListDeclHandler: |
- if (dtd->keepProcessing && attlistDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_ATTRIBUTE_ENUM_VALUE: |
- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: |
- if (dtd->keepProcessing && attlistDeclHandler) { |
- const XML_Char *prefix; |
- if (declAttributeType) { |
- prefix = enumValueSep; |
- } |
- else { |
- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE |
- ? notationPrefix |
- : enumValueStart); |
- } |
- if (!poolAppendString(&tempPool, prefix)) |
- return XML_ERROR_NO_MEMORY; |
- if (!poolAppend(&tempPool, enc, s, next)) |
- return XML_ERROR_NO_MEMORY; |
- declAttributeType = tempPool.start; |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: |
- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: |
- if (dtd->keepProcessing) { |
- if (!defineAttribute(declElementType, declAttributeId, |
- declAttributeIsCdata, declAttributeIsId, |
- 0, parser)) |
- return XML_ERROR_NO_MEMORY; |
- if (attlistDeclHandler && declAttributeType) { |
- if (*declAttributeType == XML_T(ASCII_LPAREN) |
- || (*declAttributeType == XML_T(ASCII_N) |
- && declAttributeType[1] == XML_T(ASCII_O))) { |
- /* Enumerated or Notation type */ |
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) |
- || !poolAppendChar(&tempPool, XML_T('\0'))) |
- return XML_ERROR_NO_MEMORY; |
- declAttributeType = tempPool.start; |
- poolFinish(&tempPool); |
- } |
- *eventEndPP = s; |
- attlistDeclHandler(handlerArg, declElementType->name, |
- declAttributeId->name, declAttributeType, |
- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); |
- poolClear(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- } |
- break; |
- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: |
- case XML_ROLE_FIXED_ATTRIBUTE_VALUE: |
- if (dtd->keepProcessing) { |
- const XML_Char *attVal; |
- enum XML_Error result = |
- storeAttributeValue(parser, enc, declAttributeIsCdata, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar, |
- &dtd->pool); |
- if (result) |
- return result; |
- attVal = poolStart(&dtd->pool); |
- poolFinish(&dtd->pool); |
- /* ID attributes aren't allowed to have a default */ |
- if (!defineAttribute(declElementType, declAttributeId, |
- declAttributeIsCdata, XML_FALSE, attVal, parser)) |
- return XML_ERROR_NO_MEMORY; |
- if (attlistDeclHandler && declAttributeType) { |
- if (*declAttributeType == XML_T(ASCII_LPAREN) |
- || (*declAttributeType == XML_T(ASCII_N) |
- && declAttributeType[1] == XML_T(ASCII_O))) { |
- /* Enumerated or Notation type */ |
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) |
- || !poolAppendChar(&tempPool, XML_T('\0'))) |
- return XML_ERROR_NO_MEMORY; |
- declAttributeType = tempPool.start; |
- poolFinish(&tempPool); |
- } |
- *eventEndPP = s; |
- attlistDeclHandler(handlerArg, declElementType->name, |
- declAttributeId->name, declAttributeType, |
- attVal, |
- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); |
- poolClear(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- } |
- break; |
- case XML_ROLE_ENTITY_VALUE: |
- if (dtd->keepProcessing) { |
- enum XML_Error result = storeEntityValue(parser, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (declEntity) { |
- declEntity->textPtr = poolStart(&dtd->entityValuePool); |
- declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); |
- poolFinish(&dtd->entityValuePool); |
- if (entityDeclHandler) { |
- *eventEndPP = s; |
- entityDeclHandler(handlerArg, |
- declEntity->name, |
- declEntity->is_param, |
- declEntity->textPtr, |
- declEntity->textLen, |
- curBase, 0, 0, 0); |
- handleDefault = XML_FALSE; |
- } |
- } |
- else |
- poolDiscard(&dtd->entityValuePool); |
- if (result != XML_ERROR_NONE) |
- return result; |
- } |
- break; |
- case XML_ROLE_DOCTYPE_SYSTEM_ID: |
-#ifdef XML_DTD |
- useForeignDTD = XML_FALSE; |
-#endif /* XML_DTD */ |
- dtd->hasParamEntityRefs = XML_TRUE; |
- if (startDoctypeDeclHandler) { |
- doctypeSysid = poolStoreString(&tempPool, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (doctypeSysid == NULL) |
- return XML_ERROR_NO_MEMORY; |
- poolFinish(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
-#ifdef XML_DTD |
- else |
- /* use externalSubsetName to make doctypeSysid non-NULL |
- for the case where no startDoctypeDeclHandler is set */ |
- doctypeSysid = externalSubsetName; |
-#endif /* XML_DTD */ |
- if (!dtd->standalone |
-#ifdef XML_DTD |
- && !paramEntityParsing |
-#endif /* XML_DTD */ |
- && notStandaloneHandler |
- && !notStandaloneHandler(handlerArg)) |
- return XML_ERROR_NOT_STANDALONE; |
-#ifndef XML_DTD |
- break; |
-#else /* XML_DTD */ |
- if (!declEntity) { |
- declEntity = (ENTITY *)lookup(parser, |
- &dtd->paramEntities, |
- externalSubsetName, |
- sizeof(ENTITY)); |
- if (!declEntity) |
- return XML_ERROR_NO_MEMORY; |
- declEntity->publicId = NULL; |
- } |
- /* fall through */ |
-#endif /* XML_DTD */ |
- case XML_ROLE_ENTITY_SYSTEM_ID: |
- if (dtd->keepProcessing && declEntity) { |
- declEntity->systemId = poolStoreString(&dtd->pool, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!declEntity->systemId) |
- return XML_ERROR_NO_MEMORY; |
- declEntity->base = curBase; |
- poolFinish(&dtd->pool); |
- if (entityDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_ENTITY_COMPLETE: |
- if (dtd->keepProcessing && declEntity && entityDeclHandler) { |
- *eventEndPP = s; |
- entityDeclHandler(handlerArg, |
- declEntity->name, |
- declEntity->is_param, |
- 0,0, |
- declEntity->base, |
- declEntity->systemId, |
- declEntity->publicId, |
- 0); |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_ENTITY_NOTATION_NAME: |
- if (dtd->keepProcessing && declEntity) { |
- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); |
- if (!declEntity->notation) |
- return XML_ERROR_NO_MEMORY; |
- poolFinish(&dtd->pool); |
- if (unparsedEntityDeclHandler) { |
- *eventEndPP = s; |
- unparsedEntityDeclHandler(handlerArg, |
- declEntity->name, |
- declEntity->base, |
- declEntity->systemId, |
- declEntity->publicId, |
- declEntity->notation); |
- handleDefault = XML_FALSE; |
- } |
- else if (entityDeclHandler) { |
- *eventEndPP = s; |
- entityDeclHandler(handlerArg, |
- declEntity->name, |
- 0,0,0, |
- declEntity->base, |
- declEntity->systemId, |
- declEntity->publicId, |
- declEntity->notation); |
- handleDefault = XML_FALSE; |
- } |
- } |
- break; |
- case XML_ROLE_GENERAL_ENTITY_NAME: |
- { |
- if (XmlPredefinedEntityName(enc, s, next)) { |
- declEntity = NULL; |
- break; |
- } |
- if (dtd->keepProcessing) { |
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); |
- if (!name) |
- return XML_ERROR_NO_MEMORY; |
- declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, |
- sizeof(ENTITY)); |
- if (!declEntity) |
- return XML_ERROR_NO_MEMORY; |
- if (declEntity->name != name) { |
- poolDiscard(&dtd->pool); |
- declEntity = NULL; |
- } |
- else { |
- poolFinish(&dtd->pool); |
- declEntity->publicId = NULL; |
- declEntity->is_param = XML_FALSE; |
- /* if we have a parent parser or are reading an internal parameter |
- entity, then the entity declaration is not considered "internal" |
- */ |
- declEntity->is_internal = !(parentParser || openInternalEntities); |
- if (entityDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- } |
- else { |
- poolDiscard(&dtd->pool); |
- declEntity = NULL; |
- } |
- } |
- break; |
- case XML_ROLE_PARAM_ENTITY_NAME: |
-#ifdef XML_DTD |
- if (dtd->keepProcessing) { |
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); |
- if (!name) |
- return XML_ERROR_NO_MEMORY; |
- declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, |
- name, sizeof(ENTITY)); |
- if (!declEntity) |
- return XML_ERROR_NO_MEMORY; |
- if (declEntity->name != name) { |
- poolDiscard(&dtd->pool); |
- declEntity = NULL; |
- } |
- else { |
- poolFinish(&dtd->pool); |
- declEntity->publicId = NULL; |
- declEntity->is_param = XML_TRUE; |
- /* if we have a parent parser or are reading an internal parameter |
- entity, then the entity declaration is not considered "internal" |
- */ |
- declEntity->is_internal = !(parentParser || openInternalEntities); |
- if (entityDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- } |
- else { |
- poolDiscard(&dtd->pool); |
- declEntity = NULL; |
- } |
-#else /* not XML_DTD */ |
- declEntity = NULL; |
-#endif /* XML_DTD */ |
- break; |
- case XML_ROLE_NOTATION_NAME: |
- declNotationPublicId = NULL; |
- declNotationName = NULL; |
- if (notationDeclHandler) { |
- declNotationName = poolStoreString(&tempPool, enc, s, next); |
- if (!declNotationName) |
- return XML_ERROR_NO_MEMORY; |
- poolFinish(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_NOTATION_PUBLIC_ID: |
- if (!XmlIsPublicId(enc, s, next, eventPP)) |
- return XML_ERROR_PUBLICID; |
- if (declNotationName) { /* means notationDeclHandler != NULL */ |
- XML_Char *tem = poolStoreString(&tempPool, |
- enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!tem) |
- return XML_ERROR_NO_MEMORY; |
- normalizePublicId(tem); |
- declNotationPublicId = tem; |
- poolFinish(&tempPool); |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_NOTATION_SYSTEM_ID: |
- if (declNotationName && notationDeclHandler) { |
- const XML_Char *systemId |
- = poolStoreString(&tempPool, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!systemId) |
- return XML_ERROR_NO_MEMORY; |
- *eventEndPP = s; |
- notationDeclHandler(handlerArg, |
- declNotationName, |
- curBase, |
- systemId, |
- declNotationPublicId); |
- handleDefault = XML_FALSE; |
- } |
- poolClear(&tempPool); |
- break; |
- case XML_ROLE_NOTATION_NO_SYSTEM_ID: |
- if (declNotationPublicId && notationDeclHandler) { |
- *eventEndPP = s; |
- notationDeclHandler(handlerArg, |
- declNotationName, |
- curBase, |
- 0, |
- declNotationPublicId); |
- handleDefault = XML_FALSE; |
- } |
- poolClear(&tempPool); |
- break; |
- case XML_ROLE_ERROR: |
- switch (tok) { |
- case XML_TOK_PARAM_ENTITY_REF: |
- /* PE references in internal subset are |
- not allowed within declarations. */ |
- return XML_ERROR_PARAM_ENTITY_REF; |
- case XML_TOK_XML_DECL: |
- return XML_ERROR_MISPLACED_XML_PI; |
- default: |
- return XML_ERROR_SYNTAX; |
- } |
-#ifdef XML_DTD |
- case XML_ROLE_IGNORE_SECT: |
- { |
- enum XML_Error result; |
- if (defaultHandler) |
- reportDefault(parser, enc, s, next); |
- handleDefault = XML_FALSE; |
- result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); |
- if (result != XML_ERROR_NONE) |
- return result; |
- else if (!next) { |
- processor = ignoreSectionProcessor; |
- return result; |
- } |
- } |
- break; |
-#endif /* XML_DTD */ |
- case XML_ROLE_GROUP_OPEN: |
- if (prologState.level >= groupSize) { |
- if (groupSize) { |
- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); |
- if (temp == NULL) |
- return XML_ERROR_NO_MEMORY; |
- groupConnector = temp; |
- if (dtd->scaffIndex) { |
- int *temp = (int *)REALLOC(dtd->scaffIndex, |
- groupSize * sizeof(int)); |
- if (temp == NULL) |
- return XML_ERROR_NO_MEMORY; |
- dtd->scaffIndex = temp; |
- } |
- } |
- else { |
- groupConnector = (char *)MALLOC(groupSize = 32); |
- if (!groupConnector) |
- return XML_ERROR_NO_MEMORY; |
- } |
- } |
- groupConnector[prologState.level] = 0; |
- if (dtd->in_eldecl) { |
- int myindex = nextScaffoldPart(parser); |
- if (myindex < 0) |
- return XML_ERROR_NO_MEMORY; |
- dtd->scaffIndex[dtd->scaffLevel] = myindex; |
- dtd->scaffLevel++; |
- dtd->scaffold[myindex].type = XML_CTYPE_SEQ; |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- break; |
- case XML_ROLE_GROUP_SEQUENCE: |
- if (groupConnector[prologState.level] == ASCII_PIPE) |
- return XML_ERROR_SYNTAX; |
- groupConnector[prologState.level] = ASCII_COMMA; |
- if (dtd->in_eldecl && elementDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_GROUP_CHOICE: |
- if (groupConnector[prologState.level] == ASCII_COMMA) |
- return XML_ERROR_SYNTAX; |
- if (dtd->in_eldecl |
- && !groupConnector[prologState.level] |
- && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type |
- != XML_CTYPE_MIXED) |
- ) { |
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type |
- = XML_CTYPE_CHOICE; |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- groupConnector[prologState.level] = ASCII_PIPE; |
- break; |
- case XML_ROLE_PARAM_ENTITY_REF: |
-#ifdef XML_DTD |
- case XML_ROLE_INNER_PARAM_ENTITY_REF: |
- dtd->hasParamEntityRefs = XML_TRUE; |
- if (!paramEntityParsing) |
- dtd->keepProcessing = dtd->standalone; |
- else { |
- const XML_Char *name; |
- ENTITY *entity; |
- name = poolStoreString(&dtd->pool, enc, |
- s + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!name) |
- return XML_ERROR_NO_MEMORY; |
- entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 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 handler |
- */ |
- if (prologState.documentEntity && |
- (dtd->standalone |
- ? !openInternalEntities |
- : !dtd->hasParamEntityRefs)) { |
- if (!entity) |
- return XML_ERROR_UNDEFINED_ENTITY; |
- else if (!entity->is_internal) |
- return XML_ERROR_ENTITY_DECLARED_IN_PE; |
- } |
- else if (!entity) { |
- dtd->keepProcessing = dtd->standalone; |
- /* cannot report skipped entities in declarations */ |
- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { |
- skippedEntityHandler(handlerArg, name, 1); |
- handleDefault = XML_FALSE; |
- } |
- break; |
- } |
- if (entity->open) |
- return XML_ERROR_RECURSIVE_ENTITY_REF; |
- if (entity->textPtr) { |
- enum XML_Error result; |
- XML_Bool betweenDecl = |
- (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); |
- result = processInternalEntity(parser, entity, betweenDecl); |
- if (result != XML_ERROR_NONE) |
- return result; |
- handleDefault = XML_FALSE; |
- break; |
- } |
- if (externalEntityRefHandler) { |
- dtd->paramEntityRead = XML_FALSE; |
- entity->open = XML_TRUE; |
- if (!externalEntityRefHandler(externalEntityRefHandlerArg, |
- 0, |
- entity->base, |
- entity->systemId, |
- entity->publicId)) { |
- entity->open = XML_FALSE; |
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
- } |
- entity->open = XML_FALSE; |
- handleDefault = XML_FALSE; |
- if (!dtd->paramEntityRead) { |
- dtd->keepProcessing = dtd->standalone; |
- break; |
- } |
- } |
- else { |
- dtd->keepProcessing = dtd->standalone; |
- break; |
- } |
- } |
-#endif /* XML_DTD */ |
- if (!dtd->standalone && |
- notStandaloneHandler && |
- !notStandaloneHandler(handlerArg)) |
- return XML_ERROR_NOT_STANDALONE; |
- break; |
- |
- /* Element declaration stuff */ |
- |
- case XML_ROLE_ELEMENT_NAME: |
- if (elementDeclHandler) { |
- declElementType = getElementType(parser, enc, s, next); |
- if (!declElementType) |
- return XML_ERROR_NO_MEMORY; |
- dtd->scaffLevel = 0; |
- dtd->scaffCount = 0; |
- dtd->in_eldecl = XML_TRUE; |
- handleDefault = XML_FALSE; |
- } |
- break; |
- |
- case XML_ROLE_CONTENT_ANY: |
- case XML_ROLE_CONTENT_EMPTY: |
- if (dtd->in_eldecl) { |
- if (elementDeclHandler) { |
- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); |
- if (!content) |
- return XML_ERROR_NO_MEMORY; |
- content->quant = XML_CQUANT_NONE; |
- content->name = NULL; |
- content->numchildren = 0; |
- content->children = NULL; |
- content->type = ((role == XML_ROLE_CONTENT_ANY) ? |
- XML_CTYPE_ANY : |
- XML_CTYPE_EMPTY); |
- *eventEndPP = s; |
- elementDeclHandler(handlerArg, declElementType->name, content); |
- handleDefault = XML_FALSE; |
- } |
- dtd->in_eldecl = XML_FALSE; |
- } |
- break; |
- |
- case XML_ROLE_CONTENT_PCDATA: |
- if (dtd->in_eldecl) { |
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type |
- = XML_CTYPE_MIXED; |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- break; |
- |
- case XML_ROLE_CONTENT_ELEMENT: |
- quant = XML_CQUANT_NONE; |
- goto elementContent; |
- case XML_ROLE_CONTENT_ELEMENT_OPT: |
- quant = XML_CQUANT_OPT; |
- goto elementContent; |
- case XML_ROLE_CONTENT_ELEMENT_REP: |
- quant = XML_CQUANT_REP; |
- goto elementContent; |
- case XML_ROLE_CONTENT_ELEMENT_PLUS: |
- quant = XML_CQUANT_PLUS; |
- elementContent: |
- if (dtd->in_eldecl) { |
- ELEMENT_TYPE *el; |
- const XML_Char *name; |
- int nameLen; |
- const char *nxt = (quant == XML_CQUANT_NONE |
- ? next |
- : next - enc->minBytesPerChar); |
- int myindex = nextScaffoldPart(parser); |
- if (myindex < 0) |
- return XML_ERROR_NO_MEMORY; |
- dtd->scaffold[myindex].type = XML_CTYPE_NAME; |
- dtd->scaffold[myindex].quant = quant; |
- el = getElementType(parser, enc, s, nxt); |
- if (!el) |
- return XML_ERROR_NO_MEMORY; |
- name = el->name; |
- dtd->scaffold[myindex].name = name; |
- nameLen = 0; |
- for (; name[nameLen++]; ); |
- dtd->contentStringLen += nameLen; |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- } |
- break; |
- |
- case XML_ROLE_GROUP_CLOSE: |
- quant = XML_CQUANT_NONE; |
- goto closeGroup; |
- case XML_ROLE_GROUP_CLOSE_OPT: |
- quant = XML_CQUANT_OPT; |
- goto closeGroup; |
- case XML_ROLE_GROUP_CLOSE_REP: |
- quant = XML_CQUANT_REP; |
- goto closeGroup; |
- case XML_ROLE_GROUP_CLOSE_PLUS: |
- quant = XML_CQUANT_PLUS; |
- closeGroup: |
- if (dtd->in_eldecl) { |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- dtd->scaffLevel--; |
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; |
- if (dtd->scaffLevel == 0) { |
- if (!handleDefault) { |
- XML_Content *model = build_model(parser); |
- if (!model) |
- return XML_ERROR_NO_MEMORY; |
- *eventEndPP = s; |
- elementDeclHandler(handlerArg, declElementType->name, model); |
- } |
- dtd->in_eldecl = XML_FALSE; |
- dtd->contentStringLen = 0; |
- } |
- } |
- break; |
- /* End element declaration stuff */ |
- |
- case XML_ROLE_PI: |
- if (!reportProcessingInstruction(parser, enc, s, next)) |
- return XML_ERROR_NO_MEMORY; |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_COMMENT: |
- if (!reportComment(parser, enc, s, next)) |
- return XML_ERROR_NO_MEMORY; |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_NONE: |
- switch (tok) { |
- case XML_TOK_BOM: |
- handleDefault = XML_FALSE; |
- break; |
- } |
- break; |
- case XML_ROLE_DOCTYPE_NONE: |
- if (startDoctypeDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_ENTITY_NONE: |
- if (dtd->keepProcessing && entityDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_NOTATION_NONE: |
- if (notationDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_ATTLIST_NONE: |
- if (dtd->keepProcessing && attlistDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- case XML_ROLE_ELEMENT_NONE: |
- if (elementDeclHandler) |
- handleDefault = XML_FALSE; |
- break; |
- } /* end of big switch */ |
- |
- if (handleDefault && defaultHandler) |
- reportDefault(parser, enc, s, next); |
- |
- switch (ps_parsing) { |
- case XML_SUSPENDED: |
- *nextPtr = next; |
- return XML_ERROR_NONE; |
- case XML_FINISHED: |
- return XML_ERROR_ABORTED; |
- default: |
- s = next; |
- tok = XmlPrologTok(enc, s, end, &next); |
- } |
- } |
- /* not reached */ |
-} |
- |
-static enum XML_Error PTRCALL |
-epilogProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- processor = epilogProcessor; |
- eventPtr = s; |
- for (;;) { |
- const char *next = NULL; |
- int tok = XmlPrologTok(encoding, s, end, &next); |
- eventEndPtr = next; |
- switch (tok) { |
- /* report partial linebreak - it might be the last token */ |
- case -XML_TOK_PROLOG_S: |
- if (defaultHandler) { |
- reportDefault(parser, encoding, s, next); |
- if (ps_parsing == XML_FINISHED) |
- return XML_ERROR_ABORTED; |
- } |
- *nextPtr = next; |
- return XML_ERROR_NONE; |
- case XML_TOK_NONE: |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- case XML_TOK_PROLOG_S: |
- if (defaultHandler) |
- reportDefault(parser, encoding, s, next); |
- break; |
- case XML_TOK_PI: |
- if (!reportProcessingInstruction(parser, encoding, s, next)) |
- return XML_ERROR_NO_MEMORY; |
- break; |
- case XML_TOK_COMMENT: |
- if (!reportComment(parser, encoding, s, next)) |
- return XML_ERROR_NO_MEMORY; |
- break; |
- case XML_TOK_INVALID: |
- eventPtr = next; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- if (!ps_finalBuffer) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_UNCLOSED_TOKEN; |
- case XML_TOK_PARTIAL_CHAR: |
- if (!ps_finalBuffer) { |
- *nextPtr = s; |
- return XML_ERROR_NONE; |
- } |
- return XML_ERROR_PARTIAL_CHAR; |
- default: |
- return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; |
- } |
- eventPtr = s = next; |
- switch (ps_parsing) { |
- case XML_SUSPENDED: |
- *nextPtr = next; |
- return XML_ERROR_NONE; |
- case XML_FINISHED: |
- return XML_ERROR_ABORTED; |
- default: ; |
- } |
- } |
-} |
- |
-static enum XML_Error |
-processInternalEntity(XML_Parser parser, ENTITY *entity, |
- XML_Bool betweenDecl) |
-{ |
- const char *textStart, *textEnd; |
- const char *next; |
- enum XML_Error result; |
- OPEN_INTERNAL_ENTITY *openEntity; |
- |
- if (freeInternalEntities) { |
- openEntity = freeInternalEntities; |
- freeInternalEntities = openEntity->next; |
- } |
- else { |
- openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); |
- if (!openEntity) |
- return XML_ERROR_NO_MEMORY; |
- } |
- entity->open = XML_TRUE; |
- entity->processed = 0; |
- openEntity->next = openInternalEntities; |
- openInternalEntities = openEntity; |
- openEntity->entity = entity; |
- openEntity->startTagLevel = tagLevel; |
- openEntity->betweenDecl = betweenDecl; |
- openEntity->internalEventPtr = NULL; |
- openEntity->internalEventEndPtr = NULL; |
- textStart = (char *)entity->textPtr; |
- textEnd = (char *)(entity->textPtr + entity->textLen); |
- |
-#ifdef XML_DTD |
- if (entity->is_param) { |
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); |
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, |
- next, &next, XML_FALSE); |
- } |
- else |
-#endif /* XML_DTD */ |
- result = doContent(parser, tagLevel, internalEncoding, textStart, |
- textEnd, &next, XML_FALSE); |
- |
- if (result == XML_ERROR_NONE) { |
- if (textEnd != next && ps_parsing == XML_SUSPENDED) { |
- entity->processed = (int)(next - textStart); |
- processor = internalEntityProcessor; |
- } |
- else { |
- entity->open = XML_FALSE; |
- openInternalEntities = openEntity->next; |
- /* put openEntity back in list of free instances */ |
- openEntity->next = freeInternalEntities; |
- freeInternalEntities = openEntity; |
- } |
- } |
- return result; |
-} |
- |
-static enum XML_Error PTRCALL |
-internalEntityProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- ENTITY *entity; |
- const char *textStart, *textEnd; |
- const char *next; |
- enum XML_Error result; |
- OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; |
- if (!openEntity) |
- return XML_ERROR_UNEXPECTED_STATE; |
- |
- entity = openEntity->entity; |
- textStart = ((char *)entity->textPtr) + entity->processed; |
- textEnd = (char *)(entity->textPtr + entity->textLen); |
- |
-#ifdef XML_DTD |
- if (entity->is_param) { |
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); |
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, |
- next, &next, XML_FALSE); |
- } |
- else |
-#endif /* XML_DTD */ |
- result = doContent(parser, openEntity->startTagLevel, internalEncoding, |
- textStart, textEnd, &next, XML_FALSE); |
- |
- if (result != XML_ERROR_NONE) |
- return result; |
- else if (textEnd != next && ps_parsing == XML_SUSPENDED) { |
- entity->processed = (int)(next - (char *)entity->textPtr); |
- return result; |
- } |
- else { |
- entity->open = XML_FALSE; |
- openInternalEntities = openEntity->next; |
- /* put openEntity back in list of free instances */ |
- openEntity->next = freeInternalEntities; |
- freeInternalEntities = openEntity; |
- } |
- |
-#ifdef XML_DTD |
- if (entity->is_param) { |
- int tok; |
- processor = prologProcessor; |
- tok = XmlPrologTok(encoding, s, end, &next); |
- return doProlog(parser, encoding, s, end, tok, next, nextPtr, |
- (XML_Bool)!ps_finalBuffer); |
- } |
- else |
-#endif /* XML_DTD */ |
- { |
- processor = contentProcessor; |
- /* see externalEntityContentProcessor vs contentProcessor */ |
- return doContent(parser, parentParser ? 1 : 0, encoding, s, end, |
- nextPtr, (XML_Bool)!ps_finalBuffer); |
- } |
-} |
- |
-static enum XML_Error PTRCALL |
-errorProcessor(XML_Parser parser, |
- const char *s, |
- const char *end, |
- const char **nextPtr) |
-{ |
- return errorCode; |
-} |
- |
-static enum XML_Error |
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, |
- const char *ptr, const char *end, |
- STRING_POOL *pool) |
-{ |
- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, |
- end, pool); |
- if (result) |
- return result; |
- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) |
- poolChop(pool); |
- if (!poolAppendChar(pool, XML_T('\0'))) |
- return XML_ERROR_NO_MEMORY; |
- return XML_ERROR_NONE; |
-} |
- |
-static enum XML_Error |
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, |
- const char *ptr, const char *end, |
- STRING_POOL *pool) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- for (;;) { |
- const char *next; |
- int tok = XmlAttributeValueTok(enc, ptr, end, &next); |
- switch (tok) { |
- case XML_TOK_NONE: |
- return XML_ERROR_NONE; |
- case XML_TOK_INVALID: |
- if (enc == encoding) |
- eventPtr = next; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_PARTIAL: |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_INVALID_TOKEN; |
- case XML_TOK_CHAR_REF: |
- { |
- XML_Char buf[XML_ENCODE_MAX]; |
- int i; |
- int n = XmlCharRefNumber(enc, ptr); |
- if (n < 0) { |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_BAD_CHAR_REF; |
- } |
- if (!isCdata |
- && n == 0x20 /* space */ |
- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) |
- break; |
- n = XmlEncode(n, (ICHAR *)buf); |
- if (!n) { |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_BAD_CHAR_REF; |
- } |
- for (i = 0; i < n; i++) { |
- if (!poolAppendChar(pool, buf[i])) |
- return XML_ERROR_NO_MEMORY; |
- } |
- } |
- break; |
- case XML_TOK_DATA_CHARS: |
- if (!poolAppend(pool, enc, ptr, next)) |
- return XML_ERROR_NO_MEMORY; |
- break; |
- case XML_TOK_TRAILING_CR: |
- next = ptr + enc->minBytesPerChar; |
- /* fall through */ |
- case XML_TOK_ATTRIBUTE_VALUE_S: |
- case XML_TOK_DATA_NEWLINE: |
- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) |
- break; |
- if (!poolAppendChar(pool, 0x20)) |
- return XML_ERROR_NO_MEMORY; |
- break; |
- case XML_TOK_ENTITY_REF: |
- { |
- const XML_Char *name; |
- ENTITY *entity; |
- char checkEntityDecl; |
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, |
- ptr + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (ch) { |
- if (!poolAppendChar(pool, ch)) |
- return XML_ERROR_NO_MEMORY; |
- break; |
- } |
- name = poolStoreString(&temp2Pool, enc, |
- ptr + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!name) |
- return XML_ERROR_NO_MEMORY; |
- entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); |
- poolDiscard(&temp2Pool); |
- /* First, determine if a check for an existing declaration is needed; |
- if yes, check that the entity exists, and that it is internal. |
- */ |
- if (pool == &dtd->pool) /* are we called from prolog? */ |
- checkEntityDecl = |
-#ifdef XML_DTD |
- prologState.documentEntity && |
-#endif /* XML_DTD */ |
- (dtd->standalone |
- ? !openInternalEntities |
- : !dtd->hasParamEntityRefs); |
- else /* if (pool == &tempPool): we are called from content */ |
- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; |
- if (checkEntityDecl) { |
- if (!entity) |
- return XML_ERROR_UNDEFINED_ENTITY; |
- else if (!entity->is_internal) |
- return XML_ERROR_ENTITY_DECLARED_IN_PE; |
- } |
- else if (!entity) { |
- /* Cannot report skipped entity here - see comments on |
- skippedEntityHandler. |
- if (skippedEntityHandler) |
- skippedEntityHandler(handlerArg, name, 0); |
- */ |
- /* Cannot call the default handler because this would be |
- out of sync with the call to the startElementHandler. |
- if ((pool == &tempPool) && defaultHandler) |
- reportDefault(parser, enc, ptr, next); |
- */ |
- break; |
- } |
- if (entity->open) { |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_RECURSIVE_ENTITY_REF; |
- } |
- if (entity->notation) { |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_BINARY_ENTITY_REF; |
- } |
- if (!entity->textPtr) { |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; |
- } |
- else { |
- enum XML_Error result; |
- const XML_Char *textEnd = entity->textPtr + entity->textLen; |
- entity->open = XML_TRUE; |
- result = appendAttributeValue(parser, internalEncoding, isCdata, |
- (char *)entity->textPtr, |
- (char *)textEnd, pool); |
- entity->open = XML_FALSE; |
- if (result) |
- return result; |
- } |
- } |
- break; |
- default: |
- if (enc == encoding) |
- eventPtr = ptr; |
- return XML_ERROR_UNEXPECTED_STATE; |
- } |
- ptr = next; |
- } |
- /* not reached */ |
-} |
- |
-static enum XML_Error |
-storeEntityValue(XML_Parser parser, |
- const ENCODING *enc, |
- const char *entityTextPtr, |
- const char *entityTextEnd) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- STRING_POOL *pool = &(dtd->entityValuePool); |
- enum XML_Error result = XML_ERROR_NONE; |
-#ifdef XML_DTD |
- int oldInEntityValue = prologState.inEntityValue; |
- prologState.inEntityValue = 1; |
-#endif /* XML_DTD */ |
- /* never return Null for the value argument in EntityDeclHandler, |
- since this would indicate an external entity; therefore we |
- have to make sure that entityValuePool.start is not null */ |
- if (!pool->blocks) { |
- if (!poolGrow(pool)) |
- return XML_ERROR_NO_MEMORY; |
- } |
- |
- for (;;) { |
- const char *next; |
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); |
- switch (tok) { |
- case XML_TOK_PARAM_ENTITY_REF: |
-#ifdef XML_DTD |
- if (isParamEntity || enc != encoding) { |
- const XML_Char *name; |
- ENTITY *entity; |
- name = poolStoreString(&tempPool, enc, |
- entityTextPtr + enc->minBytesPerChar, |
- next - enc->minBytesPerChar); |
- if (!name) { |
- result = XML_ERROR_NO_MEMORY; |
- goto endEntityValue; |
- } |
- entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); |
- poolDiscard(&tempPool); |
- if (!entity) { |
- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ |
- /* cannot report skipped entity here - see comments on |
- skippedEntityHandler |
- if (skippedEntityHandler) |
- skippedEntityHandler(handlerArg, name, 0); |
- */ |
- dtd->keepProcessing = dtd->standalone; |
- goto endEntityValue; |
- } |
- if (entity->open) { |
- if (enc == encoding) |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_RECURSIVE_ENTITY_REF; |
- goto endEntityValue; |
- } |
- if (entity->systemId) { |
- if (externalEntityRefHandler) { |
- dtd->paramEntityRead = XML_FALSE; |
- entity->open = XML_TRUE; |
- if (!externalEntityRefHandler(externalEntityRefHandlerArg, |
- 0, |
- entity->base, |
- entity->systemId, |
- entity->publicId)) { |
- entity->open = XML_FALSE; |
- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; |
- goto endEntityValue; |
- } |
- entity->open = XML_FALSE; |
- if (!dtd->paramEntityRead) |
- dtd->keepProcessing = dtd->standalone; |
- } |
- else |
- dtd->keepProcessing = dtd->standalone; |
- } |
- else { |
- entity->open = XML_TRUE; |
- result = storeEntityValue(parser, |
- internalEncoding, |
- (char *)entity->textPtr, |
- (char *)(entity->textPtr |
- + entity->textLen)); |
- entity->open = XML_FALSE; |
- if (result) |
- goto endEntityValue; |
- } |
- break; |
- } |
-#endif /* XML_DTD */ |
- /* In the internal subset, PE references are not legal |
- within markup declarations, e.g entity values in this case. */ |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_PARAM_ENTITY_REF; |
- goto endEntityValue; |
- case XML_TOK_NONE: |
- result = XML_ERROR_NONE; |
- goto endEntityValue; |
- case XML_TOK_ENTITY_REF: |
- case XML_TOK_DATA_CHARS: |
- if (!poolAppend(pool, enc, entityTextPtr, next)) { |
- result = XML_ERROR_NO_MEMORY; |
- goto endEntityValue; |
- } |
- break; |
- case XML_TOK_TRAILING_CR: |
- next = entityTextPtr + enc->minBytesPerChar; |
- /* fall through */ |
- case XML_TOK_DATA_NEWLINE: |
- if (pool->end == pool->ptr && !poolGrow(pool)) { |
- result = XML_ERROR_NO_MEMORY; |
- goto endEntityValue; |
- } |
- *(pool->ptr)++ = 0xA; |
- break; |
- case XML_TOK_CHAR_REF: |
- { |
- XML_Char buf[XML_ENCODE_MAX]; |
- int i; |
- int n = XmlCharRefNumber(enc, entityTextPtr); |
- if (n < 0) { |
- if (enc == encoding) |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_BAD_CHAR_REF; |
- goto endEntityValue; |
- } |
- n = XmlEncode(n, (ICHAR *)buf); |
- if (!n) { |
- if (enc == encoding) |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_BAD_CHAR_REF; |
- goto endEntityValue; |
- } |
- for (i = 0; i < n; i++) { |
- if (pool->end == pool->ptr && !poolGrow(pool)) { |
- result = XML_ERROR_NO_MEMORY; |
- goto endEntityValue; |
- } |
- *(pool->ptr)++ = buf[i]; |
- } |
- } |
- break; |
- case XML_TOK_PARTIAL: |
- if (enc == encoding) |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_INVALID_TOKEN; |
- goto endEntityValue; |
- case XML_TOK_INVALID: |
- if (enc == encoding) |
- eventPtr = next; |
- result = XML_ERROR_INVALID_TOKEN; |
- goto endEntityValue; |
- default: |
- if (enc == encoding) |
- eventPtr = entityTextPtr; |
- result = XML_ERROR_UNEXPECTED_STATE; |
- goto endEntityValue; |
- } |
- entityTextPtr = next; |
- } |
-endEntityValue: |
-#ifdef XML_DTD |
- prologState.inEntityValue = oldInEntityValue; |
-#endif /* XML_DTD */ |
- return result; |
-} |
- |
-static void FASTCALL |
-normalizeLines(XML_Char *s) |
-{ |
- XML_Char *p; |
- for (;; s++) { |
- if (*s == XML_T('\0')) |
- return; |
- if (*s == 0xD) |
- break; |
- } |
- p = s; |
- do { |
- if (*s == 0xD) { |
- *p++ = 0xA; |
- if (*++s == 0xA) |
- s++; |
- } |
- else |
- *p++ = *s++; |
- } while (*s); |
- *p = XML_T('\0'); |
-} |
- |
-static int |
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, |
- const char *start, const char *end) |
-{ |
- const XML_Char *target; |
- XML_Char *data; |
- const char *tem; |
- if (!processingInstructionHandler) { |
- if (defaultHandler) |
- reportDefault(parser, enc, start, end); |
- return 1; |
- } |
- start += enc->minBytesPerChar * 2; |
- tem = start + XmlNameLength(enc, start); |
- target = poolStoreString(&tempPool, enc, start, tem); |
- if (!target) |
- return 0; |
- poolFinish(&tempPool); |
- data = poolStoreString(&tempPool, enc, |
- XmlSkipS(enc, tem), |
- end - enc->minBytesPerChar*2); |
- if (!data) |
- return 0; |
- normalizeLines(data); |
- processingInstructionHandler(handlerArg, target, data); |
- poolClear(&tempPool); |
- return 1; |
-} |
- |
-static int |
-reportComment(XML_Parser parser, const ENCODING *enc, |
- const char *start, const char *end) |
-{ |
- XML_Char *data; |
- if (!commentHandler) { |
- if (defaultHandler) |
- reportDefault(parser, enc, start, end); |
- return 1; |
- } |
- data = poolStoreString(&tempPool, |
- enc, |
- start + enc->minBytesPerChar * 4, |
- end - enc->minBytesPerChar * 3); |
- if (!data) |
- return 0; |
- normalizeLines(data); |
- commentHandler(handlerArg, data); |
- poolClear(&tempPool); |
- return 1; |
-} |
- |
-static void |
-reportDefault(XML_Parser parser, const ENCODING *enc, |
- const char *s, const char *end) |
-{ |
- if (MUST_CONVERT(enc, s)) { |
- const char **eventPP; |
- const char **eventEndPP; |
- if (enc == encoding) { |
- eventPP = &eventPtr; |
- eventEndPP = &eventEndPtr; |
- } |
- else { |
- eventPP = &(openInternalEntities->internalEventPtr); |
- eventEndPP = &(openInternalEntities->internalEventEndPtr); |
- } |
- do { |
- ICHAR *dataPtr = (ICHAR *)dataBuf; |
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); |
- *eventEndPP = s; |
- defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); |
- *eventPP = s; |
- } while (s != end); |
- } |
- else |
- defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); |
-} |
- |
- |
-static int |
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, |
- XML_Bool isId, const XML_Char *value, XML_Parser parser) |
-{ |
- DEFAULT_ATTRIBUTE *att; |
- if (value || isId) { |
- /* The handling of default attributes gets messed up if we have |
- a default which duplicates a non-default. */ |
- int i; |
- for (i = 0; i < type->nDefaultAtts; i++) |
- if (attId == type->defaultAtts[i].id) |
- return 1; |
- if (isId && !type->idAtt && !attId->xmlns) |
- type->idAtt = attId; |
- } |
- if (type->nDefaultAtts == type->allocDefaultAtts) { |
- if (type->allocDefaultAtts == 0) { |
- type->allocDefaultAtts = 8; |
- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts |
- * sizeof(DEFAULT_ATTRIBUTE)); |
- if (!type->defaultAtts) |
- return 0; |
- } |
- else { |
- DEFAULT_ATTRIBUTE *temp; |
- int count = type->allocDefaultAtts * 2; |
- temp = (DEFAULT_ATTRIBUTE *) |
- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); |
- if (temp == NULL) |
- return 0; |
- type->allocDefaultAtts = count; |
- type->defaultAtts = temp; |
- } |
- } |
- att = type->defaultAtts + type->nDefaultAtts; |
- att->id = attId; |
- att->value = value; |
- att->isCdata = isCdata; |
- if (!isCdata) |
- attId->maybeTokenized = XML_TRUE; |
- type->nDefaultAtts += 1; |
- return 1; |
-} |
- |
-static int |
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- const XML_Char *name; |
- for (name = elementType->name; *name; name++) { |
- if (*name == XML_T(ASCII_COLON)) { |
- PREFIX *prefix; |
- const XML_Char *s; |
- for (s = elementType->name; s != name; s++) { |
- if (!poolAppendChar(&dtd->pool, *s)) |
- return 0; |
- } |
- if (!poolAppendChar(&dtd->pool, XML_T('\0'))) |
- return 0; |
- prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), |
- sizeof(PREFIX)); |
- if (!prefix) |
- return 0; |
- if (prefix->name == poolStart(&dtd->pool)) |
- poolFinish(&dtd->pool); |
- else |
- poolDiscard(&dtd->pool); |
- elementType->prefix = prefix; |
- |
- } |
- } |
- return 1; |
-} |
- |
-static ATTRIBUTE_ID * |
-getAttributeId(XML_Parser parser, const ENCODING *enc, |
- const char *start, const char *end) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- ATTRIBUTE_ID *id; |
- const XML_Char *name; |
- if (!poolAppendChar(&dtd->pool, XML_T('\0'))) |
- return NULL; |
- name = poolStoreString(&dtd->pool, enc, start, end); |
- if (!name) |
- return NULL; |
- /* skip quotation mark - its storage will be re-used (like in name[-1]) */ |
- ++name; |
- id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); |
- if (!id) |
- return NULL; |
- if (id->name != name) |
- poolDiscard(&dtd->pool); |
- else { |
- poolFinish(&dtd->pool); |
- if (!ns) |
- ; |
- else if (name[0] == XML_T(ASCII_x) |
- && name[1] == XML_T(ASCII_m) |
- && name[2] == XML_T(ASCII_l) |
- && name[3] == XML_T(ASCII_n) |
- && name[4] == XML_T(ASCII_s) |
- && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { |
- if (name[5] == XML_T('\0')) |
- id->prefix = &dtd->defaultPrefix; |
- else |
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX)); |
- id->xmlns = XML_TRUE; |
- } |
- else { |
- int i; |
- for (i = 0; name[i]; i++) { |
- /* attributes without prefix are *not* in the default namespace */ |
- if (name[i] == XML_T(ASCII_COLON)) { |
- int j; |
- for (j = 0; j < i; j++) { |
- if (!poolAppendChar(&dtd->pool, name[j])) |
- return NULL; |
- } |
- if (!poolAppendChar(&dtd->pool, XML_T('\0'))) |
- return NULL; |
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), |
- sizeof(PREFIX)); |
- if (id->prefix->name == poolStart(&dtd->pool)) |
- poolFinish(&dtd->pool); |
- else |
- poolDiscard(&dtd->pool); |
- break; |
- } |
- } |
- } |
- } |
- return id; |
-} |
- |
-#define CONTEXT_SEP XML_T(ASCII_FF) |
- |
-static const XML_Char * |
-getContext(XML_Parser parser) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- HASH_TABLE_ITER iter; |
- XML_Bool needSep = XML_FALSE; |
- |
- if (dtd->defaultPrefix.binding) { |
- int i; |
- int len; |
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) |
- return NULL; |
- len = dtd->defaultPrefix.binding->uriLen; |
- if (namespaceSeparator) |
- len--; |
- for (i = 0; i < len; i++) |
- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) |
- return NULL; |
- needSep = XML_TRUE; |
- } |
- |
- hashTableIterInit(&iter, &(dtd->prefixes)); |
- for (;;) { |
- int i; |
- int len; |
- const XML_Char *s; |
- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); |
- if (!prefix) |
- break; |
- if (!prefix->binding) |
- continue; |
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) |
- return NULL; |
- for (s = prefix->name; *s; s++) |
- if (!poolAppendChar(&tempPool, *s)) |
- return NULL; |
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) |
- return NULL; |
- len = prefix->binding->uriLen; |
- if (namespaceSeparator) |
- len--; |
- for (i = 0; i < len; i++) |
- if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) |
- return NULL; |
- needSep = XML_TRUE; |
- } |
- |
- |
- hashTableIterInit(&iter, &(dtd->generalEntities)); |
- for (;;) { |
- const XML_Char *s; |
- ENTITY *e = (ENTITY *)hashTableIterNext(&iter); |
- if (!e) |
- break; |
- if (!e->open) |
- continue; |
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) |
- return NULL; |
- for (s = e->name; *s; s++) |
- if (!poolAppendChar(&tempPool, *s)) |
- return 0; |
- needSep = XML_TRUE; |
- } |
- |
- if (!poolAppendChar(&tempPool, XML_T('\0'))) |
- return NULL; |
- return tempPool.start; |
-} |
- |
-static XML_Bool |
-setContext(XML_Parser parser, const XML_Char *context) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- const XML_Char *s = context; |
- |
- while (*context != XML_T('\0')) { |
- if (*s == CONTEXT_SEP || *s == XML_T('\0')) { |
- ENTITY *e; |
- if (!poolAppendChar(&tempPool, XML_T('\0'))) |
- return XML_FALSE; |
- e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0); |
- if (e) |
- e->open = XML_TRUE; |
- if (*s != XML_T('\0')) |
- s++; |
- context = s; |
- poolDiscard(&tempPool); |
- } |
- else if (*s == XML_T(ASCII_EQUALS)) { |
- PREFIX *prefix; |
- if (poolLength(&tempPool) == 0) |
- prefix = &dtd->defaultPrefix; |
- else { |
- if (!poolAppendChar(&tempPool, XML_T('\0'))) |
- return XML_FALSE; |
- prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool), |
- sizeof(PREFIX)); |
- if (!prefix) |
- return XML_FALSE; |
- if (prefix->name == poolStart(&tempPool)) { |
- prefix->name = poolCopyString(&dtd->pool, prefix->name); |
- if (!prefix->name) |
- return XML_FALSE; |
- } |
- poolDiscard(&tempPool); |
- } |
- for (context = s + 1; |
- *context != CONTEXT_SEP && *context != XML_T('\0'); |
- context++) |
- if (!poolAppendChar(&tempPool, *context)) |
- return XML_FALSE; |
- if (!poolAppendChar(&tempPool, XML_T('\0'))) |
- return XML_FALSE; |
- if (addBinding(parser, prefix, NULL, poolStart(&tempPool), |
- &inheritedBindings) != XML_ERROR_NONE) |
- return XML_FALSE; |
- poolDiscard(&tempPool); |
- if (*context != XML_T('\0')) |
- ++context; |
- s = context; |
- } |
- else { |
- if (!poolAppendChar(&tempPool, *s)) |
- return XML_FALSE; |
- s++; |
- } |
- } |
- return XML_TRUE; |
-} |
- |
-static void FASTCALL |
-normalizePublicId(XML_Char *publicId) |
-{ |
- XML_Char *p = publicId; |
- XML_Char *s; |
- for (s = publicId; *s; s++) { |
- switch (*s) { |
- case 0x20: |
- case 0xD: |
- case 0xA: |
- if (p != publicId && p[-1] != 0x20) |
- *p++ = 0x20; |
- break; |
- default: |
- *p++ = *s; |
- } |
- } |
- if (p != publicId && p[-1] == 0x20) |
- --p; |
- *p = XML_T('\0'); |
-} |
- |
-static DTD * |
-dtdCreate(const XML_Memory_Handling_Suite *ms) |
-{ |
- DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); |
- if (p == NULL) |
- return p; |
- poolInit(&(p->pool), ms); |
- poolInit(&(p->entityValuePool), ms); |
- hashTableInit(&(p->generalEntities), ms); |
- hashTableInit(&(p->elementTypes), ms); |
- hashTableInit(&(p->attributeIds), ms); |
- hashTableInit(&(p->prefixes), ms); |
-#ifdef XML_DTD |
- p->paramEntityRead = XML_FALSE; |
- hashTableInit(&(p->paramEntities), ms); |
-#endif /* XML_DTD */ |
- p->defaultPrefix.name = NULL; |
- p->defaultPrefix.binding = NULL; |
- |
- p->in_eldecl = XML_FALSE; |
- p->scaffIndex = NULL; |
- p->scaffold = NULL; |
- p->scaffLevel = 0; |
- p->scaffSize = 0; |
- p->scaffCount = 0; |
- p->contentStringLen = 0; |
- |
- p->keepProcessing = XML_TRUE; |
- p->hasParamEntityRefs = XML_FALSE; |
- p->standalone = XML_FALSE; |
- return p; |
-} |
- |
-static void |
-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) |
-{ |
- HASH_TABLE_ITER iter; |
- hashTableIterInit(&iter, &(p->elementTypes)); |
- for (;;) { |
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
- if (!e) |
- break; |
- if (e->allocDefaultAtts != 0) |
- ms->free_fcn(e->defaultAtts); |
- } |
- hashTableClear(&(p->generalEntities)); |
-#ifdef XML_DTD |
- p->paramEntityRead = XML_FALSE; |
- hashTableClear(&(p->paramEntities)); |
-#endif /* XML_DTD */ |
- hashTableClear(&(p->elementTypes)); |
- hashTableClear(&(p->attributeIds)); |
- hashTableClear(&(p->prefixes)); |
- poolClear(&(p->pool)); |
- poolClear(&(p->entityValuePool)); |
- p->defaultPrefix.name = NULL; |
- p->defaultPrefix.binding = NULL; |
- |
- p->in_eldecl = XML_FALSE; |
- |
- ms->free_fcn(p->scaffIndex); |
- p->scaffIndex = NULL; |
- ms->free_fcn(p->scaffold); |
- p->scaffold = NULL; |
- |
- p->scaffLevel = 0; |
- p->scaffSize = 0; |
- p->scaffCount = 0; |
- p->contentStringLen = 0; |
- |
- p->keepProcessing = XML_TRUE; |
- p->hasParamEntityRefs = XML_FALSE; |
- p->standalone = XML_FALSE; |
-} |
- |
-static void |
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) |
-{ |
- HASH_TABLE_ITER iter; |
- hashTableIterInit(&iter, &(p->elementTypes)); |
- for (;;) { |
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
- if (!e) |
- break; |
- if (e->allocDefaultAtts != 0) |
- ms->free_fcn(e->defaultAtts); |
- } |
- hashTableDestroy(&(p->generalEntities)); |
-#ifdef XML_DTD |
- hashTableDestroy(&(p->paramEntities)); |
-#endif /* XML_DTD */ |
- hashTableDestroy(&(p->elementTypes)); |
- hashTableDestroy(&(p->attributeIds)); |
- hashTableDestroy(&(p->prefixes)); |
- poolDestroy(&(p->pool)); |
- poolDestroy(&(p->entityValuePool)); |
- if (isDocEntity) { |
- ms->free_fcn(p->scaffIndex); |
- ms->free_fcn(p->scaffold); |
- } |
- ms->free_fcn(p); |
-} |
- |
-/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. |
- The new DTD has already been initialized. |
-*/ |
-static int |
-dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) |
-{ |
- HASH_TABLE_ITER iter; |
- |
- /* Copy the prefix table. */ |
- |
- hashTableIterInit(&iter, &(oldDtd->prefixes)); |
- for (;;) { |
- const XML_Char *name; |
- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); |
- if (!oldP) |
- break; |
- name = poolCopyString(&(newDtd->pool), oldP->name); |
- if (!name) |
- return 0; |
- if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) |
- return 0; |
- } |
- |
- hashTableIterInit(&iter, &(oldDtd->attributeIds)); |
- |
- /* Copy the attribute id table. */ |
- |
- for (;;) { |
- ATTRIBUTE_ID *newA; |
- const XML_Char *name; |
- const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); |
- |
- if (!oldA) |
- break; |
- /* Remember to allocate the scratch byte before the name. */ |
- if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) |
- return 0; |
- name = poolCopyString(&(newDtd->pool), oldA->name); |
- if (!name) |
- return 0; |
- ++name; |
- newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, |
- sizeof(ATTRIBUTE_ID)); |
- if (!newA) |
- return 0; |
- newA->maybeTokenized = oldA->maybeTokenized; |
- if (oldA->prefix) { |
- newA->xmlns = oldA->xmlns; |
- if (oldA->prefix == &oldDtd->defaultPrefix) |
- newA->prefix = &newDtd->defaultPrefix; |
- else |
- newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), |
- oldA->prefix->name, 0); |
- } |
- } |
- |
- /* Copy the element type table. */ |
- |
- hashTableIterInit(&iter, &(oldDtd->elementTypes)); |
- |
- for (;;) { |
- int i; |
- ELEMENT_TYPE *newE; |
- const XML_Char *name; |
- const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); |
- if (!oldE) |
- break; |
- name = poolCopyString(&(newDtd->pool), oldE->name); |
- if (!name) |
- return 0; |
- newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, |
- sizeof(ELEMENT_TYPE)); |
- if (!newE) |
- return 0; |
- if (oldE->nDefaultAtts) { |
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *) |
- ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); |
- if (!newE->defaultAtts) { |
- ms->free_fcn(newE); |
- return 0; |
- } |
- } |
- if (oldE->idAtt) |
- newE->idAtt = (ATTRIBUTE_ID *) |
- lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); |
- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; |
- if (oldE->prefix) |
- newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), |
- oldE->prefix->name, 0); |
- for (i = 0; i < newE->nDefaultAtts; i++) { |
- newE->defaultAtts[i].id = (ATTRIBUTE_ID *) |
- lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); |
- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; |
- if (oldE->defaultAtts[i].value) { |
- newE->defaultAtts[i].value |
- = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); |
- if (!newE->defaultAtts[i].value) |
- return 0; |
- } |
- else |
- newE->defaultAtts[i].value = NULL; |
- } |
- } |
- |
- /* Copy the entity tables. */ |
- if (!copyEntityTable(oldParser, |
- &(newDtd->generalEntities), |
- &(newDtd->pool), |
- &(oldDtd->generalEntities))) |
- return 0; |
- |
-#ifdef XML_DTD |
- if (!copyEntityTable(oldParser, |
- &(newDtd->paramEntities), |
- &(newDtd->pool), |
- &(oldDtd->paramEntities))) |
- return 0; |
- newDtd->paramEntityRead = oldDtd->paramEntityRead; |
-#endif /* XML_DTD */ |
- |
- newDtd->keepProcessing = oldDtd->keepProcessing; |
- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; |
- newDtd->standalone = oldDtd->standalone; |
- |
- /* Don't want deep copying for scaffolding */ |
- newDtd->in_eldecl = oldDtd->in_eldecl; |
- newDtd->scaffold = oldDtd->scaffold; |
- newDtd->contentStringLen = oldDtd->contentStringLen; |
- newDtd->scaffSize = oldDtd->scaffSize; |
- newDtd->scaffLevel = oldDtd->scaffLevel; |
- newDtd->scaffIndex = oldDtd->scaffIndex; |
- |
- return 1; |
-} /* End dtdCopy */ |
- |
-static int |
-copyEntityTable(XML_Parser oldParser, |
- HASH_TABLE *newTable, |
- STRING_POOL *newPool, |
- const HASH_TABLE *oldTable) |
-{ |
- HASH_TABLE_ITER iter; |
- const XML_Char *cachedOldBase = NULL; |
- const XML_Char *cachedNewBase = NULL; |
- |
- hashTableIterInit(&iter, oldTable); |
- |
- for (;;) { |
- ENTITY *newE; |
- const XML_Char *name; |
- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); |
- if (!oldE) |
- break; |
- name = poolCopyString(newPool, oldE->name); |
- if (!name) |
- return 0; |
- newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); |
- if (!newE) |
- return 0; |
- if (oldE->systemId) { |
- const XML_Char *tem = poolCopyString(newPool, oldE->systemId); |
- if (!tem) |
- return 0; |
- newE->systemId = tem; |
- if (oldE->base) { |
- if (oldE->base == cachedOldBase) |
- newE->base = cachedNewBase; |
- else { |
- cachedOldBase = oldE->base; |
- tem = poolCopyString(newPool, cachedOldBase); |
- if (!tem) |
- return 0; |
- cachedNewBase = newE->base = tem; |
- } |
- } |
- if (oldE->publicId) { |
- tem = poolCopyString(newPool, oldE->publicId); |
- if (!tem) |
- return 0; |
- newE->publicId = tem; |
- } |
- } |
- else { |
- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, |
- oldE->textLen); |
- if (!tem) |
- return 0; |
- newE->textPtr = tem; |
- newE->textLen = oldE->textLen; |
- } |
- if (oldE->notation) { |
- const XML_Char *tem = poolCopyString(newPool, oldE->notation); |
- if (!tem) |
- return 0; |
- newE->notation = tem; |
- } |
- newE->is_param = oldE->is_param; |
- newE->is_internal = oldE->is_internal; |
- } |
- return 1; |
-} |
- |
-#define INIT_POWER 6 |
- |
-static XML_Bool FASTCALL |
-keyeq(KEY s1, KEY s2) |
-{ |
- for (; *s1 == *s2; s1++, s2++) |
- if (*s1 == 0) |
- return XML_TRUE; |
- return XML_FALSE; |
-} |
- |
-static unsigned long FASTCALL |
-hash(XML_Parser parser, KEY s) |
-{ |
- unsigned long h = hash_secret_salt; |
- while (*s) |
- h = CHAR_HASH(h, *s++); |
- return h; |
-} |
- |
-static NAMED * |
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) |
-{ |
- size_t i; |
- if (table->size == 0) { |
- size_t tsize; |
- if (!createSize) |
- return NULL; |
- table->power = INIT_POWER; |
- /* table->size is a power of 2 */ |
- table->size = (size_t)1 << INIT_POWER; |
- tsize = table->size * sizeof(NAMED *); |
- table->v = (NAMED **)table->mem->malloc_fcn(tsize); |
- if (!table->v) { |
- table->size = 0; |
- return NULL; |
- } |
- memset(table->v, 0, tsize); |
- i = hash(parser, name) & ((unsigned long)table->size - 1); |
- } |
- else { |
- unsigned long h = hash(parser, name); |
- unsigned long mask = (unsigned long)table->size - 1; |
- unsigned char step = 0; |
- i = h & mask; |
- while (table->v[i]) { |
- if (keyeq(name, table->v[i]->name)) |
- return table->v[i]; |
- if (!step) |
- step = PROBE_STEP(h, mask, table->power); |
- i < step ? (i += table->size - step) : (i -= step); |
- } |
- if (!createSize) |
- return NULL; |
- |
- /* check for overflow (table is half full) */ |
- if (table->used >> (table->power - 1)) { |
- unsigned char newPower = table->power + 1; |
- size_t newSize = (size_t)1 << newPower; |
- unsigned long newMask = (unsigned long)newSize - 1; |
- size_t tsize = newSize * sizeof(NAMED *); |
- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); |
- if (!newV) |
- return NULL; |
- memset(newV, 0, tsize); |
- for (i = 0; i < table->size; i++) |
- if (table->v[i]) { |
- unsigned long newHash = hash(parser, table->v[i]->name); |
- size_t j = newHash & newMask; |
- step = 0; |
- while (newV[j]) { |
- if (!step) |
- step = PROBE_STEP(newHash, newMask, newPower); |
- j < step ? (j += newSize - step) : (j -= step); |
- } |
- newV[j] = table->v[i]; |
- } |
- table->mem->free_fcn(table->v); |
- table->v = newV; |
- table->power = newPower; |
- table->size = newSize; |
- i = h & newMask; |
- step = 0; |
- while (table->v[i]) { |
- if (!step) |
- step = PROBE_STEP(h, newMask, newPower); |
- i < step ? (i += newSize - step) : (i -= step); |
- } |
- } |
- } |
- table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); |
- if (!table->v[i]) |
- return NULL; |
- memset(table->v[i], 0, createSize); |
- table->v[i]->name = name; |
- (table->used)++; |
- return table->v[i]; |
-} |
- |
-static void FASTCALL |
-hashTableClear(HASH_TABLE *table) |
-{ |
- size_t i; |
- for (i = 0; i < table->size; i++) { |
- table->mem->free_fcn(table->v[i]); |
- table->v[i] = NULL; |
- } |
- table->used = 0; |
-} |
- |
-static void FASTCALL |
-hashTableDestroy(HASH_TABLE *table) |
-{ |
- size_t i; |
- for (i = 0; i < table->size; i++) |
- table->mem->free_fcn(table->v[i]); |
- table->mem->free_fcn(table->v); |
-} |
- |
-static void FASTCALL |
-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) |
-{ |
- p->power = 0; |
- p->size = 0; |
- p->used = 0; |
- p->v = NULL; |
- p->mem = ms; |
-} |
- |
-static void FASTCALL |
-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) |
-{ |
- iter->p = table->v; |
- iter->end = iter->p + table->size; |
-} |
- |
-static NAMED * FASTCALL |
-hashTableIterNext(HASH_TABLE_ITER *iter) |
-{ |
- while (iter->p != iter->end) { |
- NAMED *tem = *(iter->p)++; |
- if (tem) |
- return tem; |
- } |
- return NULL; |
-} |
- |
-static void FASTCALL |
-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) |
-{ |
- pool->blocks = NULL; |
- pool->freeBlocks = NULL; |
- pool->start = NULL; |
- pool->ptr = NULL; |
- pool->end = NULL; |
- pool->mem = ms; |
-} |
- |
-static void FASTCALL |
-poolClear(STRING_POOL *pool) |
-{ |
- if (!pool->freeBlocks) |
- pool->freeBlocks = pool->blocks; |
- else { |
- BLOCK *p = pool->blocks; |
- while (p) { |
- BLOCK *tem = p->next; |
- p->next = pool->freeBlocks; |
- pool->freeBlocks = p; |
- p = tem; |
- } |
- } |
- pool->blocks = NULL; |
- pool->start = NULL; |
- pool->ptr = NULL; |
- pool->end = NULL; |
-} |
- |
-static void FASTCALL |
-poolDestroy(STRING_POOL *pool) |
-{ |
- BLOCK *p = pool->blocks; |
- while (p) { |
- BLOCK *tem = p->next; |
- pool->mem->free_fcn(p); |
- p = tem; |
- } |
- p = pool->freeBlocks; |
- while (p) { |
- BLOCK *tem = p->next; |
- pool->mem->free_fcn(p); |
- p = tem; |
- } |
-} |
- |
-static XML_Char * |
-poolAppend(STRING_POOL *pool, const ENCODING *enc, |
- const char *ptr, const char *end) |
-{ |
- if (!pool->ptr && !poolGrow(pool)) |
- return NULL; |
- for (;;) { |
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); |
- if (ptr == end) |
- break; |
- if (!poolGrow(pool)) |
- return NULL; |
- } |
- return pool->start; |
-} |
- |
-static const XML_Char * FASTCALL |
-poolCopyString(STRING_POOL *pool, const XML_Char *s) |
-{ |
- do { |
- if (!poolAppendChar(pool, *s)) |
- return NULL; |
- } while (*s++); |
- s = pool->start; |
- poolFinish(pool); |
- return s; |
-} |
- |
-static const XML_Char * |
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) |
-{ |
- if (!pool->ptr && !poolGrow(pool)) |
- return NULL; |
- for (; n > 0; --n, s++) { |
- if (!poolAppendChar(pool, *s)) |
- return NULL; |
- } |
- s = pool->start; |
- poolFinish(pool); |
- return s; |
-} |
- |
-static const XML_Char * FASTCALL |
-poolAppendString(STRING_POOL *pool, const XML_Char *s) |
-{ |
- while (*s) { |
- if (!poolAppendChar(pool, *s)) |
- return NULL; |
- s++; |
- } |
- return pool->start; |
-} |
- |
-static XML_Char * |
-poolStoreString(STRING_POOL *pool, const ENCODING *enc, |
- const char *ptr, const char *end) |
-{ |
- if (!poolAppend(pool, enc, ptr, end)) |
- return NULL; |
- if (pool->ptr == pool->end && !poolGrow(pool)) |
- return NULL; |
- *(pool->ptr)++ = 0; |
- return pool->start; |
-} |
- |
-static XML_Bool FASTCALL |
-poolGrow(STRING_POOL *pool) |
-{ |
- if (pool->freeBlocks) { |
- if (pool->start == 0) { |
- pool->blocks = pool->freeBlocks; |
- pool->freeBlocks = pool->freeBlocks->next; |
- pool->blocks->next = NULL; |
- pool->start = pool->blocks->s; |
- pool->end = pool->start + pool->blocks->size; |
- pool->ptr = pool->start; |
- return XML_TRUE; |
- } |
- if (pool->end - pool->start < pool->freeBlocks->size) { |
- BLOCK *tem = pool->freeBlocks->next; |
- pool->freeBlocks->next = pool->blocks; |
- pool->blocks = pool->freeBlocks; |
- pool->freeBlocks = tem; |
- memcpy(pool->blocks->s, pool->start, |
- (pool->end - pool->start) * sizeof(XML_Char)); |
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start); |
- pool->start = pool->blocks->s; |
- pool->end = pool->start + pool->blocks->size; |
- return XML_TRUE; |
- } |
- } |
- if (pool->blocks && pool->start == pool->blocks->s) { |
- int blockSize = (int)(pool->end - pool->start)*2; |
- BLOCK *temp = (BLOCK *) |
- pool->mem->realloc_fcn(pool->blocks, |
- (offsetof(BLOCK, s) |
- + blockSize * sizeof(XML_Char))); |
- if (temp == NULL) |
- return XML_FALSE; |
- pool->blocks = temp; |
- pool->blocks->size = blockSize; |
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start); |
- pool->start = pool->blocks->s; |
- pool->end = pool->start + blockSize; |
- } |
- else { |
- BLOCK *tem; |
- int blockSize = (int)(pool->end - pool->start); |
- if (blockSize < INIT_BLOCK_SIZE) |
- blockSize = INIT_BLOCK_SIZE; |
- else |
- blockSize *= 2; |
- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) |
- + blockSize * sizeof(XML_Char)); |
- if (!tem) |
- return XML_FALSE; |
- tem->size = blockSize; |
- tem->next = pool->blocks; |
- pool->blocks = tem; |
- if (pool->ptr != pool->start) |
- memcpy(tem->s, pool->start, |
- (pool->ptr - pool->start) * sizeof(XML_Char)); |
- pool->ptr = tem->s + (pool->ptr - pool->start); |
- pool->start = tem->s; |
- pool->end = tem->s + blockSize; |
- } |
- return XML_TRUE; |
-} |
- |
-static int FASTCALL |
-nextScaffoldPart(XML_Parser parser) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- CONTENT_SCAFFOLD * me; |
- int next; |
- |
- if (!dtd->scaffIndex) { |
- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); |
- if (!dtd->scaffIndex) |
- return -1; |
- dtd->scaffIndex[0] = 0; |
- } |
- |
- if (dtd->scaffCount >= dtd->scaffSize) { |
- CONTENT_SCAFFOLD *temp; |
- if (dtd->scaffold) { |
- temp = (CONTENT_SCAFFOLD *) |
- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); |
- if (temp == NULL) |
- return -1; |
- dtd->scaffSize *= 2; |
- } |
- else { |
- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS |
- * sizeof(CONTENT_SCAFFOLD)); |
- if (temp == NULL) |
- return -1; |
- dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; |
- } |
- dtd->scaffold = temp; |
- } |
- next = dtd->scaffCount++; |
- me = &dtd->scaffold[next]; |
- if (dtd->scaffLevel) { |
- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; |
- if (parent->lastchild) { |
- dtd->scaffold[parent->lastchild].nextsib = next; |
- } |
- if (!parent->childcnt) |
- parent->firstchild = next; |
- parent->lastchild = next; |
- parent->childcnt++; |
- } |
- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; |
- return next; |
-} |
- |
-static void |
-build_node(XML_Parser parser, |
- int src_node, |
- XML_Content *dest, |
- XML_Content **contpos, |
- XML_Char **strpos) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- dest->type = dtd->scaffold[src_node].type; |
- dest->quant = dtd->scaffold[src_node].quant; |
- if (dest->type == XML_CTYPE_NAME) { |
- const XML_Char *src; |
- dest->name = *strpos; |
- src = dtd->scaffold[src_node].name; |
- for (;;) { |
- *(*strpos)++ = *src; |
- if (!*src) |
- break; |
- src++; |
- } |
- dest->numchildren = 0; |
- dest->children = NULL; |
- } |
- else { |
- unsigned int i; |
- int cn; |
- dest->numchildren = dtd->scaffold[src_node].childcnt; |
- dest->children = *contpos; |
- *contpos += dest->numchildren; |
- for (i = 0, cn = dtd->scaffold[src_node].firstchild; |
- i < dest->numchildren; |
- i++, cn = dtd->scaffold[cn].nextsib) { |
- build_node(parser, cn, &(dest->children[i]), contpos, strpos); |
- } |
- dest->name = NULL; |
- } |
-} |
- |
-static XML_Content * |
-build_model (XML_Parser parser) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- XML_Content *ret; |
- XML_Content *cpos; |
- XML_Char * str; |
- int allocsize = (dtd->scaffCount * sizeof(XML_Content) |
- + (dtd->contentStringLen * sizeof(XML_Char))); |
- |
- ret = (XML_Content *)MALLOC(allocsize); |
- if (!ret) |
- return NULL; |
- |
- str = (XML_Char *) (&ret[dtd->scaffCount]); |
- cpos = &ret[1]; |
- |
- build_node(parser, 0, ret, &cpos, &str); |
- return ret; |
-} |
- |
-static ELEMENT_TYPE * |
-getElementType(XML_Parser parser, |
- const ENCODING *enc, |
- const char *ptr, |
- const char *end) |
-{ |
- DTD * const dtd = _dtd; /* save one level of indirection */ |
- const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); |
- ELEMENT_TYPE *ret; |
- |
- if (!name) |
- return NULL; |
- ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); |
- if (!ret) |
- return NULL; |
- if (ret->name != name) |
- poolDiscard(&dtd->pool); |
- else { |
- poolFinish(&dtd->pool); |
- if (!setElementTypePrefix(parser, ret)) |
- return NULL; |
- } |
- return ret; |
-} |