+++ /dev/null
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above. If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include <string.h>
-#include <stdlib.h>
-#include <new.h>
-#include "xmlparse.hpp"
-
-#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 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_WCHAR_T
-#define XML_T(x) L ## x
-#else
-#define XML_T(x) x
-#endif
-
-/* Round up n to be a multiple of sz, where sz is a power of 2. */
-inline int ROUND_UP(int n, int sz)
-{
- return (n + (sz - 1)) & ~(sz - 1);
-}
-
-#include "xmltok.h"
-#include "xmlrole.h"
-
-const int INIT_BLOCK_SIZE = 1024;
-const int INIT_TAG_BUF_SIZE = 32; /* must be a multiple of sizeof(XML_Char) */
-const int INIT_DATA_BUF_SIZE = 1024;
-const int INIT_ATTS_SIZE = 16;
-const int INIT_BUFFER_SIZE = 1024;
-
-const int EXPAND_SPARE = 24;
-
-typedef const XML_Char *Key;
-
-struct Named {
- Key name;
-};
-
-class HashTable {
-public:
- HashTable();
- ~HashTable();
- Named *lookup(Key name, size_t createSize);
- friend class HashTableIter;
-private:
- static unsigned long hash(Key s);
- static int keyeq(Key, Key);
- Named **v_;
- size_t size_;
- size_t used_;
- size_t usedLim_;
-};
-
-class HashTableIter {
-public:
- HashTableIter();
- HashTableIter(const HashTable &);
- Named *next();
- void init(const HashTable &);
-private:
- Named **p_;
- Named **end_;
-};
-
-class StringPool {
-public:
- StringPool();
- ~StringPool();
- void clear();
- const XML_Char *start() const {
- return start_;
- }
- const int length() const {
- return ptr_ - start_;
- }
- void chop() {
- --ptr_;
- }
- XML_Char lastChar() const {
- return ptr_[-1];
- }
-
- void discard() {
- ptr_ = start_;
- }
- void finish() {
- start_ = ptr_;
- }
-
- int appendChar(XML_Char c) {
- if (ptr_ == end_ && !grow())
- return 0;
- else {
- *ptr_++ = c;
- return 1;
- }
- }
- XML_Char *append(const ENCODING *enc, const char *ptr, const char *end);
- XML_Char *storeString(const ENCODING *enc,
- const char *ptr, const char *end);
- const XML_Char *copyString(const XML_Char *s);
- const XML_Char *copyStringN(const XML_Char *s, int n);
-private:
- int grow();
-
- struct Block {
- Block *next;
- int size;
- XML_Char *s() {
- return (XML_Char *)(this + 1);
- }
- };
-
- Block *blocks_;
- Block *freeBlocks_;
- const XML_Char *end_;
- XML_Char *ptr_;
- XML_Char *start_;
-};
-
-struct Prefix;
-struct AttributeId;
-
-struct Binding {
- Prefix *prefix;
- Binding *nextTagBinding;
- Binding *prevPrefixBinding;
- const AttributeId *attId;
- XML_Char *uri;
- int uriLen;
- int uriAlloc;
-};
-
-struct Prefix {
- const XML_Char *name;
- Binding *binding;
-};
-
-struct TagName {
- const XML_Char *str;
- const XML_Char *localPart;
- int uriLen;
-};
-
-struct Tag {
- Tag *parent;
- const char *rawName;
- int rawNameLength;
- TagName name;
- char *buf;
- char *bufEnd;
- Binding *bindings;
-};
-
-struct Entity {
- const XML_Char *name;
- const XML_Char *textPtr;
- int textLen;
- const XML_Char *systemId;
- const XML_Char *base;
- const XML_Char *publicId;
- const XML_Char *notation;
- char open;
-};
-
-/* The XML_Char before the name is used to determine whether
-an attribute has been specified. */
-struct AttributeId {
- XML_Char *name;
- Prefix *prefix;
- char maybeTokenized;
- char xmlns;
-};
-
-struct DefaultAttribute {
- const AttributeId *id;
- char isCdata;
- const XML_Char *value;
-};
-
-struct ElementType {
- const XML_Char *name;
- Prefix *prefix;
- int nDefaultAtts;
- int allocDefaultAtts;
- DefaultAttribute *defaultAtts;
-};
-
-struct Dtd {
- HashTable generalEntities;
- HashTable elementTypes;
- HashTable attributeIds;
- HashTable prefixes;
- StringPool pool;
- int complete;
- int standalone;
-#ifdef XML_DTD
- HashTable paramEntities;
-#endif /* XML_DTD */
- Prefix defaultPrefix;
- Dtd();
- ~Dtd();
-#ifdef XML_DTD
- static void swap(Dtd &, Dtd &);
-#endif /* XML_DTD */
- static int copy(Dtd &newDtd, const Dtd &oldDtd);
- static int copyEntityTable(HashTable &, StringPool &, const HashTable &);
-};
-
-struct OpenInternalEntity {
- const char *internalEventPtr;
- const char *internalEventEndPtr;
- OpenInternalEntity *next;
- Entity *entity;
-};
-
-class XML_ParserImpl : public XML_Parser {
-public:
- char *buffer;
- // first character to be parsed
- const char *bufferPtr;
- // past last character to be parsed
- char *bufferEnd;
- // allocated end of buffer
- const char *bufferLim;
- long parseEndByteIndex;
- const char *parseEndPtr;
- XML_Char *dataBuf;
- XML_Char *dataBufEnd;
- XML_ElementHandler *elementHandler;
- XML_CharacterDataHandler *characterDataHandler;
- XML_ProcessingInstructionHandler *processingInstructionHandler;
- XML_CommentHandler *commentHandler;
- XML_CdataSectionHandler *cdataSectionHandler;
- XML_DefaultHandler *defaultHandler;
- XML_DoctypeDeclHandler *doctypeDeclHandler;
- XML_UnparsedEntityDeclHandler *unparsedEntityDeclHandler;
- XML_NotationDeclHandler *notationDeclHandler;
- XML_NamespaceDeclHandler *namespaceDeclHandler;
- XML_NotStandaloneHandler *notStandaloneHandler;
- XML_ExternalEntityRefHandler *externalEntityRefHandler;
- XML_UnknownEncodingHandler *unknownEncodingHandler;
- const ENCODING *encoding;
- INIT_ENCODING initEncoding;
- const ENCODING *internalEncoding;
- const XML_Char *protocolEncodingName;
- int ns;
- XML_Encoding *unknownEncoding;
- void *unknownEncodingMem;
- PROLOG_STATE prologState;
- Error (XML_ParserImpl::*processor)(const char *start, const char *end, const char **endPtr);
- Error errorCode;
- const char *eventPtr;
- const char *eventEndPtr;
- const char *positionPtr;
- OpenInternalEntity *openInternalEntities;
- int defaultExpandInternalEntities;
- int tagLevel;
- Entity *declEntity;
- const XML_Char *declNotationName;
- const XML_Char *declNotationPublicId;
- ElementType *declElementType;
- AttributeId *declAttributeId;
- char declAttributeIsCdata;
- Dtd dtd;
- const XML_Char *curBase;
- Tag *tagStack;
- Tag *freeTagList;
- Binding *inheritedBindings;
- Binding *freeBindingList;
- int attsSize;
- int nSpecifiedAtts;
- ATTRIBUTE *atts;
- POSITION position;
- StringPool tempPool;
- StringPool temp2Pool;
- char *groupConnector;
- unsigned groupSize;
- int hadExternalDoctype;
- XML_Char namespaceSeparator;
-#ifdef XML_DTD
- enum ParamEntityParsing paramEntityParsing;
- XML_ParserImpl *parentParser;
-#endif
-private:
- ~XML_ParserImpl();
- Error handleUnknownEncoding(const XML_Char *encodingName);
- Error processXmlDecl(int isGeneralTextEntity, const char *, const char *);
- Error initializeEncoding();
- Error doProlog(const ENCODING *enc, const char *s,
- const char *end, int tok, const char *next, const char **nextPtr);
- Error processInternalParamEntity(Entity *entity);
- Error doContent(int startTagLevel, const ENCODING *enc,
- const char *start, const char *end, const char **endPtr);
- Error doCdataSection(const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
-#ifdef XML_DTD
- Error doIgnoreSection(const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
-#endif /* XML_DTD */
- Error storeAtts(const ENCODING *, const char *s,
- TagName *tagNamePtr, Binding **bindingsPtr);
-
- int addBinding(Prefix *prefix, const AttributeId *attId, const XML_Char *uri, Binding **bindingsPtr);
- static int defineAttribute(ElementType *type, AttributeId *, int isCdata, const XML_Char *dfltValue);
- Error storeAttributeValue(const ENCODING *, int isCdata, const char *, const char *, StringPool &);
- Error appendAttributeValue(const ENCODING *, int isCdata, const char *, const char *, StringPool &);
- AttributeId *getAttributeId(const ENCODING *enc, const char *start, const char *end);
- int setElementTypePrefix(ElementType *);
- Error storeEntityValue(const ENCODING *enc, const char *start, const char *end);
- int reportProcessingInstruction(const ENCODING *enc, const char *start, const char *end);
- int reportComment(const ENCODING *enc, const char *start, const char *end);
- void reportDefault(const ENCODING *enc, const char *start, const char *end);
- const XML_Char *getContext();
- int setContext(const XML_Char *context);
- static void normalizePublicId(XML_Char *s);
- static void normalizeLines(XML_Char *s);
- Error prologProcessor(const char *start, const char *end, const char **endPtr);
- Error prologInitProcessor(const char *start, const char *end, const char **endPtr);
- Error contentProcessor(const char *start, const char *end, const char **endPtr);
- Error cdataSectionProcessor(const char *start, const char *end, const char **endPtr);
-#ifdef XML_DTD
- Error ignoreSectionProcessor(const char *start, const char *end, const char **endPtr);
-#endif /* XML_DTD */
- Error epilogProcessor(const char *start, const char *end, const char **endPtr);
- Error errorProcessor(const char *start, const char *end, const char **endPtr);
- Error externalEntityInitProcessor(const char *start, const char *end, const char **endPtr);
- Error externalEntityInitProcessor2(const char *start, const char *end, const char **endPtr);
- Error externalEntityInitProcessor3(const char *start, const char *end, const char **endPtr);
- Error externalEntityContentProcessor(const char *start, const char *end, const char **endPtr);
-public:
- int init(const XML_Char *encodingName);
- int initNS(const XML_Char *encodingName, XML_Char nsSep);
- void release();
- void setElementHandler(XML_ElementHandler *handler);
- void setCharacterDataHandler(XML_CharacterDataHandler *handler);
- void setProcessingInstructionHandler(XML_ProcessingInstructionHandler *handler);
- void setCommentHandler(XML_CommentHandler *handler);
- void setCdataSectionHandler(XML_CdataSectionHandler *handler);
- void setDefaultHandler(XML_DefaultHandler *handler);
- void setDefaultHandlerExpand(XML_DefaultHandler *handler);
- void setDoctypeDeclHandler(XML_DoctypeDeclHandler *handler);
- void setUnparsedEntityDeclHandler(XML_UnparsedEntityDeclHandler *handler);
- void setNotationDeclHandler(XML_NotationDeclHandler *handler);
- void setNamespaceDeclHandler(XML_NamespaceDeclHandler *handler);
- void setNotStandaloneHandler(XML_NotStandaloneHandler *handler);
- void setExternalEntityRefHandler(XML_ExternalEntityRefHandler *handler);
- void setUnknownEncodingHandler(XML_UnknownEncodingHandler *handler);
- void defaultCurrent();
- int setEncoding(const XML_Char *encoding);
- int setBase(const XML_Char *base);
- const XML_Char *getBase();
- int getSpecifiedAttributeCount();
- int parse(const char *s, int len, int isFinal);
- char *getBuffer(int len);
- int parseBuffer(int len, int isFinal);
- XML_Parser *externalEntityParserCreate(const XML_Char *context, const XML_Char *encoding);
- int setParamEntityParsing(ParamEntityParsing parsing);
- Error getErrorCode();
- int getCurrentLineNumber();
- int getCurrentColumnNumber();
- long getCurrentByteIndex();
- int getCurrentByteCount();
-};
-
-void XML_ParserImpl::release()
-{
- this->~XML_ParserImpl();
- free(this);
-}
-
-XML_Parser *XML_Parser::parserCreate(const XML_Char *encodingName)
-{
- void *mem = malloc(sizeof(XML_ParserImpl));
- if (!mem)
- return 0;
- XML_ParserImpl *p = new (mem) XML_ParserImpl;
- if (!p->init(encodingName)) {
- p->release();
- return 0;
- }
- return p;
-}
-
-XML_Parser *XML_Parser::parserCreateNS(const XML_Char *encodingName, XML_Char namespaceSeparator)
-{
- void *mem = malloc(sizeof(XML_ParserImpl));
- if (!mem)
- return 0;
- XML_ParserImpl *p = new (mem) XML_ParserImpl;
- if (!p->initNS(encodingName, namespaceSeparator)) {
- p->release();
- return 0;
- }
- return p;
-}
-
-
-int XML_ParserImpl::init(const XML_Char *encodingName)
-{
- processor = prologInitProcessor;
- XmlPrologStateInit(&prologState);
- elementHandler = 0;
- characterDataHandler = 0;
- processingInstructionHandler = 0;
- commentHandler = 0;
- cdataSectionHandler = 0;
- defaultHandler = 0;
- doctypeDeclHandler = 0;
- unparsedEntityDeclHandler = 0;
- notationDeclHandler = 0;
- namespaceDeclHandler = 0;
- notStandaloneHandler = 0;
- externalEntityRefHandler = 0;
- unknownEncodingHandler = 0;
- buffer = 0;
- bufferPtr = 0;
- bufferEnd = 0;
- parseEndByteIndex = 0;
- parseEndPtr = 0;
- bufferLim = 0;
- declElementType = 0;
- declAttributeId = 0;
- declEntity = 0;
- declNotationName = 0;
- declNotationPublicId = 0;
- memset(&position, 0, sizeof(POSITION));
- errorCode = ERROR_NONE;
- eventPtr = 0;
- eventEndPtr = 0;
- positionPtr = 0;
- openInternalEntities = 0;
- tagLevel = 0;
- tagStack = 0;
- freeTagList = 0;
- freeBindingList = 0;
- inheritedBindings = 0;
- attsSize = INIT_ATTS_SIZE;
- atts = (ATTRIBUTE *)malloc(attsSize * sizeof(ATTRIBUTE));
- nSpecifiedAtts = 0;
- dataBuf = (XML_Char *)malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
- groupSize = 0;
- groupConnector = 0;
- hadExternalDoctype = 0;
- unknownEncoding = 0;
- unknownEncodingMem = 0;
- namespaceSeparator = '!';
-#ifdef XML_DTD
- parentParser = 0;
- paramEntityParsing = PARAM_ENTITY_PARSING_NEVER;
-#endif
- ns = 0;
- protocolEncodingName = encodingName ? tempPool.copyString(encodingName) : 0;
- curBase = 0;
- if (!atts || !dataBuf
- || (encodingName && !protocolEncodingName))
- return 0;
- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
- XmlInitEncoding(&initEncoding, &encoding, 0);
- internalEncoding = XmlGetInternalEncoding();
- return 1;
-}
-
-
-int XML_ParserImpl::initNS(const XML_Char *encodingName, XML_Char nsSep)
-{
- static
- const XML_Char implicitContext[] = {
- XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
- XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
- XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
- XML_T('.'), XML_T('w'), XML_T('3'),
- XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
- XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
- XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
- XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
- XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
- XML_T('\0')
- };
-
- if (!init(encodingName))
- return 0;
- XmlInitEncodingNS(&initEncoding, &encoding, 0);
- ns = 1;
- internalEncoding = XmlGetInternalEncodingNS();
- namespaceSeparator = nsSep;
- if (!setContext(implicitContext))
- return 0;
- return 1;
-}
-
-int XML_ParserImpl::setEncoding(const XML_Char *encodingName)
-{
- if (!encodingName)
- protocolEncodingName = 0;
- else {
- protocolEncodingName = tempPool.copyString(encodingName);
- if (!protocolEncodingName)
- return 0;
- }
- return 1;
-}
-
-XML_Parser *
-XML_ParserImpl::externalEntityParserCreate(const XML_Char *context,
- const XML_Char *encodingName)
-{
- XML_ParserImpl *parser = (XML_ParserImpl *)(ns
- ? XML_Parser::parserCreateNS(encodingName, namespaceSeparator)
- : XML_Parser::parserCreate(encodingName));
- if (!parser)
- return 0;
- parser->elementHandler = elementHandler;
- parser->characterDataHandler = characterDataHandler;
- parser->processingInstructionHandler = processingInstructionHandler;
- parser->commentHandler = commentHandler;
- parser->cdataSectionHandler = cdataSectionHandler;
- parser->defaultHandler = defaultHandler;
- parser->namespaceDeclHandler = namespaceDeclHandler;
- parser->notStandaloneHandler = notStandaloneHandler;
- parser->externalEntityRefHandler = parser->externalEntityRefHandler;
- parser->unknownEncodingHandler = unknownEncodingHandler;
- parser->defaultExpandInternalEntities = defaultExpandInternalEntities;
-#ifdef XML_DTD
- parser->paramEntityParsing = paramEntityParsing;
- if (context) {
-#endif /* XML_DTD */
- if (!Dtd::copy(parser->dtd, dtd) || !parser->setContext(context)) {
- parser->release();
- return 0;
- }
- parser->processor = externalEntityInitProcessor;
-#ifdef XML_DTD
- }
- else {
- Dtd::swap(parser->dtd, dtd);
- parser->parentParser = this;
- XmlPrologStateInitExternalEntity(&(parser->prologState));
- parser->dtd.complete = 1;
- parser->hadExternalDoctype = 1;
- }
-#endif /* XML_DTD */
- return parser;
-}
-
-static
-void destroyBindings(Binding *bindings)
-{
- for (;;) {
- Binding *b = bindings;
- if (!b)
- break;
- bindings = b->nextTagBinding;
- free(b->uri);
- free(b);
- }
-}
-
-XML_ParserImpl::~XML_ParserImpl()
-{
- for (;;) {
- Tag *p;
- if (tagStack == 0) {
- if (freeTagList == 0)
- break;
- tagStack = freeTagList;
- freeTagList = 0;
- }
- p = tagStack;
- tagStack = tagStack->parent;
- free(p->buf);
- destroyBindings(p->bindings);
- free(p);
- }
- destroyBindings(freeBindingList);
- destroyBindings(inheritedBindings);
-#ifdef XML_DTD
- if (parentParser) {
- if (hadExternalDoctype)
- dtd.complete = 0;
- Dtd::swap(dtd, parentParser->dtd);
- }
-#endif /* XML_DTD */
- free((void *)atts);
- free(groupConnector);
- free(buffer);
- free(dataBuf);
- free(unknownEncodingMem);
- if (unknownEncoding)
- unknownEncoding->release();
-}
-
-int XML_ParserImpl::setBase(const XML_Char *p)
-{
- if (p) {
- p = dtd.pool.copyString(p);
- if (!p)
- return 0;
- curBase = p;
- }
- else
- curBase = 0;
- return 1;
-}
-
-const XML_Char *XML_ParserImpl::getBase()
-{
- return curBase;
-}
-
-int XML_ParserImpl::getSpecifiedAttributeCount()
-{
- return nSpecifiedAtts;
-}
-
-void XML_ParserImpl::setElementHandler(XML_ElementHandler *handler)
-{
- elementHandler = handler;
-}
-
-void XML_ParserImpl::setCharacterDataHandler(XML_CharacterDataHandler *handler)
-{
- characterDataHandler = handler;
-}
-
-void XML_ParserImpl::setProcessingInstructionHandler(XML_ProcessingInstructionHandler *handler)
-{
- processingInstructionHandler = handler;
-}
-
-void XML_ParserImpl::setCommentHandler(XML_CommentHandler *handler)
-{
- commentHandler = handler;
-}
-
-void XML_ParserImpl::setCdataSectionHandler(XML_CdataSectionHandler *handler)
-{
- cdataSectionHandler = handler;
-}
-
-void XML_ParserImpl::setDefaultHandler(XML_DefaultHandler *handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = 0;
-}
-
-void XML_ParserImpl::setDefaultHandlerExpand(XML_DefaultHandler *handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = 1;
-}
-
-void XML_ParserImpl::setDoctypeDeclHandler(XML_DoctypeDeclHandler *handler)
-{
- doctypeDeclHandler = handler;
-}
-
-void XML_ParserImpl::setUnparsedEntityDeclHandler(XML_UnparsedEntityDeclHandler *handler)
-{
- unparsedEntityDeclHandler = handler;
-}
-
-void XML_ParserImpl::setNotationDeclHandler(XML_NotationDeclHandler *handler)
-{
- notationDeclHandler = handler;
-}
-
-void XML_ParserImpl::setNamespaceDeclHandler(XML_NamespaceDeclHandler *handler)
-{
- namespaceDeclHandler = handler;
-}
-
-void XML_ParserImpl::setNotStandaloneHandler(XML_NotStandaloneHandler *handler)
-{
- notStandaloneHandler = handler;
-}
-
-void XML_ParserImpl::setExternalEntityRefHandler(XML_ExternalEntityRefHandler *handler)
-{
- externalEntityRefHandler = handler;
-}
-
-void XML_ParserImpl::setUnknownEncodingHandler(XML_UnknownEncodingHandler *handler)
-{
- unknownEncodingHandler = handler;
-}
-
-int XML_ParserImpl::setParamEntityParsing(ParamEntityParsing parsing)
-{
-#ifdef XML_DTD
- paramEntityParsing = parsing;
- return 1;
-#else
- return parsing == PARAM_ENTITY_PARSING_NEVER;
-#endif
-}
-
-int XML_ParserImpl::parse(const char *s, int len, int isFinal)
-{
- if (len == 0) {
- if (!isFinal)
- return 1;
- positionPtr = bufferPtr;
- errorCode = (this->*processor)(bufferPtr, parseEndPtr = bufferEnd, 0);
- if (errorCode == ERROR_NONE)
- return 1;
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return 0;
- }
- else if (bufferPtr == bufferEnd) {
- const char *end;
- int nLeftOver;
- parseEndByteIndex += len;
- positionPtr = s;
- if (isFinal) {
- errorCode = (this->*processor)(s, parseEndPtr = s + len, 0);
- if (errorCode == ERROR_NONE)
- return 1;
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return 0;
- }
- errorCode = (this->*processor)(s, parseEndPtr = s + len, &end);
- if (errorCode != ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return 0;
- }
- XmlUpdatePosition(encoding, positionPtr, end, &position);
- nLeftOver = s + len - end;
- if (nLeftOver) {
- if (buffer == 0 || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- buffer = (char *)(buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2));
- /* FIXME storage leak if realloc fails */
- if (!buffer) {
- errorCode = ERROR_NO_MEMORY;
- eventPtr = eventEndPtr = 0;
- processor = errorProcessor;
- return 0;
- }
- bufferLim = buffer + len * 2;
- }
- memcpy(buffer, end, nLeftOver);
- bufferPtr = buffer;
- bufferEnd = buffer + nLeftOver;
- }
- return 1;
- }
- else {
- memcpy(getBuffer(len), s, len);
- return parseBuffer(len, isFinal);
- }
-}
-
-int XML_ParserImpl::parseBuffer(int len, int isFinal)
-{
- const char *start = bufferPtr;
- positionPtr = start;
- bufferEnd += len;
- parseEndByteIndex += len;
- errorCode = (this->*processor)(start, parseEndPtr = bufferEnd,
- isFinal ? (const char **)0 : &bufferPtr);
- if (errorCode == ERROR_NONE) {
- if (!isFinal)
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- return 1;
- }
- else {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return 0;
- }
-}
-
-char *XML_ParserImpl::getBuffer(int len)
-{
- if (len > bufferLim - bufferEnd) {
- /* FIXME avoid integer overflow */
- int neededSize = len + (bufferEnd - bufferPtr);
- if (neededSize <= bufferLim - buffer) {
- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
- bufferEnd = buffer + (bufferEnd - bufferPtr);
- bufferPtr = buffer;
- }
- else {
- char *newBuf;
- int bufferSize = bufferLim - bufferPtr;
- if (bufferSize == 0)
- bufferSize = INIT_BUFFER_SIZE;
- do {
- bufferSize *= 2;
- } while (bufferSize < neededSize);
- newBuf = (char *)malloc(bufferSize);
- if (newBuf == 0) {
- errorCode = ERROR_NO_MEMORY;
- return 0;
- }
- bufferLim = newBuf + bufferSize;
- if (bufferPtr) {
- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
- free(buffer);
- }
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
- }
- }
- return bufferEnd;
-}
-
-XML_Parser::Error XML_ParserImpl::getErrorCode()
-{
- return errorCode;
-}
-
-long XML_ParserImpl::getCurrentByteIndex()
-{
- if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
- return -1;
-}
-
-int XML_ParserImpl::getCurrentByteCount()
-{
- if (eventEndPtr && eventPtr)
- return eventEndPtr - eventPtr;
- return 0;
-}
-
-int XML_ParserImpl::getCurrentLineNumber()
-{
- if (eventPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.lineNumber + 1;
-}
-
-int XML_ParserImpl::getCurrentColumnNumber()
-{
- if (eventPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.columnNumber;
-}
-
-void XML_ParserImpl::defaultCurrent()
-{
- if (defaultHandler) {
- if (openInternalEntities)
- reportDefault(internalEncoding,
- openInternalEntities->internalEventPtr,
- openInternalEntities->internalEventEndPtr);
- else
- reportDefault(encoding, eventPtr, eventEndPtr);
- }
-}
-
-const XML_LChar *XML_Parser::errorString(int code)
-{
- static const XML_LChar *message[] = {
- 0,
- XML_T("out of memory"),
- XML_T("syntax error"),
- XML_T("no element found"),
- XML_T("not well-formed"),
- XML_T("unclosed token"),
- XML_T("unclosed token"),
- XML_T("mismatched tag"),
- XML_T("duplicate attribute"),
- XML_T("junk after document element"),
- XML_T("illegal parameter entity reference"),
- XML_T("undefined entity"),
- XML_T("recursive entity reference"),
- XML_T("asynchronous entity"),
- XML_T("reference to invalid character number"),
- XML_T("reference to binary entity"),
- XML_T("reference to external entity in attribute"),
- XML_T("xml processing instruction not at start of external entity"),
- XML_T("unknown encoding"),
- XML_T("encoding specified in XML declaration is incorrect"),
- XML_T("unclosed CDATA section"),
- XML_T("error in processing external entity reference"),
- XML_T("document is not standalone")
- };
- if (code > 0 && code < sizeof(message)/sizeof(message[0]))
- return message[code];
- return 0;
-}
-
-XML_Parser::Error
-XML_ParserImpl::contentProcessor(const char *start,
- const char *end,
- const char **endPtr)
-{
- return doContent(0, encoding, start, end, endPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::externalEntityInitProcessor(const char *start,
- const char *end,
- const char **endPtr)
-{
- Error result = initializeEncoding();
- if (result != ERROR_NONE)
- return result;
- processor = externalEntityInitProcessor2;
- return externalEntityInitProcessor2(start, end, endPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::externalEntityInitProcessor2(const char *start,
- const char *end,
- const char **endPtr)
-{
- const char *next;
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_BOM:
- start = next;
- break;
- case XML_TOK_PARTIAL:
- if (endPtr) {
- *endPtr = start;
- return ERROR_NONE;
- }
- eventPtr = start;
- return ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (endPtr) {
- *endPtr = start;
- return ERROR_NONE;
- }
- eventPtr = start;
- return ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityInitProcessor3;
- return externalEntityInitProcessor3(start, end, endPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::externalEntityInitProcessor3(const char *start,
- const char *end,
- const char **endPtr)
-{
- const char *next;
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_XML_DECL:
- {
- Error result = processXmlDecl(1, start, next);
- if (result != ERROR_NONE)
- return result;
- start = next;
- }
- break;
- case XML_TOK_PARTIAL:
- if (endPtr) {
- *endPtr = start;
- return ERROR_NONE;
- }
- eventPtr = start;
- return ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (endPtr) {
- *endPtr = start;
- return ERROR_NONE;
- }
- eventPtr = start;
- return ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityContentProcessor;
- tagLevel = 1;
- return doContent(1, encoding, start, end, endPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::externalEntityContentProcessor(const char *start,
- const char *end,
- const char **endPtr)
-{
- return doContent(1, encoding, start, end, endPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::doContent(int startTagLevel,
- const ENCODING *enc,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- 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 (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- *eventEndPP = end;
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler->characterData(&c, 1);
- }
- else if (defaultHandler)
- reportDefault(enc, s, end);
- if (startTagLevel == 0)
- return ERROR_NO_ELEMENTS;
- if (tagLevel != startTagLevel)
- return ERROR_ASYNC_ENTITY;
- return ERROR_NONE;
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- if (startTagLevel > 0) {
- if (tagLevel != startTagLevel)
- return ERROR_ASYNC_ENTITY;
- return ERROR_NONE;
- }
- return ERROR_NO_ELEMENTS;
- case XML_TOK_INVALID:
- *eventPP = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_PARTIAL_CHAR;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- Entity *entity;
- XML_Char ch = XmlPredefinedEntityName(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (characterDataHandler)
- characterDataHandler->characterData(&ch, 1);
- else if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- }
- name = dtd.pool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return ERROR_NO_MEMORY;
- entity = (Entity *)dtd.generalEntities.lookup(name, 0);
- dtd.pool.discard();
- if (!entity) {
- if (dtd.complete || dtd.standalone)
- return ERROR_UNDEFINED_ENTITY;
- if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- }
- if (entity->open)
- return ERROR_RECURSIVE_ENTITY_REF;
- if (entity->notation)
- return ERROR_BINARY_ENTITY_REF;
- if (entity) {
- if (entity->textPtr) {
- Error result;
- OpenInternalEntity openEntity;
- if (defaultHandler && !defaultExpandInternalEntities) {
- reportDefault(enc, s, next);
- break;
- }
- entity->open = 1;
- openEntity.next = openInternalEntities;
- openInternalEntities = &openEntity;
- openEntity.entity = entity;
- openEntity.internalEventPtr = 0;
- openEntity.internalEventEndPtr = 0;
- result = doContent(tagLevel,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr + entity->textLen),
- 0);
- entity->open = 0;
- openInternalEntities = openEntity.next;
- if (result)
- return result;
- }
- else if (externalEntityRefHandler) {
- const XML_Char *context;
- entity->open = 1;
- context = getContext();
- entity->open = 0;
- if (!context)
- return ERROR_NO_MEMORY;
- if (!externalEntityRefHandler->externalEntityRef(this,
- context,
- entity->base,
- entity->systemId,
- entity->publicId))
- return ERROR_EXTERNAL_ENTITY_HANDLING;
- tempPool.discard();
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- }
- break;
- }
- case XML_TOK_START_TAG_WITH_ATTS:
- if (!elementHandler) {
- Error result = storeAtts(enc, s, 0, 0);
- if (result)
- return result;
- }
- /* fall through */
- case XML_TOK_START_TAG_NO_ATTS:
- {
- Tag *tag;
- if (freeTagList) {
- tag = freeTagList;
- freeTagList = freeTagList->parent;
- }
- else {
- tag = (Tag *)malloc(sizeof(Tag));
- if (!tag)
- return ERROR_NO_MEMORY;
- tag->buf = (char *)malloc(INIT_TAG_BUF_SIZE);
- if (!tag->buf)
- return ERROR_NO_MEMORY;
- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
- }
- tag->bindings = 0;
- tag->parent = tagStack;
- tagStack = tag;
- tag->name.localPart = 0;
- tag->rawName = s + enc->minBytesPerChar;
- tag->rawNameLength = XmlNameLength(enc, tag->rawName);
- if (nextPtr) {
- /* Need to guarantee that:
- tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
- if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
- int bufSize = tag->rawNameLength * 4;
- bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
- tag->buf = (char *)realloc(tag->buf, bufSize);
- if (!tag->buf)
- return ERROR_NO_MEMORY;
- tag->bufEnd = tag->buf + bufSize;
- }
- memcpy(tag->buf, tag->rawName, tag->rawNameLength);
- tag->rawName = tag->buf;
- }
- ++tagLevel;
- if (elementHandler) {
- Error result;
- XML_Char *toPtr;
- for (;;) {
- const char *rawNameEnd = tag->rawName + tag->rawNameLength;
- const char *fromPtr = tag->rawName;
- int bufSize;
- if (nextPtr)
- toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
- else
- toPtr = (XML_Char *)tag->buf;
- tag->name.str = toPtr;
- XmlConvert(enc,
- &fromPtr, rawNameEnd,
- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
- if (fromPtr == rawNameEnd)
- break;
- bufSize = (tag->bufEnd - tag->buf) << 1;
- tag->buf = (char *)realloc(tag->buf, bufSize);
- if (!tag->buf)
- return ERROR_NO_MEMORY;
- tag->bufEnd = tag->buf + bufSize;
- if (nextPtr)
- tag->rawName = tag->buf;
- }
- *toPtr = XML_T('\0');
- result = storeAtts(enc, s, &(tag->name), &(tag->bindings));
- if (result)
- return result;
- elementHandler->startElement(tag->name.str, (const XML_Char **)atts);
- tempPool.clear();
- }
- else {
- tag->name.str = 0;
- if (defaultHandler)
- reportDefault(enc, s, next);
- }
- break;
- }
- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
- if (!elementHandler) {
- Error result = storeAtts(enc, s, 0, 0);
- if (result)
- return result;
- }
- /* fall through */
- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
- if (elementHandler) {
- const char *rawName = s + enc->minBytesPerChar;
- Error result;
- Binding *bindings = 0;
- TagName name;
- name.str = tempPool.storeString(enc, rawName,
- rawName + XmlNameLength(enc, rawName));
- if (!name.str)
- return ERROR_NO_MEMORY;
- tempPool.finish();
- result = storeAtts(enc, s, &name, &bindings);
- if (result)
- return result;
- tempPool.finish();
- if (elementHandler) {
- elementHandler->startElement(name.str, (const XML_Char **)atts);
- *eventPP = *eventEndPP;
- elementHandler->endElement(name.str);
- }
- tempPool.clear();
- while (bindings) {
- Binding *b = bindings;
- if (namespaceDeclHandler)
- namespaceDeclHandler->endNamespaceDecl(b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- if (tagLevel == 0)
- return epilogProcessor(next, end, nextPtr);
- break;
- case XML_TOK_END_TAG:
- if (tagLevel == startTagLevel)
- return 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 ERROR_TAG_MISMATCH;
- }
- --tagLevel;
- if (elementHandler && tag->name.str) {
- if (tag->name.localPart) {
- XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
- const XML_Char *from = tag->name.localPart;
- while ((*to++ = *from++) != 0)
- ;
- }
- elementHandler->endElement(tag->name.str);
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- while (tag->bindings) {
- Binding *b = tag->bindings;
- if (namespaceDeclHandler)
- namespaceDeclHandler->endNamespaceDecl(b->prefix->name);
- tag->bindings = tag->bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- if (tagLevel == 0)
- return epilogProcessor(next, end, nextPtr);
- }
- break;
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(enc, s);
- if (n < 0)
- return ERROR_BAD_CHAR_REF;
- if (characterDataHandler) {
- XML_Char buf[XML_ENCODE_MAX];
- characterDataHandler->characterData(buf, XmlEncode(n, (ICHAR *)buf));
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- }
- break;
- case XML_TOK_XML_DECL:
- return ERROR_MISPLACED_XML_PI;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler->characterData(&c, 1);
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- case XML_TOK_CDATA_SECT_OPEN:
- {
- Error result;
- if (cdataSectionHandler)
- cdataSectionHandler->startCdataSection();
-#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->characterData(dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(enc, s, next);
- result = doCdataSection(enc, &next, end, nextPtr);
- if (!next) {
- processor = cdataSectionProcessor;
- return result;
- }
- }
- break;
- case XML_TOK_TRAILING_RSQB:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- characterDataHandler->characterData(dataBuf, dataPtr - (ICHAR *)dataBuf);
- }
- else
- characterDataHandler->characterData((XML_Char *)s,
- (XML_Char *)end - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(enc, s, end);
- if (startTagLevel == 0) {
- *eventPP = end;
- return ERROR_NO_ELEMENTS;
- }
- if (tagLevel != startTagLevel) {
- *eventPP = end;
- return ERROR_ASYNC_ENTITY;
- }
- return ERROR_NONE;
- case XML_TOK_DATA_CHARS:
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- characterDataHandler->characterData(dataBuf, dataPtr - (ICHAR *)dataBuf);
- if (s == next)
- break;
- *eventPP = s;
- }
- }
- else
- characterDataHandler->characterData((XML_Char *)s,
- (XML_Char *)next - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(enc, s, next))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(enc, s, next))
- return ERROR_NO_MEMORY;
- break;
- default:
- if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- }
- *eventPP = s = next;
- }
- /* not reached */
-}
-
-/* If tagNamePtr is non-null, build a real list of attributes,
-otherwise just check the attributes for well-formedness. */
-
-XML_Parser::Error
-XML_ParserImpl::storeAtts(const ENCODING *enc,
- const char *attStr, TagName *tagNamePtr,
- Binding **bindingsPtr)
-{
- ElementType *elementType = 0;
- int nDefaultAtts = 0;
- const XML_Char **appAtts; /* the attribute list to pass to the application */
- int attIndex = 0;
- int i;
- int n;
- int nPrefixes = 0;
- Binding *binding;
- const XML_Char *localPart;
-
- /* lookup the element type name */
- if (tagNamePtr) {
- elementType = (ElementType *)dtd.elementTypes.lookup(tagNamePtr->str, 0);
- if (!elementType) {
- tagNamePtr->str = dtd.pool.copyString(tagNamePtr->str);
- if (!tagNamePtr->str)
- return ERROR_NO_MEMORY;
- elementType = (ElementType *)dtd.elementTypes.lookup(tagNamePtr->str, sizeof(ElementType));
- if (!elementType)
- return ERROR_NO_MEMORY;
- if (ns && !setElementTypePrefix(elementType))
- return 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;
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
- atts = (ATTRIBUTE *)realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (!atts)
- return ERROR_NO_MEMORY;
- if (n > oldAttsSize)
- XmlGetAttributes(enc, attStr, n, atts);
- }
- appAtts = (const XML_Char **)atts;
- for (i = 0; i < n; i++) {
- /* add the name and value to the attribute list */
- AttributeId *attId = getAttributeId(enc, atts[i].name,
- atts[i].name
- + XmlNameLength(enc, atts[i].name));
- if (!attId)
- return ERROR_NO_MEMORY;
- /* detect duplicate attributes */
- if ((attId->name)[-1]) {
- if (enc == encoding)
- eventPtr = atts[i].name;
- return ERROR_DUPLICATE_ATTRIBUTE;
- }
- (attId->name)[-1] = 1;
- appAtts[attIndex++] = attId->name;
- if (!atts[i].normalized) {
- Error result;
- int isCdata = 1;
-
- /* 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(enc, isCdata,
- atts[i].valuePtr, atts[i].valueEnd,
- tempPool);
- if (result)
- return result;
- if (tagNamePtr) {
- appAtts[attIndex] = tempPool.start();
- tempPool.finish();
- }
- else
- tempPool.discard();
- }
- else if (tagNamePtr) {
- appAtts[attIndex] = tempPool.storeString(enc, atts[i].valuePtr, atts[i].valueEnd);
- if (appAtts[attIndex] == 0)
- return ERROR_NO_MEMORY;
- tempPool.finish();
- }
- /* handle prefixed attribute names */
- if (attId->prefix && tagNamePtr) {
- if (attId->xmlns) {
- /* deal with namespace declarations here */
- if (!addBinding(attId->prefix, attId, appAtts[attIndex], bindingsPtr))
- return ERROR_NO_MEMORY;
- --attIndex;
- }
- else {
- /* deal with other prefixed names later */
- attIndex++;
- nPrefixes++;
- (attId->name)[-1] = 2;
- }
- }
- else
- attIndex++;
- }
- nSpecifiedAtts = attIndex;
- /* do attribute defaulting */
- if (tagNamePtr) {
- int j;
- for (j = 0; j < nDefaultAtts; j++) {
- const DefaultAttribute *da = elementType->defaultAtts + j;
- if (!(da->id->name)[-1] && da->value) {
- if (da->id->prefix) {
- if (da->id->xmlns) {
- if (!addBinding(da->id->prefix, da->id, da->value, bindingsPtr))
- return ERROR_NO_MEMORY;
- }
- 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;
- }
- i = 0;
- if (nPrefixes) {
- /* expand prefixed attribute names */
- for (; i < attIndex; i += 2) {
- if (appAtts[i][-1] == 2) {
- AttributeId *id;
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- id = (AttributeId *)dtd.attributeIds.lookup(appAtts[i], 0);
- if (id->prefix->binding) {
- int j;
- const Binding *b = id->prefix->binding;
- const XML_Char *s = appAtts[i];
- for (j = 0; j < b->uriLen; j++) {
- if (!tempPool.appendChar(b->uri[j]))
- return ERROR_NO_MEMORY;
- }
- while (*s++ != ':')
- ;
- do {
- if (!tempPool.appendChar(*s))
- return ERROR_NO_MEMORY;
- } while (*s++);
- appAtts[i] = tempPool.start();
- tempPool.finish();
- }
- if (!--nPrefixes)
- break;
- }
- else
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- }
- }
- /* clear the flags that say whether attributes were specified */
- for (; i < attIndex; i += 2)
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- if (!tagNamePtr)
- return ERROR_NONE;
- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
- binding->attId->name[-1] = 0;
- /* expand the element type name */
- if (elementType->prefix) {
- binding = elementType->prefix->binding;
- if (!binding)
- return ERROR_NONE;
- localPart = tagNamePtr->str;
- while (*localPart++ != XML_T(':'))
- ;
- }
- else if (dtd.defaultPrefix.binding) {
- binding = dtd.defaultPrefix.binding;
- localPart = tagNamePtr->str;
- }
- else
- return ERROR_NONE;
- tagNamePtr->localPart = localPart;
- tagNamePtr->uriLen = binding->uriLen;
- i = binding->uriLen;
- do {
- if (i == binding->uriAlloc) {
- binding->uri = (XML_Char *)realloc(binding->uri, (binding->uriAlloc *= 2) * sizeof(XML_Char));
- if (!binding->uri)
- return ERROR_NO_MEMORY;
- }
- binding->uri[i++] = *localPart;
- } while (*localPart++);
- tagNamePtr->str = binding->uri;
- return ERROR_NONE;
-}
-
-int XML_ParserImpl::addBinding(Prefix *prefix, const AttributeId *attId, const XML_Char *uri, Binding **bindingsPtr)
-{
- Binding *b;
- int len;
- for (len = 0; uri[len]; len++)
- ;
- if (namespaceSeparator)
- len++;
- if (freeBindingList) {
- b = freeBindingList;
- if (len > b->uriAlloc) {
- b->uri = (XML_Char *)realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri)
- return 0;
- b->uriAlloc = len + EXPAND_SPARE;
- }
- freeBindingList = b->nextTagBinding;
- }
- else {
- b = (Binding *)malloc(sizeof(Binding));
- if (!b)
- return 0;
- b->uri = (XML_Char *)malloc(sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri) {
- free(b);
- return 0;
- }
- 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;
- if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
- prefix->binding = 0;
- else
- prefix->binding = b;
- b->nextTagBinding = *bindingsPtr;
- *bindingsPtr = b;
- if (namespaceDeclHandler)
- namespaceDeclHandler->startNamespaceDecl(prefix->name,
- prefix->binding ? uri : 0);
- return 1;
-}
-
-/* The idea here is to avoid using stack for each CDATA section when
-the whole file is parsed with one call. */
-
-XML_Parser::Error
-XML_ParserImpl::cdataSectionProcessor(const char *start,
- const char *end,
- const char **endPtr)
-{
- Error result = doCdataSection(encoding, &start, end, endPtr);
- if (start) {
- processor = contentProcessor;
- return contentProcessor(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. */
-
-XML_Parser::Error
-XML_ParserImpl::doCdataSection(const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr)
-{
- 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 = 0;
- for (;;) {
- const char *next;
- int tok = XmlCdataSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_CDATA_SECT_CLOSE:
- if (cdataSectionHandler)
- cdataSectionHandler->endCdataSection();
-#if 0
- /* see comment under XML_TOK_CDATA_SECT_OPEN */
- else if (characterDataHandler)
- characterDataHandler->characterData(dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(enc, s, next);
- *startPtr = next;
- return ERROR_NONE;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler->characterData(&c, 1);
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- case XML_TOK_DATA_CHARS:
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = next;
- characterDataHandler->characterData(dataBuf, dataPtr - (ICHAR *)dataBuf);
- if (s == next)
- break;
- *eventPP = s;
- }
- }
- else
- characterDataHandler->characterData((XML_Char *)s,
- (XML_Char *)next - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- case XML_TOK_INVALID:
- *eventPP = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_UNCLOSED_CDATA_SECTION;
- default:
- abort();
- }
- *eventPP = s = next;
- }
- /* 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. */
-
-XML_Parser::Error
-XML_ParserImpl::ignoreSectionProcessor(const char *start,
- const char *end,
- const char **endPtr)
-{
- Error result = doIgnoreSection(encoding, &start, end, endPtr);
- if (start) {
- processor = prologProcessor;
- return prologProcessor(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. */
-
-XML_Parser::Error
-XML_ParserImpl::doIgnoreSection(const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr)
-{
- 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 = 0;
- tok = XmlIgnoreSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_IGNORE_SECT:
- if (defaultHandler)
- reportDefault(enc, s, next);
- *startPtr = next;
- return ERROR_NONE;
- case XML_TOK_INVALID:
- *eventPP = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_SYNTAX; /* ERROR_UNCLOSED_IGNORE_SECTION */
- default:
- abort();
- }
- /* not reached */
-}
-
-#endif /* XML_DTD */
-
-XML_Parser::Error
-XML_ParserImpl::initializeEncoding()
-{
- const char *s;
-#ifdef XML_UNICODE
- char encodingBuf[128];
- if (!protocolEncodingName)
- s = 0;
- else {
- int i;
- for (i = 0; protocolEncodingName[i]; i++) {
- if (i == sizeof(encodingBuf) - 1
- || protocolEncodingName[i] >= 0x80
- || protocolEncodingName[i] < 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 ERROR_NONE;
- return handleUnknownEncoding(protocolEncodingName);
-}
-
-XML_Parser::Error
-XML_ParserImpl::processXmlDecl(int isGeneralTextEntity,
- const char *s, const char *next)
-{
- const char *encodingName = 0;
- const ENCODING *newEncoding = 0;
- const char *version;
- int standalone = -1;
- if (!(ns
- ? XmlParseXmlDeclNS
- : XmlParseXmlDecl)(isGeneralTextEntity,
- encoding,
- s,
- next,
- &eventPtr,
- &version,
- &encodingName,
- &newEncoding,
- &standalone))
- return ERROR_SYNTAX;
- if (!isGeneralTextEntity && standalone == 1) {
- dtd.standalone = 1;
-#ifdef XML_DTD
- if (paramEntityParsing == PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
- paramEntityParsing = PARAM_ENTITY_PARSING_NEVER;
-#endif /* XML_DTD */
- }
- if (defaultHandler)
- reportDefault(encoding, s, next);
- if (!protocolEncodingName) {
- if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
- eventPtr = encodingName;
- return ERROR_INCORRECT_ENCODING;
- }
- encoding = newEncoding;
- }
- else if (encodingName) {
- Error result;
- const XML_Char *s = tempPool.storeString(encoding,
- encodingName,
- encodingName
- + XmlNameLength(encoding, encodingName));
- if (!s)
- return ERROR_NO_MEMORY;
- result = handleUnknownEncoding(s);
- tempPool.discard();
- if (result == ERROR_UNKNOWN_ENCODING)
- eventPtr = encodingName;
- return result;
- }
- }
- return ERROR_NONE;
-}
-
-static int convertFunction(void *userData, const char *s)
-{
- return ((XML_Encoding *)userData)->convert(s);
-}
-
-XML_Parser::Error
-XML_ParserImpl::handleUnknownEncoding(const XML_Char *encodingName)
-{
- if (unknownEncodingHandler) {
- XML_Encoding *info = unknownEncodingHandler->unknownEncoding(encodingName);
- if (info) {
- ENCODING *enc;
- unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
- if (!unknownEncodingMem) {
- info->release();
- return ERROR_NO_MEMORY;
- }
- enc = (ns
- ? XmlInitUnknownEncodingNS
- : XmlInitUnknownEncoding)(unknownEncodingMem,
- info->map,
- convertFunction,
- info);
- if (enc) {
- unknownEncoding = info;
- encoding = enc;
- return ERROR_NONE;
- }
- info->release();
- }
- }
- return ERROR_UNKNOWN_ENCODING;
-}
-
-XML_Parser::Error
-XML_ParserImpl::prologInitProcessor(const char *s,
- const char *end,
- const char **nextPtr)
-{
- Error result = initializeEncoding();
- if (result != ERROR_NONE)
- return result;
- processor = prologProcessor;
- return prologProcessor(s, end, nextPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::prologProcessor(const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *next;
- int tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(encoding, s, end, tok, next, nextPtr);
-}
-
-XML_Parser::Error
-XML_ParserImpl::doProlog(const ENCODING *enc,
- const char *s,
- const char *end,
- int tok,
- const char *next,
- const char **nextPtr)
-{
-#ifdef XML_DTD
- static const XML_Char externalSubsetName[] = { '#' , '\0' };
-#endif /* XML_DTD */
-
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- for (;;) {
- int role;
- *eventPP = s;
- *eventEndPP = next;
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- *eventPP = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE:
-#ifdef XML_DTD
- if (enc != encoding)
- return ERROR_NONE;
- if (parentParser) {
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
- == XML_ROLE_ERROR)
- return ERROR_SYNTAX;
- hadExternalDoctype = 0;
- return ERROR_NONE;
- }
-#endif /* XML_DTD */
- return ERROR_NO_ELEMENTS;
- default:
- tok = -tok;
- next = end;
- break;
- }
- }
- role = XmlTokenRole(&prologState, tok, s, next, enc);
- switch (role) {
- case XML_ROLE_XML_DECL:
- {
- Error result = processXmlDecl(0, s, next);
- if (result != ERROR_NONE)
- return result;
- enc = encoding;
- }
- break;
- case XML_ROLE_DOCTYPE_NAME:
- if (doctypeDeclHandler) {
- const XML_Char *name = tempPool.storeString(enc, s, next);
- if (!name)
- return ERROR_NO_MEMORY;
- doctypeDeclHandler->startDoctypeDecl(name);
- tempPool.clear();
- }
- break;
-#ifdef XML_DTD
- case XML_ROLE_TEXT_DECL:
- {
- Error result = processXmlDecl(1, s, next);
- if (result != ERROR_NONE)
- return result;
- enc = encoding;
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_DOCTYPE_PUBLIC_ID:
-#ifdef XML_DTD
- declEntity = (Entity *)dtd.paramEntities.lookup(externalSubsetName,
- sizeof(Entity));
- if (!declEntity)
- return ERROR_NO_MEMORY;
-#endif /* XML_DTD */
- /* fall through */
- case XML_ROLE_ENTITY_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return ERROR_SYNTAX;
- if (declEntity) {
- XML_Char *tem = dtd.pool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declEntity->publicId = tem;
- dtd.pool.finish();
- }
- break;
- case XML_ROLE_DOCTYPE_CLOSE:
- if (dtd.complete && hadExternalDoctype) {
- dtd.complete = 0;
-#ifdef XML_DTD
- if (paramEntityParsing && externalEntityRefHandler) {
- Entity *entity = (Entity *)dtd.paramEntities.lookup(externalSubsetName,
- 0);
- if (!externalEntityRefHandler->externalEntityRef(this,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return ERROR_EXTERNAL_ENTITY_HANDLING;
- }
-#endif /* XML_DTD */
- if (!dtd.complete
- && !dtd.standalone
- && notStandaloneHandler
- && !notStandaloneHandler->notStandalone())
- return ERROR_NOT_STANDALONE;
- }
- if (doctypeDeclHandler)
- doctypeDeclHandler->endDoctypeDecl();
- break;
- case XML_ROLE_INSTANCE_START:
- processor = contentProcessor;
- return contentProcessor(s, end, nextPtr);
- case XML_ROLE_ATTLIST_ELEMENT_NAME:
- {
- const XML_Char *name = dtd.pool.storeString(enc, s, next);
- if (!name)
- return ERROR_NO_MEMORY;
- declElementType = (ElementType *)dtd.elementTypes.lookup(name, sizeof(ElementType));
- if (!declElementType)
- return ERROR_NO_MEMORY;
- if (declElementType->name != name)
- dtd.pool.discard();
- else {
- dtd.pool.finish();
- if (!setElementTypePrefix(declElementType))
- return ERROR_NO_MEMORY;
- }
- break;
- }
- case XML_ROLE_ATTRIBUTE_NAME:
- declAttributeId = getAttributeId(enc, s, next);
- if (!declAttributeId)
- return ERROR_NO_MEMORY;
- declAttributeIsCdata = 0;
- break;
- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
- declAttributeIsCdata = 1;
- break;
- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
- if (dtd.complete
- && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
- return ERROR_NO_MEMORY;
- break;
- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
- {
- const XML_Char *attVal;
- Error result
- = storeAttributeValue(enc, declAttributeIsCdata,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar,
- dtd.pool);
- if (result)
- return result;
- attVal = dtd.pool.start();
- dtd.pool.finish();
- if (dtd.complete
- && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
- return ERROR_NO_MEMORY;
- break;
- }
- case XML_ROLE_ENTITY_VALUE:
- {
- Error result = storeEntityValue(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (declEntity) {
- declEntity->textPtr = dtd.pool.start();
- declEntity->textLen = dtd.pool.length();
- dtd.pool.finish();
- }
- else
- dtd.pool.discard();
- if (result != ERROR_NONE)
- return result;
- }
- break;
- case XML_ROLE_DOCTYPE_SYSTEM_ID:
- if (!dtd.standalone
-#ifdef XML_DTD
- && !paramEntityParsing
-#endif /* XML_DTD */
- && notStandaloneHandler
- && !notStandaloneHandler->notStandalone())
- return ERROR_NOT_STANDALONE;
- hadExternalDoctype = 1;
-#ifndef XML_DTD
- break;
-#else /* XML_DTD */
- if (!declEntity) {
- declEntity = (Entity *)dtd.paramEntities.lookup(externalSubsetName,
- sizeof(Entity));
- if (!declEntity)
- return ERROR_NO_MEMORY;
- }
- /* fall through */
-#endif /* XML_DTD */
- case XML_ROLE_ENTITY_SYSTEM_ID:
- if (declEntity) {
- declEntity->systemId = dtd.pool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!declEntity->systemId)
- return ERROR_NO_MEMORY;
- declEntity->base = curBase;
- dtd.pool.finish();
- }
- break;
- case XML_ROLE_ENTITY_NOTATION_NAME:
- if (declEntity) {
- declEntity->notation = dtd.pool.storeString(enc, s, next);
- if (!declEntity->notation)
- return ERROR_NO_MEMORY;
- dtd.pool.finish();
- if (unparsedEntityDeclHandler) {
- *eventEndPP = s;
- unparsedEntityDeclHandler->unparsedEntityDecl(declEntity->name,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- }
-
- }
- break;
- case XML_ROLE_GENERAL_ENTITY_NAME:
- {
- const XML_Char *name;
- if (XmlPredefinedEntityName(enc, s, next)) {
- declEntity = 0;
- break;
- }
- name = dtd.pool.storeString(enc, s, next);
- if (!name)
- return ERROR_NO_MEMORY;
- if (dtd.complete) {
- declEntity = (Entity *)dtd.generalEntities.lookup(name, sizeof(Entity));
- if (!declEntity)
- return ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- dtd.pool.discard();
- declEntity = 0;
- }
- else
- dtd.pool.finish();
- }
- else {
- dtd.pool.discard();
- declEntity = 0;
- }
- }
- break;
- case XML_ROLE_PARAM_ENTITY_NAME:
-#ifdef XML_DTD
- if (dtd.complete) {
- const XML_Char *name = dtd.pool.storeString(enc, s, next);
- if (!name)
- return ERROR_NO_MEMORY;
- declEntity = (Entity *)dtd.paramEntities.lookup(name, sizeof(Entity));
- if (!declEntity)
- return ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- dtd.pool.discard();
- declEntity = 0;
- }
- else
- dtd.pool.finish();
- }
-#else /* not XML_DTD */
- declEntity = 0;
-#endif /* not XML_DTD */
- break;
- case XML_ROLE_NOTATION_NAME:
- declNotationPublicId = 0;
- declNotationName = 0;
- if (notationDeclHandler) {
- declNotationName = tempPool.storeString(enc, s, next);
- if (!declNotationName)
- return ERROR_NO_MEMORY;
- tempPool.finish();
- }
- break;
- case XML_ROLE_NOTATION_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return ERROR_SYNTAX;
- if (declNotationName) {
- XML_Char *tem = tempPool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declNotationPublicId = tem;
- tempPool.finish();
- }
- break;
- case XML_ROLE_NOTATION_SYSTEM_ID:
- if (declNotationName && notationDeclHandler) {
- const XML_Char *systemId
- = tempPool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!systemId)
- return ERROR_NO_MEMORY;
- *eventEndPP = s;
- notationDeclHandler->notationDecl(declNotationName,
- curBase,
- systemId,
- declNotationPublicId);
- }
- tempPool.clear();
- break;
- case XML_ROLE_NOTATION_NO_SYSTEM_ID:
- if (declNotationPublicId && notationDeclHandler) {
- *eventEndPP = s;
- notationDeclHandler->notationDecl(declNotationName,
- curBase,
- 0,
- declNotationPublicId);
- }
- tempPool.clear();
- break;
- case XML_ROLE_ERROR:
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
- return ERROR_PARAM_ENTITY_REF;
- case XML_TOK_XML_DECL:
- return ERROR_MISPLACED_XML_PI;
- default:
- return ERROR_SYNTAX;
- }
-#ifdef XML_DTD
- case XML_ROLE_IGNORE_SECT:
- {
- Error result;
- if (defaultHandler)
- reportDefault(enc, s, next);
- result = doIgnoreSection(enc, &next, end, nextPtr);
- if (!next) {
- processor = ignoreSectionProcessor;
- return result;
- }
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_GROUP_OPEN:
- if (prologState.level >= groupSize) {
- if (groupSize)
- groupConnector = (char *)realloc(groupConnector, groupSize *= 2);
- else
- groupConnector = (char *)malloc(groupSize = 32);
- if (!groupConnector)
- return ERROR_NO_MEMORY;
- }
- groupConnector[prologState.level] = 0;
- break;
- case XML_ROLE_GROUP_SEQUENCE:
- if (groupConnector[prologState.level] == '|')
- return ERROR_SYNTAX;
- groupConnector[prologState.level] = ',';
- break;
- case XML_ROLE_GROUP_CHOICE:
- if (groupConnector[prologState.level] == ',')
- return ERROR_SYNTAX;
- groupConnector[prologState.level] = '|';
- break;
- case XML_ROLE_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- case XML_ROLE_INNER_PARAM_ENTITY_REF:
- if (paramEntityParsing
- && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
- const XML_Char *name;
- Entity *entity;
- name = dtd.pool.storeString(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return ERROR_NO_MEMORY;
- entity = (Entity *)dtd.paramEntities.lookup(name, 0);
- dtd.pool.discard();
- if (!entity) {
- /* FIXME what to do if !dtd.complete? */
- return ERROR_UNDEFINED_ENTITY;
- }
- if (entity->open)
- return ERROR_RECURSIVE_ENTITY_REF;
- if (entity->textPtr) {
- Error result;
- result = processInternalParamEntity(entity);
- if (result != ERROR_NONE)
- return result;
- break;
- }
- if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
- return ERROR_PARAM_ENTITY_REF;
- if (externalEntityRefHandler) {
- dtd.complete = 0;
- entity->open = 1;
- if (!externalEntityRefHandler->externalEntityRef(this,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = 0;
- return ERROR_EXTERNAL_ENTITY_HANDLING;
- }
- entity->open = 0;
- if (dtd.complete)
- break;
- }
- }
-#endif /* XML_DTD */
- if (!dtd.standalone
- && notStandaloneHandler
- && !notStandaloneHandler->notStandalone())
- return ERROR_NOT_STANDALONE;
- dtd.complete = 0;
- if (defaultHandler)
- reportDefault(enc, s, next);
- break;
- case XML_ROLE_NONE:
- switch (tok) {
- case XML_TOK_PI:
- if (!reportProcessingInstruction(enc, s, next))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(enc, s, next))
- return ERROR_NO_MEMORY;
- break;
- }
- break;
- }
- if (defaultHandler) {
- switch (tok) {
- case XML_TOK_PI:
- case XML_TOK_COMMENT:
- case XML_TOK_BOM:
- case XML_TOK_XML_DECL:
-#ifdef XML_DTD
- case XML_TOK_IGNORE_SECT:
-#endif /* XML_DTD */
- case XML_TOK_PARAM_ENTITY_REF:
- break;
- default:
-#ifdef XML_DTD
- if (role != XML_ROLE_IGNORE_SECT)
-#endif /* XML_DTD */
- reportDefault(enc, s, next);
- }
- }
- s = next;
- tok = XmlPrologTok(enc, s, end, &next);
- }
- /* not reached */
-}
-
-XML_Parser::Error
-XML_ParserImpl::epilogProcessor(const char *s,
- const char *end,
- const char **nextPtr)
-{
- processor = epilogProcessor;
- eventPtr = s;
- for (;;) {
- const char *next;
- int tok = XmlPrologTok(encoding, s, end, &next);
- eventEndPtr = next;
- switch (tok) {
- case -XML_TOK_PROLOG_S:
- if (defaultHandler) {
- eventEndPtr = end;
- reportDefault(encoding, s, end);
- }
- /* fall through */
- case XML_TOK_NONE:
- if (nextPtr)
- *nextPtr = end;
- return ERROR_NONE;
- case XML_TOK_PROLOG_S:
- if (defaultHandler)
- reportDefault(encoding, s, next);
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(encoding, s, next))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(encoding, s, next))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_INVALID:
- eventPtr = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return ERROR_NONE;
- }
- return ERROR_PARTIAL_CHAR;
- default:
- return ERROR_JUNK_AFTER_DOC_ELEMENT;
- }
- eventPtr = s = next;
- }
-}
-
-#ifdef XML_DTD
-
-XML_Parser::Error
-XML_ParserImpl::processInternalParamEntity(Entity *entity)
-{
- const char *s, *end, *next;
- int tok;
- Error result;
- OpenInternalEntity openEntity;
- entity->open = 1;
- openEntity.next = openInternalEntities;
- openInternalEntities = &openEntity;
- openEntity.entity = entity;
- openEntity.internalEventPtr = 0;
- openEntity.internalEventEndPtr = 0;
- s = (char *)entity->textPtr;
- end = (char *)(entity->textPtr + entity->textLen);
- tok = XmlPrologTok(internalEncoding, s, end, &next);
- result = doProlog(internalEncoding, s, end, tok, next, 0);
- entity->open = 0;
- openInternalEntities = openEntity.next;
- return result;
-}
-
-#endif /* XML_DTD */
-
-XML_Parser::Error
-XML_ParserImpl::errorProcessor(const char *s,
- const char *end,
- const char **nextPtr)
-{
- return errorCode;
-}
-
-XML_Parser::Error
-XML_ParserImpl::storeAttributeValue(const ENCODING *enc, int isCdata,
- const char *ptr, const char *end,
- StringPool &pool)
-{
- Error result = appendAttributeValue(enc, isCdata, ptr, end, pool);
- if (result)
- return result;
- if (!isCdata && pool.length() && pool.lastChar() == 0x20)
- pool.chop();
- if (!pool.appendChar(XML_T('\0')))
- return ERROR_NO_MEMORY;
- return ERROR_NONE;
-}
-
-XML_Parser::Error
-XML_ParserImpl::appendAttributeValue(const ENCODING *enc, int isCdata,
- const char *ptr, const char *end,
- StringPool &pool)
-{
- for (;;) {
- const char *next;
- int tok = XmlAttributeValueTok(enc, ptr, end, &next);
- switch (tok) {
- case XML_TOK_NONE:
- return ERROR_NONE;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = ptr;
- return 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 ERROR_BAD_CHAR_REF;
- }
- if (!isCdata
- && n == 0x20 /* space */
- && (pool.length() == 0 || pool.lastChar() == 0x20))
- break;
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = ptr;
- return ERROR_BAD_CHAR_REF;
- }
- for (i = 0; i < n; i++) {
- if (!pool.appendChar(buf[i]))
- return ERROR_NO_MEMORY;
- }
- }
- break;
- case XML_TOK_DATA_CHARS:
- if (!pool.append(enc, ptr, next))
- return ERROR_NO_MEMORY;
- break;
- 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 && (pool.length() == 0 || pool.lastChar() == 0x20))
- break;
- if (!pool.appendChar(0x20))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- Entity *entity;
- XML_Char ch = XmlPredefinedEntityName(enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (!pool.appendChar(ch))
- return ERROR_NO_MEMORY;
- break;
- }
- name = temp2Pool.storeString(enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return ERROR_NO_MEMORY;
- entity = (Entity *)dtd.generalEntities.lookup(name, 0);
- temp2Pool.discard();
- if (!entity) {
- if (dtd.complete) {
- if (enc == encoding)
- eventPtr = ptr;
- return ERROR_UNDEFINED_ENTITY;
- }
- }
- else if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
- return ERROR_RECURSIVE_ENTITY_REF;
- }
- else if (entity->notation) {
- if (enc == encoding)
- eventPtr = ptr;
- return ERROR_BINARY_ENTITY_REF;
- }
- else if (!entity->textPtr) {
- if (enc == encoding)
- eventPtr = ptr;
- return ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
- }
- else {
- Error result;
- const XML_Char *textEnd = entity->textPtr + entity->textLen;
- entity->open = 1;
- result = appendAttributeValue(internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
- entity->open = 0;
- if (result)
- return result;
- }
- }
- break;
- default:
- abort();
- }
- ptr = next;
- }
- /* not reached */
-}
-
-XML_Parser::Error
-XML_ParserImpl::storeEntityValue(const ENCODING *enc,
- const char *entityTextPtr,
- const char *entityTextEnd)
-{
- StringPool &pool = dtd.pool;
- for (;;) {
- const char *next;
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- if (parentParser || enc != encoding) {
- Error result;
- const XML_Char *name;
- Entity *entity;
- name = tempPool.storeString(enc,
- entityTextPtr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return ERROR_NO_MEMORY;
- entity = (Entity *)dtd.paramEntities.lookup(name, 0);
- tempPool.discard();
- if (!entity) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- return ERROR_UNDEFINED_ENTITY;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- return ERROR_RECURSIVE_ENTITY_REF;
- }
- if (entity->systemId) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- return ERROR_PARAM_ENTITY_REF;
- }
- entity->open = 1;
- result = storeEntityValue(internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr + entity->textLen));
- entity->open = 0;
- if (result)
- return result;
- break;
- }
-#endif /* XML_DTD */
- eventPtr = entityTextPtr;
- return ERROR_SYNTAX;
- case XML_TOK_NONE:
- return ERROR_NONE;
- case XML_TOK_ENTITY_REF:
- case XML_TOK_DATA_CHARS:
- if (!pool.append(enc, entityTextPtr, next))
- return ERROR_NO_MEMORY;
- break;
- case XML_TOK_TRAILING_CR:
- next = entityTextPtr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_DATA_NEWLINE:
- if (!pool.appendChar(0xA))
- return ERROR_NO_MEMORY;
- 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;
- return ERROR_BAD_CHAR_REF;
- }
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- return ERROR_BAD_CHAR_REF;
- }
- for (i = 0; i < n; i++)
- if (!pool.appendChar(buf[i]))
- return ERROR_NO_MEMORY;
- }
- break;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- return ERROR_INVALID_TOKEN;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- return ERROR_INVALID_TOKEN;
- default:
- abort();
- }
- entityTextPtr = next;
- }
- /* not reached */
-}
-
-void XML_ParserImpl::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');
-}
-
-int
-XML_ParserImpl::reportProcessingInstruction(const ENCODING *enc, const char *start, const char *end)
-{
- const XML_Char *target;
- XML_Char *data;
- const char *tem;
- if (!processingInstructionHandler) {
- if (defaultHandler)
- reportDefault(enc, start, end);
- return 1;
- }
- start += enc->minBytesPerChar * 2;
- tem = start + XmlNameLength(enc, start);
- target = tempPool.storeString(enc, start, tem);
- if (!target)
- return 0;
- tempPool.finish();
- data = tempPool.storeString(enc,
- XmlSkipS(enc, tem),
- end - enc->minBytesPerChar*2);
- if (!data)
- return 0;
- normalizeLines(data);
- processingInstructionHandler->processingInstruction(target, data);
- tempPool.clear();
- return 1;
-}
-
-int
-XML_ParserImpl::reportComment(const ENCODING *enc, const char *start, const char *end)
-{
- XML_Char *data;
- if (!commentHandler) {
- if (defaultHandler)
- reportDefault(enc, start, end);
- return 1;
- }
- data = tempPool.storeString(enc,
- start + enc->minBytesPerChar * 4,
- end - enc->minBytesPerChar * 3);
- if (!data)
- return 0;
- normalizeLines(data);
- commentHandler->comment(data);
- tempPool.clear();
- return 1;
-}
-
-void
-XML_ParserImpl::reportDefault(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->doDefault(dataBuf, dataPtr - (ICHAR *)dataBuf);
- *eventPP = s;
- } while (s != end);
- }
- else
- defaultHandler->doDefault((XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
-}
-
-
-int
-XML_ParserImpl::defineAttribute(ElementType *type, AttributeId *attId, int isCdata, const XML_Char *value)
-{
- DefaultAttribute *att;
- if (value) {
- /* 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 (type->nDefaultAtts == type->allocDefaultAtts) {
- if (type->allocDefaultAtts == 0) {
- type->allocDefaultAtts = 8;
- type->defaultAtts = (DefaultAttribute *)malloc(type->allocDefaultAtts * sizeof(DefaultAttribute));
- }
- else {
- type->allocDefaultAtts *= 2;
- type->defaultAtts = (DefaultAttribute *)realloc(type->defaultAtts,
- type->allocDefaultAtts*sizeof(DefaultAttribute));
- }
- if (!type->defaultAtts)
- return 0;
- }
- att = type->defaultAtts + type->nDefaultAtts;
- att->id = attId;
- att->value = value;
- att->isCdata = isCdata;
- if (!isCdata)
- attId->maybeTokenized = 1;
- type->nDefaultAtts += 1;
- return 1;
-}
-
-int
-XML_ParserImpl::setElementTypePrefix(ElementType *elementType)
-{
- const XML_Char *name;
- for (name = elementType->name; *name; name++) {
- if (*name == XML_T(':')) {
- Prefix *prefix;
- const XML_Char *s;
- for (s = elementType->name; s != name; s++) {
- if (!dtd.pool.appendChar(*s))
- return 0;
- }
- if (!dtd.pool.appendChar(XML_T('\0')))
- return 0;
- prefix = (Prefix *)dtd.prefixes.lookup(dtd.pool.start(), sizeof(Prefix));
- if (!prefix)
- return 0;
- if (prefix->name == dtd.pool.start())
- dtd.pool.finish();
- else
- dtd.pool.discard();
- elementType->prefix = prefix;
- }
- }
- return 1;
-}
-
-AttributeId *
-XML_ParserImpl::getAttributeId(const ENCODING *enc, const char *start, const char *end)
-{
- AttributeId *id;
- const XML_Char *name;
- if (!dtd.pool.appendChar(XML_T('\0')))
- return 0;
- name = dtd.pool.storeString(enc, start, end);
- if (!name)
- return 0;
- ++name;
- id = (AttributeId *)dtd.attributeIds.lookup(name, sizeof(AttributeId));
- if (!id)
- return 0;
- if (id->name != name)
- dtd.pool.discard();
- else {
- dtd.pool.finish();
- if (!ns)
- ;
- else if (name[0] == 'x'
- && name[1] == 'm'
- && name[2] == 'l'
- && name[3] == 'n'
- && name[4] == 's'
- && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
- if (name[5] == '\0')
- id->prefix = &dtd.defaultPrefix;
- else
- id->prefix = (Prefix *)dtd.prefixes.lookup(name + 6, sizeof(Prefix));
- id->xmlns = 1;
- }
- else {
- int i;
- for (i = 0; name[i]; i++) {
- if (name[i] == XML_T(':')) {
- int j;
- for (j = 0; j < i; j++) {
- if (!dtd.pool.appendChar(name[j]))
- return 0;
- }
- if (!dtd.pool.appendChar(XML_T('\0')))
- return 0;
- id->prefix = (Prefix *)dtd.prefixes.lookup(dtd.pool.start(), sizeof(Prefix));
- if (id->prefix->name == dtd.pool.start())
- dtd.pool.finish();
- else
- dtd.pool.discard();
- break;
- }
- }
- }
- }
- return id;
-}
-
-const XML_Char CONTEXT_SEP = XML_T('\f');
-
-const XML_Char *XML_ParserImpl::getContext()
-{
- HashTableIter iter;
- int needSep = 0;
-
- if (dtd.defaultPrefix.binding) {
- int i;
- int len;
- if (!tempPool.appendChar(XML_T('=')))
- return 0;
- len = dtd.defaultPrefix.binding->uriLen;
- if (namespaceSeparator != XML_T('\0'))
- len--;
- for (i = 0; i < len; i++)
- if (!tempPool.appendChar(dtd.defaultPrefix.binding->uri[i]))
- return 0;
- needSep = 1;
- }
-
- iter.init(dtd.prefixes);
- for (;;) {
- int i;
- int len;
- const XML_Char *s;
- Prefix *prefix = (Prefix *)iter.next();
- if (!prefix)
- break;
- if (!prefix->binding)
- continue;
- if (needSep && !tempPool.appendChar(CONTEXT_SEP))
- return 0;
- for (s = prefix->name; *s; s++)
- if (!tempPool.appendChar(*s))
- return 0;
- if (!tempPool.appendChar(XML_T('=')))
- return 0;
- len = prefix->binding->uriLen;
- if (namespaceSeparator != XML_T('\0'))
- len--;
- for (i = 0; i < len; i++)
- if (!tempPool.appendChar(prefix->binding->uri[i]))
- return 0;
- needSep = 1;
- }
-
-
- iter.init(dtd.generalEntities);
- for (;;) {
- const XML_Char *s;
- Entity *e = (Entity *)iter.next();
- if (!e)
- break;
- if (!e->open)
- continue;
- if (needSep && !tempPool.appendChar(CONTEXT_SEP))
- return 0;
- for (s = e->name; *s; s++)
- if (!tempPool.appendChar(*s))
- return 0;
- needSep = 1;
- }
-
- if (!tempPool.appendChar(XML_T('\0')))
- return 0;
- return tempPool.start();
-}
-
-int XML_ParserImpl::setContext(const XML_Char *context)
-{
- const XML_Char *s = context;
-
- while (*context != XML_T('\0')) {
- if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
- Entity *e;
- if (!tempPool.appendChar(XML_T('\0')))
- return 0;
- e = (Entity *)dtd.generalEntities.lookup(tempPool.start(), 0);
- if (e)
- e->open = 1;
- if (*s != XML_T('\0'))
- s++;
- context = s;
- tempPool.discard();
- }
- else if (*s == '=') {
- Prefix *prefix;
- if (tempPool.length() == 0)
- prefix = &dtd.defaultPrefix;
- else {
- if (!tempPool.appendChar(XML_T('\0')))
- return 0;
- prefix = (Prefix *)dtd.prefixes.lookup(tempPool.start(), sizeof(Prefix));
- if (!prefix)
- return 0;
- if (prefix->name == tempPool.start())
- tempPool.finish();
- else
- tempPool.discard();
- }
- for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
- if (!tempPool.appendChar(*context))
- return 0;
- if (!tempPool.appendChar(XML_T('\0')))
- return 0;
- if (!addBinding(prefix, 0, tempPool.start(), &inheritedBindings))
- return 0;
- tempPool.discard();
- if (*context != XML_T('\0'))
- ++context;
- s = context;
- }
- else {
- if (!tempPool.appendChar(*s))
- return 0;
- s++;
- }
- }
- return 1;
-}
-
-
-void XML_ParserImpl::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');
-}
-
-Dtd::Dtd()
-{
- complete = 1;
- standalone = 0;
- defaultPrefix.name = 0;
- defaultPrefix.binding = 0;
-}
-
-#ifdef XML_DTD
-
-void Dtd::swap(Dtd &d1, Dtd &d2)
-{
- Dtd tem;
- memcpy(&tem, &d1, sizeof(Dtd));
- memcpy(&d1, &d2, sizeof(Dtd));
- memcpy(&d2, &tem, sizeof(Dtd));
-}
-
-#endif /* XML_DTD */
-
-Dtd::~Dtd()
-{
- HashTableIter iter;
- iter.init(elementTypes);
- for (;;) {
- ElementType *e = (ElementType *)iter.next();
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- free(e->defaultAtts);
- }
-}
-
-/* Do a deep copy of the Dtd. Return 0 for out of memory; non-zero otherwise.
-The new Dtd has already been initialized. */
-
-int Dtd::copy(Dtd &newDtd, const Dtd &oldDtd)
-{
- HashTableIter iter;
-
- /* Copy the prefix table. */
-
- iter.init(oldDtd.prefixes);
- for (;;) {
- const XML_Char *name;
- const Prefix *oldP = (Prefix *)iter.next();
- if (!oldP)
- break;
- name = newDtd.pool.copyString(oldP->name);
- if (!name)
- return 0;
- if (!newDtd.prefixes.lookup(name, sizeof(Prefix)))
- return 0;
- }
-
- iter.init(oldDtd.attributeIds);
-
- /* Copy the attribute id table. */
-
- for (;;) {
- AttributeId *newA;
- const XML_Char *name;
- const AttributeId *oldA = (AttributeId *)iter.next();
-
- if (!oldA)
- break;
- /* Remember to allocate the scratch byte before the name. */
- if (!newDtd.pool.appendChar(XML_T('\0')))
- return 0;
- name = newDtd.pool.copyString(oldA->name);
- if (!name)
- return 0;
- ++name;
- newA = (AttributeId *)newDtd.attributeIds.lookup(name, sizeof(AttributeId));
- 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 *)newDtd.prefixes.lookup(oldA->prefix->name, 0);
- }
- }
-
- /* Copy the element type table. */
-
- iter.init(oldDtd.elementTypes);
-
- for (;;) {
- int i;
- ElementType *newE;
- const XML_Char *name;
- const ElementType *oldE = (ElementType *)iter.next();
- if (!oldE)
- break;
- name = newDtd.pool.copyString(oldE->name);
- if (!name)
- return 0;
- newE = (ElementType *)newDtd.elementTypes.lookup(name, sizeof(ElementType));
- if (!newE)
- return 0;
- if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DefaultAttribute *)malloc(oldE->nDefaultAtts * sizeof(DefaultAttribute));
- if (!newE->defaultAtts)
- return 0;
- }
- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
- if (oldE->prefix)
- newE->prefix = (Prefix *)newDtd.prefixes.lookup(oldE->prefix->name, 0);
- for (i = 0; i < newE->nDefaultAtts; i++) {
- newE->defaultAtts[i].id = (AttributeId *)newDtd.attributeIds.lookup(oldE->defaultAtts[i].id->name, 0);
- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
- if (oldE->defaultAtts[i].value) {
- newE->defaultAtts[i].value = newDtd.pool.copyString(oldE->defaultAtts[i].value);
- if (!newE->defaultAtts[i].value)
- return 0;
- }
- else
- newE->defaultAtts[i].value = 0;
- }
- }
-
- /* Copy the entity tables. */
- if (!copyEntityTable(newDtd.generalEntities,
- newDtd.pool,
- oldDtd.generalEntities))
- return 0;
-
-#ifdef XML_DTD
- if (!copyEntityTable(newDtd.paramEntities,
- newDtd.pool,
- oldDtd.paramEntities))
- return 0;
-#endif /* XML_DTD */
-
- newDtd.complete = oldDtd.complete;
- newDtd.standalone = oldDtd.standalone;
- return 1;
-}
-
-int Dtd::copyEntityTable(HashTable &newTable,
- StringPool &newPool,
- const HashTable &oldTable)
-{
- HashTableIter iter;
- const XML_Char *cachedOldBase = 0;
- const XML_Char *cachedNewBase = 0;
-
- iter.init(oldTable);
-
- for (;;) {
- Entity *newE;
- const XML_Char *name;
- const Entity *oldE = (Entity *)iter.next();
- if (!oldE)
- break;
- name = newPool.copyString(oldE->name);
- if (!name)
- return 0;
- newE = (Entity *)newTable.lookup(name, sizeof(Entity));
- if (!newE)
- return 0;
- if (oldE->systemId) {
- const XML_Char *tem = newPool.copyString(oldE->systemId);
- if (!tem)
- return 0;
- newE->systemId = tem;
- if (oldE->base) {
- if (oldE->base == cachedOldBase)
- newE->base = cachedNewBase;
- else {
- cachedOldBase = oldE->base;
- tem = newPool.copyString(cachedOldBase);
- if (!tem)
- return 0;
- cachedNewBase = newE->base = tem;
- }
- }
- }
- else {
- const XML_Char *tem = newPool.copyStringN(oldE->textPtr, oldE->textLen);
- if (!tem)
- return 0;
- newE->textPtr = tem;
- newE->textLen = oldE->textLen;
- }
- if (oldE->notation) {
- const XML_Char *tem = newPool.copyString(oldE->notation);
- if (!tem)
- return 0;
- newE->notation = tem;
- }
- }
- return 1;
-}
-
-
-StringPool::StringPool()
-{
- blocks_ = 0;
- freeBlocks_ = 0;
- start_ = 0;
- ptr_ = 0;
- end_ = 0;
-}
-
-StringPool::~StringPool()
-{
- Block *p = blocks_;
- while (p) {
- Block *tem = p->next;
- free(p);
- p = tem;
- }
- blocks_ = 0;
- p = freeBlocks_;
- while (p) {
- Block *tem = p->next;
- free(p);
- p = tem;
- }
- freeBlocks_ = 0;
- ptr_ = 0;
- start_ = 0;
- end_ = 0;
-}
-
-
-void StringPool::clear()
-{
- if (!freeBlocks_)
- freeBlocks_ = blocks_;
- else {
- Block *p = blocks_;
- while (p) {
- Block *tem = p->next;
- p->next = freeBlocks_;
- freeBlocks_ = p;
- p = tem;
- }
- }
- blocks_ = 0;
- start_ = 0;
- ptr_ = 0;
- end_ = 0;
-}
-
-XML_Char *StringPool::append(const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!ptr_ && !grow())
- return 0;
- for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(ptr_), (ICHAR *)end_);
- if (ptr == end)
- break;
- if (!grow())
- return 0;
- }
- return start_;
-}
-
-const XML_Char *StringPool::copyString(const XML_Char *s)
-{
- do {
- if (!appendChar(*s))
- return 0;
- } while (*s++);
- s = start_;
- finish();
- return s;
-}
-
-const XML_Char *StringPool::copyStringN(const XML_Char *s, int n)
-{
- if (!ptr_ && !grow())
- return 0;
- for (; n > 0; --n, s++) {
- if (!appendChar(*s))
- return 0;
-
- }
- s = start_;
- finish();
- return s;
-}
-
-XML_Char *StringPool::storeString(const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!append(enc, ptr, end))
- return 0;
- if (ptr_ == end_ && !grow())
- return 0;
- *(ptr_)++ = 0;
- return start_;
-}
-
-int StringPool::grow()
-{
- if (freeBlocks_) {
- if (start_ == 0) {
- blocks_ = freeBlocks_;
- freeBlocks_ = freeBlocks_->next;
- blocks_->next = 0;
- start_ = blocks_->s();
- end_ = start_ + blocks_->size;
- ptr_ = start_;
- return 1;
- }
- if (end_ - start_ < freeBlocks_->size) {
- Block *tem = freeBlocks_->next;
- freeBlocks_->next = blocks_;
- blocks_ = freeBlocks_;
- freeBlocks_ = tem;
- memcpy(blocks_->s(), start_, (end_ - start_) * sizeof(XML_Char));
- ptr_ = blocks_->s() + (ptr_ - start_);
- start_ = blocks_->s();
- end_ = start_ + blocks_->size;
- return 1;
- }
- }
- if (blocks_ && start_ == blocks_->s()) {
- int blockSize = (end_ - start_)*2;
- Block *tem = (Block *)malloc(sizeof(Block)
- + blockSize*sizeof(XML_Char));
- if (!tem)
- return 0;
- memcpy(tem->s(), blocks_->s(), (end_ - start_)*sizeof(XML_Char));
- blocks_ = tem;
- if (!blocks_)
- return 0;
- blocks_->size = blockSize;
- ptr_ = blocks_->s() + (ptr_ - start_);
- start_ = blocks_->s();
- end_ = start_ + blockSize;
- }
- else {
- Block *tem;
- int blockSize = end_ - start_;
- if (blockSize < INIT_BLOCK_SIZE)
- blockSize = INIT_BLOCK_SIZE;
- else
- blockSize *= 2;
- tem = (Block *)malloc(sizeof(Block)
- + blockSize*sizeof(XML_Char));
- if (!tem)
- return 0;
- tem->size = blockSize;
- tem->next = blocks_;
- blocks_ = tem;
- memcpy(tem->s(), start_, (ptr_ - start_) * sizeof(XML_Char));
- ptr_ = tem->s() + (ptr_ - start_);
- start_ = tem->s();
- end_ = tem->s() + blockSize;
- }
- return 1;
-}
-
-const int INIT_SIZE = 64;
-
-int HashTable::keyeq(Key s1, Key s2)
-{
- for (; *s1 == *s2; s1++, s2++)
- if (*s1 == 0)
- return 1;
- return 0;
-}
-
-unsigned long HashTable::hash(Key s)
-{
- unsigned long h = 0;
- while (*s)
- h = (h << 5) + h + (unsigned char)*s++;
- return h;
-}
-
-Named *HashTable::lookup(Key name, size_t createSize)
-{
- size_t i;
- if (size_ == 0) {
- if (!createSize)
- return 0;
- v_ = (Named **)calloc(INIT_SIZE, sizeof(Named *));
- if (!v_)
- return 0;
- size_ = INIT_SIZE;
- usedLim_ = INIT_SIZE / 2;
- i = hash(name) & (size_ - 1);
- }
- else {
- unsigned long h = hash(name);
- for (i = h & (size_ - 1);
- v_[i];
- i == 0 ? i = size_ - 1 : --i) {
- if (keyeq(name, v_[i]->name))
- return v_[i];
- }
- if (!createSize)
- return 0;
- if (used_ == usedLim_) {
- /* check for overflow */
- size_t newSize = size_ * 2;
- Named **newV = (Named **)calloc(newSize, sizeof(Named *));
- if (!newV)
- return 0;
- for (i = 0; i < size_; i++)
- if (v_[i]) {
- size_t j;
- for (j = hash(v_[i]->name) & (newSize - 1);
- newV[j];
- j == 0 ? j = newSize - 1 : --j)
- ;
- newV[j] = v_[i];
- }
- free(v_);
- v_ = newV;
- size_ = newSize;
- usedLim_ = newSize/2;
- for (i = h & (size_ - 1);
- v_[i];
- i == 0 ? i = size_ - 1 : --i)
- ;
- }
- }
- v_[i] = (Named *)calloc(1, createSize);
- if (!v_[i])
- return 0;
- v_[i]->name = name;
- used_++;
- return v_[i];
-}
-
-HashTable::~HashTable()
-{
- size_t i;
- for (i = 0; i < size_; i++) {
- Named *p = v_[i];
- if (p)
- free(p);
- }
- free(v_);
-}
-
-HashTable::HashTable()
-{
- size_ = 0;
- usedLim_ = 0;
- used_ = 0;
- v_ = 0;
-}
-
-HashTableIter::HashTableIter()
-{
- p_ = 0;
- end_ = 0;
-}
-
-HashTableIter::HashTableIter(const HashTable &table)
-{
- p_ = table.v_;
- end_ = p_ + table.size_;
-}
-
-void HashTableIter::init(const HashTable &table)
-{
- p_ = table.v_;
- end_ = p_ + table.size_;
-}
-
-Named *HashTableIter::next()
-{
- while (p_ != end_) {
- Named *tem = *p_++;
- if (tem)
- return tem;
- }
- return 0;
-}
+++ /dev/null
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above. If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlParse_INCLUDED
-#define XmlParse_INCLUDED 1
-
-#ifndef XMLPARSEAPI
-#define XMLPARSEAPI /* as nothing */
-#endif
-
-#ifdef XML_UNICODE_WCHAR_T
-
-/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
-uses Unicode. */
-/* Information is UTF-16 encoded as wchar_ts */
-
-#ifndef XML_UNICODE
-#define XML_UNICODE
-#endif
-
-#include <stddef.h>
-typedef wchar_t XML_Char;
-typedef wchar_t XML_LChar;
-
-#else /* not XML_UNICODE_WCHAR_T */
-
-#ifdef XML_UNICODE
-
-/* Information is UTF-16 encoded as unsigned shorts */
-typedef unsigned short XML_Char;
-typedef char XML_LChar;
-
-#else /* not XML_UNICODE */
-
-/* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-
-#endif /* not XML_UNICODE */
-
-#endif /* not XML_UNICODE_WCHAR_T */
-
-class XML_ElementHandler {
- public:
- /* atts is array of name/value pairs, terminated by 0; names and
- values are 0 terminated. */
- virtual void startElement(const XML_Char *name, const XML_Char **atts) = 0;
- virtual void endElement(const XML_Char *name) = 0;
-};
-
-class XML_CharacterDataHandler {
- public:
- /* s is not 0 terminated. */
- virtual void characterData(const XML_Char *s, int len) = 0;
-};
-
-class XML_ProcessingInstructionHandler {
- public:
- /* target and data are 0 terminated */
- virtual void processingInstruction(const XML_Char *target, const XML_Char *data) = 0;
-};
-
-/* data is 0 terminated */
-class XML_CommentHandler {
- public:
- virtual void comment(const XML_Char *data) = 0;
-};
-
-class XML_CdataSectionHandler {
- public:
- virtual void startCdataSection() = 0;
- virtual void endCdataSection() = 0;
-};
-
-class XML_DefaultHandler {
- public:
- /* This is called for any characters in the XML document for which
- there is no applicable handler. This includes both characters
- that are part of markup which is of a kind that is not reported
- (comments, markup declarations), or characters that are part of a
- construct which could be reported but for which no handler has
- been supplied. The characters are passed exactly as they were in
- the XML document except that they will be encoded in UTF-8. Line
- boundaries are not normalized. Note that a byte order mark
- character is not passed to the default handler. There are no
- guarantees about how characters are divided between calls to the
- default handler: for example, a comment might be split between
- multiple calls. */
- virtual void doDefault(const XML_Char *s, int len) = 0;
-};
-
-class XML_DoctypeDeclHandler {
- public:
- /* This is called for the start of the DOCTYPE declaration when the
- name of the DOCTYPE is encountered. */
- virtual void startDoctypeDecl(const XML_Char *doctypeName) = 0;
- /* This is called for the start of the DOCTYPE declaration when the
- closing > is encountered, but after processing any external subset. */
- virtual void endDoctypeDecl() = 0;
-};
-
-class XML_UnparsedEntityDeclHandler {
- public:
- /* This is called for a declaration of an unparsed (NDATA)
- entity. The base argument is whatever was set by XML_SetBase.
- The entityName, systemId and notationName arguments will never be null.
- The other arguments may be. */
- virtual void unparsedEntityDecl(const XML_Char *entityName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName) = 0;
-};
-
-class XML_NotationDeclHandler {
- public:
- /* This is called for a declaration of notation. The base argument
- is whatever was set by XML_SetBase. The notationName will never
- be null. The other arguments can be. */
- virtual void notationDecl(const XML_Char *notationName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId) = 0;
-};
-
-class XML_NamespaceDeclHandler {
- public:
- /* When namespace processing is enabled, these are called once for
- each namespace declaration. The call to the start and end element
- handlers occur between the calls to the start and end namespace
- declaration handlers. For an xmlns attribute, prefix will be
- null. For an xmlns="" attribute, uri will be null. */
-
- virtual void startNamespaceDecl(const XML_Char *prefix,
- const XML_Char *uri) = 0;
-
- virtual void endNamespaceDecl(const XML_Char *prefix) = 0;
-};
-
-class XML_NotStandaloneHandler {
- public:
- /* This is called if the document is not standalone (it has an
- external subset or a reference to a parameter entity, but does
- not have standalone="yes"). If this handler returns 0, then
- processing will not continue, and the parser will return a
- ERROR_NOT_STANDALONE error. */
- virtual int notStandalone() = 0;
-};
-
-class XML_Parser;
-
-class XML_ExternalEntityRefHandler {
- public:
- /* This is called for a reference to an external parsed general
- entity. The referenced entity is not automatically parsed. The
- application can parse it immediately or later using
- externalEntityParserCreate. The parser argument is the parser
- parsing the entity containing the reference; it can be passed as
- the parser argument to externalEntityParserCreate. The systemId
- argument is the system identifier as specified in the entity
- declaration; it will not be null. The base argument is the
- system identifier that should be used as the base for resolving
- systemId if systemId was relative; this is set by setBase; it may
- be null. The publicId argument is the public identifier as
- specified in the entity declaration, or null if none was
- specified; the whitespace in the public identifier will have been
- normalized as required by the XML spec. The context argument
- specifies the parsing context in the format expected by the
- context argument to externalEntityParserCreate; context is valid
- only until the handler returns, so if the referenced entity is to
- be parsed later, it must be copied. The handler should return 0
- if processing should not continue because of a fatal error in the
- handling of the external entity. In this case the calling parser
- will return an ERROR_EXTERNAL_ENTITY_HANDLING error. Note that
- unlike other handlers the first argument is the parser, not
- userData. */
-
- virtual int externalEntityRef(XML_Parser *parser,
- const XML_Char *context,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId) = 0;
-};
-
-/* This object is returned by the XML_UnknownEncodingHandler
-to provide information to the parser about encodings that are unknown
-to the parser.
-The map[b] member gives information about byte sequences
-whose first byte is b.
-If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
-If map[b] is -1, then the byte sequence is malformed.
-If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
-sequence that encodes a single Unicode scalar value.
-The data member will be passed as the first argument to the convert function.
-The convert function is used to convert multibyte sequences;
-s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
-The convert function must return the Unicode scalar value
-represented by this byte sequence or -1 if the byte sequence is malformed.
-The convert function may be null if the encoding is a single-byte encoding,
-that is if map[b] >= -1 for all bytes b.
-When the parser is finished with the encoding, then if release is not null,
-it will call release passing it the data member;
-once release has been called, the convert function will not be called again.
-
-Expat places certain restrictions on the encodings that are supported
-using this mechanism.
-
-1. Every ASCII character that can appear in a well-formed XML document,
-other than the characters
-
- $@\^`{}~
-
-must be represented by a single byte, and that byte must be the
-same byte that represents that character in ASCII.
-
-2. No character may require more than 4 bytes to encode.
-
-3. All characters encoded must have Unicode scalar values <= 0xFFFF,
-(ie characters that would be encoded by surrogates in UTF-16
-are not allowed). Note that this restriction doesn't apply to
-the built-in support for UTF-8 and UTF-16.
-
-4. No Unicode character may be encoded by more than one distinct sequence
-of bytes. */
-
-class XMLPARSEAPI XML_Encoding {
-public:
- int map[256];
- virtual int convert(const char *s);
- virtual void release();
-};
-
-class XML_UnknownEncodingHandler {
-public:
- /* This is called for an encoding that is unknown to the parser.
- The encodingHandlerData argument is that which was passed as the
- second argument to XML_SetUnknownEncodingHandler. The name
- argument gives the name of the encoding as specified in the
- encoding declaration. If the callback can provide information
- about the encoding, it must fill in the XML_Encoding structure,
- and return 1. Otherwise it must return 0. If info does not
- describe a suitable encoding, then the parser will return an
- XML_UNKNOWN_ENCODING error. */
- virtual XML_Encoding *unknownEncoding(const XML_Char *name) = 0;
-};
-
-class XMLPARSEAPI XML_Parser {
- public:
- /* Constructs a new parser; encoding is the encoding specified by
- the external protocol or null if there is none specified. */
- static XML_Parser *parserCreate(const XML_Char *encoding = 0);
-
- /* Constructs a new parser and namespace processor. Element type
- names and attribute names that belong to a namespace will be
- expanded; unprefixed attribute names are never expanded;
- unprefixed element type names are expanded only if there is a
- default namespace. The expanded name is the concatenation of the
- namespace URI, the namespace separator character, and the local
- part of the name. If the namespace separator is '\0' then the
- namespace URI and the local part will be concatenated without any
- separator. When a namespace is not declared, the name and prefix
- will be passed through without expansion. */
-
- static XML_Parser *parserCreateNS(const XML_Char *encoding,
- XML_Char namespaceSeparator);
-
- virtual void release() = 0;
- virtual void setElementHandler(XML_ElementHandler *handler) = 0;
- virtual void setCharacterDataHandler(XML_CharacterDataHandler *handler) = 0;
- virtual void setProcessingInstructionHandler(XML_ProcessingInstructionHandler *handler) = 0;
- virtual void setCommentHandler(XML_CommentHandler *handler) = 0;
- virtual void setCdataSectionHandler(XML_CdataSectionHandler *handler) = 0;
-
- /* This sets the default handler and also inhibits expansion of
- internal entities. The entity reference will be passed to the
- default handler. */
-
- virtual void setDefaultHandler(XML_DefaultHandler *handler) = 0;
-
- /* This sets the default handler but does not inhibit expansion of
- internal entities. The entity reference will not be passed to
- the default handler. */
-
- virtual void setDefaultHandlerExpand(XML_DefaultHandler *handler) = 0;
-
- virtual void setDoctypeDeclHandler(XML_DoctypeDeclHandler *handler) = 0;
- virtual void setUnparsedEntityDeclHandler(XML_UnparsedEntityDeclHandler *handler) = 0;
- virtual void setNotationDeclHandler(XML_NotationDeclHandler *handler) = 0;
- virtual void setNamespaceDeclHandler(XML_NamespaceDeclHandler *handler) = 0;
- virtual void setNotStandaloneHandler(XML_NotStandaloneHandler *handler) = 0;
- virtual void setExternalEntityRefHandler(XML_ExternalEntityRefHandler *handler) = 0;
- virtual void setUnknownEncodingHandler(XML_UnknownEncodingHandler *handler) = 0;
-
- /* This can be called within a handler for a start element, end
- element, processing instruction or character data. It causes the
- corresponding markup to be passed to the default handler. */
- virtual void defaultCurrent() = 0;
-
- /* This is equivalent to supplying an encoding argument
- to XML_ParserCreate. It must not be called after XML_Parse
- or XML_ParseBuffer. */
- virtual int setEncoding(const XML_Char *encoding) = 0;
-
- /* Sets the base to be used for resolving relative URIs in system
- identifiers in declarations. Resolving relative identifiers is
- left to the application: this value will be passed through as the
- base argument to the XML_ExternalEntityRefHandler,
- XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The
- base argument will be copied. Returns zero if out of memory,
- non-zero otherwise. */
-
- virtual int setBase(const XML_Char *base) = 0;
-
- virtual const XML_Char *getBase() = 0;
-
- /* Returns the number of the attributes passed in last call to the
- XML_StartElementHandler that were specified in the start-tag rather
- than defaulted. */
- virtual int getSpecifiedAttributeCount() = 0;
-
- /* Parses some input. Returns 0 if a fatal error is detected.
- The last call to XML_Parse must have isFinal true;
- len may be zero for this call (or any other). */
- virtual int parse(const char *s, int len, int isFinal) = 0;
-
- virtual char *getBuffer(int len) = 0;
-
- virtual int parseBuffer(int len, int isFinal) = 0;
-
- /* Creates an XML_Parser object that can parse an external general
- entity; context is a '\0'-terminated string specifying the parse
- context; encoding is a '\0'-terminated string giving the name of
- the externally specified encoding, or null if there is no
- externally specified encoding. The context string consists of a
- sequence of tokens separated by formfeeds (\f); a token
- consisting of a name specifies that the general entity of the
- name is open; a token of the form prefix=uri specifies the
- namespace for a particular prefix; a token of the form =uri
- specifies the default namespace. This can be called at any point
- after the first call to an ExternalEntityRefHandler so longer as
- the parser has not yet been freed. The new parser is completely
- independent and may safely be used in a separate thread. The
- handlers and userData are initialized from the parser argument.
- Returns 0 if out of memory. Otherwise returns a new XML_Parser
- object. */
-
- virtual XML_Parser *externalEntityParserCreate(const XML_Char *context,
- const XML_Char *encoding) = 0;
-
- enum ParamEntityParsing {
- PARAM_ENTITY_PARSING_NEVER,
- PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
- PARAM_ENTITY_PARSING_ALWAYS
- };
-
- /* Controls parsing of parameter entities (including the external
- DTD subset). If parsing of parameter entities is enabled, then
- references to external parameter entities (including the external
- DTD subset) will be passed to the handler set with
- XML_SetExternalEntityRefHandler. The context passed will be 0.
- Unlike external general entities, external parameter entities can
- only be parsed synchronously. If the external parameter entity
- is to be parsed, it must be parsed during the call to the
- external entity ref handler: the complete sequence of
- XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
- XML_ParserFree calls must be made during this call. After
- XML_ExternalEntityParserCreate has been called to create the
- parser for the external parameter entity (context must be 0 for
- this call), it is illegal to make any calls on the old parser
- until XML_ParserFree has been called on the newly created parser.
- If the library has been compiled without support for parameter
- entity parsing (ie without XML_DTD being defined), then
- XML_SetParamEntityParsing will return 0 if parsing of parameter
- entities is requested; otherwise it will return non-zero. */
-
- virtual int setParamEntityParsing(ParamEntityParsing parsing) = 0;
-
- enum Error {
- ERROR_NONE,
- ERROR_NO_MEMORY,
- ERROR_SYNTAX,
- ERROR_NO_ELEMENTS,
- ERROR_INVALID_TOKEN,
- ERROR_UNCLOSED_TOKEN,
- ERROR_PARTIAL_CHAR,
- ERROR_TAG_MISMATCH,
- ERROR_DUPLICATE_ATTRIBUTE,
- ERROR_JUNK_AFTER_DOC_ELEMENT,
- ERROR_PARAM_ENTITY_REF,
- ERROR_UNDEFINED_ENTITY,
- ERROR_RECURSIVE_ENTITY_REF,
- ERROR_ASYNC_ENTITY,
- ERROR_BAD_CHAR_REF,
- ERROR_BINARY_ENTITY_REF,
- ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
- ERROR_MISPLACED_XML_PI,
- ERROR_UNKNOWN_ENCODING,
- ERROR_INCORRECT_ENCODING,
- ERROR_UNCLOSED_CDATA_SECTION,
- ERROR_EXTERNAL_ENTITY_HANDLING,
- ERROR_NOT_STANDALONE
- };
-
- /* If parse or XML_parseBuffer have returned 0, then XML_GetErrorCode
- returns information about the error. */
-
- virtual Error getErrorCode() = 0;
-
- /* These functions return information about the current parse
- location. They may be called when XML_Parse or XML_ParseBuffer
- return 0; in this case the location is the location of the
- character at which the error was detected. They may also be
- called from any other callback called to report some parse event;
- in this the location is the location of the first of the sequence
- of characters that generated the event. */
-
- virtual int getCurrentLineNumber() = 0;
- virtual int getCurrentColumnNumber() = 0;
- virtual long getCurrentByteIndex() = 0;
-
- /* Return the number of bytes in the current event.
- Returns 0 if the event is in an internal entity. */
- virtual int getCurrentByteCount() = 0;
-
- /* Returns a string describing the error. */
- static const XML_LChar *errorString(int code);
-protected:
- ~XML_Parser() { }
-};
-
-#endif /* not XmlParse_INCLUDED */