Annotation of libwww/modules/expat/xmlparse/xmlparse.c, revision 1.1
1.1 ! frystyk 1: /*
! 2: The contents of this file are subject to the Mozilla Public License
! 3: Version 1.0 (the "License"); you may not use this file except in
! 4: compliance with the License. You may obtain a copy of the License at
! 5: http://www.mozilla.org/MPL/
! 6:
! 7: Software distributed under the License is distributed on an "AS IS"
! 8: basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
! 9: License for the specific language governing rights and limitations
! 10: under the License.
! 11:
! 12: The Original Code is expat.
! 13:
! 14: The Initial Developer of the Original Code is James Clark.
! 15: Portions created by James Clark are Copyright (C) 1998
! 16: James Clark. All Rights Reserved.
! 17:
! 18: Contributor(s):
! 19: */
! 20:
! 21: #include <stdlib.h>
! 22: #include <string.h>
! 23: #include <stddef.h>
! 24:
! 25: #include "xmldef.h"
! 26:
! 27: #ifdef XML_UNICODE
! 28: #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
! 29: #define XmlConvert XmlUtf16Convert
! 30: #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
! 31: #define XmlEncode XmlUtf16Encode
! 32: #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
! 33: typedef unsigned short ICHAR;
! 34: #else
! 35: #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
! 36: #define XmlConvert XmlUtf8Convert
! 37: #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
! 38: #define XmlEncode XmlUtf8Encode
! 39: #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
! 40: typedef char ICHAR;
! 41: #endif
! 42:
! 43: #ifdef XML_UNICODE_WCHAR_T
! 44: #define XML_T(x) L ## x
! 45: #else
! 46: #define XML_T(x) x
! 47: #endif
! 48:
! 49: /* Round up n to be a multiple of sz, where sz is a power of 2. */
! 50: #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
! 51:
! 52: #include "xmlparse.h"
! 53: #include "xmltok.h"
! 54: #include "xmlrole.h"
! 55: #include "hashtable.h"
! 56:
! 57: #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
! 58: #define INIT_DATA_BUF_SIZE 1024
! 59: #define INIT_ATTS_SIZE 16
! 60: #define INIT_BLOCK_SIZE 1024
! 61: #define INIT_BUFFER_SIZE 1024
! 62:
! 63: typedef struct tag {
! 64: struct tag *parent;
! 65: const char *rawName;
! 66: int rawNameLength;
! 67: const XML_Char *name;
! 68: char *buf;
! 69: char *bufEnd;
! 70: } TAG;
! 71:
! 72: typedef struct {
! 73: const XML_Char *name;
! 74: const XML_Char *textPtr;
! 75: int textLen;
! 76: const XML_Char *systemId;
! 77: const XML_Char *base;
! 78: const XML_Char *publicId;
! 79: const XML_Char *notation;
! 80: char open;
! 81: } ENTITY;
! 82:
! 83: typedef struct block {
! 84: struct block *next;
! 85: int size;
! 86: XML_Char s[1];
! 87: } BLOCK;
! 88:
! 89: typedef struct {
! 90: BLOCK *blocks;
! 91: BLOCK *freeBlocks;
! 92: const XML_Char *end;
! 93: XML_Char *ptr;
! 94: XML_Char *start;
! 95: } STRING_POOL;
! 96:
! 97: /* The XML_Char before the name is used to determine whether
! 98: an attribute has been specified. */
! 99: typedef struct {
! 100: XML_Char *name;
! 101: char maybeTokenized;
! 102: } ATTRIBUTE_ID;
! 103:
! 104: typedef struct {
! 105: const ATTRIBUTE_ID *id;
! 106: char isCdata;
! 107: const XML_Char *value;
! 108: } DEFAULT_ATTRIBUTE;
! 109:
! 110: typedef struct {
! 111: const XML_Char *name;
! 112: int nDefaultAtts;
! 113: int allocDefaultAtts;
! 114: DEFAULT_ATTRIBUTE *defaultAtts;
! 115: } ELEMENT_TYPE;
! 116:
! 117: typedef struct {
! 118: HASH_TABLE generalEntities;
! 119: HASH_TABLE elementTypes;
! 120: HASH_TABLE attributeIds;
! 121: STRING_POOL pool;
! 122: int complete;
! 123: int standalone;
! 124: const XML_Char *base;
! 125: } DTD;
! 126:
! 127: typedef enum XML_Error Processor(XML_Parser parser,
! 128: const char *start,
! 129: const char *end,
! 130: const char **endPtr);
! 131:
! 132: static Processor prologProcessor;
! 133: static Processor prologInitProcessor;
! 134: static Processor contentProcessor;
! 135: static Processor cdataSectionProcessor;
! 136: static Processor epilogProcessor;
! 137: static Processor errorProcessor;
! 138: static Processor externalEntityInitProcessor;
! 139: static Processor externalEntityInitProcessor2;
! 140: static Processor externalEntityInitProcessor3;
! 141: static Processor externalEntityContentProcessor;
! 142:
! 143: static enum XML_Error
! 144: handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
! 145: static enum XML_Error
! 146: processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
! 147: static enum XML_Error
! 148: initializeEncoding(XML_Parser parser);
! 149: static enum XML_Error
! 150: doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
! 151: const char *start, const char *end, const char **endPtr);
! 152: static enum XML_Error
! 153: doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
! 154: static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const XML_Char *tagName, const char *s);
! 155: static int
! 156: defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
! 157: static enum XML_Error
! 158: storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
! 159: STRING_POOL *);
! 160: static enum XML_Error
! 161: appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
! 162: STRING_POOL *);
! 163: static ATTRIBUTE_ID *
! 164: getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
! 165: static enum XML_Error
! 166: storeEntityValue(XML_Parser parser, const char *start, const char *end);
! 167: static int
! 168: reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
! 169: static void
! 170: reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
! 171:
! 172: static const XML_Char *getOpenEntityNames(XML_Parser parser);
! 173: static int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames);
! 174: static void normalizePublicId(XML_Char *s);
! 175: static int dtdInit(DTD *);
! 176: static void dtdDestroy(DTD *);
! 177: static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
! 178: static void poolInit(STRING_POOL *);
! 179: static void poolClear(STRING_POOL *);
! 180: static void poolDestroy(STRING_POOL *);
! 181: static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
! 182: const char *ptr, const char *end);
! 183: static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
! 184: const char *ptr, const char *end);
! 185: static int poolGrow(STRING_POOL *pool);
! 186: static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
! 187: static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
! 188:
! 189: #define poolStart(pool) ((pool)->start)
! 190: #define poolEnd(pool) ((pool)->ptr)
! 191: #define poolLength(pool) ((pool)->ptr - (pool)->start)
! 192: #define poolChop(pool) ((void)--(pool->ptr))
! 193: #define poolLastChar(pool) (((pool)->ptr)[-1])
! 194: #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
! 195: #define poolFinish(pool) ((pool)->start = (pool)->ptr)
! 196: #define poolAppendChar(pool, c) \
! 197: (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
! 198: ? 0 \
! 199: : ((*((pool)->ptr)++ = c), 1))
! 200:
! 201: typedef struct {
! 202: /* The first member must be userData so that the XML_GetUserData macro works. */
! 203: void *userData;
! 204: void *handlerArg;
! 205: char *buffer;
! 206: /* first character to be parsed */
! 207: const char *bufferPtr;
! 208: /* past last character to be parsed */
! 209: char *bufferEnd;
! 210: /* allocated end of buffer */
! 211: const char *bufferLim;
! 212: long parseEndByteIndex;
! 213: const char *parseEndPtr;
! 214: XML_Char *dataBuf;
! 215: XML_Char *dataBufEnd;
! 216: XML_StartElementHandler startElementHandler;
! 217: XML_EndElementHandler endElementHandler;
! 218: XML_CharacterDataHandler characterDataHandler;
! 219: XML_ProcessingInstructionHandler processingInstructionHandler;
! 220: XML_DefaultHandler defaultHandler;
! 221: XML_UnparsedEntityDeclHandler unparsedEntityDeclHandler;
! 222: XML_NotationDeclHandler notationDeclHandler;
! 223: XML_ExternalEntityRefHandler externalEntityRefHandler;
! 224: XML_UnknownEncodingHandler unknownEncodingHandler;
! 225: const ENCODING *encoding;
! 226: INIT_ENCODING initEncoding;
! 227: const XML_Char *protocolEncodingName;
! 228: void *unknownEncodingMem;
! 229: void *unknownEncodingData;
! 230: void *unknownEncodingHandlerData;
! 231: void (*unknownEncodingRelease)(void *);
! 232: PROLOG_STATE prologState;
! 233: Processor *processor;
! 234: enum XML_Error errorCode;
! 235: const char *eventPtr;
! 236: const char *eventEndPtr;
! 237: const char *positionPtr;
! 238: int tagLevel;
! 239: ENTITY *declEntity;
! 240: const XML_Char *declNotationName;
! 241: const XML_Char *declNotationPublicId;
! 242: ELEMENT_TYPE *declElementType;
! 243: ATTRIBUTE_ID *declAttributeId;
! 244: char declAttributeIsCdata;
! 245: DTD dtd;
! 246: TAG *tagStack;
! 247: TAG *freeTagList;
! 248: int attsSize;
! 249: ATTRIBUTE *atts;
! 250: POSITION position;
! 251: STRING_POOL tempPool;
! 252: STRING_POOL temp2Pool;
! 253: char *groupConnector;
! 254: unsigned groupSize;
! 255: int hadExternalDoctype;
! 256: } Parser;
! 257:
! 258: #define userData (((Parser *)parser)->userData)
! 259: #define handlerArg (((Parser *)parser)->handlerArg)
! 260: #define startElementHandler (((Parser *)parser)->startElementHandler)
! 261: #define endElementHandler (((Parser *)parser)->endElementHandler)
! 262: #define characterDataHandler (((Parser *)parser)->characterDataHandler)
! 263: #define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler)
! 264: #define defaultHandler (((Parser *)parser)->defaultHandler)
! 265: #define unparsedEntityDeclHandler (((Parser *)parser)->unparsedEntityDeclHandler)
! 266: #define notationDeclHandler (((Parser *)parser)->notationDeclHandler)
! 267: #define externalEntityRefHandler (((Parser *)parser)->externalEntityRefHandler)
! 268: #define unknownEncodingHandler (((Parser *)parser)->unknownEncodingHandler)
! 269: #define encoding (((Parser *)parser)->encoding)
! 270: #define initEncoding (((Parser *)parser)->initEncoding)
! 271: #define unknownEncodingMem (((Parser *)parser)->unknownEncodingMem)
! 272: #define unknownEncodingData (((Parser *)parser)->unknownEncodingData)
! 273: #define unknownEncodingHandlerData \
! 274: (((Parser *)parser)->unknownEncodingHandlerData)
! 275: #define unknownEncodingRelease (((Parser *)parser)->unknownEncodingRelease)
! 276: #define protocolEncodingName (((Parser *)parser)->protocolEncodingName)
! 277: #define prologState (((Parser *)parser)->prologState)
! 278: #define processor (((Parser *)parser)->processor)
! 279: #define errorCode (((Parser *)parser)->errorCode)
! 280: #define eventPtr (((Parser *)parser)->eventPtr)
! 281: #define eventEndPtr (((Parser *)parser)->eventEndPtr)
! 282: #define positionPtr (((Parser *)parser)->positionPtr)
! 283: #define position (((Parser *)parser)->position)
! 284: #define tagLevel (((Parser *)parser)->tagLevel)
! 285: #define buffer (((Parser *)parser)->buffer)
! 286: #define bufferPtr (((Parser *)parser)->bufferPtr)
! 287: #define bufferEnd (((Parser *)parser)->bufferEnd)
! 288: #define parseEndByteIndex (((Parser *)parser)->parseEndByteIndex)
! 289: #define parseEndPtr (((Parser *)parser)->parseEndPtr)
! 290: #define bufferLim (((Parser *)parser)->bufferLim)
! 291: #define dataBuf (((Parser *)parser)->dataBuf)
! 292: #define dataBufEnd (((Parser *)parser)->dataBufEnd)
! 293: #define dtd (((Parser *)parser)->dtd)
! 294: #define declEntity (((Parser *)parser)->declEntity)
! 295: #define declNotationName (((Parser *)parser)->declNotationName)
! 296: #define declNotationPublicId (((Parser *)parser)->declNotationPublicId)
! 297: #define declElementType (((Parser *)parser)->declElementType)
! 298: #define declAttributeId (((Parser *)parser)->declAttributeId)
! 299: #define declAttributeIsCdata (((Parser *)parser)->declAttributeIsCdata)
! 300: #define freeTagList (((Parser *)parser)->freeTagList)
! 301: #define tagStack (((Parser *)parser)->tagStack)
! 302: #define atts (((Parser *)parser)->atts)
! 303: #define attsSize (((Parser *)parser)->attsSize)
! 304: #define tempPool (((Parser *)parser)->tempPool)
! 305: #define temp2Pool (((Parser *)parser)->temp2Pool)
! 306: #define groupConnector (((Parser *)parser)->groupConnector)
! 307: #define groupSize (((Parser *)parser)->groupSize)
! 308: #define hadExternalDoctype (((Parser *)parser)->hadExternalDoctype)
! 309:
! 310: XML_Parser XML_ParserCreate(const XML_Char *encodingName)
! 311: {
! 312: XML_Parser parser = malloc(sizeof(Parser));
! 313: if (!parser)
! 314: return parser;
! 315: processor = prologInitProcessor;
! 316: XmlPrologStateInit(&prologState);
! 317: userData = 0;
! 318: handlerArg = 0;
! 319: startElementHandler = 0;
! 320: endElementHandler = 0;
! 321: characterDataHandler = 0;
! 322: processingInstructionHandler = 0;
! 323: defaultHandler = 0;
! 324: unparsedEntityDeclHandler = 0;
! 325: notationDeclHandler = 0;
! 326: externalEntityRefHandler = 0;
! 327: unknownEncodingHandler = 0;
! 328: buffer = 0;
! 329: bufferPtr = 0;
! 330: bufferEnd = 0;
! 331: parseEndByteIndex = 0;
! 332: parseEndPtr = 0;
! 333: bufferLim = 0;
! 334: declElementType = 0;
! 335: declAttributeId = 0;
! 336: declEntity = 0;
! 337: declNotationName = 0;
! 338: declNotationPublicId = 0;
! 339: memset(&position, 0, sizeof(POSITION));
! 340: errorCode = XML_ERROR_NONE;
! 341: eventPtr = 0;
! 342: eventEndPtr = 0;
! 343: positionPtr = 0;
! 344: tagLevel = 0;
! 345: tagStack = 0;
! 346: freeTagList = 0;
! 347: attsSize = INIT_ATTS_SIZE;
! 348: atts = malloc(attsSize * sizeof(ATTRIBUTE));
! 349: dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
! 350: groupSize = 0;
! 351: groupConnector = 0;
! 352: hadExternalDoctype = 0;
! 353: unknownEncodingMem = 0;
! 354: unknownEncodingRelease = 0;
! 355: unknownEncodingData = 0;
! 356: unknownEncodingHandlerData = 0;
! 357: poolInit(&tempPool);
! 358: poolInit(&temp2Pool);
! 359: protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
! 360: if (!dtdInit(&dtd) || !atts || !dataBuf
! 361: || (encodingName && !protocolEncodingName)) {
! 362: XML_ParserFree(parser);
! 363: return 0;
! 364: }
! 365: dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
! 366: XmlInitEncoding(&initEncoding, &encoding, 0);
! 367: return parser;
! 368: }
! 369:
! 370: XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
! 371: const XML_Char *openEntityNames,
! 372: const XML_Char *encodingName)
! 373: {
! 374: XML_Parser parser = oldParser;
! 375: DTD *oldDtd = &dtd;
! 376: XML_StartElementHandler oldStartElementHandler = startElementHandler;
! 377: XML_EndElementHandler oldEndElementHandler = endElementHandler;
! 378: XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
! 379: XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
! 380: XML_DefaultHandler oldDefaultHandler = defaultHandler;
! 381: XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
! 382: XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
! 383: void *oldUserData = userData;
! 384: void *oldHandlerArg = handlerArg;
! 385:
! 386: parser = XML_ParserCreate(encodingName);
! 387: if (!parser)
! 388: return 0;
! 389: startElementHandler = oldStartElementHandler;
! 390: endElementHandler = oldEndElementHandler;
! 391: characterDataHandler = oldCharacterDataHandler;
! 392: processingInstructionHandler = oldProcessingInstructionHandler;
! 393: defaultHandler = oldDefaultHandler;
! 394: externalEntityRefHandler = oldExternalEntityRefHandler;
! 395: unknownEncodingHandler = oldUnknownEncodingHandler;
! 396: userData = oldUserData;
! 397: if (oldUserData == oldHandlerArg)
! 398: handlerArg = userData;
! 399: else
! 400: handlerArg = parser;
! 401: if (!dtdCopy(&dtd, oldDtd) || !setOpenEntityNames(parser, openEntityNames)) {
! 402: XML_ParserFree(parser);
! 403: return 0;
! 404: }
! 405: processor = externalEntityInitProcessor;
! 406: return parser;
! 407: }
! 408:
! 409: void XML_ParserFree(XML_Parser parser)
! 410: {
! 411: for (;;) {
! 412: TAG *p;
! 413: if (tagStack == 0) {
! 414: if (freeTagList == 0)
! 415: break;
! 416: tagStack = freeTagList;
! 417: freeTagList = 0;
! 418: }
! 419: p = tagStack;
! 420: tagStack = tagStack->parent;
! 421: free(p->buf);
! 422: free(p);
! 423: }
! 424: poolDestroy(&tempPool);
! 425: poolDestroy(&temp2Pool);
! 426: dtdDestroy(&dtd);
! 427: free((void *)atts);
! 428: free(groupConnector);
! 429: free(buffer);
! 430: free(dataBuf);
! 431: free(unknownEncodingMem);
! 432: if (unknownEncodingRelease)
! 433: unknownEncodingRelease(unknownEncodingData);
! 434: free(parser);
! 435: }
! 436:
! 437: void XML_UseParserAsHandlerArg(XML_Parser parser)
! 438: {
! 439: handlerArg = parser;
! 440: }
! 441:
! 442: void XML_SetUserData(XML_Parser parser, void *p)
! 443: {
! 444: if (handlerArg == userData)
! 445: handlerArg = userData = p;
! 446: else
! 447: userData = p;
! 448: }
! 449:
! 450: int XML_SetBase(XML_Parser parser, const XML_Char *p)
! 451: {
! 452: if (p) {
! 453: p = poolCopyString(&dtd.pool, p);
! 454: if (!p)
! 455: return 0;
! 456: dtd.base = p;
! 457: }
! 458: else
! 459: dtd.base = 0;
! 460: return 1;
! 461: }
! 462:
! 463: const XML_Char *XML_GetBase(XML_Parser parser)
! 464: {
! 465: return dtd.base;
! 466: }
! 467:
! 468: void XML_SetElementHandler(XML_Parser parser,
! 469: XML_StartElementHandler start,
! 470: XML_EndElementHandler end)
! 471: {
! 472: startElementHandler = start;
! 473: endElementHandler = end;
! 474: }
! 475:
! 476: void XML_SetCharacterDataHandler(XML_Parser parser,
! 477: XML_CharacterDataHandler handler)
! 478: {
! 479: characterDataHandler = handler;
! 480: }
! 481:
! 482: void XML_SetProcessingInstructionHandler(XML_Parser parser,
! 483: XML_ProcessingInstructionHandler handler)
! 484: {
! 485: processingInstructionHandler = handler;
! 486: }
! 487:
! 488: void XML_SetDefaultHandler(XML_Parser parser,
! 489: XML_DefaultHandler handler)
! 490: {
! 491: defaultHandler = handler;
! 492: }
! 493:
! 494: void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
! 495: XML_UnparsedEntityDeclHandler handler)
! 496: {
! 497: unparsedEntityDeclHandler = handler;
! 498: }
! 499:
! 500: void XML_SetNotationDeclHandler(XML_Parser parser,
! 501: XML_NotationDeclHandler handler)
! 502: {
! 503: notationDeclHandler = handler;
! 504: }
! 505:
! 506: void XML_SetExternalEntityRefHandler(XML_Parser parser,
! 507: XML_ExternalEntityRefHandler handler)
! 508: {
! 509: externalEntityRefHandler = handler;
! 510: }
! 511:
! 512: void XML_SetUnknownEncodingHandler(XML_Parser parser,
! 513: XML_UnknownEncodingHandler handler,
! 514: void *data)
! 515: {
! 516: unknownEncodingHandler = handler;
! 517: unknownEncodingHandlerData = data;
! 518: }
! 519:
! 520: int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
! 521: {
! 522: if (len == 0) {
! 523: if (!isFinal)
! 524: return 1;
! 525: errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
! 526: if (errorCode == XML_ERROR_NONE)
! 527: return 1;
! 528: eventEndPtr = eventPtr;
! 529: return 0;
! 530: }
! 531: else if (bufferPtr == bufferEnd) {
! 532: const char *end;
! 533: int nLeftOver;
! 534: parseEndByteIndex += len;
! 535: positionPtr = s;
! 536: if (isFinal) {
! 537: errorCode = processor(parser, s, parseEndPtr = s + len, 0);
! 538: if (errorCode == XML_ERROR_NONE)
! 539: return 1;
! 540: eventEndPtr = eventPtr;
! 541: return 0;
! 542: }
! 543: errorCode = processor(parser, s, parseEndPtr = s + len, &end);
! 544: if (errorCode != XML_ERROR_NONE) {
! 545: eventEndPtr = eventPtr;
! 546: return 0;
! 547: }
! 548: XmlUpdatePosition(encoding, positionPtr, end, &position);
! 549: nLeftOver = s + len - end;
! 550: if (nLeftOver) {
! 551: if (buffer == 0 || nLeftOver > bufferLim - buffer) {
! 552: /* FIXME avoid integer overflow */
! 553: buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
! 554: if (!buffer) {
! 555: errorCode = XML_ERROR_NO_MEMORY;
! 556: eventPtr = eventEndPtr = 0;
! 557: return 0;
! 558: }
! 559: bufferLim = buffer + len * 2;
! 560: }
! 561: memcpy(buffer, end, nLeftOver);
! 562: bufferPtr = buffer;
! 563: bufferEnd = buffer + nLeftOver;
! 564: }
! 565: return 1;
! 566: }
! 567: else {
! 568: memcpy(XML_GetBuffer(parser, len), s, len);
! 569: return XML_ParseBuffer(parser, len, isFinal);
! 570: }
! 571: }
! 572:
! 573: int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
! 574: {
! 575: const char *start = bufferPtr;
! 576: positionPtr = start;
! 577: bufferEnd += len;
! 578: parseEndByteIndex += len;
! 579: errorCode = processor(parser, start, parseEndPtr = bufferEnd,
! 580: isFinal ? (const char **)0 : &bufferPtr);
! 581: if (errorCode == XML_ERROR_NONE) {
! 582: if (!isFinal)
! 583: XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
! 584: return 1;
! 585: }
! 586: else {
! 587: eventEndPtr = eventPtr;
! 588: return 0;
! 589: }
! 590: }
! 591:
! 592: void *XML_GetBuffer(XML_Parser parser, int len)
! 593: {
! 594: if (len > bufferLim - bufferEnd) {
! 595: /* FIXME avoid integer overflow */
! 596: int neededSize = len + (bufferEnd - bufferPtr);
! 597: if (neededSize <= bufferLim - buffer) {
! 598: memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
! 599: bufferEnd = buffer + (bufferEnd - bufferPtr);
! 600: bufferPtr = buffer;
! 601: }
! 602: else {
! 603: char *newBuf;
! 604: int bufferSize = bufferLim - bufferPtr;
! 605: if (bufferSize == 0)
! 606: bufferSize = INIT_BUFFER_SIZE;
! 607: do {
! 608: bufferSize *= 2;
! 609: } while (bufferSize < neededSize);
! 610: newBuf = malloc(bufferSize);
! 611: if (newBuf == 0) {
! 612: errorCode = XML_ERROR_NO_MEMORY;
! 613: return 0;
! 614: }
! 615: bufferLim = newBuf + bufferSize;
! 616: if (bufferPtr) {
! 617: memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
! 618: free(buffer);
! 619: }
! 620: bufferEnd = newBuf + (bufferEnd - bufferPtr);
! 621: bufferPtr = buffer = newBuf;
! 622: }
! 623: }
! 624: return bufferEnd;
! 625: }
! 626:
! 627: enum XML_Error XML_GetErrorCode(XML_Parser parser)
! 628: {
! 629: return errorCode;
! 630: }
! 631:
! 632: long XML_GetCurrentByteIndex(XML_Parser parser)
! 633: {
! 634: if (eventPtr)
! 635: return parseEndByteIndex - (parseEndPtr - eventPtr);
! 636: return -1;
! 637: }
! 638:
! 639: int XML_GetCurrentLineNumber(XML_Parser parser)
! 640: {
! 641: if (eventPtr) {
! 642: XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
! 643: positionPtr = eventPtr;
! 644: }
! 645: return position.lineNumber + 1;
! 646: }
! 647:
! 648: int XML_GetCurrentColumnNumber(XML_Parser parser)
! 649: {
! 650: if (eventPtr) {
! 651: XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
! 652: positionPtr = eventPtr;
! 653: }
! 654: return position.columnNumber;
! 655: }
! 656:
! 657: void XML_DefaultCurrent(XML_Parser parser)
! 658: {
! 659: if (defaultHandler)
! 660: reportDefault(parser, encoding, eventPtr, eventEndPtr);
! 661: }
! 662:
! 663: const XML_LChar *XML_ErrorString(int code)
! 664: {
! 665: static const XML_LChar *message[] = {
! 666: 0,
! 667: XML_T("out of memory"),
! 668: XML_T("syntax error"),
! 669: XML_T("no element found"),
! 670: XML_T("not well-formed"),
! 671: XML_T("unclosed token"),
! 672: XML_T("unclosed token"),
! 673: XML_T("mismatched tag"),
! 674: XML_T("duplicate attribute"),
! 675: XML_T("junk after document element"),
! 676: XML_T("illegal parameter entity reference"),
! 677: XML_T("undefined entity"),
! 678: XML_T("recursive entity reference"),
! 679: XML_T("asynchronous entity"),
! 680: XML_T("reference to invalid character number"),
! 681: XML_T("reference to binary entity"),
! 682: XML_T("reference to external entity in attribute"),
! 683: XML_T("xml processing instruction not at start of external entity"),
! 684: XML_T("unknown encoding"),
! 685: XML_T("encoding specified in XML declaration is incorrect"),
! 686: XML_T("unclosed CDATA section"),
! 687: XML_T("error in processing external entity reference")
! 688: };
! 689: if (code > 0 && code < sizeof(message)/sizeof(message[0]))
! 690: return message[code];
! 691: return 0;
! 692: }
! 693:
! 694: static
! 695: enum XML_Error contentProcessor(XML_Parser parser,
! 696: const char *start,
! 697: const char *end,
! 698: const char **endPtr)
! 699: {
! 700: return doContent(parser, 0, encoding, start, end, endPtr);
! 701: }
! 702:
! 703: static
! 704: enum XML_Error externalEntityInitProcessor(XML_Parser parser,
! 705: const char *start,
! 706: const char *end,
! 707: const char **endPtr)
! 708: {
! 709: enum XML_Error result = initializeEncoding(parser);
! 710: if (result != XML_ERROR_NONE)
! 711: return result;
! 712: processor = externalEntityInitProcessor2;
! 713: return externalEntityInitProcessor2(parser, start, end, endPtr);
! 714: }
! 715:
! 716: static
! 717: enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
! 718: const char *start,
! 719: const char *end,
! 720: const char **endPtr)
! 721: {
! 722: const char *next;
! 723: int tok = XmlContentTok(encoding, start, end, &next);
! 724: switch (tok) {
! 725: case XML_TOK_BOM:
! 726: start = next;
! 727: break;
! 728: case XML_TOK_PARTIAL:
! 729: if (endPtr) {
! 730: *endPtr = start;
! 731: return XML_ERROR_NONE;
! 732: }
! 733: eventPtr = start;
! 734: return XML_ERROR_UNCLOSED_TOKEN;
! 735: case XML_TOK_PARTIAL_CHAR:
! 736: if (endPtr) {
! 737: *endPtr = start;
! 738: return XML_ERROR_NONE;
! 739: }
! 740: eventPtr = start;
! 741: return XML_ERROR_PARTIAL_CHAR;
! 742: }
! 743: processor = externalEntityInitProcessor3;
! 744: return externalEntityInitProcessor3(parser, start, end, endPtr);
! 745: }
! 746:
! 747: static
! 748: enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
! 749: const char *start,
! 750: const char *end,
! 751: const char **endPtr)
! 752: {
! 753: const char *next;
! 754: int tok = XmlContentTok(encoding, start, end, &next);
! 755: switch (tok) {
! 756: case XML_TOK_XML_DECL:
! 757: {
! 758: enum XML_Error result = processXmlDecl(parser, 1, start, next);
! 759: if (result != XML_ERROR_NONE)
! 760: return result;
! 761: start = next;
! 762: }
! 763: break;
! 764: case XML_TOK_PARTIAL:
! 765: if (endPtr) {
! 766: *endPtr = start;
! 767: return XML_ERROR_NONE;
! 768: }
! 769: eventPtr = start;
! 770: return XML_ERROR_UNCLOSED_TOKEN;
! 771: case XML_TOK_PARTIAL_CHAR:
! 772: if (endPtr) {
! 773: *endPtr = start;
! 774: return XML_ERROR_NONE;
! 775: }
! 776: eventPtr = start;
! 777: return XML_ERROR_PARTIAL_CHAR;
! 778: }
! 779: processor = externalEntityContentProcessor;
! 780: tagLevel = 1;
! 781: return doContent(parser, 1, encoding, start, end, endPtr);
! 782: }
! 783:
! 784: static
! 785: enum XML_Error externalEntityContentProcessor(XML_Parser parser,
! 786: const char *start,
! 787: const char *end,
! 788: const char **endPtr)
! 789: {
! 790: return doContent(parser, 1, encoding, start, end, endPtr);
! 791: }
! 792:
! 793: static enum XML_Error
! 794: doContent(XML_Parser parser,
! 795: int startTagLevel,
! 796: const ENCODING *enc,
! 797: const char *s,
! 798: const char *end,
! 799: const char **nextPtr)
! 800: {
! 801: const ENCODING *internalEnc = XmlGetInternalEncoding();
! 802: const char *dummy;
! 803: const char **eventPP;
! 804: const char **eventEndPP;
! 805: if (enc == encoding) {
! 806: eventPP = &eventPtr;
! 807: *eventPP = s;
! 808: eventEndPP = &eventEndPtr;
! 809: }
! 810: else
! 811: eventPP = eventEndPP = &dummy;
! 812: for (;;) {
! 813: const char *next;
! 814: int tok = XmlContentTok(enc, s, end, &next);
! 815: *eventEndPP = next;
! 816: switch (tok) {
! 817: case XML_TOK_TRAILING_CR:
! 818: if (nextPtr) {
! 819: *nextPtr = s;
! 820: return XML_ERROR_NONE;
! 821: }
! 822: *eventEndPP = end;
! 823: if (characterDataHandler) {
! 824: XML_Char c = XML_T('\n');
! 825: characterDataHandler(handlerArg, &c, 1);
! 826: }
! 827: else if (defaultHandler)
! 828: reportDefault(parser, enc, s, end);
! 829: if (startTagLevel == 0)
! 830: return XML_ERROR_NO_ELEMENTS;
! 831: if (tagLevel != startTagLevel)
! 832: return XML_ERROR_ASYNC_ENTITY;
! 833: return XML_ERROR_NONE;
! 834: case XML_TOK_NONE:
! 835: if (nextPtr) {
! 836: *nextPtr = s;
! 837: return XML_ERROR_NONE;
! 838: }
! 839: if (startTagLevel > 0) {
! 840: if (tagLevel != startTagLevel)
! 841: return XML_ERROR_ASYNC_ENTITY;
! 842: return XML_ERROR_NONE;
! 843: }
! 844: return XML_ERROR_NO_ELEMENTS;
! 845: case XML_TOK_INVALID:
! 846: *eventPP = next;
! 847: return XML_ERROR_INVALID_TOKEN;
! 848: case XML_TOK_PARTIAL:
! 849: if (nextPtr) {
! 850: *nextPtr = s;
! 851: return XML_ERROR_NONE;
! 852: }
! 853: return XML_ERROR_UNCLOSED_TOKEN;
! 854: case XML_TOK_PARTIAL_CHAR:
! 855: if (nextPtr) {
! 856: *nextPtr = s;
! 857: return XML_ERROR_NONE;
! 858: }
! 859: return XML_ERROR_PARTIAL_CHAR;
! 860: case XML_TOK_ENTITY_REF:
! 861: {
! 862: const XML_Char *name;
! 863: ENTITY *entity;
! 864: XML_Char ch = XmlPredefinedEntityName(enc,
! 865: s + enc->minBytesPerChar,
! 866: next - enc->minBytesPerChar);
! 867: if (ch) {
! 868: if (characterDataHandler)
! 869: characterDataHandler(handlerArg, &ch, 1);
! 870: else if (defaultHandler)
! 871: reportDefault(parser, enc, s, next);
! 872: break;
! 873: }
! 874: name = poolStoreString(&dtd.pool, enc,
! 875: s + enc->minBytesPerChar,
! 876: next - enc->minBytesPerChar);
! 877: if (!name)
! 878: return XML_ERROR_NO_MEMORY;
! 879: entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
! 880: poolDiscard(&dtd.pool);
! 881: if (!entity) {
! 882: if (dtd.complete || dtd.standalone)
! 883: return XML_ERROR_UNDEFINED_ENTITY;
! 884: if (defaultHandler)
! 885: reportDefault(parser, enc, s, next);
! 886: break;
! 887: }
! 888: if (entity->open)
! 889: return XML_ERROR_RECURSIVE_ENTITY_REF;
! 890: if (entity->notation)
! 891: return XML_ERROR_BINARY_ENTITY_REF;
! 892: if (entity) {
! 893: if (entity->textPtr) {
! 894: enum XML_Error result;
! 895: if (defaultHandler) {
! 896: reportDefault(parser, enc, s, next);
! 897: break;
! 898: }
! 899: /* Protect against the possibility that somebody sets
! 900: the defaultHandler from inside another handler. */
! 901: *eventEndPP = *eventPP;
! 902: entity->open = 1;
! 903: result = doContent(parser,
! 904: tagLevel,
! 905: internalEnc,
! 906: (char *)entity->textPtr,
! 907: (char *)(entity->textPtr + entity->textLen),
! 908: 0);
! 909: entity->open = 0;
! 910: if (result)
! 911: return result;
! 912: }
! 913: else if (externalEntityRefHandler) {
! 914: const XML_Char *openEntityNames;
! 915: entity->open = 1;
! 916: openEntityNames = getOpenEntityNames(parser);
! 917: entity->open = 0;
! 918: if (!openEntityNames)
! 919: return XML_ERROR_NO_MEMORY;
! 920: if (!externalEntityRefHandler(parser, openEntityNames, dtd.base, entity->systemId, entity->publicId))
! 921: return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
! 922: poolDiscard(&tempPool);
! 923: }
! 924: else if (defaultHandler)
! 925: reportDefault(parser, enc, s, next);
! 926: }
! 927: break;
! 928: }
! 929: case XML_TOK_START_TAG_WITH_ATTS:
! 930: if (!startElementHandler) {
! 931: enum XML_Error result = storeAtts(parser, enc, 0, s);
! 932: if (result)
! 933: return result;
! 934: }
! 935: /* fall through */
! 936: case XML_TOK_START_TAG_NO_ATTS:
! 937: {
! 938: TAG *tag;
! 939: if (freeTagList) {
! 940: tag = freeTagList;
! 941: freeTagList = freeTagList->parent;
! 942: }
! 943: else {
! 944: tag = malloc(sizeof(TAG));
! 945: if (!tag)
! 946: return XML_ERROR_NO_MEMORY;
! 947: tag->buf = malloc(INIT_TAG_BUF_SIZE);
! 948: if (!tag->buf)
! 949: return XML_ERROR_NO_MEMORY;
! 950: tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
! 951: }
! 952: tag->parent = tagStack;
! 953: tagStack = tag;
! 954: tag->rawName = s + enc->minBytesPerChar;
! 955: tag->rawNameLength = XmlNameLength(enc, tag->rawName);
! 956: if (nextPtr) {
! 957: if (tag->rawNameLength > tag->bufEnd - tag->buf) {
! 958: int bufSize = tag->rawNameLength * 4;
! 959: bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
! 960: tag->buf = realloc(tag->buf, bufSize);
! 961: if (!tag->buf)
! 962: return XML_ERROR_NO_MEMORY;
! 963: tag->bufEnd = tag->buf + bufSize;
! 964: }
! 965: memcpy(tag->buf, tag->rawName, tag->rawNameLength);
! 966: tag->rawName = tag->buf;
! 967: }
! 968: ++tagLevel;
! 969: if (startElementHandler) {
! 970: enum XML_Error result;
! 971: XML_Char *toPtr;
! 972: for (;;) {
! 973: const char *rawNameEnd = tag->rawName + tag->rawNameLength;
! 974: const char *fromPtr = tag->rawName;
! 975: int bufSize;
! 976: if (nextPtr)
! 977: toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
! 978: else
! 979: toPtr = (XML_Char *)tag->buf;
! 980: tag->name = toPtr;
! 981: XmlConvert(enc,
! 982: &fromPtr, rawNameEnd,
! 983: (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
! 984: if (fromPtr == rawNameEnd)
! 985: break;
! 986: bufSize = (tag->bufEnd - tag->buf) << 1;
! 987: tag->buf = realloc(tag->buf, bufSize);
! 988: if (!tag->buf)
! 989: return XML_ERROR_NO_MEMORY;
! 990: tag->bufEnd = tag->buf + bufSize;
! 991: if (nextPtr)
! 992: tag->rawName = tag->buf;
! 993: }
! 994: *toPtr = XML_T('\0');
! 995: result = storeAtts(parser, enc, tag->name, s);
! 996: if (result)
! 997: return result;
! 998: startElementHandler(handlerArg, tag->name, (const XML_Char **)atts);
! 999: poolClear(&tempPool);
! 1000: }
! 1001: else {
! 1002: tag->name = 0;
! 1003: if (defaultHandler)
! 1004: reportDefault(parser, enc, s, next);
! 1005: }
! 1006: break;
! 1007: }
! 1008: case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
! 1009: if (!startElementHandler) {
! 1010: enum XML_Error result = storeAtts(parser, enc, 0, s);
! 1011: if (result)
! 1012: return result;
! 1013: }
! 1014: /* fall through */
! 1015: case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
! 1016: if (startElementHandler || endElementHandler) {
! 1017: const char *rawName = s + enc->minBytesPerChar;
! 1018: const XML_Char *name = poolStoreString(&tempPool, enc, rawName,
! 1019: rawName
! 1020: + XmlNameLength(enc, rawName));
! 1021: if (!name)
! 1022: return XML_ERROR_NO_MEMORY;
! 1023: poolFinish(&tempPool);
! 1024: if (startElementHandler) {
! 1025: enum XML_Error result = storeAtts(parser, enc, name, s);
! 1026: if (result)
! 1027: return result;
! 1028: startElementHandler(handlerArg, name, (const XML_Char **)atts);
! 1029: }
! 1030: if (endElementHandler) {
! 1031: if (startElementHandler)
! 1032: *eventPP = *eventEndPP;
! 1033: endElementHandler(handlerArg, name);
! 1034: }
! 1035: poolClear(&tempPool);
! 1036: }
! 1037: else if (defaultHandler)
! 1038: reportDefault(parser, enc, s, next);
! 1039: if (tagLevel == 0)
! 1040: return epilogProcessor(parser, next, end, nextPtr);
! 1041: break;
! 1042: case XML_TOK_END_TAG:
! 1043: if (tagLevel == startTagLevel)
! 1044: return XML_ERROR_ASYNC_ENTITY;
! 1045: else {
! 1046: int len;
! 1047: const char *rawName;
! 1048: TAG *tag = tagStack;
! 1049: tagStack = tag->parent;
! 1050: tag->parent = freeTagList;
! 1051: freeTagList = tag;
! 1052: rawName = s + enc->minBytesPerChar*2;
! 1053: len = XmlNameLength(enc, rawName);
! 1054: if (len != tag->rawNameLength
! 1055: || memcmp(tag->rawName, rawName, len) != 0) {
! 1056: *eventPP = rawName;
! 1057: return XML_ERROR_TAG_MISMATCH;
! 1058: }
! 1059: --tagLevel;
! 1060: if (endElementHandler) {
! 1061: if (tag->name)
! 1062: endElementHandler(handlerArg, tag->name);
! 1063: else {
! 1064: const XML_Char *name = poolStoreString(&tempPool, enc, rawName,
! 1065: rawName + len);
! 1066: if (!name)
! 1067: return XML_ERROR_NO_MEMORY;
! 1068: endElementHandler(handlerArg, name);
! 1069: poolClear(&tempPool);
! 1070: }
! 1071: }
! 1072: else if (defaultHandler)
! 1073: reportDefault(parser, enc, s, next);
! 1074: if (tagLevel == 0)
! 1075: return epilogProcessor(parser, next, end, nextPtr);
! 1076: }
! 1077: break;
! 1078: case XML_TOK_CHAR_REF:
! 1079: {
! 1080: int n = XmlCharRefNumber(enc, s);
! 1081: if (n < 0)
! 1082: return XML_ERROR_BAD_CHAR_REF;
! 1083: if (characterDataHandler) {
! 1084: XML_Char buf[XML_ENCODE_MAX];
! 1085: characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
! 1086: }
! 1087: else if (defaultHandler)
! 1088: reportDefault(parser, enc, s, next);
! 1089: }
! 1090: break;
! 1091: case XML_TOK_XML_DECL:
! 1092: return XML_ERROR_MISPLACED_XML_PI;
! 1093: case XML_TOK_DATA_NEWLINE:
! 1094: if (characterDataHandler) {
! 1095: XML_Char c = XML_T('\n');
! 1096: characterDataHandler(handlerArg, &c, 1);
! 1097: }
! 1098: else if (defaultHandler)
! 1099: reportDefault(parser, enc, s, next);
! 1100: break;
! 1101: case XML_TOK_CDATA_SECT_OPEN:
! 1102: {
! 1103: enum XML_Error result;
! 1104: if (characterDataHandler)
! 1105: characterDataHandler(handlerArg, dataBuf, 0);
! 1106: else if (defaultHandler)
! 1107: reportDefault(parser, enc, s, next);
! 1108: result = doCdataSection(parser, enc, &next, end, nextPtr);
! 1109: if (!next) {
! 1110: processor = cdataSectionProcessor;
! 1111: return result;
! 1112: }
! 1113: }
! 1114: break;
! 1115: case XML_TOK_TRAILING_RSQB:
! 1116: if (nextPtr) {
! 1117: *nextPtr = s;
! 1118: return XML_ERROR_NONE;
! 1119: }
! 1120: if (characterDataHandler) {
! 1121: if (MUST_CONVERT(enc, s)) {
! 1122: ICHAR *dataPtr = (ICHAR *)dataBuf;
! 1123: XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
! 1124: characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 1125: }
! 1126: else
! 1127: characterDataHandler(handlerArg,
! 1128: (XML_Char *)s,
! 1129: (XML_Char *)end - (XML_Char *)s);
! 1130: }
! 1131: else if (defaultHandler)
! 1132: reportDefault(parser, enc, s, end);
! 1133: if (startTagLevel == 0) {
! 1134: *eventPP = end;
! 1135: return XML_ERROR_NO_ELEMENTS;
! 1136: }
! 1137: if (tagLevel != startTagLevel) {
! 1138: *eventPP = end;
! 1139: return XML_ERROR_ASYNC_ENTITY;
! 1140: }
! 1141: return XML_ERROR_NONE;
! 1142: case XML_TOK_DATA_CHARS:
! 1143: if (characterDataHandler) {
! 1144: if (MUST_CONVERT(enc, s)) {
! 1145: for (;;) {
! 1146: ICHAR *dataPtr = (ICHAR *)dataBuf;
! 1147: XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
! 1148: *eventEndPP = s;
! 1149: characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 1150: if (s == next)
! 1151: break;
! 1152: *eventPP = s;
! 1153: }
! 1154: }
! 1155: else
! 1156: characterDataHandler(handlerArg,
! 1157: (XML_Char *)s,
! 1158: (XML_Char *)next - (XML_Char *)s);
! 1159: }
! 1160: else if (defaultHandler)
! 1161: reportDefault(parser, enc, s, next);
! 1162: break;
! 1163: case XML_TOK_PI:
! 1164: if (!reportProcessingInstruction(parser, enc, s, next))
! 1165: return XML_ERROR_NO_MEMORY;
! 1166: break;
! 1167: default:
! 1168: if (defaultHandler)
! 1169: reportDefault(parser, enc, s, next);
! 1170: break;
! 1171: }
! 1172: *eventPP = s = next;
! 1173: }
! 1174: /* not reached */
! 1175: }
! 1176:
! 1177: /* If tagName is non-null, build a real list of attributes,
! 1178: otherwise just check the attributes for well-formedness. */
! 1179:
! 1180: static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
! 1181: const XML_Char *tagName, const char *s)
! 1182: {
! 1183: ELEMENT_TYPE *elementType = 0;
! 1184: int nDefaultAtts = 0;
! 1185: const XML_Char **appAtts;
! 1186: int i;
! 1187: int n;
! 1188:
! 1189: if (tagName) {
! 1190: elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagName, 0);
! 1191: if (elementType)
! 1192: nDefaultAtts = elementType->nDefaultAtts;
! 1193: }
! 1194:
! 1195: n = XmlGetAttributes(enc, s, attsSize, atts);
! 1196: if (n + nDefaultAtts > attsSize) {
! 1197: int oldAttsSize = attsSize;
! 1198: attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
! 1199: atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
! 1200: if (!atts)
! 1201: return XML_ERROR_NO_MEMORY;
! 1202: if (n > oldAttsSize)
! 1203: XmlGetAttributes(enc, s, n, atts);
! 1204: }
! 1205: appAtts = (const XML_Char **)atts;
! 1206: for (i = 0; i < n; i++) {
! 1207: ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
! 1208: atts[i].name
! 1209: + XmlNameLength(enc, atts[i].name));
! 1210: if (!attId)
! 1211: return XML_ERROR_NO_MEMORY;
! 1212: if ((attId->name)[-1]) {
! 1213: if (enc == encoding)
! 1214: eventPtr = atts[i].name;
! 1215: return XML_ERROR_DUPLICATE_ATTRIBUTE;
! 1216: }
! 1217: (attId->name)[-1] = 1;
! 1218: appAtts[i << 1] = attId->name;
! 1219: if (!atts[i].normalized) {
! 1220: enum XML_Error result;
! 1221: int isCdata = 1;
! 1222:
! 1223: if (attId->maybeTokenized) {
! 1224: int j;
! 1225: for (j = 0; j < nDefaultAtts; j++) {
! 1226: if (attId == elementType->defaultAtts[j].id) {
! 1227: isCdata = elementType->defaultAtts[j].isCdata;
! 1228: break;
! 1229: }
! 1230: }
! 1231: }
! 1232:
! 1233: result = storeAttributeValue(parser, enc, isCdata,
! 1234: atts[i].valuePtr, atts[i].valueEnd,
! 1235: &tempPool);
! 1236: if (result)
! 1237: return result;
! 1238: if (tagName) {
! 1239: appAtts[(i << 1) + 1] = poolStart(&tempPool);
! 1240: poolFinish(&tempPool);
! 1241: }
! 1242: else
! 1243: poolDiscard(&tempPool);
! 1244: }
! 1245: else if (tagName) {
! 1246: appAtts[(i << 1) + 1] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
! 1247: if (appAtts[(i << 1) + 1] == 0)
! 1248: return XML_ERROR_NO_MEMORY;
! 1249: poolFinish(&tempPool);
! 1250: }
! 1251: }
! 1252: if (tagName) {
! 1253: int j;
! 1254: for (j = 0; j < nDefaultAtts; j++) {
! 1255: const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
! 1256: if (!(da->id->name)[-1] && da->value) {
! 1257: (da->id->name)[-1] = 1;
! 1258: appAtts[i << 1] = da->id->name;
! 1259: appAtts[(i << 1) + 1] = da->value;
! 1260: i++;
! 1261: }
! 1262: }
! 1263: appAtts[i << 1] = 0;
! 1264: }
! 1265: while (i-- > 0)
! 1266: ((XML_Char *)appAtts[i << 1])[-1] = 0;
! 1267: return XML_ERROR_NONE;
! 1268: }
! 1269:
! 1270: /* The idea here is to avoid using stack for each CDATA section when
! 1271: the whole file is parsed with one call. */
! 1272:
! 1273: static
! 1274: enum XML_Error cdataSectionProcessor(XML_Parser parser,
! 1275: const char *start,
! 1276: const char *end,
! 1277: const char **endPtr)
! 1278: {
! 1279: enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
! 1280: if (start) {
! 1281: processor = contentProcessor;
! 1282: return contentProcessor(parser, start, end, endPtr);
! 1283: }
! 1284: return result;
! 1285: }
! 1286:
! 1287: /* startPtr gets set to non-null is the section is closed, and to null if
! 1288: the section is not yet closed. */
! 1289:
! 1290: static
! 1291: enum XML_Error doCdataSection(XML_Parser parser,
! 1292: const ENCODING *enc,
! 1293: const char **startPtr,
! 1294: const char *end,
! 1295: const char **nextPtr)
! 1296: {
! 1297: const char *s = *startPtr;
! 1298: const char *dummy;
! 1299: const char **eventPP;
! 1300: const char **eventEndPP;
! 1301: if (enc == encoding) {
! 1302: eventPP = &eventPtr;
! 1303: *eventPP = s;
! 1304: eventEndPP = &eventEndPtr;
! 1305: }
! 1306: else
! 1307: eventPP = eventEndPP = &dummy;
! 1308: *startPtr = 0;
! 1309: for (;;) {
! 1310: const char *next;
! 1311: int tok = XmlCdataSectionTok(enc, s, end, &next);
! 1312: *eventEndPP = next;
! 1313: switch (tok) {
! 1314: case XML_TOK_CDATA_SECT_CLOSE:
! 1315: if (characterDataHandler)
! 1316: characterDataHandler(handlerArg, dataBuf, 0);
! 1317: else if (defaultHandler)
! 1318: reportDefault(parser, enc, s, next);
! 1319: *startPtr = next;
! 1320: return XML_ERROR_NONE;
! 1321: case XML_TOK_DATA_NEWLINE:
! 1322: if (characterDataHandler) {
! 1323: XML_Char c = XML_T('\n');
! 1324: characterDataHandler(handlerArg, &c, 1);
! 1325: }
! 1326: else if (defaultHandler)
! 1327: reportDefault(parser, enc, s, next);
! 1328: break;
! 1329: case XML_TOK_DATA_CHARS:
! 1330: if (characterDataHandler) {
! 1331: if (MUST_CONVERT(enc, s)) {
! 1332: for (;;) {
! 1333: ICHAR *dataPtr = (ICHAR *)dataBuf;
! 1334: XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
! 1335: *eventEndPP = next;
! 1336: characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 1337: if (s == next)
! 1338: break;
! 1339: *eventPP = s;
! 1340: }
! 1341: }
! 1342: else
! 1343: characterDataHandler(handlerArg,
! 1344: (XML_Char *)s,
! 1345: (XML_Char *)next - (XML_Char *)s);
! 1346: }
! 1347: else if (defaultHandler)
! 1348: reportDefault(parser, enc, s, next);
! 1349: break;
! 1350: case XML_TOK_INVALID:
! 1351: *eventPP = next;
! 1352: return XML_ERROR_INVALID_TOKEN;
! 1353: case XML_TOK_PARTIAL_CHAR:
! 1354: if (nextPtr) {
! 1355: *nextPtr = s;
! 1356: return XML_ERROR_NONE;
! 1357: }
! 1358: return XML_ERROR_PARTIAL_CHAR;
! 1359: case XML_TOK_PARTIAL:
! 1360: case XML_TOK_NONE:
! 1361: if (nextPtr) {
! 1362: *nextPtr = s;
! 1363: return XML_ERROR_NONE;
! 1364: }
! 1365: return XML_ERROR_UNCLOSED_CDATA_SECTION;
! 1366: default:
! 1367: abort();
! 1368: }
! 1369: *eventPP = s = next;
! 1370: }
! 1371: /* not reached */
! 1372: }
! 1373:
! 1374: static enum XML_Error
! 1375: initializeEncoding(XML_Parser parser)
! 1376: {
! 1377: const char *s;
! 1378: #ifdef XML_UNICODE
! 1379: char encodingBuf[128];
! 1380: if (!protocolEncodingName)
! 1381: s = 0;
! 1382: else {
! 1383: int i;
! 1384: for (i = 0; protocolEncodingName[i]; i++) {
! 1385: if (i == sizeof(encodingBuf) - 1
! 1386: || protocolEncodingName[i] >= 0x80
! 1387: || protocolEncodingName[i] < 0) {
! 1388: encodingBuf[0] = '\0';
! 1389: break;
! 1390: }
! 1391: encodingBuf[i] = (char)protocolEncodingName[i];
! 1392: }
! 1393: encodingBuf[i] = '\0';
! 1394: s = encodingBuf;
! 1395: }
! 1396: #else
! 1397: s = protocolEncodingName;
! 1398: #endif
! 1399: if (XmlInitEncoding(&initEncoding, &encoding, s))
! 1400: return XML_ERROR_NONE;
! 1401: return handleUnknownEncoding(parser, protocolEncodingName);
! 1402: }
! 1403:
! 1404: static enum XML_Error
! 1405: processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
! 1406: const char *s, const char *next)
! 1407: {
! 1408: const char *encodingName = 0;
! 1409: const ENCODING *newEncoding = 0;
! 1410: const char *version;
! 1411: int standalone = -1;
! 1412: if (!XmlParseXmlDecl(isGeneralTextEntity,
! 1413: encoding,
! 1414: s,
! 1415: next,
! 1416: &eventPtr,
! 1417: &version,
! 1418: &encodingName,
! 1419: &newEncoding,
! 1420: &standalone))
! 1421: return XML_ERROR_SYNTAX;
! 1422: if (!isGeneralTextEntity && standalone == 1)
! 1423: dtd.standalone = 1;
! 1424: if (defaultHandler)
! 1425: reportDefault(parser, encoding, s, next);
! 1426: if (!protocolEncodingName) {
! 1427: if (newEncoding) {
! 1428: if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
! 1429: eventPtr = encodingName;
! 1430: return XML_ERROR_INCORRECT_ENCODING;
! 1431: }
! 1432: encoding = newEncoding;
! 1433: }
! 1434: else if (encodingName) {
! 1435: enum XML_Error result;
! 1436: const XML_Char *s = poolStoreString(&tempPool,
! 1437: encoding,
! 1438: encodingName,
! 1439: encodingName
! 1440: + XmlNameLength(encoding, encodingName));
! 1441: if (!s)
! 1442: return XML_ERROR_NO_MEMORY;
! 1443: result = handleUnknownEncoding(parser, s);
! 1444: poolDiscard(&tempPool);
! 1445: if (result == XML_ERROR_UNKNOWN_ENCODING)
! 1446: eventPtr = encodingName;
! 1447: return result;
! 1448: }
! 1449: }
! 1450: return XML_ERROR_NONE;
! 1451: }
! 1452:
! 1453: static enum XML_Error
! 1454: handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
! 1455: {
! 1456: if (unknownEncodingHandler) {
! 1457: XML_Encoding info;
! 1458: int i;
! 1459: for (i = 0; i < 256; i++)
! 1460: info.map[i] = -1;
! 1461: info.convert = 0;
! 1462: info.data = 0;
! 1463: info.release = 0;
! 1464: if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
! 1465: ENCODING *enc;
! 1466: unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
! 1467: if (!unknownEncodingMem) {
! 1468: if (info.release)
! 1469: info.release(info.data);
! 1470: return XML_ERROR_NO_MEMORY;
! 1471: }
! 1472: enc = XmlInitUnknownEncoding(unknownEncodingMem,
! 1473: info.map,
! 1474: info.convert,
! 1475: info.data);
! 1476: if (enc) {
! 1477: unknownEncodingData = info.data;
! 1478: unknownEncodingRelease = info.release;
! 1479: encoding = enc;
! 1480: return XML_ERROR_NONE;
! 1481: }
! 1482: }
! 1483: if (info.release)
! 1484: info.release(info.data);
! 1485: }
! 1486: return XML_ERROR_UNKNOWN_ENCODING;
! 1487: }
! 1488:
! 1489: static enum XML_Error
! 1490: prologInitProcessor(XML_Parser parser,
! 1491: const char *s,
! 1492: const char *end,
! 1493: const char **nextPtr)
! 1494: {
! 1495: enum XML_Error result = initializeEncoding(parser);
! 1496: if (result != XML_ERROR_NONE)
! 1497: return result;
! 1498: processor = prologProcessor;
! 1499: return prologProcessor(parser, s, end, nextPtr);
! 1500: }
! 1501:
! 1502: static enum XML_Error
! 1503: prologProcessor(XML_Parser parser,
! 1504: const char *s,
! 1505: const char *end,
! 1506: const char **nextPtr)
! 1507: {
! 1508: for (;;) {
! 1509: const char *next;
! 1510: int tok = XmlPrologTok(encoding, s, end, &next);
! 1511: if (tok <= 0) {
! 1512: if (nextPtr != 0 && tok != XML_TOK_INVALID) {
! 1513: *nextPtr = s;
! 1514: return XML_ERROR_NONE;
! 1515: }
! 1516: switch (tok) {
! 1517: case XML_TOK_INVALID:
! 1518: eventPtr = next;
! 1519: return XML_ERROR_INVALID_TOKEN;
! 1520: case XML_TOK_NONE:
! 1521: return XML_ERROR_NO_ELEMENTS;
! 1522: case XML_TOK_PARTIAL:
! 1523: return XML_ERROR_UNCLOSED_TOKEN;
! 1524: case XML_TOK_PARTIAL_CHAR:
! 1525: return XML_ERROR_PARTIAL_CHAR;
! 1526: case XML_TOK_TRAILING_CR:
! 1527: eventPtr = s + encoding->minBytesPerChar;
! 1528: return XML_ERROR_NO_ELEMENTS;
! 1529: default:
! 1530: abort();
! 1531: }
! 1532: }
! 1533: switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
! 1534: case XML_ROLE_XML_DECL:
! 1535: {
! 1536: enum XML_Error result = processXmlDecl(parser, 0, s, next);
! 1537: if (result != XML_ERROR_NONE)
! 1538: return result;
! 1539: }
! 1540: break;
! 1541: case XML_ROLE_DOCTYPE_SYSTEM_ID:
! 1542: hadExternalDoctype = 1;
! 1543: break;
! 1544: case XML_ROLE_DOCTYPE_PUBLIC_ID:
! 1545: case XML_ROLE_ENTITY_PUBLIC_ID:
! 1546: if (!XmlIsPublicId(encoding, s, next, &eventPtr))
! 1547: return XML_ERROR_SYNTAX;
! 1548: if (declEntity) {
! 1549: XML_Char *tem = poolStoreString(&dtd.pool,
! 1550: encoding,
! 1551: s + encoding->minBytesPerChar,
! 1552: next - encoding->minBytesPerChar);
! 1553: if (!tem)
! 1554: return XML_ERROR_NO_MEMORY;
! 1555: normalizePublicId(tem);
! 1556: declEntity->publicId = tem;
! 1557: poolFinish(&dtd.pool);
! 1558: }
! 1559: break;
! 1560: case XML_ROLE_INSTANCE_START:
! 1561: processor = contentProcessor;
! 1562: if (hadExternalDoctype)
! 1563: dtd.complete = 0;
! 1564: return contentProcessor(parser, s, end, nextPtr);
! 1565: case XML_ROLE_ATTLIST_ELEMENT_NAME:
! 1566: {
! 1567: const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
! 1568: if (!name)
! 1569: return XML_ERROR_NO_MEMORY;
! 1570: declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
! 1571: if (!declElementType)
! 1572: return XML_ERROR_NO_MEMORY;
! 1573: if (declElementType->name != name)
! 1574: poolDiscard(&dtd.pool);
! 1575: else
! 1576: poolFinish(&dtd.pool);
! 1577: break;
! 1578: }
! 1579: case XML_ROLE_ATTRIBUTE_NAME:
! 1580: declAttributeId = getAttributeId(parser, encoding, s, next);
! 1581: if (!declAttributeId)
! 1582: return XML_ERROR_NO_MEMORY;
! 1583: declAttributeIsCdata = 0;
! 1584: break;
! 1585: case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
! 1586: declAttributeIsCdata = 1;
! 1587: break;
! 1588: case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
! 1589: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
! 1590: if (dtd.complete
! 1591: && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
! 1592: return XML_ERROR_NO_MEMORY;
! 1593: break;
! 1594: case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
! 1595: case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
! 1596: {
! 1597: const XML_Char *attVal;
! 1598: enum XML_Error result
! 1599: = storeAttributeValue(parser, encoding, declAttributeIsCdata,
! 1600: s + encoding->minBytesPerChar,
! 1601: next - encoding->minBytesPerChar,
! 1602: &dtd.pool);
! 1603: if (result)
! 1604: return result;
! 1605: attVal = poolStart(&dtd.pool);
! 1606: poolFinish(&dtd.pool);
! 1607: if (dtd.complete
! 1608: && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
! 1609: return XML_ERROR_NO_MEMORY;
! 1610: break;
! 1611: }
! 1612: case XML_ROLE_ENTITY_VALUE:
! 1613: {
! 1614: enum XML_Error result = storeEntityValue(parser, s, next);
! 1615: if (result != XML_ERROR_NONE)
! 1616: return result;
! 1617: }
! 1618: break;
! 1619: case XML_ROLE_ENTITY_SYSTEM_ID:
! 1620: if (declEntity) {
! 1621: declEntity->systemId = poolStoreString(&dtd.pool, encoding,
! 1622: s + encoding->minBytesPerChar,
! 1623: next - encoding->minBytesPerChar);
! 1624: if (!declEntity->systemId)
! 1625: return XML_ERROR_NO_MEMORY;
! 1626: declEntity->base = dtd.base;
! 1627: poolFinish(&dtd.pool);
! 1628: }
! 1629: break;
! 1630: case XML_ROLE_ENTITY_NOTATION_NAME:
! 1631: if (declEntity) {
! 1632: declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
! 1633: if (!declEntity->notation)
! 1634: return XML_ERROR_NO_MEMORY;
! 1635: poolFinish(&dtd.pool);
! 1636: if (unparsedEntityDeclHandler) {
! 1637: eventPtr = eventEndPtr = s;
! 1638: unparsedEntityDeclHandler(handlerArg,
! 1639: declEntity->name,
! 1640: declEntity->base,
! 1641: declEntity->systemId,
! 1642: declEntity->publicId,
! 1643: declEntity->notation);
! 1644: }
! 1645:
! 1646: }
! 1647: break;
! 1648: case XML_ROLE_GENERAL_ENTITY_NAME:
! 1649: {
! 1650: const XML_Char *name;
! 1651: if (XmlPredefinedEntityName(encoding, s, next)) {
! 1652: declEntity = 0;
! 1653: break;
! 1654: }
! 1655: name = poolStoreString(&dtd.pool, encoding, s, next);
! 1656: if (!name)
! 1657: return XML_ERROR_NO_MEMORY;
! 1658: if (dtd.complete) {
! 1659: declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
! 1660: if (!declEntity)
! 1661: return XML_ERROR_NO_MEMORY;
! 1662: if (declEntity->name != name) {
! 1663: poolDiscard(&dtd.pool);
! 1664: declEntity = 0;
! 1665: }
! 1666: else
! 1667: poolFinish(&dtd.pool);
! 1668: }
! 1669: else {
! 1670: poolDiscard(&dtd.pool);
! 1671: declEntity = 0;
! 1672: }
! 1673: }
! 1674: break;
! 1675: case XML_ROLE_PARAM_ENTITY_NAME:
! 1676: declEntity = 0;
! 1677: break;
! 1678: case XML_ROLE_NOTATION_NAME:
! 1679: declNotationPublicId = 0;
! 1680: declNotationName = 0;
! 1681: if (notationDeclHandler) {
! 1682: declNotationName = poolStoreString(&tempPool, encoding, s, next);
! 1683: if (!declNotationName)
! 1684: return XML_ERROR_NO_MEMORY;
! 1685: poolFinish(&tempPool);
! 1686: }
! 1687: break;
! 1688: case XML_ROLE_NOTATION_PUBLIC_ID:
! 1689: if (!XmlIsPublicId(encoding, s, next, &eventPtr))
! 1690: return XML_ERROR_SYNTAX;
! 1691: if (declNotationName) {
! 1692: XML_Char *tem = poolStoreString(&tempPool,
! 1693: encoding,
! 1694: s + encoding->minBytesPerChar,
! 1695: next - encoding->minBytesPerChar);
! 1696: if (!tem)
! 1697: return XML_ERROR_NO_MEMORY;
! 1698: normalizePublicId(tem);
! 1699: declNotationPublicId = tem;
! 1700: poolFinish(&tempPool);
! 1701: }
! 1702: break;
! 1703: case XML_ROLE_NOTATION_SYSTEM_ID:
! 1704: if (declNotationName && notationDeclHandler) {
! 1705: const XML_Char *systemId
! 1706: = poolStoreString(&tempPool, encoding,
! 1707: s + encoding->minBytesPerChar,
! 1708: next - encoding->minBytesPerChar);
! 1709: if (!systemId)
! 1710: return XML_ERROR_NO_MEMORY;
! 1711: eventPtr = eventEndPtr = s;
! 1712: notationDeclHandler(handlerArg,
! 1713: declNotationName,
! 1714: dtd.base,
! 1715: systemId,
! 1716: declNotationPublicId);
! 1717: }
! 1718: poolClear(&tempPool);
! 1719: break;
! 1720: case XML_ROLE_NOTATION_NO_SYSTEM_ID:
! 1721: if (declNotationPublicId && notationDeclHandler) {
! 1722: eventPtr = eventEndPtr = s;
! 1723: notationDeclHandler(handlerArg,
! 1724: declNotationName,
! 1725: dtd.base,
! 1726: 0,
! 1727: declNotationPublicId);
! 1728: }
! 1729: poolClear(&tempPool);
! 1730: break;
! 1731: case XML_ROLE_ERROR:
! 1732: eventPtr = s;
! 1733: switch (tok) {
! 1734: case XML_TOK_PARAM_ENTITY_REF:
! 1735: return XML_ERROR_PARAM_ENTITY_REF;
! 1736: case XML_TOK_XML_DECL:
! 1737: return XML_ERROR_MISPLACED_XML_PI;
! 1738: default:
! 1739: return XML_ERROR_SYNTAX;
! 1740: }
! 1741: case XML_ROLE_GROUP_OPEN:
! 1742: if (prologState.level >= groupSize) {
! 1743: if (groupSize)
! 1744: groupConnector = realloc(groupConnector, groupSize *= 2);
! 1745: else
! 1746: groupConnector = malloc(groupSize = 32);
! 1747: if (!groupConnector)
! 1748: return XML_ERROR_NO_MEMORY;
! 1749: }
! 1750: groupConnector[prologState.level] = 0;
! 1751: break;
! 1752: case XML_ROLE_GROUP_SEQUENCE:
! 1753: if (groupConnector[prologState.level] == '|') {
! 1754: eventPtr = s;
! 1755: return XML_ERROR_SYNTAX;
! 1756: }
! 1757: groupConnector[prologState.level] = ',';
! 1758: break;
! 1759: case XML_ROLE_GROUP_CHOICE:
! 1760: if (groupConnector[prologState.level] == ',') {
! 1761: eventPtr = s;
! 1762: return XML_ERROR_SYNTAX;
! 1763: }
! 1764: groupConnector[prologState.level] = '|';
! 1765: break;
! 1766: case XML_ROLE_PARAM_ENTITY_REF:
! 1767: dtd.complete = 0;
! 1768: break;
! 1769: case XML_ROLE_NONE:
! 1770: switch (tok) {
! 1771: case XML_TOK_PI:
! 1772: eventPtr = s;
! 1773: eventEndPtr = next;
! 1774: if (!reportProcessingInstruction(parser, encoding, s, next))
! 1775: return XML_ERROR_NO_MEMORY;
! 1776: break;
! 1777: }
! 1778: break;
! 1779: }
! 1780: if (defaultHandler) {
! 1781: switch (tok) {
! 1782: case XML_TOK_PI:
! 1783: case XML_TOK_BOM:
! 1784: case XML_TOK_XML_DECL:
! 1785: break;
! 1786: default:
! 1787: eventPtr = s;
! 1788: eventEndPtr = next;
! 1789: reportDefault(parser, encoding, s, next);
! 1790: }
! 1791: }
! 1792: s = next;
! 1793: }
! 1794: /* not reached */
! 1795: }
! 1796:
! 1797: static
! 1798: enum XML_Error epilogProcessor(XML_Parser parser,
! 1799: const char *s,
! 1800: const char *end,
! 1801: const char **nextPtr)
! 1802: {
! 1803: processor = epilogProcessor;
! 1804: eventPtr = s;
! 1805: for (;;) {
! 1806: const char *next;
! 1807: int tok = XmlPrologTok(encoding, s, end, &next);
! 1808: eventEndPtr = next;
! 1809: switch (tok) {
! 1810: case XML_TOK_TRAILING_CR:
! 1811: if (defaultHandler) {
! 1812: eventEndPtr = end;
! 1813: reportDefault(parser, encoding, s, end);
! 1814: }
! 1815: /* fall through */
! 1816: case XML_TOK_NONE:
! 1817: if (nextPtr)
! 1818: *nextPtr = end;
! 1819: return XML_ERROR_NONE;
! 1820: case XML_TOK_PROLOG_S:
! 1821: case XML_TOK_COMMENT:
! 1822: if (defaultHandler)
! 1823: reportDefault(parser, encoding, s, next);
! 1824: break;
! 1825: case XML_TOK_PI:
! 1826: if (!reportProcessingInstruction(parser, encoding, s, next))
! 1827: return XML_ERROR_NO_MEMORY;
! 1828: break;
! 1829: case XML_TOK_INVALID:
! 1830: eventPtr = next;
! 1831: return XML_ERROR_INVALID_TOKEN;
! 1832: case XML_TOK_PARTIAL:
! 1833: if (nextPtr) {
! 1834: *nextPtr = s;
! 1835: return XML_ERROR_NONE;
! 1836: }
! 1837: return XML_ERROR_UNCLOSED_TOKEN;
! 1838: case XML_TOK_PARTIAL_CHAR:
! 1839: if (nextPtr) {
! 1840: *nextPtr = s;
! 1841: return XML_ERROR_NONE;
! 1842: }
! 1843: return XML_ERROR_PARTIAL_CHAR;
! 1844: default:
! 1845: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
! 1846: }
! 1847: eventPtr = s = next;
! 1848: }
! 1849: }
! 1850:
! 1851: static
! 1852: enum XML_Error errorProcessor(XML_Parser parser,
! 1853: const char *s,
! 1854: const char *end,
! 1855: const char **nextPtr)
! 1856: {
! 1857: return errorCode;
! 1858: }
! 1859:
! 1860: static enum XML_Error
! 1861: storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
! 1862: const char *ptr, const char *end,
! 1863: STRING_POOL *pool)
! 1864: {
! 1865: enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
! 1866: if (result)
! 1867: return result;
! 1868: if (!isCdata && poolLength(pool) && poolLastChar(pool) == XML_T(' '))
! 1869: poolChop(pool);
! 1870: if (!poolAppendChar(pool, XML_T('\0')))
! 1871: return XML_ERROR_NO_MEMORY;
! 1872: return XML_ERROR_NONE;
! 1873: }
! 1874:
! 1875: static enum XML_Error
! 1876: appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
! 1877: const char *ptr, const char *end,
! 1878: STRING_POOL *pool)
! 1879: {
! 1880: const ENCODING *internalEnc = XmlGetInternalEncoding();
! 1881: for (;;) {
! 1882: const char *next;
! 1883: int tok = XmlAttributeValueTok(enc, ptr, end, &next);
! 1884: switch (tok) {
! 1885: case XML_TOK_NONE:
! 1886: return XML_ERROR_NONE;
! 1887: case XML_TOK_INVALID:
! 1888: if (enc == encoding)
! 1889: eventPtr = next;
! 1890: return XML_ERROR_INVALID_TOKEN;
! 1891: case XML_TOK_PARTIAL:
! 1892: if (enc == encoding)
! 1893: eventPtr = ptr;
! 1894: return XML_ERROR_INVALID_TOKEN;
! 1895: case XML_TOK_CHAR_REF:
! 1896: {
! 1897: XML_Char buf[XML_ENCODE_MAX];
! 1898: int i;
! 1899: int n = XmlCharRefNumber(enc, ptr);
! 1900: if (n < 0) {
! 1901: if (enc == encoding)
! 1902: eventPtr = ptr;
! 1903: return XML_ERROR_BAD_CHAR_REF;
! 1904: }
! 1905: if (!isCdata
! 1906: && n == 0x20 /* space */
! 1907: && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
! 1908: break;
! 1909: n = XmlEncode(n, (ICHAR *)buf);
! 1910: if (!n) {
! 1911: if (enc == encoding)
! 1912: eventPtr = ptr;
! 1913: return XML_ERROR_BAD_CHAR_REF;
! 1914: }
! 1915: for (i = 0; i < n; i++) {
! 1916: if (!poolAppendChar(pool, buf[i]))
! 1917: return XML_ERROR_NO_MEMORY;
! 1918: }
! 1919: }
! 1920: break;
! 1921: case XML_TOK_DATA_CHARS:
! 1922: if (!poolAppend(pool, enc, ptr, next))
! 1923: return XML_ERROR_NO_MEMORY;
! 1924: break;
! 1925: break;
! 1926: case XML_TOK_TRAILING_CR:
! 1927: next = ptr + enc->minBytesPerChar;
! 1928: /* fall through */
! 1929: case XML_TOK_ATTRIBUTE_VALUE_S:
! 1930: case XML_TOK_DATA_NEWLINE:
! 1931: if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
! 1932: break;
! 1933: if (!poolAppendChar(pool, XML_T(' ')))
! 1934: return XML_ERROR_NO_MEMORY;
! 1935: break;
! 1936: case XML_TOK_ENTITY_REF:
! 1937: {
! 1938: const XML_Char *name;
! 1939: ENTITY *entity;
! 1940: XML_Char ch = XmlPredefinedEntityName(enc,
! 1941: ptr + enc->minBytesPerChar,
! 1942: next - enc->minBytesPerChar);
! 1943: if (ch) {
! 1944: if (!poolAppendChar(pool, ch))
! 1945: return XML_ERROR_NO_MEMORY;
! 1946: break;
! 1947: }
! 1948: name = poolStoreString(&temp2Pool, enc,
! 1949: ptr + enc->minBytesPerChar,
! 1950: next - enc->minBytesPerChar);
! 1951: if (!name)
! 1952: return XML_ERROR_NO_MEMORY;
! 1953: entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
! 1954: poolDiscard(&temp2Pool);
! 1955: if (!entity) {
! 1956: if (dtd.complete) {
! 1957: if (enc == encoding)
! 1958: eventPtr = ptr;
! 1959: return XML_ERROR_UNDEFINED_ENTITY;
! 1960: }
! 1961: }
! 1962: else if (entity->open) {
! 1963: if (enc == encoding)
! 1964: eventPtr = ptr;
! 1965: return XML_ERROR_RECURSIVE_ENTITY_REF;
! 1966: }
! 1967: else if (entity->notation) {
! 1968: if (enc == encoding)
! 1969: eventPtr = ptr;
! 1970: return XML_ERROR_BINARY_ENTITY_REF;
! 1971: }
! 1972: else if (!entity->textPtr) {
! 1973: if (enc == encoding)
! 1974: eventPtr = ptr;
! 1975: return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
! 1976: }
! 1977: else {
! 1978: enum XML_Error result;
! 1979: const XML_Char *textEnd = entity->textPtr + entity->textLen;
! 1980: entity->open = 1;
! 1981: result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
! 1982: entity->open = 0;
! 1983: if (result)
! 1984: return result;
! 1985: }
! 1986: }
! 1987: break;
! 1988: default:
! 1989: abort();
! 1990: }
! 1991: ptr = next;
! 1992: }
! 1993: /* not reached */
! 1994: }
! 1995:
! 1996: static
! 1997: enum XML_Error storeEntityValue(XML_Parser parser,
! 1998: const char *entityTextPtr,
! 1999: const char *entityTextEnd)
! 2000: {
! 2001: const ENCODING *internalEnc = XmlGetInternalEncoding();
! 2002: STRING_POOL *pool = &(dtd.pool);
! 2003: entityTextPtr += encoding->minBytesPerChar;
! 2004: entityTextEnd -= encoding->minBytesPerChar;
! 2005: for (;;) {
! 2006: const char *next;
! 2007: int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next);
! 2008: switch (tok) {
! 2009: case XML_TOK_PARAM_ENTITY_REF:
! 2010: eventPtr = entityTextPtr;
! 2011: return XML_ERROR_SYNTAX;
! 2012: case XML_TOK_NONE:
! 2013: if (declEntity) {
! 2014: declEntity->textPtr = pool->start;
! 2015: declEntity->textLen = pool->ptr - pool->start;
! 2016: poolFinish(pool);
! 2017: }
! 2018: else
! 2019: poolDiscard(pool);
! 2020: return XML_ERROR_NONE;
! 2021: case XML_TOK_ENTITY_REF:
! 2022: case XML_TOK_DATA_CHARS:
! 2023: if (!poolAppend(pool, encoding, entityTextPtr, next))
! 2024: return XML_ERROR_NO_MEMORY;
! 2025: break;
! 2026: case XML_TOK_TRAILING_CR:
! 2027: next = entityTextPtr + encoding->minBytesPerChar;
! 2028: /* fall through */
! 2029: case XML_TOK_DATA_NEWLINE:
! 2030: if (pool->end == pool->ptr && !poolGrow(pool))
! 2031: return XML_ERROR_NO_MEMORY;
! 2032: *(pool->ptr)++ = XML_T('\n');
! 2033: break;
! 2034: case XML_TOK_CHAR_REF:
! 2035: {
! 2036: XML_Char buf[XML_ENCODE_MAX];
! 2037: int i;
! 2038: int n = XmlCharRefNumber(encoding, entityTextPtr);
! 2039: if (n < 0) {
! 2040: eventPtr = entityTextPtr;
! 2041: return XML_ERROR_BAD_CHAR_REF;
! 2042: }
! 2043: n = XmlEncode(n, (ICHAR *)buf);
! 2044: if (!n) {
! 2045: eventPtr = entityTextPtr;
! 2046: return XML_ERROR_BAD_CHAR_REF;
! 2047: }
! 2048: for (i = 0; i < n; i++) {
! 2049: if (pool->end == pool->ptr && !poolGrow(pool))
! 2050: return XML_ERROR_NO_MEMORY;
! 2051: *(pool->ptr)++ = buf[i];
! 2052: }
! 2053: }
! 2054: break;
! 2055: case XML_TOK_PARTIAL:
! 2056: eventPtr = entityTextPtr;
! 2057: return XML_ERROR_INVALID_TOKEN;
! 2058: case XML_TOK_INVALID:
! 2059: eventPtr = next;
! 2060: return XML_ERROR_INVALID_TOKEN;
! 2061: default:
! 2062: abort();
! 2063: }
! 2064: entityTextPtr = next;
! 2065: }
! 2066: /* not reached */
! 2067: }
! 2068:
! 2069: static void
! 2070: normalizeLines(XML_Char *s)
! 2071: {
! 2072: XML_Char *p;
! 2073: for (;; s++) {
! 2074: if (*s == XML_T('\0'))
! 2075: return;
! 2076: if (*s == XML_T('\r'))
! 2077: break;
! 2078: }
! 2079: p = s;
! 2080: do {
! 2081: if (*s == XML_T('\r')) {
! 2082: *p++ = XML_T('\n');
! 2083: if (*++s == XML_T('\n'))
! 2084: s++;
! 2085: }
! 2086: else
! 2087: *p++ = *s++;
! 2088: } while (*s);
! 2089: *p = XML_T('\0');
! 2090: }
! 2091:
! 2092: static int
! 2093: reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
! 2094: {
! 2095: const XML_Char *target;
! 2096: XML_Char *data;
! 2097: const char *tem;
! 2098: if (!processingInstructionHandler) {
! 2099: if (defaultHandler)
! 2100: reportDefault(parser, enc, start, end);
! 2101: return 1;
! 2102: }
! 2103: start += enc->minBytesPerChar * 2;
! 2104: tem = start + XmlNameLength(enc, start);
! 2105: target = poolStoreString(&tempPool, enc, start, tem);
! 2106: if (!target)
! 2107: return 0;
! 2108: poolFinish(&tempPool);
! 2109: data = poolStoreString(&tempPool, enc,
! 2110: XmlSkipS(enc, tem),
! 2111: end - enc->minBytesPerChar*2);
! 2112: if (!data)
! 2113: return 0;
! 2114: normalizeLines(data);
! 2115: processingInstructionHandler(handlerArg, target, data);
! 2116: poolClear(&tempPool);
! 2117: return 1;
! 2118: }
! 2119:
! 2120: static void
! 2121: reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
! 2122: {
! 2123: if (MUST_CONVERT(enc, s)) {
! 2124: for (;;) {
! 2125: ICHAR *dataPtr = (ICHAR *)dataBuf;
! 2126: XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
! 2127: if (s == end) {
! 2128: defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 2129: break;
! 2130: }
! 2131: if (enc == encoding) {
! 2132: eventEndPtr = s;
! 2133: defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 2134: eventPtr = s;
! 2135: }
! 2136: else
! 2137: defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
! 2138: }
! 2139: }
! 2140: else
! 2141: defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
! 2142: }
! 2143:
! 2144:
! 2145: static int
! 2146: defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
! 2147: {
! 2148: DEFAULT_ATTRIBUTE *att;
! 2149: if (type->nDefaultAtts == type->allocDefaultAtts) {
! 2150: if (type->allocDefaultAtts == 0) {
! 2151: type->allocDefaultAtts = 8;
! 2152: type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
! 2153: }
! 2154: else {
! 2155: type->allocDefaultAtts *= 2;
! 2156: type->defaultAtts = realloc(type->defaultAtts,
! 2157: type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
! 2158: }
! 2159: if (!type->defaultAtts)
! 2160: return 0;
! 2161: }
! 2162: att = type->defaultAtts + type->nDefaultAtts;
! 2163: att->id = attId;
! 2164: att->value = value;
! 2165: att->isCdata = isCdata;
! 2166: if (!isCdata)
! 2167: attId->maybeTokenized = 1;
! 2168: type->nDefaultAtts += 1;
! 2169: return 1;
! 2170: }
! 2171:
! 2172: static ATTRIBUTE_ID *
! 2173: getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
! 2174: {
! 2175: ATTRIBUTE_ID *id;
! 2176: const XML_Char *name;
! 2177: if (!poolAppendChar(&dtd.pool, XML_T('\0')))
! 2178: return 0;
! 2179: name = poolStoreString(&dtd.pool, enc, start, end);
! 2180: if (!name)
! 2181: return 0;
! 2182: ++name;
! 2183: id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
! 2184: if (!id)
! 2185: return 0;
! 2186: if (id->name != name)
! 2187: poolDiscard(&dtd.pool);
! 2188: else
! 2189: poolFinish(&dtd.pool);
! 2190: return id;
! 2191: }
! 2192:
! 2193: static
! 2194: const XML_Char *getOpenEntityNames(XML_Parser parser)
! 2195: {
! 2196: HASH_TABLE_ITER iter;
! 2197:
! 2198: hashTableIterInit(&iter, &(dtd.generalEntities));
! 2199: for (;;) {
! 2200: const XML_Char *s;
! 2201: ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
! 2202: if (!e)
! 2203: break;
! 2204: if (!e->open)
! 2205: continue;
! 2206: if (poolLength(&tempPool) > 0 && !poolAppendChar(&tempPool, XML_T(' ')))
! 2207: return 0;
! 2208: for (s = e->name; *s; s++)
! 2209: if (!poolAppendChar(&tempPool, *s))
! 2210: return 0;
! 2211: }
! 2212:
! 2213: if (!poolAppendChar(&tempPool, XML_T('\0')))
! 2214: return 0;
! 2215: return tempPool.start;
! 2216: }
! 2217:
! 2218: static
! 2219: int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames)
! 2220: {
! 2221: const XML_Char *s = openEntityNames;
! 2222: while (*openEntityNames != XML_T('\0')) {
! 2223: if (*s == XML_T(' ') || *s == XML_T('\0')) {
! 2224: ENTITY *e;
! 2225: if (!poolAppendChar(&tempPool, XML_T('\0')))
! 2226: return 0;
! 2227: e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
! 2228: if (e)
! 2229: e->open = 1;
! 2230: if (*s == XML_T(' '))
! 2231: s++;
! 2232: openEntityNames = s;
! 2233: poolDiscard(&tempPool);
! 2234: }
! 2235: else {
! 2236: if (!poolAppendChar(&tempPool, *s))
! 2237: return 0;
! 2238: s++;
! 2239: }
! 2240: }
! 2241: return 1;
! 2242: }
! 2243:
! 2244:
! 2245: static
! 2246: void normalizePublicId(XML_Char *publicId)
! 2247: {
! 2248: XML_Char *p = publicId;
! 2249: XML_Char *s;
! 2250: for (s = publicId; *s; s++) {
! 2251: switch (*s) {
! 2252: case XML_T(' '):
! 2253: case XML_T('\r'):
! 2254: case XML_T('\n'):
! 2255: if (p != publicId && p[-1] != XML_T(' '))
! 2256: *p++ = XML_T(' ');
! 2257: break;
! 2258: default:
! 2259: *p++ = *s;
! 2260: }
! 2261: }
! 2262: if (p != publicId && p[-1] == XML_T(' '))
! 2263: --p;
! 2264: *p = XML_T('\0');
! 2265: }
! 2266:
! 2267: static int dtdInit(DTD *p)
! 2268: {
! 2269: poolInit(&(p->pool));
! 2270: hashTableInit(&(p->generalEntities));
! 2271: hashTableInit(&(p->elementTypes));
! 2272: hashTableInit(&(p->attributeIds));
! 2273: p->complete = 1;
! 2274: p->standalone = 0;
! 2275: p->base = 0;
! 2276: return 1;
! 2277: }
! 2278:
! 2279: static void dtdDestroy(DTD *p)
! 2280: {
! 2281: HASH_TABLE_ITER iter;
! 2282: hashTableIterInit(&iter, &(p->elementTypes));
! 2283: for (;;) {
! 2284: ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
! 2285: if (!e)
! 2286: break;
! 2287: if (e->allocDefaultAtts != 0)
! 2288: free(e->defaultAtts);
! 2289: }
! 2290: hashTableDestroy(&(p->generalEntities));
! 2291: hashTableDestroy(&(p->elementTypes));
! 2292: hashTableDestroy(&(p->attributeIds));
! 2293: poolDestroy(&(p->pool));
! 2294: }
! 2295:
! 2296: /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
! 2297: The new DTD has already been initialized. */
! 2298:
! 2299: static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
! 2300: {
! 2301: HASH_TABLE_ITER iter;
! 2302:
! 2303: if (oldDtd->base) {
! 2304: const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base);
! 2305: if (!tem)
! 2306: return 0;
! 2307: newDtd->base = tem;
! 2308: }
! 2309:
! 2310: hashTableIterInit(&iter, &(oldDtd->attributeIds));
! 2311:
! 2312: /* Copy the attribute id table. */
! 2313:
! 2314: for (;;) {
! 2315: ATTRIBUTE_ID *newA;
! 2316: const XML_Char *name;
! 2317: const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
! 2318:
! 2319: if (!oldA)
! 2320: break;
! 2321: /* Remember to allocate the scratch byte before the name. */
! 2322: if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
! 2323: return 0;
! 2324: name = poolCopyString(&(newDtd->pool), oldA->name);
! 2325: if (!name)
! 2326: return 0;
! 2327: ++name;
! 2328: newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
! 2329: if (!newA)
! 2330: return 0;
! 2331: newA->maybeTokenized = oldA->maybeTokenized;
! 2332: }
! 2333:
! 2334: /* Copy the element type table. */
! 2335:
! 2336: hashTableIterInit(&iter, &(oldDtd->elementTypes));
! 2337:
! 2338: for (;;) {
! 2339: int i;
! 2340: ELEMENT_TYPE *newE;
! 2341: const XML_Char *name;
! 2342: const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
! 2343: if (!oldE)
! 2344: break;
! 2345: name = poolCopyString(&(newDtd->pool), oldE->name);
! 2346: if (!name)
! 2347: return 0;
! 2348: newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
! 2349: if (!newE)
! 2350: return 0;
! 2351: newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
! 2352: if (!newE->defaultAtts)
! 2353: return 0;
! 2354: newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
! 2355: for (i = 0; i < newE->nDefaultAtts; i++) {
! 2356: newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
! 2357: newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
! 2358: if (oldE->defaultAtts[i].value) {
! 2359: newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
! 2360: if (!newE->defaultAtts[i].value)
! 2361: return 0;
! 2362: }
! 2363: else
! 2364: newE->defaultAtts[i].value = 0;
! 2365: }
! 2366: }
! 2367:
! 2368: /* Copy the entity table. */
! 2369:
! 2370: hashTableIterInit(&iter, &(oldDtd->generalEntities));
! 2371:
! 2372: for (;;) {
! 2373: ENTITY *newE;
! 2374: const XML_Char *name;
! 2375: const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
! 2376: if (!oldE)
! 2377: break;
! 2378: name = poolCopyString(&(newDtd->pool), oldE->name);
! 2379: if (!name)
! 2380: return 0;
! 2381: newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY));
! 2382: if (!newE)
! 2383: return 0;
! 2384: if (oldE->systemId) {
! 2385: const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId);
! 2386: if (!tem)
! 2387: return 0;
! 2388: newE->systemId = tem;
! 2389: if (oldE->base) {
! 2390: if (oldE->base == oldDtd->base)
! 2391: newE->base = newDtd->base;
! 2392: tem = poolCopyString(&(newDtd->pool), oldE->base);
! 2393: if (!tem)
! 2394: return 0;
! 2395: newE->base = tem;
! 2396: }
! 2397: }
! 2398: else {
! 2399: const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen);
! 2400: if (!tem)
! 2401: return 0;
! 2402: newE->textPtr = tem;
! 2403: newE->textLen = oldE->textLen;
! 2404: }
! 2405: if (oldE->notation) {
! 2406: const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation);
! 2407: if (!tem)
! 2408: return 0;
! 2409: newE->notation = tem;
! 2410: }
! 2411: }
! 2412:
! 2413: newDtd->complete = oldDtd->complete;
! 2414: newDtd->standalone = oldDtd->standalone;
! 2415: return 1;
! 2416: }
! 2417:
! 2418: static
! 2419: void poolInit(STRING_POOL *pool)
! 2420: {
! 2421: pool->blocks = 0;
! 2422: pool->freeBlocks = 0;
! 2423: pool->start = 0;
! 2424: pool->ptr = 0;
! 2425: pool->end = 0;
! 2426: }
! 2427:
! 2428: static
! 2429: void poolClear(STRING_POOL *pool)
! 2430: {
! 2431: if (!pool->freeBlocks)
! 2432: pool->freeBlocks = pool->blocks;
! 2433: else {
! 2434: BLOCK *p = pool->blocks;
! 2435: while (p) {
! 2436: BLOCK *tem = p->next;
! 2437: p->next = pool->freeBlocks;
! 2438: pool->freeBlocks = p;
! 2439: p = tem;
! 2440: }
! 2441: }
! 2442: pool->blocks = 0;
! 2443: pool->start = 0;
! 2444: pool->ptr = 0;
! 2445: pool->end = 0;
! 2446: }
! 2447:
! 2448: static
! 2449: void poolDestroy(STRING_POOL *pool)
! 2450: {
! 2451: BLOCK *p = pool->blocks;
! 2452: while (p) {
! 2453: BLOCK *tem = p->next;
! 2454: free(p);
! 2455: p = tem;
! 2456: }
! 2457: pool->blocks = 0;
! 2458: p = pool->freeBlocks;
! 2459: while (p) {
! 2460: BLOCK *tem = p->next;
! 2461: free(p);
! 2462: p = tem;
! 2463: }
! 2464: pool->freeBlocks = 0;
! 2465: pool->ptr = 0;
! 2466: pool->start = 0;
! 2467: pool->end = 0;
! 2468: }
! 2469:
! 2470: static
! 2471: XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
! 2472: const char *ptr, const char *end)
! 2473: {
! 2474: if (!pool->ptr && !poolGrow(pool))
! 2475: return 0;
! 2476: for (;;) {
! 2477: XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
! 2478: if (ptr == end)
! 2479: break;
! 2480: if (!poolGrow(pool))
! 2481: return 0;
! 2482: }
! 2483: return pool->start;
! 2484: }
! 2485:
! 2486: static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
! 2487: {
! 2488: do {
! 2489: if (!poolAppendChar(pool, *s))
! 2490: return 0;
! 2491: } while (*s++);
! 2492: s = pool->start;
! 2493: poolFinish(pool);
! 2494: return s;
! 2495: }
! 2496:
! 2497: static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
! 2498: {
! 2499: if (!pool->ptr && !poolGrow(pool))
! 2500: return 0;
! 2501: for (; n > 0; --n, s++) {
! 2502: if (!poolAppendChar(pool, *s))
! 2503: return 0;
! 2504:
! 2505: }
! 2506: s = pool->start;
! 2507: poolFinish(pool);
! 2508: return s;
! 2509: }
! 2510:
! 2511: static
! 2512: XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
! 2513: const char *ptr, const char *end)
! 2514: {
! 2515: if (!poolAppend(pool, enc, ptr, end))
! 2516: return 0;
! 2517: if (pool->ptr == pool->end && !poolGrow(pool))
! 2518: return 0;
! 2519: *(pool->ptr)++ = 0;
! 2520: return pool->start;
! 2521: }
! 2522:
! 2523: static
! 2524: int poolGrow(STRING_POOL *pool)
! 2525: {
! 2526: if (pool->freeBlocks) {
! 2527: if (pool->start == 0) {
! 2528: pool->blocks = pool->freeBlocks;
! 2529: pool->freeBlocks = pool->freeBlocks->next;
! 2530: pool->blocks->next = 0;
! 2531: pool->start = pool->blocks->s;
! 2532: pool->end = pool->start + pool->blocks->size;
! 2533: pool->ptr = pool->start;
! 2534: return 1;
! 2535: }
! 2536: if (pool->end - pool->start < pool->freeBlocks->size) {
! 2537: BLOCK *tem = pool->freeBlocks->next;
! 2538: pool->freeBlocks->next = pool->blocks;
! 2539: pool->blocks = pool->freeBlocks;
! 2540: pool->freeBlocks = tem;
! 2541: memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
! 2542: pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
! 2543: pool->start = pool->blocks->s;
! 2544: pool->end = pool->start + pool->blocks->size;
! 2545: return 1;
! 2546: }
! 2547: }
! 2548: if (pool->blocks && pool->start == pool->blocks->s) {
! 2549: int blockSize = (pool->end - pool->start)*2;
! 2550: pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
! 2551: if (!pool->blocks)
! 2552: return 0;
! 2553: pool->blocks->size = blockSize;
! 2554: pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
! 2555: pool->start = pool->blocks->s;
! 2556: pool->end = pool->start + blockSize;
! 2557: }
! 2558: else {
! 2559: BLOCK *tem;
! 2560: int blockSize = pool->end - pool->start;
! 2561: if (blockSize < INIT_BLOCK_SIZE)
! 2562: blockSize = INIT_BLOCK_SIZE;
! 2563: else
! 2564: blockSize *= 2;
! 2565: tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
! 2566: if (!tem)
! 2567: return 0;
! 2568: tem->size = blockSize;
! 2569: tem->next = pool->blocks;
! 2570: pool->blocks = tem;
! 2571: memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
! 2572: pool->ptr = tem->s + (pool->ptr - pool->start);
! 2573: pool->start = tem->s;
! 2574: pool->end = tem->s + blockSize;
! 2575: }
! 2576: return 1;
! 2577: }
Webmaster