| 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;
|
| -}
|
|
|