Annotation of embedaddon/expat/lib/xmlparse.c, revision 1.1.1.2
1.1 misho 1: /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2: See the file COPYING for copying permission.
3: */
4:
5: #include <stddef.h>
6: #include <string.h> /* memset(), memcpy() */
7: #include <assert.h>
1.1.1.2 ! misho 8: #include <limits.h> /* UINT_MAX */
! 9: #include <time.h> /* time() */
1.1 misho 10:
11: #define XML_BUILDING_EXPAT 1
12:
13: #ifdef COMPILED_FROM_DSP
14: #include "winconfig.h"
15: #elif defined(MACOS_CLASSIC)
16: #include "macconfig.h"
1.1.1.2 ! misho 17: #elif defined(__amigaos__)
1.1 misho 18: #include "amigaconfig.h"
19: #elif defined(__WATCOMC__)
20: #include "watcomconfig.h"
21: #elif defined(HAVE_EXPAT_CONFIG_H)
22: #include <expat_config.h>
23: #endif /* ndef COMPILED_FROM_DSP */
24:
25: #include "ascii.h"
26: #include "expat.h"
27:
28: #ifdef XML_UNICODE
29: #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30: #define XmlConvert XmlUtf16Convert
31: #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32: #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33: #define XmlEncode XmlUtf16Encode
34: /* Using pointer subtraction to convert to integer type. */
35: #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
36: typedef unsigned short ICHAR;
37: #else
38: #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
39: #define XmlConvert XmlUtf8Convert
40: #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
41: #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
42: #define XmlEncode XmlUtf8Encode
43: #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
44: typedef char ICHAR;
45: #endif
46:
47:
48: #ifndef XML_NS
49:
50: #define XmlInitEncodingNS XmlInitEncoding
51: #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
52: #undef XmlGetInternalEncodingNS
53: #define XmlGetInternalEncodingNS XmlGetInternalEncoding
54: #define XmlParseXmlDeclNS XmlParseXmlDecl
55:
56: #endif
57:
58: #ifdef XML_UNICODE
59:
60: #ifdef XML_UNICODE_WCHAR_T
61: #define XML_T(x) (const wchar_t)x
62: #define XML_L(x) L ## x
63: #else
64: #define XML_T(x) (const unsigned short)x
65: #define XML_L(x) x
66: #endif
67:
68: #else
69:
70: #define XML_T(x) x
71: #define XML_L(x) x
72:
73: #endif
74:
75: /* Round up n to be a multiple of sz, where sz is a power of 2. */
76: #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
77:
78: /* Handle the case where memmove() doesn't exist. */
79: #ifndef HAVE_MEMMOVE
80: #ifdef HAVE_BCOPY
81: #define memmove(d,s,l) bcopy((s),(d),(l))
82: #else
83: #error memmove does not exist on this platform, nor is a substitute available
84: #endif /* HAVE_BCOPY */
85: #endif /* HAVE_MEMMOVE */
86:
87: #include "internal.h"
88: #include "xmltok.h"
89: #include "xmlrole.h"
90:
91: typedef const XML_Char *KEY;
92:
93: typedef struct {
94: KEY name;
95: } NAMED;
96:
97: typedef struct {
98: NAMED **v;
99: unsigned char power;
100: size_t size;
101: size_t used;
102: const XML_Memory_Handling_Suite *mem;
103: } HASH_TABLE;
104:
105: /* Basic character hash algorithm, taken from Python's string hash:
106: h = h * 1000003 ^ character, the constant being a prime number.
107:
108: */
109: #ifdef XML_UNICODE
110: #define CHAR_HASH(h, c) \
111: (((h) * 0xF4243) ^ (unsigned short)(c))
112: #else
113: #define CHAR_HASH(h, c) \
114: (((h) * 0xF4243) ^ (unsigned char)(c))
115: #endif
116:
117: /* For probing (after a collision) we need a step size relative prime
118: to the hash table size, which is a power of 2. We use double-hashing,
119: since we can calculate a second hash value cheaply by taking those bits
120: of the first hash value that were discarded (masked out) when the table
121: index was calculated: index = hash & mask, where mask = table->size - 1.
122: We limit the maximum step size to table->size / 4 (mask >> 2) and make
123: it odd, since odd numbers are always relative prime to a power of 2.
124: */
125: #define SECOND_HASH(hash, mask, power) \
126: ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
127: #define PROBE_STEP(hash, mask, power) \
128: ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
129:
130: typedef struct {
131: NAMED **p;
132: NAMED **end;
133: } HASH_TABLE_ITER;
134:
135: #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
136: #define INIT_DATA_BUF_SIZE 1024
137: #define INIT_ATTS_SIZE 16
138: #define INIT_ATTS_VERSION 0xFFFFFFFF
139: #define INIT_BLOCK_SIZE 1024
140: #define INIT_BUFFER_SIZE 1024
141:
142: #define EXPAND_SPARE 24
143:
144: typedef struct binding {
145: struct prefix *prefix;
146: struct binding *nextTagBinding;
147: struct binding *prevPrefixBinding;
148: const struct attribute_id *attId;
149: XML_Char *uri;
150: int uriLen;
151: int uriAlloc;
152: } BINDING;
153:
154: typedef struct prefix {
155: const XML_Char *name;
156: BINDING *binding;
157: } PREFIX;
158:
159: typedef struct {
160: const XML_Char *str;
161: const XML_Char *localPart;
162: const XML_Char *prefix;
163: int strLen;
164: int uriLen;
165: int prefixLen;
166: } TAG_NAME;
167:
168: /* TAG represents an open element.
169: The name of the element is stored in both the document and API
170: encodings. The memory buffer 'buf' is a separately-allocated
171: memory area which stores the name. During the XML_Parse()/
172: XMLParseBuffer() when the element is open, the memory for the 'raw'
173: version of the name (in the document encoding) is shared with the
174: document buffer. If the element is open across calls to
175: XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
176: contain the 'raw' name as well.
177:
178: A parser re-uses these structures, maintaining a list of allocated
179: TAG objects in a free list.
180: */
181: typedef struct tag {
182: struct tag *parent; /* parent of this element */
183: const char *rawName; /* tagName in the original encoding */
184: int rawNameLength;
185: TAG_NAME name; /* tagName in the API encoding */
186: char *buf; /* buffer for name components */
187: char *bufEnd; /* end of the buffer */
188: BINDING *bindings;
189: } TAG;
190:
191: typedef struct {
192: const XML_Char *name;
193: const XML_Char *textPtr;
194: int textLen; /* length in XML_Chars */
195: int processed; /* # of processed bytes - when suspended */
196: const XML_Char *systemId;
197: const XML_Char *base;
198: const XML_Char *publicId;
199: const XML_Char *notation;
200: XML_Bool open;
201: XML_Bool is_param;
202: XML_Bool is_internal; /* true if declared in internal subset outside PE */
203: } ENTITY;
204:
205: typedef struct {
206: enum XML_Content_Type type;
207: enum XML_Content_Quant quant;
208: const XML_Char * name;
209: int firstchild;
210: int lastchild;
211: int childcnt;
212: int nextsib;
213: } CONTENT_SCAFFOLD;
214:
215: #define INIT_SCAFFOLD_ELEMENTS 32
216:
217: typedef struct block {
218: struct block *next;
219: int size;
220: XML_Char s[1];
221: } BLOCK;
222:
223: typedef struct {
224: BLOCK *blocks;
225: BLOCK *freeBlocks;
226: const XML_Char *end;
227: XML_Char *ptr;
228: XML_Char *start;
229: const XML_Memory_Handling_Suite *mem;
230: } STRING_POOL;
231:
232: /* The XML_Char before the name is used to determine whether
233: an attribute has been specified. */
234: typedef struct attribute_id {
235: XML_Char *name;
236: PREFIX *prefix;
237: XML_Bool maybeTokenized;
238: XML_Bool xmlns;
239: } ATTRIBUTE_ID;
240:
241: typedef struct {
242: const ATTRIBUTE_ID *id;
243: XML_Bool isCdata;
244: const XML_Char *value;
245: } DEFAULT_ATTRIBUTE;
246:
247: typedef struct {
248: unsigned long version;
249: unsigned long hash;
250: const XML_Char *uriName;
251: } NS_ATT;
252:
253: typedef struct {
254: const XML_Char *name;
255: PREFIX *prefix;
256: const ATTRIBUTE_ID *idAtt;
257: int nDefaultAtts;
258: int allocDefaultAtts;
259: DEFAULT_ATTRIBUTE *defaultAtts;
260: } ELEMENT_TYPE;
261:
262: typedef struct {
263: HASH_TABLE generalEntities;
264: HASH_TABLE elementTypes;
265: HASH_TABLE attributeIds;
266: HASH_TABLE prefixes;
267: STRING_POOL pool;
268: STRING_POOL entityValuePool;
269: /* false once a parameter entity reference has been skipped */
270: XML_Bool keepProcessing;
271: /* true once an internal or external PE reference has been encountered;
272: this includes the reference to an external subset */
273: XML_Bool hasParamEntityRefs;
274: XML_Bool standalone;
275: #ifdef XML_DTD
276: /* indicates if external PE has been read */
277: XML_Bool paramEntityRead;
278: HASH_TABLE paramEntities;
279: #endif /* XML_DTD */
280: PREFIX defaultPrefix;
281: /* === scaffolding for building content model === */
282: XML_Bool in_eldecl;
283: CONTENT_SCAFFOLD *scaffold;
284: unsigned contentStringLen;
285: unsigned scaffSize;
286: unsigned scaffCount;
287: int scaffLevel;
288: int *scaffIndex;
289: } DTD;
290:
291: typedef struct open_internal_entity {
292: const char *internalEventPtr;
293: const char *internalEventEndPtr;
294: struct open_internal_entity *next;
295: ENTITY *entity;
296: int startTagLevel;
297: XML_Bool betweenDecl; /* WFC: PE Between Declarations */
298: } OPEN_INTERNAL_ENTITY;
299:
300: typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
301: const char *start,
302: const char *end,
303: const char **endPtr);
304:
305: static Processor prologProcessor;
306: static Processor prologInitProcessor;
307: static Processor contentProcessor;
308: static Processor cdataSectionProcessor;
309: #ifdef XML_DTD
310: static Processor ignoreSectionProcessor;
311: static Processor externalParEntProcessor;
312: static Processor externalParEntInitProcessor;
313: static Processor entityValueProcessor;
314: static Processor entityValueInitProcessor;
315: #endif /* XML_DTD */
316: static Processor epilogProcessor;
317: static Processor errorProcessor;
318: static Processor externalEntityInitProcessor;
319: static Processor externalEntityInitProcessor2;
320: static Processor externalEntityInitProcessor3;
321: static Processor externalEntityContentProcessor;
322: static Processor internalEntityProcessor;
323:
324: static enum XML_Error
325: handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
326: static enum XML_Error
327: processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
328: const char *s, const char *next);
329: static enum XML_Error
330: initializeEncoding(XML_Parser parser);
331: static enum XML_Error
1.1.1.2 ! misho 332: doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
! 333: const char *end, int tok, const char *next, const char **nextPtr,
1.1 misho 334: XML_Bool haveMore);
335: static enum XML_Error
1.1.1.2 ! misho 336: processInternalEntity(XML_Parser parser, ENTITY *entity,
1.1 misho 337: XML_Bool betweenDecl);
338: static enum XML_Error
339: doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
1.1.1.2 ! misho 340: const char *start, const char *end, const char **endPtr,
1.1 misho 341: XML_Bool haveMore);
342: static enum XML_Error
343: doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
344: const char *end, const char **nextPtr, XML_Bool haveMore);
345: #ifdef XML_DTD
346: static enum XML_Error
347: doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
348: const char *end, const char **nextPtr, XML_Bool haveMore);
349: #endif /* XML_DTD */
350:
351: static enum XML_Error
352: storeAtts(XML_Parser parser, const ENCODING *, const char *s,
353: TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
354: static enum XML_Error
355: addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
356: const XML_Char *uri, BINDING **bindingsPtr);
357: static int
1.1.1.2 ! misho 358: defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
1.1 misho 359: XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
360: static enum XML_Error
361: storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362: const char *, const char *, STRING_POOL *);
363: static enum XML_Error
364: appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
365: const char *, const char *, STRING_POOL *);
366: static ATTRIBUTE_ID *
367: getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
368: const char *end);
369: static int
370: setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
371: static enum XML_Error
372: storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
373: const char *end);
374: static int
375: reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
376: const char *start, const char *end);
377: static int
378: reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
379: const char *end);
380: static void
381: reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
382: const char *end);
383:
384: static const XML_Char * getContext(XML_Parser parser);
385: static XML_Bool
386: setContext(XML_Parser parser, const XML_Char *context);
387:
388: static void FASTCALL normalizePublicId(XML_Char *s);
389:
390: static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
391: /* do not call if parentParser != NULL */
392: static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
393: static void
394: dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
395: static int
1.1.1.2 ! misho 396: dtdCopy(XML_Parser oldParser,
! 397: DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
1.1 misho 398: static int
1.1.1.2 ! misho 399: copyEntityTable(XML_Parser oldParser,
! 400: HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
1.1 misho 401: static NAMED *
1.1.1.2 ! misho 402: lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
1.1 misho 403: static void FASTCALL
404: hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
405: static void FASTCALL hashTableClear(HASH_TABLE *);
406: static void FASTCALL hashTableDestroy(HASH_TABLE *);
407: static void FASTCALL
408: hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
409: static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
410:
411: static void FASTCALL
412: poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
413: static void FASTCALL poolClear(STRING_POOL *);
414: static void FASTCALL poolDestroy(STRING_POOL *);
415: static XML_Char *
416: poolAppend(STRING_POOL *pool, const ENCODING *enc,
417: const char *ptr, const char *end);
418: static XML_Char *
419: poolStoreString(STRING_POOL *pool, const ENCODING *enc,
420: const char *ptr, const char *end);
421: static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
422: static const XML_Char * FASTCALL
423: poolCopyString(STRING_POOL *pool, const XML_Char *s);
424: static const XML_Char *
425: poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
426: static const XML_Char * FASTCALL
427: poolAppendString(STRING_POOL *pool, const XML_Char *s);
428:
429: static int FASTCALL nextScaffoldPart(XML_Parser parser);
430: static XML_Content * build_model(XML_Parser parser);
431: static ELEMENT_TYPE *
432: getElementType(XML_Parser parser, const ENCODING *enc,
433: const char *ptr, const char *end);
434:
1.1.1.2 ! misho 435: static unsigned long generate_hash_secret_salt(void);
! 436: static XML_Bool startParsing(XML_Parser parser);
! 437:
1.1 misho 438: static XML_Parser
439: parserCreate(const XML_Char *encodingName,
440: const XML_Memory_Handling_Suite *memsuite,
441: const XML_Char *nameSep,
442: DTD *dtd);
1.1.1.2 ! misho 443:
1.1 misho 444: static void
445: parserInit(XML_Parser parser, const XML_Char *encodingName);
446:
447: #define poolStart(pool) ((pool)->start)
448: #define poolEnd(pool) ((pool)->ptr)
449: #define poolLength(pool) ((pool)->ptr - (pool)->start)
450: #define poolChop(pool) ((void)--(pool->ptr))
451: #define poolLastChar(pool) (((pool)->ptr)[-1])
452: #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
453: #define poolFinish(pool) ((pool)->start = (pool)->ptr)
454: #define poolAppendChar(pool, c) \
455: (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
456: ? 0 \
457: : ((*((pool)->ptr)++ = c), 1))
458:
459: struct XML_ParserStruct {
460: /* The first member must be userData so that the XML_GetUserData
461: macro works. */
462: void *m_userData;
463: void *m_handlerArg;
464: char *m_buffer;
465: const XML_Memory_Handling_Suite m_mem;
466: /* first character to be parsed */
467: const char *m_bufferPtr;
468: /* past last character to be parsed */
469: char *m_bufferEnd;
470: /* allocated end of buffer */
471: const char *m_bufferLim;
472: XML_Index m_parseEndByteIndex;
473: const char *m_parseEndPtr;
474: XML_Char *m_dataBuf;
475: XML_Char *m_dataBufEnd;
476: XML_StartElementHandler m_startElementHandler;
477: XML_EndElementHandler m_endElementHandler;
478: XML_CharacterDataHandler m_characterDataHandler;
479: XML_ProcessingInstructionHandler m_processingInstructionHandler;
480: XML_CommentHandler m_commentHandler;
481: XML_StartCdataSectionHandler m_startCdataSectionHandler;
482: XML_EndCdataSectionHandler m_endCdataSectionHandler;
483: XML_DefaultHandler m_defaultHandler;
484: XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
485: XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
486: XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
487: XML_NotationDeclHandler m_notationDeclHandler;
488: XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
489: XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
490: XML_NotStandaloneHandler m_notStandaloneHandler;
491: XML_ExternalEntityRefHandler m_externalEntityRefHandler;
492: XML_Parser m_externalEntityRefHandlerArg;
493: XML_SkippedEntityHandler m_skippedEntityHandler;
494: XML_UnknownEncodingHandler m_unknownEncodingHandler;
495: XML_ElementDeclHandler m_elementDeclHandler;
496: XML_AttlistDeclHandler m_attlistDeclHandler;
497: XML_EntityDeclHandler m_entityDeclHandler;
498: XML_XmlDeclHandler m_xmlDeclHandler;
499: const ENCODING *m_encoding;
500: INIT_ENCODING m_initEncoding;
501: const ENCODING *m_internalEncoding;
502: const XML_Char *m_protocolEncodingName;
503: XML_Bool m_ns;
504: XML_Bool m_ns_triplets;
505: void *m_unknownEncodingMem;
506: void *m_unknownEncodingData;
507: void *m_unknownEncodingHandlerData;
508: void (XMLCALL *m_unknownEncodingRelease)(void *);
509: PROLOG_STATE m_prologState;
510: Processor *m_processor;
511: enum XML_Error m_errorCode;
512: const char *m_eventPtr;
513: const char *m_eventEndPtr;
514: const char *m_positionPtr;
515: OPEN_INTERNAL_ENTITY *m_openInternalEntities;
516: OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
517: XML_Bool m_defaultExpandInternalEntities;
518: int m_tagLevel;
519: ENTITY *m_declEntity;
520: const XML_Char *m_doctypeName;
521: const XML_Char *m_doctypeSysid;
522: const XML_Char *m_doctypePubid;
523: const XML_Char *m_declAttributeType;
524: const XML_Char *m_declNotationName;
525: const XML_Char *m_declNotationPublicId;
526: ELEMENT_TYPE *m_declElementType;
527: ATTRIBUTE_ID *m_declAttributeId;
528: XML_Bool m_declAttributeIsCdata;
529: XML_Bool m_declAttributeIsId;
530: DTD *m_dtd;
531: const XML_Char *m_curBase;
532: TAG *m_tagStack;
533: TAG *m_freeTagList;
534: BINDING *m_inheritedBindings;
535: BINDING *m_freeBindingList;
536: int m_attsSize;
537: int m_nSpecifiedAtts;
538: int m_idAttIndex;
539: ATTRIBUTE *m_atts;
540: NS_ATT *m_nsAtts;
541: unsigned long m_nsAttsVersion;
542: unsigned char m_nsAttsPower;
1.1.1.2 ! misho 543: #ifdef XML_ATTR_INFO
! 544: XML_AttrInfo *m_attInfo;
! 545: #endif
1.1 misho 546: POSITION m_position;
547: STRING_POOL m_tempPool;
548: STRING_POOL m_temp2Pool;
549: char *m_groupConnector;
550: unsigned int m_groupSize;
551: XML_Char m_namespaceSeparator;
552: XML_Parser m_parentParser;
553: XML_ParsingStatus m_parsingStatus;
554: #ifdef XML_DTD
555: XML_Bool m_isParamEntity;
556: XML_Bool m_useForeignDTD;
557: enum XML_ParamEntityParsing m_paramEntityParsing;
558: #endif
1.1.1.2 ! misho 559: unsigned long m_hash_secret_salt;
1.1 misho 560: };
561:
562: #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
563: #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
564: #define FREE(p) (parser->m_mem.free_fcn((p)))
565:
566: #define userData (parser->m_userData)
567: #define handlerArg (parser->m_handlerArg)
568: #define startElementHandler (parser->m_startElementHandler)
569: #define endElementHandler (parser->m_endElementHandler)
570: #define characterDataHandler (parser->m_characterDataHandler)
571: #define processingInstructionHandler \
572: (parser->m_processingInstructionHandler)
573: #define commentHandler (parser->m_commentHandler)
574: #define startCdataSectionHandler \
575: (parser->m_startCdataSectionHandler)
576: #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
577: #define defaultHandler (parser->m_defaultHandler)
578: #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
579: #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
580: #define unparsedEntityDeclHandler \
581: (parser->m_unparsedEntityDeclHandler)
582: #define notationDeclHandler (parser->m_notationDeclHandler)
583: #define startNamespaceDeclHandler \
584: (parser->m_startNamespaceDeclHandler)
585: #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
586: #define notStandaloneHandler (parser->m_notStandaloneHandler)
587: #define externalEntityRefHandler \
588: (parser->m_externalEntityRefHandler)
589: #define externalEntityRefHandlerArg \
590: (parser->m_externalEntityRefHandlerArg)
591: #define internalEntityRefHandler \
592: (parser->m_internalEntityRefHandler)
593: #define skippedEntityHandler (parser->m_skippedEntityHandler)
594: #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
595: #define elementDeclHandler (parser->m_elementDeclHandler)
596: #define attlistDeclHandler (parser->m_attlistDeclHandler)
597: #define entityDeclHandler (parser->m_entityDeclHandler)
598: #define xmlDeclHandler (parser->m_xmlDeclHandler)
599: #define encoding (parser->m_encoding)
600: #define initEncoding (parser->m_initEncoding)
601: #define internalEncoding (parser->m_internalEncoding)
602: #define unknownEncodingMem (parser->m_unknownEncodingMem)
603: #define unknownEncodingData (parser->m_unknownEncodingData)
604: #define unknownEncodingHandlerData \
605: (parser->m_unknownEncodingHandlerData)
606: #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
607: #define protocolEncodingName (parser->m_protocolEncodingName)
608: #define ns (parser->m_ns)
609: #define ns_triplets (parser->m_ns_triplets)
610: #define prologState (parser->m_prologState)
611: #define processor (parser->m_processor)
612: #define errorCode (parser->m_errorCode)
613: #define eventPtr (parser->m_eventPtr)
614: #define eventEndPtr (parser->m_eventEndPtr)
615: #define positionPtr (parser->m_positionPtr)
616: #define position (parser->m_position)
617: #define openInternalEntities (parser->m_openInternalEntities)
618: #define freeInternalEntities (parser->m_freeInternalEntities)
619: #define defaultExpandInternalEntities \
620: (parser->m_defaultExpandInternalEntities)
621: #define tagLevel (parser->m_tagLevel)
622: #define buffer (parser->m_buffer)
623: #define bufferPtr (parser->m_bufferPtr)
624: #define bufferEnd (parser->m_bufferEnd)
625: #define parseEndByteIndex (parser->m_parseEndByteIndex)
626: #define parseEndPtr (parser->m_parseEndPtr)
627: #define bufferLim (parser->m_bufferLim)
628: #define dataBuf (parser->m_dataBuf)
629: #define dataBufEnd (parser->m_dataBufEnd)
630: #define _dtd (parser->m_dtd)
631: #define curBase (parser->m_curBase)
632: #define declEntity (parser->m_declEntity)
633: #define doctypeName (parser->m_doctypeName)
634: #define doctypeSysid (parser->m_doctypeSysid)
635: #define doctypePubid (parser->m_doctypePubid)
636: #define declAttributeType (parser->m_declAttributeType)
637: #define declNotationName (parser->m_declNotationName)
638: #define declNotationPublicId (parser->m_declNotationPublicId)
639: #define declElementType (parser->m_declElementType)
640: #define declAttributeId (parser->m_declAttributeId)
641: #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
642: #define declAttributeIsId (parser->m_declAttributeIsId)
643: #define freeTagList (parser->m_freeTagList)
644: #define freeBindingList (parser->m_freeBindingList)
645: #define inheritedBindings (parser->m_inheritedBindings)
646: #define tagStack (parser->m_tagStack)
647: #define atts (parser->m_atts)
648: #define attsSize (parser->m_attsSize)
649: #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
650: #define idAttIndex (parser->m_idAttIndex)
651: #define nsAtts (parser->m_nsAtts)
652: #define nsAttsVersion (parser->m_nsAttsVersion)
653: #define nsAttsPower (parser->m_nsAttsPower)
1.1.1.2 ! misho 654: #define attInfo (parser->m_attInfo)
1.1 misho 655: #define tempPool (parser->m_tempPool)
656: #define temp2Pool (parser->m_temp2Pool)
657: #define groupConnector (parser->m_groupConnector)
658: #define groupSize (parser->m_groupSize)
659: #define namespaceSeparator (parser->m_namespaceSeparator)
660: #define parentParser (parser->m_parentParser)
661: #define ps_parsing (parser->m_parsingStatus.parsing)
662: #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
663: #ifdef XML_DTD
664: #define isParamEntity (parser->m_isParamEntity)
665: #define useForeignDTD (parser->m_useForeignDTD)
666: #define paramEntityParsing (parser->m_paramEntityParsing)
667: #endif /* XML_DTD */
1.1.1.2 ! misho 668: #define hash_secret_salt (parser->m_hash_secret_salt)
1.1 misho 669:
670: XML_Parser XMLCALL
671: XML_ParserCreate(const XML_Char *encodingName)
672: {
673: return XML_ParserCreate_MM(encodingName, NULL, NULL);
674: }
675:
676: XML_Parser XMLCALL
677: XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
678: {
679: XML_Char tmp[2];
680: *tmp = nsSep;
681: return XML_ParserCreate_MM(encodingName, NULL, tmp);
682: }
683:
684: static const XML_Char implicitContext[] = {
685: ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
1.1.1.2 ! misho 686: ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
1.1 misho 687: ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
688: ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
689: ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
690: ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
691: };
692:
1.1.1.2 ! misho 693: static unsigned long
! 694: generate_hash_secret_salt(void)
! 695: {
! 696: unsigned int seed = time(NULL) % UINT_MAX;
! 697: srand(seed);
! 698: return rand();
! 699: }
! 700:
! 701: static XML_Bool /* only valid for root parser */
! 702: startParsing(XML_Parser parser)
! 703: {
! 704: /* hash functions must be initialized before setContext() is called */
! 705: if (hash_secret_salt == 0)
! 706: hash_secret_salt = generate_hash_secret_salt();
! 707: if (ns) {
! 708: /* implicit context only set for root parser, since child
! 709: parsers (i.e. external entity parsers) will inherit it
! 710: */
! 711: return setContext(parser, implicitContext);
! 712: }
! 713: return XML_TRUE;
! 714: }
! 715:
1.1 misho 716: XML_Parser XMLCALL
717: XML_ParserCreate_MM(const XML_Char *encodingName,
718: const XML_Memory_Handling_Suite *memsuite,
719: const XML_Char *nameSep)
720: {
1.1.1.2 ! misho 721: return parserCreate(encodingName, memsuite, nameSep, NULL);
1.1 misho 722: }
723:
724: static XML_Parser
725: parserCreate(const XML_Char *encodingName,
726: const XML_Memory_Handling_Suite *memsuite,
727: const XML_Char *nameSep,
728: DTD *dtd)
729: {
730: XML_Parser parser;
731:
732: if (memsuite) {
733: XML_Memory_Handling_Suite *mtemp;
734: parser = (XML_Parser)
735: memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
736: if (parser != NULL) {
737: mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738: mtemp->malloc_fcn = memsuite->malloc_fcn;
739: mtemp->realloc_fcn = memsuite->realloc_fcn;
740: mtemp->free_fcn = memsuite->free_fcn;
741: }
742: }
743: else {
744: XML_Memory_Handling_Suite *mtemp;
745: parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
746: if (parser != NULL) {
747: mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
748: mtemp->malloc_fcn = malloc;
749: mtemp->realloc_fcn = realloc;
750: mtemp->free_fcn = free;
751: }
752: }
753:
754: if (!parser)
755: return parser;
756:
757: buffer = NULL;
758: bufferLim = NULL;
759:
760: attsSize = INIT_ATTS_SIZE;
761: atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
762: if (atts == NULL) {
763: FREE(parser);
764: return NULL;
765: }
1.1.1.2 ! misho 766: #ifdef XML_ATTR_INFO
! 767: attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
! 768: if (attInfo == NULL) {
! 769: FREE(atts);
! 770: FREE(parser);
! 771: return NULL;
! 772: }
! 773: #endif
1.1 misho 774: dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
775: if (dataBuf == NULL) {
776: FREE(atts);
1.1.1.2 ! misho 777: #ifdef XML_ATTR_INFO
! 778: FREE(attInfo);
! 779: #endif
1.1 misho 780: FREE(parser);
781: return NULL;
782: }
783: dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
784:
785: if (dtd)
786: _dtd = dtd;
787: else {
788: _dtd = dtdCreate(&parser->m_mem);
789: if (_dtd == NULL) {
790: FREE(dataBuf);
791: FREE(atts);
1.1.1.2 ! misho 792: #ifdef XML_ATTR_INFO
! 793: FREE(attInfo);
! 794: #endif
1.1 misho 795: FREE(parser);
796: return NULL;
797: }
798: }
799:
800: freeBindingList = NULL;
801: freeTagList = NULL;
802: freeInternalEntities = NULL;
803:
804: groupSize = 0;
805: groupConnector = NULL;
806:
807: unknownEncodingHandler = NULL;
808: unknownEncodingHandlerData = NULL;
809:
810: namespaceSeparator = ASCII_EXCL;
811: ns = XML_FALSE;
812: ns_triplets = XML_FALSE;
813:
814: nsAtts = NULL;
815: nsAttsVersion = 0;
816: nsAttsPower = 0;
817:
818: poolInit(&tempPool, &(parser->m_mem));
819: poolInit(&temp2Pool, &(parser->m_mem));
820: parserInit(parser, encodingName);
821:
822: if (encodingName && !protocolEncodingName) {
823: XML_ParserFree(parser);
824: return NULL;
825: }
826:
827: if (nameSep) {
828: ns = XML_TRUE;
829: internalEncoding = XmlGetInternalEncodingNS();
830: namespaceSeparator = *nameSep;
831: }
832: else {
833: internalEncoding = XmlGetInternalEncoding();
834: }
835:
836: return parser;
837: }
838:
839: static void
840: parserInit(XML_Parser parser, const XML_Char *encodingName)
841: {
842: processor = prologInitProcessor;
843: XmlPrologStateInit(&prologState);
844: protocolEncodingName = (encodingName != NULL
845: ? poolCopyString(&tempPool, encodingName)
846: : NULL);
847: curBase = NULL;
848: XmlInitEncoding(&initEncoding, &encoding, 0);
849: userData = NULL;
850: handlerArg = NULL;
851: startElementHandler = NULL;
852: endElementHandler = NULL;
853: characterDataHandler = NULL;
854: processingInstructionHandler = NULL;
855: commentHandler = NULL;
856: startCdataSectionHandler = NULL;
857: endCdataSectionHandler = NULL;
858: defaultHandler = NULL;
859: startDoctypeDeclHandler = NULL;
860: endDoctypeDeclHandler = NULL;
861: unparsedEntityDeclHandler = NULL;
862: notationDeclHandler = NULL;
863: startNamespaceDeclHandler = NULL;
864: endNamespaceDeclHandler = NULL;
865: notStandaloneHandler = NULL;
866: externalEntityRefHandler = NULL;
867: externalEntityRefHandlerArg = parser;
868: skippedEntityHandler = NULL;
869: elementDeclHandler = NULL;
870: attlistDeclHandler = NULL;
871: entityDeclHandler = NULL;
872: xmlDeclHandler = NULL;
873: bufferPtr = buffer;
874: bufferEnd = buffer;
875: parseEndByteIndex = 0;
876: parseEndPtr = NULL;
877: declElementType = NULL;
878: declAttributeId = NULL;
879: declEntity = NULL;
880: doctypeName = NULL;
881: doctypeSysid = NULL;
882: doctypePubid = NULL;
883: declAttributeType = NULL;
884: declNotationName = NULL;
885: declNotationPublicId = NULL;
886: declAttributeIsCdata = XML_FALSE;
887: declAttributeIsId = XML_FALSE;
888: memset(&position, 0, sizeof(POSITION));
889: errorCode = XML_ERROR_NONE;
890: eventPtr = NULL;
891: eventEndPtr = NULL;
892: positionPtr = NULL;
893: openInternalEntities = NULL;
894: defaultExpandInternalEntities = XML_TRUE;
895: tagLevel = 0;
896: tagStack = NULL;
897: inheritedBindings = NULL;
898: nSpecifiedAtts = 0;
899: unknownEncodingMem = NULL;
900: unknownEncodingRelease = NULL;
901: unknownEncodingData = NULL;
902: parentParser = NULL;
903: ps_parsing = XML_INITIALIZED;
904: #ifdef XML_DTD
905: isParamEntity = XML_FALSE;
906: useForeignDTD = XML_FALSE;
907: paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
908: #endif
1.1.1.2 ! misho 909: hash_secret_salt = 0;
1.1 misho 910: }
911:
912: /* moves list of bindings to freeBindingList */
913: static void FASTCALL
914: moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
915: {
916: while (bindings) {
917: BINDING *b = bindings;
918: bindings = bindings->nextTagBinding;
919: b->nextTagBinding = freeBindingList;
920: freeBindingList = b;
921: }
922: }
923:
924: XML_Bool XMLCALL
925: XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
926: {
927: TAG *tStk;
928: OPEN_INTERNAL_ENTITY *openEntityList;
929: if (parentParser)
930: return XML_FALSE;
931: /* move tagStack to freeTagList */
932: tStk = tagStack;
933: while (tStk) {
934: TAG *tag = tStk;
935: tStk = tStk->parent;
936: tag->parent = freeTagList;
937: moveToFreeBindingList(parser, tag->bindings);
938: tag->bindings = NULL;
939: freeTagList = tag;
940: }
941: /* move openInternalEntities to freeInternalEntities */
942: openEntityList = openInternalEntities;
943: while (openEntityList) {
944: OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
945: openEntityList = openEntity->next;
946: openEntity->next = freeInternalEntities;
947: freeInternalEntities = openEntity;
948: }
949: moveToFreeBindingList(parser, inheritedBindings);
950: FREE(unknownEncodingMem);
951: if (unknownEncodingRelease)
952: unknownEncodingRelease(unknownEncodingData);
953: poolClear(&tempPool);
954: poolClear(&temp2Pool);
955: parserInit(parser, encodingName);
956: dtdReset(_dtd, &parser->m_mem);
1.1.1.2 ! misho 957: return XML_TRUE;
1.1 misho 958: }
959:
960: enum XML_Status XMLCALL
961: XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
962: {
963: /* Block after XML_Parse()/XML_ParseBuffer() has been called.
964: XXX There's no way for the caller to determine which of the
965: XXX possible error cases caused the XML_STATUS_ERROR return.
966: */
967: if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
968: return XML_STATUS_ERROR;
969: if (encodingName == NULL)
970: protocolEncodingName = NULL;
971: else {
972: protocolEncodingName = poolCopyString(&tempPool, encodingName);
973: if (!protocolEncodingName)
974: return XML_STATUS_ERROR;
975: }
976: return XML_STATUS_OK;
977: }
978:
979: XML_Parser XMLCALL
980: XML_ExternalEntityParserCreate(XML_Parser oldParser,
981: const XML_Char *context,
982: const XML_Char *encodingName)
983: {
984: XML_Parser parser = oldParser;
985: DTD *newDtd = NULL;
986: DTD *oldDtd = _dtd;
987: XML_StartElementHandler oldStartElementHandler = startElementHandler;
988: XML_EndElementHandler oldEndElementHandler = endElementHandler;
989: XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
990: XML_ProcessingInstructionHandler oldProcessingInstructionHandler
991: = processingInstructionHandler;
992: XML_CommentHandler oldCommentHandler = commentHandler;
993: XML_StartCdataSectionHandler oldStartCdataSectionHandler
994: = startCdataSectionHandler;
995: XML_EndCdataSectionHandler oldEndCdataSectionHandler
996: = endCdataSectionHandler;
997: XML_DefaultHandler oldDefaultHandler = defaultHandler;
998: XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
999: = unparsedEntityDeclHandler;
1000: XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1001: XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1002: = startNamespaceDeclHandler;
1003: XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1004: = endNamespaceDeclHandler;
1005: XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1006: XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1007: = externalEntityRefHandler;
1008: XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1009: XML_UnknownEncodingHandler oldUnknownEncodingHandler
1010: = unknownEncodingHandler;
1011: XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1012: XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1013: XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1014: XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1015: ELEMENT_TYPE * oldDeclElementType = declElementType;
1016:
1017: void *oldUserData = userData;
1018: void *oldHandlerArg = handlerArg;
1019: XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1020: XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1021: #ifdef XML_DTD
1022: enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1023: int oldInEntityValue = prologState.inEntityValue;
1024: #endif
1025: XML_Bool oldns_triplets = ns_triplets;
1.1.1.2 ! misho 1026: /* Note that the new parser shares the same hash secret as the old
! 1027: parser, so that dtdCopy and copyEntityTable can lookup values
! 1028: from hash tables associated with either parser without us having
! 1029: to worry which hash secrets each table has.
! 1030: */
! 1031: unsigned long oldhash_secret_salt = hash_secret_salt;
1.1 misho 1032:
1033: #ifdef XML_DTD
1034: if (!context)
1035: newDtd = oldDtd;
1036: #endif /* XML_DTD */
1037:
1038: /* Note that the magical uses of the pre-processor to make field
1039: access look more like C++ require that `parser' be overwritten
1040: here. This makes this function more painful to follow than it
1041: would be otherwise.
1042: */
1043: if (ns) {
1044: XML_Char tmp[2];
1045: *tmp = namespaceSeparator;
1046: parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1047: }
1048: else {
1049: parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1050: }
1051:
1052: if (!parser)
1053: return NULL;
1054:
1055: startElementHandler = oldStartElementHandler;
1056: endElementHandler = oldEndElementHandler;
1057: characterDataHandler = oldCharacterDataHandler;
1058: processingInstructionHandler = oldProcessingInstructionHandler;
1059: commentHandler = oldCommentHandler;
1060: startCdataSectionHandler = oldStartCdataSectionHandler;
1061: endCdataSectionHandler = oldEndCdataSectionHandler;
1062: defaultHandler = oldDefaultHandler;
1063: unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1064: notationDeclHandler = oldNotationDeclHandler;
1065: startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1066: endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1067: notStandaloneHandler = oldNotStandaloneHandler;
1068: externalEntityRefHandler = oldExternalEntityRefHandler;
1069: skippedEntityHandler = oldSkippedEntityHandler;
1070: unknownEncodingHandler = oldUnknownEncodingHandler;
1071: elementDeclHandler = oldElementDeclHandler;
1072: attlistDeclHandler = oldAttlistDeclHandler;
1073: entityDeclHandler = oldEntityDeclHandler;
1074: xmlDeclHandler = oldXmlDeclHandler;
1075: declElementType = oldDeclElementType;
1076: userData = oldUserData;
1077: if (oldUserData == oldHandlerArg)
1078: handlerArg = userData;
1079: else
1080: handlerArg = parser;
1081: if (oldExternalEntityRefHandlerArg != oldParser)
1082: externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1083: defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1084: ns_triplets = oldns_triplets;
1.1.1.2 ! misho 1085: hash_secret_salt = oldhash_secret_salt;
1.1 misho 1086: parentParser = oldParser;
1087: #ifdef XML_DTD
1088: paramEntityParsing = oldParamEntityParsing;
1089: prologState.inEntityValue = oldInEntityValue;
1090: if (context) {
1091: #endif /* XML_DTD */
1.1.1.2 ! misho 1092: if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1.1 misho 1093: || !setContext(parser, context)) {
1094: XML_ParserFree(parser);
1095: return NULL;
1096: }
1097: processor = externalEntityInitProcessor;
1098: #ifdef XML_DTD
1099: }
1100: else {
1101: /* The DTD instance referenced by _dtd is shared between the document's
1102: root parser and external PE parsers, therefore one does not need to
1103: call setContext. In addition, one also *must* not call setContext,
1104: because this would overwrite existing prefix->binding pointers in
1105: _dtd with ones that get destroyed with the external PE parser.
1106: This would leave those prefixes with dangling pointers.
1107: */
1108: isParamEntity = XML_TRUE;
1109: XmlPrologStateInitExternalEntity(&prologState);
1110: processor = externalParEntInitProcessor;
1111: }
1112: #endif /* XML_DTD */
1113: return parser;
1114: }
1115:
1116: static void FASTCALL
1117: destroyBindings(BINDING *bindings, XML_Parser parser)
1118: {
1119: for (;;) {
1120: BINDING *b = bindings;
1121: if (!b)
1122: break;
1123: bindings = b->nextTagBinding;
1124: FREE(b->uri);
1125: FREE(b);
1126: }
1127: }
1128:
1129: void XMLCALL
1130: XML_ParserFree(XML_Parser parser)
1131: {
1132: TAG *tagList;
1133: OPEN_INTERNAL_ENTITY *entityList;
1134: if (parser == NULL)
1135: return;
1136: /* free tagStack and freeTagList */
1137: tagList = tagStack;
1138: for (;;) {
1139: TAG *p;
1140: if (tagList == NULL) {
1141: if (freeTagList == NULL)
1142: break;
1143: tagList = freeTagList;
1144: freeTagList = NULL;
1145: }
1146: p = tagList;
1147: tagList = tagList->parent;
1148: FREE(p->buf);
1149: destroyBindings(p->bindings, parser);
1150: FREE(p);
1151: }
1152: /* free openInternalEntities and freeInternalEntities */
1153: entityList = openInternalEntities;
1154: for (;;) {
1155: OPEN_INTERNAL_ENTITY *openEntity;
1156: if (entityList == NULL) {
1157: if (freeInternalEntities == NULL)
1158: break;
1159: entityList = freeInternalEntities;
1160: freeInternalEntities = NULL;
1161: }
1162: openEntity = entityList;
1163: entityList = entityList->next;
1164: FREE(openEntity);
1165: }
1166:
1167: destroyBindings(freeBindingList, parser);
1168: destroyBindings(inheritedBindings, parser);
1169: poolDestroy(&tempPool);
1170: poolDestroy(&temp2Pool);
1171: #ifdef XML_DTD
1172: /* external parameter entity parsers share the DTD structure
1173: parser->m_dtd with the root parser, so we must not destroy it
1174: */
1175: if (!isParamEntity && _dtd)
1176: #else
1177: if (_dtd)
1178: #endif /* XML_DTD */
1179: dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1180: FREE((void *)atts);
1.1.1.2 ! misho 1181: #ifdef XML_ATTR_INFO
! 1182: FREE((void *)attInfo);
! 1183: #endif
1.1 misho 1184: FREE(groupConnector);
1185: FREE(buffer);
1186: FREE(dataBuf);
1187: FREE(nsAtts);
1188: FREE(unknownEncodingMem);
1189: if (unknownEncodingRelease)
1190: unknownEncodingRelease(unknownEncodingData);
1191: FREE(parser);
1192: }
1193:
1194: void XMLCALL
1195: XML_UseParserAsHandlerArg(XML_Parser parser)
1196: {
1197: handlerArg = parser;
1198: }
1199:
1200: enum XML_Error XMLCALL
1201: XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1202: {
1203: #ifdef XML_DTD
1204: /* block after XML_Parse()/XML_ParseBuffer() has been called */
1205: if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1206: return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207: useForeignDTD = useDTD;
1208: return XML_ERROR_NONE;
1209: #else
1210: return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1211: #endif
1212: }
1213:
1214: void XMLCALL
1215: XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1216: {
1217: /* block after XML_Parse()/XML_ParseBuffer() has been called */
1218: if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1219: return;
1220: ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1221: }
1222:
1223: void XMLCALL
1224: XML_SetUserData(XML_Parser parser, void *p)
1225: {
1226: if (handlerArg == userData)
1227: handlerArg = userData = p;
1228: else
1229: userData = p;
1230: }
1231:
1232: enum XML_Status XMLCALL
1233: XML_SetBase(XML_Parser parser, const XML_Char *p)
1234: {
1235: if (p) {
1236: p = poolCopyString(&_dtd->pool, p);
1237: if (!p)
1238: return XML_STATUS_ERROR;
1239: curBase = p;
1240: }
1241: else
1242: curBase = NULL;
1243: return XML_STATUS_OK;
1244: }
1245:
1246: const XML_Char * XMLCALL
1247: XML_GetBase(XML_Parser parser)
1248: {
1249: return curBase;
1250: }
1251:
1252: int XMLCALL
1253: XML_GetSpecifiedAttributeCount(XML_Parser parser)
1254: {
1255: return nSpecifiedAtts;
1256: }
1257:
1258: int XMLCALL
1259: XML_GetIdAttributeIndex(XML_Parser parser)
1260: {
1261: return idAttIndex;
1262: }
1263:
1.1.1.2 ! misho 1264: #ifdef XML_ATTR_INFO
! 1265: const XML_AttrInfo * XMLCALL
! 1266: XML_GetAttributeInfo(XML_Parser parser)
! 1267: {
! 1268: return attInfo;
! 1269: }
! 1270: #endif
! 1271:
1.1 misho 1272: void XMLCALL
1273: XML_SetElementHandler(XML_Parser parser,
1274: XML_StartElementHandler start,
1275: XML_EndElementHandler end)
1276: {
1277: startElementHandler = start;
1278: endElementHandler = end;
1279: }
1280:
1281: void XMLCALL
1282: XML_SetStartElementHandler(XML_Parser parser,
1283: XML_StartElementHandler start) {
1284: startElementHandler = start;
1285: }
1286:
1287: void XMLCALL
1288: XML_SetEndElementHandler(XML_Parser parser,
1289: XML_EndElementHandler end) {
1290: endElementHandler = end;
1291: }
1292:
1293: void XMLCALL
1294: XML_SetCharacterDataHandler(XML_Parser parser,
1295: XML_CharacterDataHandler handler)
1296: {
1297: characterDataHandler = handler;
1298: }
1299:
1300: void XMLCALL
1301: XML_SetProcessingInstructionHandler(XML_Parser parser,
1302: XML_ProcessingInstructionHandler handler)
1303: {
1304: processingInstructionHandler = handler;
1305: }
1306:
1307: void XMLCALL
1308: XML_SetCommentHandler(XML_Parser parser,
1309: XML_CommentHandler handler)
1310: {
1311: commentHandler = handler;
1312: }
1313:
1314: void XMLCALL
1315: XML_SetCdataSectionHandler(XML_Parser parser,
1316: XML_StartCdataSectionHandler start,
1317: XML_EndCdataSectionHandler end)
1318: {
1319: startCdataSectionHandler = start;
1320: endCdataSectionHandler = end;
1321: }
1322:
1323: void XMLCALL
1324: XML_SetStartCdataSectionHandler(XML_Parser parser,
1325: XML_StartCdataSectionHandler start) {
1326: startCdataSectionHandler = start;
1327: }
1328:
1329: void XMLCALL
1330: XML_SetEndCdataSectionHandler(XML_Parser parser,
1331: XML_EndCdataSectionHandler end) {
1332: endCdataSectionHandler = end;
1333: }
1334:
1335: void XMLCALL
1336: XML_SetDefaultHandler(XML_Parser parser,
1337: XML_DefaultHandler handler)
1338: {
1339: defaultHandler = handler;
1340: defaultExpandInternalEntities = XML_FALSE;
1341: }
1342:
1343: void XMLCALL
1344: XML_SetDefaultHandlerExpand(XML_Parser parser,
1345: XML_DefaultHandler handler)
1346: {
1347: defaultHandler = handler;
1348: defaultExpandInternalEntities = XML_TRUE;
1349: }
1350:
1351: void XMLCALL
1352: XML_SetDoctypeDeclHandler(XML_Parser parser,
1353: XML_StartDoctypeDeclHandler start,
1354: XML_EndDoctypeDeclHandler end)
1355: {
1356: startDoctypeDeclHandler = start;
1357: endDoctypeDeclHandler = end;
1358: }
1359:
1360: void XMLCALL
1361: XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1362: XML_StartDoctypeDeclHandler start) {
1363: startDoctypeDeclHandler = start;
1364: }
1365:
1366: void XMLCALL
1367: XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1368: XML_EndDoctypeDeclHandler end) {
1369: endDoctypeDeclHandler = end;
1370: }
1371:
1372: void XMLCALL
1373: XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1374: XML_UnparsedEntityDeclHandler handler)
1375: {
1376: unparsedEntityDeclHandler = handler;
1377: }
1378:
1379: void XMLCALL
1380: XML_SetNotationDeclHandler(XML_Parser parser,
1381: XML_NotationDeclHandler handler)
1382: {
1383: notationDeclHandler = handler;
1384: }
1385:
1386: void XMLCALL
1387: XML_SetNamespaceDeclHandler(XML_Parser parser,
1388: XML_StartNamespaceDeclHandler start,
1389: XML_EndNamespaceDeclHandler end)
1390: {
1391: startNamespaceDeclHandler = start;
1392: endNamespaceDeclHandler = end;
1393: }
1394:
1395: void XMLCALL
1396: XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1397: XML_StartNamespaceDeclHandler start) {
1398: startNamespaceDeclHandler = start;
1399: }
1400:
1401: void XMLCALL
1402: XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1403: XML_EndNamespaceDeclHandler end) {
1404: endNamespaceDeclHandler = end;
1405: }
1406:
1407: void XMLCALL
1408: XML_SetNotStandaloneHandler(XML_Parser parser,
1409: XML_NotStandaloneHandler handler)
1410: {
1411: notStandaloneHandler = handler;
1412: }
1413:
1414: void XMLCALL
1415: XML_SetExternalEntityRefHandler(XML_Parser parser,
1416: XML_ExternalEntityRefHandler handler)
1417: {
1418: externalEntityRefHandler = handler;
1419: }
1420:
1421: void XMLCALL
1422: XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1423: {
1424: if (arg)
1425: externalEntityRefHandlerArg = (XML_Parser)arg;
1426: else
1427: externalEntityRefHandlerArg = parser;
1428: }
1429:
1430: void XMLCALL
1431: XML_SetSkippedEntityHandler(XML_Parser parser,
1432: XML_SkippedEntityHandler handler)
1433: {
1434: skippedEntityHandler = handler;
1435: }
1436:
1437: void XMLCALL
1438: XML_SetUnknownEncodingHandler(XML_Parser parser,
1439: XML_UnknownEncodingHandler handler,
1440: void *data)
1441: {
1442: unknownEncodingHandler = handler;
1443: unknownEncodingHandlerData = data;
1444: }
1445:
1446: void XMLCALL
1447: XML_SetElementDeclHandler(XML_Parser parser,
1448: XML_ElementDeclHandler eldecl)
1449: {
1450: elementDeclHandler = eldecl;
1451: }
1452:
1453: void XMLCALL
1454: XML_SetAttlistDeclHandler(XML_Parser parser,
1455: XML_AttlistDeclHandler attdecl)
1456: {
1457: attlistDeclHandler = attdecl;
1458: }
1459:
1460: void XMLCALL
1461: XML_SetEntityDeclHandler(XML_Parser parser,
1462: XML_EntityDeclHandler handler)
1463: {
1464: entityDeclHandler = handler;
1465: }
1466:
1467: void XMLCALL
1468: XML_SetXmlDeclHandler(XML_Parser parser,
1469: XML_XmlDeclHandler handler) {
1470: xmlDeclHandler = handler;
1471: }
1472:
1473: int XMLCALL
1474: XML_SetParamEntityParsing(XML_Parser parser,
1475: enum XML_ParamEntityParsing peParsing)
1476: {
1477: /* block after XML_Parse()/XML_ParseBuffer() has been called */
1478: if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1479: return 0;
1480: #ifdef XML_DTD
1481: paramEntityParsing = peParsing;
1482: return 1;
1483: #else
1484: return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1485: #endif
1486: }
1487:
1.1.1.2 ! misho 1488: int XMLCALL
! 1489: XML_SetHashSalt(XML_Parser parser,
! 1490: unsigned long hash_salt)
! 1491: {
! 1492: /* block after XML_Parse()/XML_ParseBuffer() has been called */
! 1493: if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
! 1494: return 0;
! 1495: hash_secret_salt = hash_salt;
! 1496: return 1;
! 1497: }
! 1498:
1.1 misho 1499: enum XML_Status XMLCALL
1500: XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1501: {
1502: switch (ps_parsing) {
1503: case XML_SUSPENDED:
1504: errorCode = XML_ERROR_SUSPENDED;
1505: return XML_STATUS_ERROR;
1506: case XML_FINISHED:
1507: errorCode = XML_ERROR_FINISHED;
1508: return XML_STATUS_ERROR;
1.1.1.2 ! misho 1509: case XML_INITIALIZED:
! 1510: if (parentParser == NULL && !startParsing(parser)) {
! 1511: errorCode = XML_ERROR_NO_MEMORY;
! 1512: return XML_STATUS_ERROR;
! 1513: }
1.1 misho 1514: default:
1515: ps_parsing = XML_PARSING;
1516: }
1517:
1518: if (len == 0) {
1519: ps_finalBuffer = (XML_Bool)isFinal;
1520: if (!isFinal)
1521: return XML_STATUS_OK;
1522: positionPtr = bufferPtr;
1523: parseEndPtr = bufferEnd;
1524:
1525: /* If data are left over from last buffer, and we now know that these
1526: data are the final chunk of input, then we have to check them again
1527: to detect errors based on that fact.
1528: */
1529: errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1530:
1531: if (errorCode == XML_ERROR_NONE) {
1532: switch (ps_parsing) {
1533: case XML_SUSPENDED:
1534: XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1535: positionPtr = bufferPtr;
1536: return XML_STATUS_SUSPENDED;
1.1.1.2 ! misho 1537: case XML_INITIALIZED:
1.1 misho 1538: case XML_PARSING:
1539: ps_parsing = XML_FINISHED;
1540: /* fall through */
1541: default:
1542: return XML_STATUS_OK;
1543: }
1544: }
1545: eventEndPtr = eventPtr;
1546: processor = errorProcessor;
1547: return XML_STATUS_ERROR;
1548: }
1549: #ifndef XML_CONTEXT_BYTES
1550: else if (bufferPtr == bufferEnd) {
1551: const char *end;
1552: int nLeftOver;
1553: enum XML_Error result;
1554: parseEndByteIndex += len;
1555: positionPtr = s;
1556: ps_finalBuffer = (XML_Bool)isFinal;
1557:
1558: errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1559:
1560: if (errorCode != XML_ERROR_NONE) {
1561: eventEndPtr = eventPtr;
1562: processor = errorProcessor;
1563: return XML_STATUS_ERROR;
1564: }
1565: else {
1566: switch (ps_parsing) {
1567: case XML_SUSPENDED:
1568: result = XML_STATUS_SUSPENDED;
1569: break;
1570: case XML_INITIALIZED:
1571: case XML_PARSING:
1572: if (isFinal) {
1573: ps_parsing = XML_FINISHED;
1.1.1.2 ! misho 1574: return XML_STATUS_OK;
1.1 misho 1575: }
1.1.1.2 ! misho 1576: /* fall through */
! 1577: default:
! 1578: result = XML_STATUS_OK;
1.1 misho 1579: }
1580: }
1581:
1582: XmlUpdatePosition(encoding, positionPtr, end, &position);
1583: nLeftOver = s + len - end;
1584: if (nLeftOver) {
1585: if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1586: /* FIXME avoid integer overflow */
1587: char *temp;
1588: temp = (buffer == NULL
1589: ? (char *)MALLOC(len * 2)
1590: : (char *)REALLOC(buffer, len * 2));
1591: if (temp == NULL) {
1592: errorCode = XML_ERROR_NO_MEMORY;
1593: eventPtr = eventEndPtr = NULL;
1594: processor = errorProcessor;
1595: return XML_STATUS_ERROR;
1596: }
1.1.1.2 ! misho 1597: buffer = temp;
1.1 misho 1598: bufferLim = buffer + len * 2;
1599: }
1600: memcpy(buffer, end, nLeftOver);
1601: }
1602: bufferPtr = buffer;
1603: bufferEnd = buffer + nLeftOver;
1604: positionPtr = bufferPtr;
1605: parseEndPtr = bufferEnd;
1606: eventPtr = bufferPtr;
1607: eventEndPtr = bufferPtr;
1608: return result;
1609: }
1610: #endif /* not defined XML_CONTEXT_BYTES */
1611: else {
1612: void *buff = XML_GetBuffer(parser, len);
1613: if (buff == NULL)
1614: return XML_STATUS_ERROR;
1615: else {
1616: memcpy(buff, s, len);
1617: return XML_ParseBuffer(parser, len, isFinal);
1618: }
1619: }
1620: }
1621:
1622: enum XML_Status XMLCALL
1623: XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1624: {
1625: const char *start;
1626: enum XML_Status result = XML_STATUS_OK;
1627:
1628: switch (ps_parsing) {
1629: case XML_SUSPENDED:
1630: errorCode = XML_ERROR_SUSPENDED;
1631: return XML_STATUS_ERROR;
1632: case XML_FINISHED:
1633: errorCode = XML_ERROR_FINISHED;
1634: return XML_STATUS_ERROR;
1.1.1.2 ! misho 1635: case XML_INITIALIZED:
! 1636: if (parentParser == NULL && !startParsing(parser)) {
! 1637: errorCode = XML_ERROR_NO_MEMORY;
! 1638: return XML_STATUS_ERROR;
! 1639: }
1.1 misho 1640: default:
1641: ps_parsing = XML_PARSING;
1642: }
1643:
1644: start = bufferPtr;
1645: positionPtr = start;
1646: bufferEnd += len;
1647: parseEndPtr = bufferEnd;
1648: parseEndByteIndex += len;
1649: ps_finalBuffer = (XML_Bool)isFinal;
1650:
1651: errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1652:
1653: if (errorCode != XML_ERROR_NONE) {
1654: eventEndPtr = eventPtr;
1655: processor = errorProcessor;
1656: return XML_STATUS_ERROR;
1657: }
1658: else {
1659: switch (ps_parsing) {
1660: case XML_SUSPENDED:
1661: result = XML_STATUS_SUSPENDED;
1662: break;
1.1.1.2 ! misho 1663: case XML_INITIALIZED:
1.1 misho 1664: case XML_PARSING:
1665: if (isFinal) {
1666: ps_parsing = XML_FINISHED;
1667: return result;
1668: }
1669: default: ; /* should not happen */
1670: }
1671: }
1672:
1673: XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1674: positionPtr = bufferPtr;
1675: return result;
1676: }
1677:
1678: void * XMLCALL
1679: XML_GetBuffer(XML_Parser parser, int len)
1680: {
1681: switch (ps_parsing) {
1682: case XML_SUSPENDED:
1683: errorCode = XML_ERROR_SUSPENDED;
1684: return NULL;
1685: case XML_FINISHED:
1686: errorCode = XML_ERROR_FINISHED;
1687: return NULL;
1688: default: ;
1689: }
1690:
1691: if (len > bufferLim - bufferEnd) {
1692: /* FIXME avoid integer overflow */
1693: int neededSize = len + (int)(bufferEnd - bufferPtr);
1694: #ifdef XML_CONTEXT_BYTES
1695: int keep = (int)(bufferPtr - buffer);
1696:
1697: if (keep > XML_CONTEXT_BYTES)
1698: keep = XML_CONTEXT_BYTES;
1699: neededSize += keep;
1700: #endif /* defined XML_CONTEXT_BYTES */
1701: if (neededSize <= bufferLim - buffer) {
1702: #ifdef XML_CONTEXT_BYTES
1703: if (keep < bufferPtr - buffer) {
1704: int offset = (int)(bufferPtr - buffer) - keep;
1705: memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1706: bufferEnd -= offset;
1707: bufferPtr -= offset;
1708: }
1709: #else
1710: memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1711: bufferEnd = buffer + (bufferEnd - bufferPtr);
1712: bufferPtr = buffer;
1713: #endif /* not defined XML_CONTEXT_BYTES */
1714: }
1715: else {
1716: char *newBuf;
1717: int bufferSize = (int)(bufferLim - bufferPtr);
1718: if (bufferSize == 0)
1719: bufferSize = INIT_BUFFER_SIZE;
1720: do {
1721: bufferSize *= 2;
1722: } while (bufferSize < neededSize);
1723: newBuf = (char *)MALLOC(bufferSize);
1724: if (newBuf == 0) {
1725: errorCode = XML_ERROR_NO_MEMORY;
1726: return NULL;
1727: }
1728: bufferLim = newBuf + bufferSize;
1729: #ifdef XML_CONTEXT_BYTES
1730: if (bufferPtr) {
1731: int keep = (int)(bufferPtr - buffer);
1732: if (keep > XML_CONTEXT_BYTES)
1733: keep = XML_CONTEXT_BYTES;
1734: memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1735: FREE(buffer);
1736: buffer = newBuf;
1737: bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1738: bufferPtr = buffer + keep;
1739: }
1740: else {
1741: bufferEnd = newBuf + (bufferEnd - bufferPtr);
1742: bufferPtr = buffer = newBuf;
1743: }
1744: #else
1745: if (bufferPtr) {
1746: memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1747: FREE(buffer);
1748: }
1749: bufferEnd = newBuf + (bufferEnd - bufferPtr);
1750: bufferPtr = buffer = newBuf;
1751: #endif /* not defined XML_CONTEXT_BYTES */
1752: }
1.1.1.2 ! misho 1753: eventPtr = eventEndPtr = NULL;
! 1754: positionPtr = NULL;
1.1 misho 1755: }
1756: return bufferEnd;
1757: }
1758:
1759: enum XML_Status XMLCALL
1760: XML_StopParser(XML_Parser parser, XML_Bool resumable)
1761: {
1762: switch (ps_parsing) {
1763: case XML_SUSPENDED:
1764: if (resumable) {
1765: errorCode = XML_ERROR_SUSPENDED;
1766: return XML_STATUS_ERROR;
1767: }
1768: ps_parsing = XML_FINISHED;
1769: break;
1770: case XML_FINISHED:
1771: errorCode = XML_ERROR_FINISHED;
1772: return XML_STATUS_ERROR;
1773: default:
1774: if (resumable) {
1775: #ifdef XML_DTD
1776: if (isParamEntity) {
1777: errorCode = XML_ERROR_SUSPEND_PE;
1778: return XML_STATUS_ERROR;
1779: }
1780: #endif
1781: ps_parsing = XML_SUSPENDED;
1782: }
1783: else
1784: ps_parsing = XML_FINISHED;
1785: }
1786: return XML_STATUS_OK;
1787: }
1788:
1789: enum XML_Status XMLCALL
1790: XML_ResumeParser(XML_Parser parser)
1791: {
1792: enum XML_Status result = XML_STATUS_OK;
1793:
1794: if (ps_parsing != XML_SUSPENDED) {
1795: errorCode = XML_ERROR_NOT_SUSPENDED;
1796: return XML_STATUS_ERROR;
1797: }
1798: ps_parsing = XML_PARSING;
1799:
1800: errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1801:
1802: if (errorCode != XML_ERROR_NONE) {
1803: eventEndPtr = eventPtr;
1804: processor = errorProcessor;
1805: return XML_STATUS_ERROR;
1806: }
1807: else {
1808: switch (ps_parsing) {
1809: case XML_SUSPENDED:
1810: result = XML_STATUS_SUSPENDED;
1811: break;
1.1.1.2 ! misho 1812: case XML_INITIALIZED:
1.1 misho 1813: case XML_PARSING:
1814: if (ps_finalBuffer) {
1815: ps_parsing = XML_FINISHED;
1816: return result;
1817: }
1818: default: ;
1819: }
1820: }
1821:
1822: XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1823: positionPtr = bufferPtr;
1824: return result;
1825: }
1826:
1827: void XMLCALL
1828: XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1829: {
1830: assert(status != NULL);
1831: *status = parser->m_parsingStatus;
1832: }
1833:
1834: enum XML_Error XMLCALL
1835: XML_GetErrorCode(XML_Parser parser)
1836: {
1837: return errorCode;
1838: }
1839:
1840: XML_Index XMLCALL
1841: XML_GetCurrentByteIndex(XML_Parser parser)
1842: {
1843: if (eventPtr)
1844: return parseEndByteIndex - (parseEndPtr - eventPtr);
1845: return -1;
1846: }
1847:
1848: int XMLCALL
1849: XML_GetCurrentByteCount(XML_Parser parser)
1850: {
1851: if (eventEndPtr && eventPtr)
1852: return (int)(eventEndPtr - eventPtr);
1853: return 0;
1854: }
1855:
1856: const char * XMLCALL
1857: XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1858: {
1859: #ifdef XML_CONTEXT_BYTES
1860: if (eventPtr && buffer) {
1861: *offset = (int)(eventPtr - buffer);
1862: *size = (int)(bufferEnd - buffer);
1863: return buffer;
1864: }
1865: #endif /* defined XML_CONTEXT_BYTES */
1866: return (char *) 0;
1867: }
1868:
1869: XML_Size XMLCALL
1870: XML_GetCurrentLineNumber(XML_Parser parser)
1871: {
1872: if (eventPtr && eventPtr >= positionPtr) {
1873: XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1874: positionPtr = eventPtr;
1875: }
1876: return position.lineNumber + 1;
1877: }
1878:
1879: XML_Size XMLCALL
1880: XML_GetCurrentColumnNumber(XML_Parser parser)
1881: {
1882: if (eventPtr && eventPtr >= positionPtr) {
1883: XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1884: positionPtr = eventPtr;
1885: }
1886: return position.columnNumber;
1887: }
1888:
1889: void XMLCALL
1890: XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1891: {
1892: FREE(model);
1893: }
1894:
1895: void * XMLCALL
1896: XML_MemMalloc(XML_Parser parser, size_t size)
1897: {
1898: return MALLOC(size);
1899: }
1900:
1901: void * XMLCALL
1902: XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1903: {
1904: return REALLOC(ptr, size);
1905: }
1906:
1907: void XMLCALL
1908: XML_MemFree(XML_Parser parser, void *ptr)
1909: {
1910: FREE(ptr);
1911: }
1912:
1913: void XMLCALL
1914: XML_DefaultCurrent(XML_Parser parser)
1915: {
1916: if (defaultHandler) {
1917: if (openInternalEntities)
1918: reportDefault(parser,
1919: internalEncoding,
1920: openInternalEntities->internalEventPtr,
1921: openInternalEntities->internalEventEndPtr);
1922: else
1923: reportDefault(parser, encoding, eventPtr, eventEndPtr);
1924: }
1925: }
1926:
1927: const XML_LChar * XMLCALL
1928: XML_ErrorString(enum XML_Error code)
1929: {
1930: static const XML_LChar* const message[] = {
1931: 0,
1932: XML_L("out of memory"),
1933: XML_L("syntax error"),
1934: XML_L("no element found"),
1935: XML_L("not well-formed (invalid token)"),
1936: XML_L("unclosed token"),
1937: XML_L("partial character"),
1938: XML_L("mismatched tag"),
1939: XML_L("duplicate attribute"),
1940: XML_L("junk after document element"),
1941: XML_L("illegal parameter entity reference"),
1942: XML_L("undefined entity"),
1943: XML_L("recursive entity reference"),
1944: XML_L("asynchronous entity"),
1945: XML_L("reference to invalid character number"),
1946: XML_L("reference to binary entity"),
1947: XML_L("reference to external entity in attribute"),
1948: XML_L("XML or text declaration not at start of entity"),
1949: XML_L("unknown encoding"),
1950: XML_L("encoding specified in XML declaration is incorrect"),
1951: XML_L("unclosed CDATA section"),
1952: XML_L("error in processing external entity reference"),
1953: XML_L("document is not standalone"),
1954: XML_L("unexpected parser state - please send a bug report"),
1955: XML_L("entity declared in parameter entity"),
1956: XML_L("requested feature requires XML_DTD support in Expat"),
1957: XML_L("cannot change setting once parsing has begun"),
1958: XML_L("unbound prefix"),
1959: XML_L("must not undeclare prefix"),
1960: XML_L("incomplete markup in parameter entity"),
1961: XML_L("XML declaration not well-formed"),
1962: XML_L("text declaration not well-formed"),
1963: XML_L("illegal character(s) in public id"),
1964: XML_L("parser suspended"),
1965: XML_L("parser not suspended"),
1966: XML_L("parsing aborted"),
1967: XML_L("parsing finished"),
1968: XML_L("cannot suspend in external parameter entity"),
1969: XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1970: XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1971: XML_L("prefix must not be bound to one of the reserved namespace names")
1972: };
1973: if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1974: return message[code];
1975: return NULL;
1976: }
1977:
1978: const XML_LChar * XMLCALL
1979: XML_ExpatVersion(void) {
1980:
1981: /* V1 is used to string-ize the version number. However, it would
1982: string-ize the actual version macro *names* unless we get them
1983: substituted before being passed to V1. CPP is defined to expand
1984: a macro, then rescan for more expansions. Thus, we use V2 to expand
1985: the version macros, then CPP will expand the resulting V1() macro
1986: with the correct numerals. */
1987: /* ### I'm assuming cpp is portable in this respect... */
1988:
1989: #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1990: #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1991:
1992: return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1993:
1994: #undef V1
1995: #undef V2
1996: }
1997:
1998: XML_Expat_Version XMLCALL
1999: XML_ExpatVersionInfo(void)
2000: {
2001: XML_Expat_Version version;
2002:
2003: version.major = XML_MAJOR_VERSION;
2004: version.minor = XML_MINOR_VERSION;
2005: version.micro = XML_MICRO_VERSION;
2006:
2007: return version;
2008: }
2009:
2010: const XML_Feature * XMLCALL
2011: XML_GetFeatureList(void)
2012: {
2013: static const XML_Feature features[] = {
2014: {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2015: sizeof(XML_Char)},
2016: {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2017: sizeof(XML_LChar)},
2018: #ifdef XML_UNICODE
2019: {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2020: #endif
2021: #ifdef XML_UNICODE_WCHAR_T
2022: {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2023: #endif
2024: #ifdef XML_DTD
2025: {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2026: #endif
2027: #ifdef XML_CONTEXT_BYTES
2028: {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2029: XML_CONTEXT_BYTES},
2030: #endif
2031: #ifdef XML_MIN_SIZE
2032: {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2033: #endif
2034: #ifdef XML_NS
2035: {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2036: #endif
2037: #ifdef XML_LARGE_SIZE
2038: {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
1.1.1.2 ! misho 2039: #endif
! 2040: #ifdef XML_ATTR_INFO
! 2041: {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
! 2042: #endif
1.1 misho 2043: {XML_FEATURE_END, NULL, 0}
2044: };
2045:
2046: return features;
2047: }
2048:
2049: /* Initially tag->rawName always points into the parse buffer;
2050: for those TAG instances opened while the current parse buffer was
2051: processed, and not yet closed, we need to store tag->rawName in a more
2052: permanent location, since the parse buffer is about to be discarded.
2053: */
2054: static XML_Bool
2055: storeRawNames(XML_Parser parser)
2056: {
2057: TAG *tag = tagStack;
2058: while (tag) {
2059: int bufSize;
2060: int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2061: char *rawNameBuf = tag->buf + nameLen;
2062: /* Stop if already stored. Since tagStack is a stack, we can stop
2063: at the first entry that has already been copied; everything
2064: below it in the stack is already been accounted for in a
2065: previous call to this function.
2066: */
2067: if (tag->rawName == rawNameBuf)
2068: break;
2069: /* For re-use purposes we need to ensure that the
2070: size of tag->buf is a multiple of sizeof(XML_Char).
2071: */
2072: bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2073: if (bufSize > tag->bufEnd - tag->buf) {
2074: char *temp = (char *)REALLOC(tag->buf, bufSize);
2075: if (temp == NULL)
2076: return XML_FALSE;
2077: /* if tag->name.str points to tag->buf (only when namespace
2078: processing is off) then we have to update it
2079: */
2080: if (tag->name.str == (XML_Char *)tag->buf)
2081: tag->name.str = (XML_Char *)temp;
2082: /* if tag->name.localPart is set (when namespace processing is on)
2083: then update it as well, since it will always point into tag->buf
2084: */
2085: if (tag->name.localPart)
2086: tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2087: (XML_Char *)tag->buf);
2088: tag->buf = temp;
2089: tag->bufEnd = temp + bufSize;
2090: rawNameBuf = temp + nameLen;
2091: }
2092: memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2093: tag->rawName = rawNameBuf;
2094: tag = tag->parent;
2095: }
2096: return XML_TRUE;
2097: }
2098:
2099: static enum XML_Error PTRCALL
2100: contentProcessor(XML_Parser parser,
2101: const char *start,
2102: const char *end,
2103: const char **endPtr)
2104: {
1.1.1.2 ! misho 2105: enum XML_Error result = doContent(parser, 0, encoding, start, end,
1.1 misho 2106: endPtr, (XML_Bool)!ps_finalBuffer);
2107: if (result == XML_ERROR_NONE) {
2108: if (!storeRawNames(parser))
2109: return XML_ERROR_NO_MEMORY;
2110: }
2111: return result;
2112: }
2113:
2114: static enum XML_Error PTRCALL
2115: externalEntityInitProcessor(XML_Parser parser,
2116: const char *start,
2117: const char *end,
2118: const char **endPtr)
2119: {
2120: enum XML_Error result = initializeEncoding(parser);
2121: if (result != XML_ERROR_NONE)
2122: return result;
2123: processor = externalEntityInitProcessor2;
2124: return externalEntityInitProcessor2(parser, start, end, endPtr);
2125: }
2126:
2127: static enum XML_Error PTRCALL
2128: externalEntityInitProcessor2(XML_Parser parser,
2129: const char *start,
2130: const char *end,
2131: const char **endPtr)
2132: {
2133: const char *next = start; /* XmlContentTok doesn't always set the last arg */
2134: int tok = XmlContentTok(encoding, start, end, &next);
2135: switch (tok) {
2136: case XML_TOK_BOM:
2137: /* If we are at the end of the buffer, this would cause the next stage,
2138: i.e. externalEntityInitProcessor3, to pass control directly to
2139: doContent (by detecting XML_TOK_NONE) without processing any xml text
2140: declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2141: */
2142: if (next == end && !ps_finalBuffer) {
2143: *endPtr = next;
2144: return XML_ERROR_NONE;
2145: }
2146: start = next;
2147: break;
2148: case XML_TOK_PARTIAL:
2149: if (!ps_finalBuffer) {
2150: *endPtr = start;
2151: return XML_ERROR_NONE;
2152: }
2153: eventPtr = start;
2154: return XML_ERROR_UNCLOSED_TOKEN;
2155: case XML_TOK_PARTIAL_CHAR:
2156: if (!ps_finalBuffer) {
2157: *endPtr = start;
2158: return XML_ERROR_NONE;
2159: }
2160: eventPtr = start;
2161: return XML_ERROR_PARTIAL_CHAR;
2162: }
2163: processor = externalEntityInitProcessor3;
2164: return externalEntityInitProcessor3(parser, start, end, endPtr);
2165: }
2166:
2167: static enum XML_Error PTRCALL
2168: externalEntityInitProcessor3(XML_Parser parser,
2169: const char *start,
2170: const char *end,
2171: const char **endPtr)
2172: {
2173: int tok;
2174: const char *next = start; /* XmlContentTok doesn't always set the last arg */
2175: eventPtr = start;
2176: tok = XmlContentTok(encoding, start, end, &next);
2177: eventEndPtr = next;
2178:
2179: switch (tok) {
2180: case XML_TOK_XML_DECL:
2181: {
2182: enum XML_Error result;
2183: result = processXmlDecl(parser, 1, start, next);
2184: if (result != XML_ERROR_NONE)
2185: return result;
2186: switch (ps_parsing) {
1.1.1.2 ! misho 2187: case XML_SUSPENDED:
1.1 misho 2188: *endPtr = next;
2189: return XML_ERROR_NONE;
2190: case XML_FINISHED:
2191: return XML_ERROR_ABORTED;
2192: default:
2193: start = next;
2194: }
2195: }
2196: break;
2197: case XML_TOK_PARTIAL:
2198: if (!ps_finalBuffer) {
2199: *endPtr = start;
2200: return XML_ERROR_NONE;
2201: }
2202: return XML_ERROR_UNCLOSED_TOKEN;
2203: case XML_TOK_PARTIAL_CHAR:
2204: if (!ps_finalBuffer) {
2205: *endPtr = start;
2206: return XML_ERROR_NONE;
2207: }
2208: return XML_ERROR_PARTIAL_CHAR;
2209: }
2210: processor = externalEntityContentProcessor;
2211: tagLevel = 1;
2212: return externalEntityContentProcessor(parser, start, end, endPtr);
2213: }
2214:
2215: static enum XML_Error PTRCALL
2216: externalEntityContentProcessor(XML_Parser parser,
2217: const char *start,
2218: const char *end,
2219: const char **endPtr)
2220: {
1.1.1.2 ! misho 2221: enum XML_Error result = doContent(parser, 1, encoding, start, end,
1.1 misho 2222: endPtr, (XML_Bool)!ps_finalBuffer);
2223: if (result == XML_ERROR_NONE) {
2224: if (!storeRawNames(parser))
2225: return XML_ERROR_NO_MEMORY;
2226: }
2227: return result;
2228: }
2229:
2230: static enum XML_Error
2231: doContent(XML_Parser parser,
2232: int startTagLevel,
2233: const ENCODING *enc,
2234: const char *s,
2235: const char *end,
2236: const char **nextPtr,
2237: XML_Bool haveMore)
2238: {
2239: /* save one level of indirection */
1.1.1.2 ! misho 2240: DTD * const dtd = _dtd;
1.1 misho 2241:
2242: const char **eventPP;
2243: const char **eventEndPP;
2244: if (enc == encoding) {
2245: eventPP = &eventPtr;
2246: eventEndPP = &eventEndPtr;
2247: }
2248: else {
2249: eventPP = &(openInternalEntities->internalEventPtr);
2250: eventEndPP = &(openInternalEntities->internalEventEndPtr);
2251: }
2252: *eventPP = s;
2253:
2254: for (;;) {
2255: const char *next = s; /* XmlContentTok doesn't always set the last arg */
2256: int tok = XmlContentTok(enc, s, end, &next);
2257: *eventEndPP = next;
2258: switch (tok) {
2259: case XML_TOK_TRAILING_CR:
2260: if (haveMore) {
2261: *nextPtr = s;
2262: return XML_ERROR_NONE;
2263: }
2264: *eventEndPP = end;
2265: if (characterDataHandler) {
2266: XML_Char c = 0xA;
2267: characterDataHandler(handlerArg, &c, 1);
2268: }
2269: else if (defaultHandler)
2270: reportDefault(parser, enc, s, end);
1.1.1.2 ! misho 2271: /* We are at the end of the final buffer, should we check for
! 2272: XML_SUSPENDED, XML_FINISHED?
1.1 misho 2273: */
2274: if (startTagLevel == 0)
2275: return XML_ERROR_NO_ELEMENTS;
2276: if (tagLevel != startTagLevel)
2277: return XML_ERROR_ASYNC_ENTITY;
2278: *nextPtr = end;
2279: return XML_ERROR_NONE;
2280: case XML_TOK_NONE:
2281: if (haveMore) {
2282: *nextPtr = s;
2283: return XML_ERROR_NONE;
2284: }
2285: if (startTagLevel > 0) {
2286: if (tagLevel != startTagLevel)
2287: return XML_ERROR_ASYNC_ENTITY;
2288: *nextPtr = s;
2289: return XML_ERROR_NONE;
2290: }
2291: return XML_ERROR_NO_ELEMENTS;
2292: case XML_TOK_INVALID:
2293: *eventPP = next;
2294: return XML_ERROR_INVALID_TOKEN;
2295: case XML_TOK_PARTIAL:
2296: if (haveMore) {
2297: *nextPtr = s;
2298: return XML_ERROR_NONE;
2299: }
2300: return XML_ERROR_UNCLOSED_TOKEN;
2301: case XML_TOK_PARTIAL_CHAR:
2302: if (haveMore) {
2303: *nextPtr = s;
2304: return XML_ERROR_NONE;
2305: }
2306: return XML_ERROR_PARTIAL_CHAR;
2307: case XML_TOK_ENTITY_REF:
2308: {
2309: const XML_Char *name;
2310: ENTITY *entity;
2311: XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2312: s + enc->minBytesPerChar,
2313: next - enc->minBytesPerChar);
2314: if (ch) {
2315: if (characterDataHandler)
2316: characterDataHandler(handlerArg, &ch, 1);
2317: else if (defaultHandler)
2318: reportDefault(parser, enc, s, next);
2319: break;
2320: }
2321: name = poolStoreString(&dtd->pool, enc,
2322: s + enc->minBytesPerChar,
2323: next - enc->minBytesPerChar);
2324: if (!name)
2325: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 2326: entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
1.1 misho 2327: poolDiscard(&dtd->pool);
2328: /* First, determine if a check for an existing declaration is needed;
2329: if yes, check that the entity exists, and that it is internal,
2330: otherwise call the skipped entity or default handler.
2331: */
2332: if (!dtd->hasParamEntityRefs || dtd->standalone) {
2333: if (!entity)
2334: return XML_ERROR_UNDEFINED_ENTITY;
2335: else if (!entity->is_internal)
2336: return XML_ERROR_ENTITY_DECLARED_IN_PE;
2337: }
2338: else if (!entity) {
2339: if (skippedEntityHandler)
2340: skippedEntityHandler(handlerArg, name, 0);
2341: else if (defaultHandler)
2342: reportDefault(parser, enc, s, next);
2343: break;
2344: }
2345: if (entity->open)
2346: return XML_ERROR_RECURSIVE_ENTITY_REF;
2347: if (entity->notation)
2348: return XML_ERROR_BINARY_ENTITY_REF;
2349: if (entity->textPtr) {
2350: enum XML_Error result;
2351: if (!defaultExpandInternalEntities) {
2352: if (skippedEntityHandler)
2353: skippedEntityHandler(handlerArg, entity->name, 0);
2354: else if (defaultHandler)
2355: reportDefault(parser, enc, s, next);
2356: break;
2357: }
2358: result = processInternalEntity(parser, entity, XML_FALSE);
2359: if (result != XML_ERROR_NONE)
2360: return result;
2361: }
2362: else if (externalEntityRefHandler) {
2363: const XML_Char *context;
2364: entity->open = XML_TRUE;
2365: context = getContext(parser);
2366: entity->open = XML_FALSE;
2367: if (!context)
2368: return XML_ERROR_NO_MEMORY;
2369: if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2370: context,
2371: entity->base,
2372: entity->systemId,
2373: entity->publicId))
2374: return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2375: poolDiscard(&tempPool);
2376: }
2377: else if (defaultHandler)
2378: reportDefault(parser, enc, s, next);
2379: break;
2380: }
2381: case XML_TOK_START_TAG_NO_ATTS:
2382: /* fall through */
2383: case XML_TOK_START_TAG_WITH_ATTS:
2384: {
2385: TAG *tag;
2386: enum XML_Error result;
2387: XML_Char *toPtr;
2388: if (freeTagList) {
2389: tag = freeTagList;
2390: freeTagList = freeTagList->parent;
2391: }
2392: else {
2393: tag = (TAG *)MALLOC(sizeof(TAG));
2394: if (!tag)
2395: return XML_ERROR_NO_MEMORY;
2396: tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2397: if (!tag->buf) {
2398: FREE(tag);
2399: return XML_ERROR_NO_MEMORY;
2400: }
2401: tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2402: }
2403: tag->bindings = NULL;
2404: tag->parent = tagStack;
2405: tagStack = tag;
2406: tag->name.localPart = NULL;
2407: tag->name.prefix = NULL;
2408: tag->rawName = s + enc->minBytesPerChar;
2409: tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2410: ++tagLevel;
2411: {
2412: const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2413: const char *fromPtr = tag->rawName;
2414: toPtr = (XML_Char *)tag->buf;
2415: for (;;) {
2416: int bufSize;
2417: int convLen;
2418: XmlConvert(enc,
2419: &fromPtr, rawNameEnd,
2420: (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2421: convLen = (int)(toPtr - (XML_Char *)tag->buf);
2422: if (fromPtr == rawNameEnd) {
2423: tag->name.strLen = convLen;
2424: break;
2425: }
2426: bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2427: {
2428: char *temp = (char *)REALLOC(tag->buf, bufSize);
2429: if (temp == NULL)
2430: return XML_ERROR_NO_MEMORY;
2431: tag->buf = temp;
2432: tag->bufEnd = temp + bufSize;
2433: toPtr = (XML_Char *)temp + convLen;
2434: }
2435: }
2436: }
2437: tag->name.str = (XML_Char *)tag->buf;
2438: *toPtr = XML_T('\0');
2439: result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2440: if (result)
2441: return result;
2442: if (startElementHandler)
2443: startElementHandler(handlerArg, tag->name.str,
2444: (const XML_Char **)atts);
2445: else if (defaultHandler)
2446: reportDefault(parser, enc, s, next);
2447: poolClear(&tempPool);
2448: break;
2449: }
2450: case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2451: /* fall through */
2452: case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2453: {
2454: const char *rawName = s + enc->minBytesPerChar;
2455: enum XML_Error result;
2456: BINDING *bindings = NULL;
2457: XML_Bool noElmHandlers = XML_TRUE;
2458: TAG_NAME name;
2459: name.str = poolStoreString(&tempPool, enc, rawName,
2460: rawName + XmlNameLength(enc, rawName));
2461: if (!name.str)
2462: return XML_ERROR_NO_MEMORY;
2463: poolFinish(&tempPool);
2464: result = storeAtts(parser, enc, s, &name, &bindings);
2465: if (result)
2466: return result;
2467: poolFinish(&tempPool);
2468: if (startElementHandler) {
2469: startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2470: noElmHandlers = XML_FALSE;
2471: }
2472: if (endElementHandler) {
2473: if (startElementHandler)
2474: *eventPP = *eventEndPP;
2475: endElementHandler(handlerArg, name.str);
2476: noElmHandlers = XML_FALSE;
2477: }
2478: if (noElmHandlers && defaultHandler)
2479: reportDefault(parser, enc, s, next);
2480: poolClear(&tempPool);
2481: while (bindings) {
2482: BINDING *b = bindings;
2483: if (endNamespaceDeclHandler)
2484: endNamespaceDeclHandler(handlerArg, b->prefix->name);
2485: bindings = bindings->nextTagBinding;
2486: b->nextTagBinding = freeBindingList;
2487: freeBindingList = b;
2488: b->prefix->binding = b->prevPrefixBinding;
2489: }
2490: }
2491: if (tagLevel == 0)
2492: return epilogProcessor(parser, next, end, nextPtr);
2493: break;
2494: case XML_TOK_END_TAG:
2495: if (tagLevel == startTagLevel)
2496: return XML_ERROR_ASYNC_ENTITY;
2497: else {
2498: int len;
2499: const char *rawName;
2500: TAG *tag = tagStack;
2501: tagStack = tag->parent;
2502: tag->parent = freeTagList;
2503: freeTagList = tag;
2504: rawName = s + enc->minBytesPerChar*2;
2505: len = XmlNameLength(enc, rawName);
2506: if (len != tag->rawNameLength
2507: || memcmp(tag->rawName, rawName, len) != 0) {
2508: *eventPP = rawName;
2509: return XML_ERROR_TAG_MISMATCH;
2510: }
2511: --tagLevel;
2512: if (endElementHandler) {
2513: const XML_Char *localPart;
2514: const XML_Char *prefix;
2515: XML_Char *uri;
2516: localPart = tag->name.localPart;
2517: if (ns && localPart) {
2518: /* localPart and prefix may have been overwritten in
2519: tag->name.str, since this points to the binding->uri
2520: buffer which gets re-used; so we have to add them again
2521: */
2522: uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2523: /* don't need to check for space - already done in storeAtts() */
2524: while (*localPart) *uri++ = *localPart++;
2525: prefix = (XML_Char *)tag->name.prefix;
2526: if (ns_triplets && prefix) {
2527: *uri++ = namespaceSeparator;
2528: while (*prefix) *uri++ = *prefix++;
2529: }
2530: *uri = XML_T('\0');
2531: }
2532: endElementHandler(handlerArg, tag->name.str);
2533: }
2534: else if (defaultHandler)
2535: reportDefault(parser, enc, s, next);
2536: while (tag->bindings) {
2537: BINDING *b = tag->bindings;
2538: if (endNamespaceDeclHandler)
2539: endNamespaceDeclHandler(handlerArg, b->prefix->name);
2540: tag->bindings = tag->bindings->nextTagBinding;
2541: b->nextTagBinding = freeBindingList;
2542: freeBindingList = b;
2543: b->prefix->binding = b->prevPrefixBinding;
2544: }
2545: if (tagLevel == 0)
2546: return epilogProcessor(parser, next, end, nextPtr);
2547: }
2548: break;
2549: case XML_TOK_CHAR_REF:
2550: {
2551: int n = XmlCharRefNumber(enc, s);
2552: if (n < 0)
2553: return XML_ERROR_BAD_CHAR_REF;
2554: if (characterDataHandler) {
2555: XML_Char buf[XML_ENCODE_MAX];
2556: characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2557: }
2558: else if (defaultHandler)
2559: reportDefault(parser, enc, s, next);
2560: }
2561: break;
2562: case XML_TOK_XML_DECL:
2563: return XML_ERROR_MISPLACED_XML_PI;
2564: case XML_TOK_DATA_NEWLINE:
2565: if (characterDataHandler) {
2566: XML_Char c = 0xA;
2567: characterDataHandler(handlerArg, &c, 1);
2568: }
2569: else if (defaultHandler)
2570: reportDefault(parser, enc, s, next);
2571: break;
2572: case XML_TOK_CDATA_SECT_OPEN:
2573: {
2574: enum XML_Error result;
2575: if (startCdataSectionHandler)
2576: startCdataSectionHandler(handlerArg);
2577: #if 0
2578: /* Suppose you doing a transformation on a document that involves
2579: changing only the character data. You set up a defaultHandler
2580: and a characterDataHandler. The defaultHandler simply copies
2581: characters through. The characterDataHandler does the
2582: transformation and writes the characters out escaping them as
2583: necessary. This case will fail to work if we leave out the
2584: following two lines (because & and < inside CDATA sections will
2585: be incorrectly escaped).
2586:
2587: However, now we have a start/endCdataSectionHandler, so it seems
2588: easier to let the user deal with this.
2589: */
2590: else if (characterDataHandler)
2591: characterDataHandler(handlerArg, dataBuf, 0);
2592: #endif
2593: else if (defaultHandler)
2594: reportDefault(parser, enc, s, next);
2595: result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2596: if (result != XML_ERROR_NONE)
2597: return result;
2598: else if (!next) {
2599: processor = cdataSectionProcessor;
2600: return result;
2601: }
2602: }
2603: break;
2604: case XML_TOK_TRAILING_RSQB:
2605: if (haveMore) {
2606: *nextPtr = s;
2607: return XML_ERROR_NONE;
2608: }
2609: if (characterDataHandler) {
2610: if (MUST_CONVERT(enc, s)) {
2611: ICHAR *dataPtr = (ICHAR *)dataBuf;
2612: XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2613: characterDataHandler(handlerArg, dataBuf,
2614: (int)(dataPtr - (ICHAR *)dataBuf));
2615: }
2616: else
2617: characterDataHandler(handlerArg,
2618: (XML_Char *)s,
2619: (int)((XML_Char *)end - (XML_Char *)s));
2620: }
2621: else if (defaultHandler)
2622: reportDefault(parser, enc, s, end);
1.1.1.2 ! misho 2623: /* We are at the end of the final buffer, should we check for
! 2624: XML_SUSPENDED, XML_FINISHED?
1.1 misho 2625: */
2626: if (startTagLevel == 0) {
2627: *eventPP = end;
2628: return XML_ERROR_NO_ELEMENTS;
2629: }
2630: if (tagLevel != startTagLevel) {
2631: *eventPP = end;
2632: return XML_ERROR_ASYNC_ENTITY;
2633: }
2634: *nextPtr = end;
2635: return XML_ERROR_NONE;
1.1.1.2 ! misho 2636: case XML_TOK_DATA_CHARS:
1.1 misho 2637: {
2638: XML_CharacterDataHandler charDataHandler = characterDataHandler;
2639: if (charDataHandler) {
2640: if (MUST_CONVERT(enc, s)) {
2641: for (;;) {
2642: ICHAR *dataPtr = (ICHAR *)dataBuf;
2643: XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2644: *eventEndPP = s;
2645: charDataHandler(handlerArg, dataBuf,
2646: (int)(dataPtr - (ICHAR *)dataBuf));
2647: if (s == next)
2648: break;
2649: *eventPP = s;
2650: }
2651: }
2652: else
2653: charDataHandler(handlerArg,
2654: (XML_Char *)s,
2655: (int)((XML_Char *)next - (XML_Char *)s));
2656: }
2657: else if (defaultHandler)
2658: reportDefault(parser, enc, s, next);
2659: }
2660: break;
2661: case XML_TOK_PI:
2662: if (!reportProcessingInstruction(parser, enc, s, next))
2663: return XML_ERROR_NO_MEMORY;
2664: break;
2665: case XML_TOK_COMMENT:
2666: if (!reportComment(parser, enc, s, next))
2667: return XML_ERROR_NO_MEMORY;
2668: break;
2669: default:
2670: if (defaultHandler)
2671: reportDefault(parser, enc, s, next);
2672: break;
2673: }
2674: *eventPP = s = next;
2675: switch (ps_parsing) {
1.1.1.2 ! misho 2676: case XML_SUSPENDED:
1.1 misho 2677: *nextPtr = next;
2678: return XML_ERROR_NONE;
2679: case XML_FINISHED:
2680: return XML_ERROR_ABORTED;
2681: default: ;
2682: }
2683: }
2684: /* not reached */
2685: }
2686:
2687: /* Precondition: all arguments must be non-NULL;
2688: Purpose:
2689: - normalize attributes
2690: - check attributes for well-formedness
2691: - generate namespace aware attribute names (URI, prefix)
2692: - build list of attributes for startElementHandler
2693: - default attributes
2694: - process namespace declarations (check and report them)
2695: - generate namespace aware element name (URI, prefix)
2696: */
2697: static enum XML_Error
2698: storeAtts(XML_Parser parser, const ENCODING *enc,
2699: const char *attStr, TAG_NAME *tagNamePtr,
2700: BINDING **bindingsPtr)
2701: {
2702: DTD * const dtd = _dtd; /* save one level of indirection */
2703: ELEMENT_TYPE *elementType;
2704: int nDefaultAtts;
2705: const XML_Char **appAtts; /* the attribute list for the application */
2706: int attIndex = 0;
2707: int prefixLen;
2708: int i;
2709: int n;
2710: XML_Char *uri;
2711: int nPrefixes = 0;
2712: BINDING *binding;
2713: const XML_Char *localPart;
2714:
2715: /* lookup the element type name */
1.1.1.2 ! misho 2716: elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
1.1 misho 2717: if (!elementType) {
2718: const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2719: if (!name)
2720: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 2721: elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
1.1 misho 2722: sizeof(ELEMENT_TYPE));
2723: if (!elementType)
2724: return XML_ERROR_NO_MEMORY;
2725: if (ns && !setElementTypePrefix(parser, elementType))
2726: return XML_ERROR_NO_MEMORY;
2727: }
2728: nDefaultAtts = elementType->nDefaultAtts;
2729:
2730: /* get the attributes from the tokenizer */
2731: n = XmlGetAttributes(enc, attStr, attsSize, atts);
2732: if (n + nDefaultAtts > attsSize) {
2733: int oldAttsSize = attsSize;
2734: ATTRIBUTE *temp;
1.1.1.2 ! misho 2735: #ifdef XML_ATTR_INFO
! 2736: XML_AttrInfo *temp2;
! 2737: #endif
1.1 misho 2738: attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2739: temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2740: if (temp == NULL)
2741: return XML_ERROR_NO_MEMORY;
2742: atts = temp;
1.1.1.2 ! misho 2743: #ifdef XML_ATTR_INFO
! 2744: temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
! 2745: if (temp2 == NULL)
! 2746: return XML_ERROR_NO_MEMORY;
! 2747: attInfo = temp2;
! 2748: #endif
1.1 misho 2749: if (n > oldAttsSize)
2750: XmlGetAttributes(enc, attStr, n, atts);
2751: }
2752:
2753: appAtts = (const XML_Char **)atts;
2754: for (i = 0; i < n; i++) {
1.1.1.2 ! misho 2755: ATTRIBUTE *currAtt = &atts[i];
! 2756: #ifdef XML_ATTR_INFO
! 2757: XML_AttrInfo *currAttInfo = &attInfo[i];
! 2758: #endif
1.1 misho 2759: /* add the name and value to the attribute list */
1.1.1.2 ! misho 2760: ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
! 2761: currAtt->name
! 2762: + XmlNameLength(enc, currAtt->name));
1.1 misho 2763: if (!attId)
2764: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 2765: #ifdef XML_ATTR_INFO
! 2766: currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
! 2767: currAttInfo->nameEnd = currAttInfo->nameStart +
! 2768: XmlNameLength(enc, currAtt->name);
! 2769: currAttInfo->valueStart = parseEndByteIndex -
! 2770: (parseEndPtr - currAtt->valuePtr);
! 2771: currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
! 2772: #endif
1.1 misho 2773: /* Detect duplicate attributes by their QNames. This does not work when
2774: namespace processing is turned on and different prefixes for the same
2775: namespace are used. For this case we have a check further down.
2776: */
2777: if ((attId->name)[-1]) {
2778: if (enc == encoding)
2779: eventPtr = atts[i].name;
2780: return XML_ERROR_DUPLICATE_ATTRIBUTE;
2781: }
2782: (attId->name)[-1] = 1;
2783: appAtts[attIndex++] = attId->name;
2784: if (!atts[i].normalized) {
2785: enum XML_Error result;
2786: XML_Bool isCdata = XML_TRUE;
2787:
2788: /* figure out whether declared as other than CDATA */
2789: if (attId->maybeTokenized) {
2790: int j;
2791: for (j = 0; j < nDefaultAtts; j++) {
2792: if (attId == elementType->defaultAtts[j].id) {
2793: isCdata = elementType->defaultAtts[j].isCdata;
2794: break;
2795: }
2796: }
2797: }
2798:
2799: /* normalize the attribute value */
2800: result = storeAttributeValue(parser, enc, isCdata,
2801: atts[i].valuePtr, atts[i].valueEnd,
2802: &tempPool);
2803: if (result)
2804: return result;
2805: appAtts[attIndex] = poolStart(&tempPool);
2806: poolFinish(&tempPool);
2807: }
2808: else {
2809: /* the value did not need normalizing */
2810: appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2811: atts[i].valueEnd);
2812: if (appAtts[attIndex] == 0)
2813: return XML_ERROR_NO_MEMORY;
2814: poolFinish(&tempPool);
2815: }
2816: /* handle prefixed attribute names */
2817: if (attId->prefix) {
2818: if (attId->xmlns) {
2819: /* deal with namespace declarations here */
2820: enum XML_Error result = addBinding(parser, attId->prefix, attId,
2821: appAtts[attIndex], bindingsPtr);
2822: if (result)
2823: return result;
2824: --attIndex;
2825: }
2826: else {
2827: /* deal with other prefixed names later */
2828: attIndex++;
2829: nPrefixes++;
2830: (attId->name)[-1] = 2;
2831: }
2832: }
2833: else
2834: attIndex++;
2835: }
2836:
2837: /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2838: nSpecifiedAtts = attIndex;
2839: if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2840: for (i = 0; i < attIndex; i += 2)
2841: if (appAtts[i] == elementType->idAtt->name) {
2842: idAttIndex = i;
2843: break;
2844: }
2845: }
2846: else
2847: idAttIndex = -1;
2848:
2849: /* do attribute defaulting */
2850: for (i = 0; i < nDefaultAtts; i++) {
2851: const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2852: if (!(da->id->name)[-1] && da->value) {
2853: if (da->id->prefix) {
2854: if (da->id->xmlns) {
2855: enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2856: da->value, bindingsPtr);
2857: if (result)
2858: return result;
2859: }
2860: else {
2861: (da->id->name)[-1] = 2;
2862: nPrefixes++;
2863: appAtts[attIndex++] = da->id->name;
2864: appAtts[attIndex++] = da->value;
2865: }
2866: }
2867: else {
2868: (da->id->name)[-1] = 1;
2869: appAtts[attIndex++] = da->id->name;
2870: appAtts[attIndex++] = da->value;
2871: }
2872: }
2873: }
2874: appAtts[attIndex] = 0;
2875:
2876: /* expand prefixed attribute names, check for duplicates,
2877: and clear flags that say whether attributes were specified */
2878: i = 0;
2879: if (nPrefixes) {
2880: int j; /* hash table index */
2881: unsigned long version = nsAttsVersion;
2882: int nsAttsSize = (int)1 << nsAttsPower;
2883: /* size of hash table must be at least 2 * (# of prefixed attributes) */
2884: if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2885: NS_ATT *temp;
2886: /* hash table size must also be a power of 2 and >= 8 */
2887: while (nPrefixes >> nsAttsPower++);
2888: if (nsAttsPower < 3)
2889: nsAttsPower = 3;
2890: nsAttsSize = (int)1 << nsAttsPower;
2891: temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2892: if (!temp)
2893: return XML_ERROR_NO_MEMORY;
2894: nsAtts = temp;
2895: version = 0; /* force re-initialization of nsAtts hash table */
2896: }
2897: /* using a version flag saves us from initializing nsAtts every time */
2898: if (!version) { /* initialize version flags when version wraps around */
2899: version = INIT_ATTS_VERSION;
2900: for (j = nsAttsSize; j != 0; )
2901: nsAtts[--j].version = version;
2902: }
2903: nsAttsVersion = --version;
2904:
2905: /* expand prefixed names and check for duplicates */
2906: for (; i < attIndex; i += 2) {
2907: const XML_Char *s = appAtts[i];
2908: if (s[-1] == 2) { /* prefixed */
2909: ATTRIBUTE_ID *id;
2910: const BINDING *b;
1.1.1.2 ! misho 2911: unsigned long uriHash = hash_secret_salt;
1.1 misho 2912: ((XML_Char *)s)[-1] = 0; /* clear flag */
1.1.1.2 ! misho 2913: id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
1.1 misho 2914: b = id->prefix->binding;
2915: if (!b)
2916: return XML_ERROR_UNBOUND_PREFIX;
2917:
2918: /* as we expand the name we also calculate its hash value */
2919: for (j = 0; j < b->uriLen; j++) {
2920: const XML_Char c = b->uri[j];
2921: if (!poolAppendChar(&tempPool, c))
2922: return XML_ERROR_NO_MEMORY;
2923: uriHash = CHAR_HASH(uriHash, c);
2924: }
2925: while (*s++ != XML_T(ASCII_COLON))
2926: ;
2927: do { /* copies null terminator */
2928: const XML_Char c = *s;
2929: if (!poolAppendChar(&tempPool, *s))
2930: return XML_ERROR_NO_MEMORY;
2931: uriHash = CHAR_HASH(uriHash, c);
2932: } while (*s++);
2933:
2934: { /* Check hash table for duplicate of expanded name (uriName).
1.1.1.2 ! misho 2935: Derived from code in lookup(parser, HASH_TABLE *table, ...).
1.1 misho 2936: */
2937: unsigned char step = 0;
2938: unsigned long mask = nsAttsSize - 1;
2939: j = uriHash & mask; /* index into hash table */
2940: while (nsAtts[j].version == version) {
2941: /* for speed we compare stored hash values first */
2942: if (uriHash == nsAtts[j].hash) {
2943: const XML_Char *s1 = poolStart(&tempPool);
2944: const XML_Char *s2 = nsAtts[j].uriName;
2945: /* s1 is null terminated, but not s2 */
2946: for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2947: if (*s1 == 0)
2948: return XML_ERROR_DUPLICATE_ATTRIBUTE;
2949: }
2950: if (!step)
2951: step = PROBE_STEP(uriHash, mask, nsAttsPower);
2952: j < step ? (j += nsAttsSize - step) : (j -= step);
2953: }
2954: }
2955:
2956: if (ns_triplets) { /* append namespace separator and prefix */
2957: tempPool.ptr[-1] = namespaceSeparator;
2958: s = b->prefix->name;
2959: do {
2960: if (!poolAppendChar(&tempPool, *s))
2961: return XML_ERROR_NO_MEMORY;
2962: } while (*s++);
2963: }
2964:
2965: /* store expanded name in attribute list */
2966: s = poolStart(&tempPool);
2967: poolFinish(&tempPool);
2968: appAtts[i] = s;
2969:
2970: /* fill empty slot with new version, uriName and hash value */
2971: nsAtts[j].version = version;
2972: nsAtts[j].hash = uriHash;
2973: nsAtts[j].uriName = s;
2974:
2975: if (!--nPrefixes) {
2976: i += 2;
2977: break;
2978: }
2979: }
2980: else /* not prefixed */
2981: ((XML_Char *)s)[-1] = 0; /* clear flag */
2982: }
2983: }
2984: /* clear flags for the remaining attributes */
2985: for (; i < attIndex; i += 2)
2986: ((XML_Char *)(appAtts[i]))[-1] = 0;
2987: for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2988: binding->attId->name[-1] = 0;
2989:
2990: if (!ns)
2991: return XML_ERROR_NONE;
2992:
2993: /* expand the element type name */
2994: if (elementType->prefix) {
2995: binding = elementType->prefix->binding;
2996: if (!binding)
2997: return XML_ERROR_UNBOUND_PREFIX;
2998: localPart = tagNamePtr->str;
2999: while (*localPart++ != XML_T(ASCII_COLON))
3000: ;
3001: }
3002: else if (dtd->defaultPrefix.binding) {
3003: binding = dtd->defaultPrefix.binding;
3004: localPart = tagNamePtr->str;
3005: }
3006: else
3007: return XML_ERROR_NONE;
3008: prefixLen = 0;
3009: if (ns_triplets && binding->prefix->name) {
3010: for (; binding->prefix->name[prefixLen++];)
3011: ; /* prefixLen includes null terminator */
3012: }
3013: tagNamePtr->localPart = localPart;
3014: tagNamePtr->uriLen = binding->uriLen;
3015: tagNamePtr->prefix = binding->prefix->name;
3016: tagNamePtr->prefixLen = prefixLen;
3017: for (i = 0; localPart[i++];)
3018: ; /* i includes null terminator */
3019: n = i + binding->uriLen + prefixLen;
3020: if (n > binding->uriAlloc) {
3021: TAG *p;
3022: uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3023: if (!uri)
3024: return XML_ERROR_NO_MEMORY;
3025: binding->uriAlloc = n + EXPAND_SPARE;
3026: memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3027: for (p = tagStack; p; p = p->parent)
3028: if (p->name.str == binding->uri)
3029: p->name.str = uri;
3030: FREE(binding->uri);
3031: binding->uri = uri;
3032: }
3033: /* if namespaceSeparator != '\0' then uri includes it already */
3034: uri = binding->uri + binding->uriLen;
3035: memcpy(uri, localPart, i * sizeof(XML_Char));
3036: /* we always have a namespace separator between localPart and prefix */
3037: if (prefixLen) {
3038: uri += i - 1;
3039: *uri = namespaceSeparator; /* replace null terminator */
3040: memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3041: }
3042: tagNamePtr->str = binding->uri;
3043: return XML_ERROR_NONE;
3044: }
3045:
3046: /* addBinding() overwrites the value of prefix->binding without checking.
3047: Therefore one must keep track of the old value outside of addBinding().
3048: */
3049: static enum XML_Error
3050: addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3051: const XML_Char *uri, BINDING **bindingsPtr)
3052: {
3053: static const XML_Char xmlNamespace[] = {
3054: ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3055: ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
1.1.1.2 ! misho 3056: ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
1.1 misho 3057: ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3058: ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3059: ASCII_e, '\0'
3060: };
1.1.1.2 ! misho 3061: static const int xmlLen =
1.1 misho 3062: (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3063: static const XML_Char xmlnsNamespace[] = {
3064: ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3065: ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
1.1.1.2 ! misho 3066: ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
! 3067: ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
1.1 misho 3068: ASCII_SLASH, '\0'
3069: };
1.1.1.2 ! misho 3070: static const int xmlnsLen =
1.1 misho 3071: (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3072:
3073: XML_Bool mustBeXML = XML_FALSE;
3074: XML_Bool isXML = XML_TRUE;
3075: XML_Bool isXMLNS = XML_TRUE;
1.1.1.2 ! misho 3076:
1.1 misho 3077: BINDING *b;
3078: int len;
3079:
3080: /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3081: if (*uri == XML_T('\0') && prefix->name)
3082: return XML_ERROR_UNDECLARING_PREFIX;
3083:
3084: if (prefix->name
3085: && prefix->name[0] == XML_T(ASCII_x)
3086: && prefix->name[1] == XML_T(ASCII_m)
3087: && prefix->name[2] == XML_T(ASCII_l)) {
3088:
3089: /* Not allowed to bind xmlns */
3090: if (prefix->name[3] == XML_T(ASCII_n)
3091: && prefix->name[4] == XML_T(ASCII_s)
3092: && prefix->name[5] == XML_T('\0'))
3093: return XML_ERROR_RESERVED_PREFIX_XMLNS;
3094:
3095: if (prefix->name[3] == XML_T('\0'))
3096: mustBeXML = XML_TRUE;
3097: }
3098:
3099: for (len = 0; uri[len]; len++) {
3100: if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3101: isXML = XML_FALSE;
3102:
1.1.1.2 ! misho 3103: if (!mustBeXML && isXMLNS
1.1 misho 3104: && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3105: isXMLNS = XML_FALSE;
3106: }
3107: isXML = isXML && len == xmlLen;
3108: isXMLNS = isXMLNS && len == xmlnsLen;
3109:
3110: if (mustBeXML != isXML)
3111: return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3112: : XML_ERROR_RESERVED_NAMESPACE_URI;
3113:
3114: if (isXMLNS)
3115: return XML_ERROR_RESERVED_NAMESPACE_URI;
3116:
3117: if (namespaceSeparator)
3118: len++;
3119: if (freeBindingList) {
3120: b = freeBindingList;
3121: if (len > b->uriAlloc) {
3122: XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3123: sizeof(XML_Char) * (len + EXPAND_SPARE));
3124: if (temp == NULL)
3125: return XML_ERROR_NO_MEMORY;
3126: b->uri = temp;
3127: b->uriAlloc = len + EXPAND_SPARE;
3128: }
3129: freeBindingList = b->nextTagBinding;
3130: }
3131: else {
3132: b = (BINDING *)MALLOC(sizeof(BINDING));
3133: if (!b)
3134: return XML_ERROR_NO_MEMORY;
3135: b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3136: if (!b->uri) {
3137: FREE(b);
3138: return XML_ERROR_NO_MEMORY;
3139: }
3140: b->uriAlloc = len + EXPAND_SPARE;
3141: }
3142: b->uriLen = len;
3143: memcpy(b->uri, uri, len * sizeof(XML_Char));
3144: if (namespaceSeparator)
3145: b->uri[len - 1] = namespaceSeparator;
3146: b->prefix = prefix;
3147: b->attId = attId;
3148: b->prevPrefixBinding = prefix->binding;
3149: /* NULL binding when default namespace undeclared */
3150: if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3151: prefix->binding = NULL;
3152: else
3153: prefix->binding = b;
3154: b->nextTagBinding = *bindingsPtr;
3155: *bindingsPtr = b;
3156: /* if attId == NULL then we are not starting a namespace scope */
3157: if (attId && startNamespaceDeclHandler)
3158: startNamespaceDeclHandler(handlerArg, prefix->name,
3159: prefix->binding ? uri : 0);
3160: return XML_ERROR_NONE;
3161: }
3162:
3163: /* The idea here is to avoid using stack for each CDATA section when
3164: the whole file is parsed with one call.
3165: */
3166: static enum XML_Error PTRCALL
3167: cdataSectionProcessor(XML_Parser parser,
3168: const char *start,
3169: const char *end,
3170: const char **endPtr)
3171: {
3172: enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3173: endPtr, (XML_Bool)!ps_finalBuffer);
3174: if (result != XML_ERROR_NONE)
3175: return result;
3176: if (start) {
3177: if (parentParser) { /* we are parsing an external entity */
3178: processor = externalEntityContentProcessor;
3179: return externalEntityContentProcessor(parser, start, end, endPtr);
3180: }
3181: else {
3182: processor = contentProcessor;
3183: return contentProcessor(parser, start, end, endPtr);
3184: }
3185: }
3186: return result;
3187: }
3188:
3189: /* startPtr gets set to non-null if the section is closed, and to null if
3190: the section is not yet closed.
3191: */
3192: static enum XML_Error
3193: doCdataSection(XML_Parser parser,
3194: const ENCODING *enc,
3195: const char **startPtr,
3196: const char *end,
3197: const char **nextPtr,
3198: XML_Bool haveMore)
3199: {
3200: const char *s = *startPtr;
3201: const char **eventPP;
3202: const char **eventEndPP;
3203: if (enc == encoding) {
3204: eventPP = &eventPtr;
3205: *eventPP = s;
3206: eventEndPP = &eventEndPtr;
3207: }
3208: else {
3209: eventPP = &(openInternalEntities->internalEventPtr);
3210: eventEndPP = &(openInternalEntities->internalEventEndPtr);
3211: }
3212: *eventPP = s;
3213: *startPtr = NULL;
3214:
3215: for (;;) {
3216: const char *next;
3217: int tok = XmlCdataSectionTok(enc, s, end, &next);
3218: *eventEndPP = next;
3219: switch (tok) {
3220: case XML_TOK_CDATA_SECT_CLOSE:
3221: if (endCdataSectionHandler)
3222: endCdataSectionHandler(handlerArg);
3223: #if 0
3224: /* see comment under XML_TOK_CDATA_SECT_OPEN */
3225: else if (characterDataHandler)
3226: characterDataHandler(handlerArg, dataBuf, 0);
3227: #endif
3228: else if (defaultHandler)
3229: reportDefault(parser, enc, s, next);
3230: *startPtr = next;
3231: *nextPtr = next;
3232: if (ps_parsing == XML_FINISHED)
3233: return XML_ERROR_ABORTED;
3234: else
3235: return XML_ERROR_NONE;
3236: case XML_TOK_DATA_NEWLINE:
3237: if (characterDataHandler) {
3238: XML_Char c = 0xA;
3239: characterDataHandler(handlerArg, &c, 1);
3240: }
3241: else if (defaultHandler)
3242: reportDefault(parser, enc, s, next);
3243: break;
3244: case XML_TOK_DATA_CHARS:
3245: {
3246: XML_CharacterDataHandler charDataHandler = characterDataHandler;
3247: if (charDataHandler) {
3248: if (MUST_CONVERT(enc, s)) {
3249: for (;;) {
3250: ICHAR *dataPtr = (ICHAR *)dataBuf;
3251: XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3252: *eventEndPP = next;
3253: charDataHandler(handlerArg, dataBuf,
3254: (int)(dataPtr - (ICHAR *)dataBuf));
3255: if (s == next)
3256: break;
3257: *eventPP = s;
3258: }
3259: }
3260: else
3261: charDataHandler(handlerArg,
3262: (XML_Char *)s,
3263: (int)((XML_Char *)next - (XML_Char *)s));
3264: }
3265: else if (defaultHandler)
3266: reportDefault(parser, enc, s, next);
3267: }
3268: break;
3269: case XML_TOK_INVALID:
3270: *eventPP = next;
3271: return XML_ERROR_INVALID_TOKEN;
3272: case XML_TOK_PARTIAL_CHAR:
3273: if (haveMore) {
3274: *nextPtr = s;
3275: return XML_ERROR_NONE;
3276: }
3277: return XML_ERROR_PARTIAL_CHAR;
3278: case XML_TOK_PARTIAL:
3279: case XML_TOK_NONE:
3280: if (haveMore) {
3281: *nextPtr = s;
3282: return XML_ERROR_NONE;
3283: }
3284: return XML_ERROR_UNCLOSED_CDATA_SECTION;
3285: default:
3286: *eventPP = next;
3287: return XML_ERROR_UNEXPECTED_STATE;
3288: }
3289:
3290: *eventPP = s = next;
3291: switch (ps_parsing) {
3292: case XML_SUSPENDED:
3293: *nextPtr = next;
3294: return XML_ERROR_NONE;
3295: case XML_FINISHED:
3296: return XML_ERROR_ABORTED;
3297: default: ;
3298: }
3299: }
3300: /* not reached */
3301: }
3302:
3303: #ifdef XML_DTD
3304:
3305: /* The idea here is to avoid using stack for each IGNORE section when
3306: the whole file is parsed with one call.
3307: */
3308: static enum XML_Error PTRCALL
3309: ignoreSectionProcessor(XML_Parser parser,
3310: const char *start,
3311: const char *end,
3312: const char **endPtr)
3313: {
1.1.1.2 ! misho 3314: enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
1.1 misho 3315: endPtr, (XML_Bool)!ps_finalBuffer);
3316: if (result != XML_ERROR_NONE)
3317: return result;
3318: if (start) {
3319: processor = prologProcessor;
3320: return prologProcessor(parser, start, end, endPtr);
3321: }
3322: return result;
3323: }
3324:
3325: /* startPtr gets set to non-null is the section is closed, and to null
3326: if the section is not yet closed.
3327: */
3328: static enum XML_Error
3329: doIgnoreSection(XML_Parser parser,
3330: const ENCODING *enc,
3331: const char **startPtr,
3332: const char *end,
3333: const char **nextPtr,
3334: XML_Bool haveMore)
3335: {
3336: const char *next;
3337: int tok;
3338: const char *s = *startPtr;
3339: const char **eventPP;
3340: const char **eventEndPP;
3341: if (enc == encoding) {
3342: eventPP = &eventPtr;
3343: *eventPP = s;
3344: eventEndPP = &eventEndPtr;
3345: }
3346: else {
3347: eventPP = &(openInternalEntities->internalEventPtr);
3348: eventEndPP = &(openInternalEntities->internalEventEndPtr);
3349: }
3350: *eventPP = s;
3351: *startPtr = NULL;
3352: tok = XmlIgnoreSectionTok(enc, s, end, &next);
3353: *eventEndPP = next;
3354: switch (tok) {
3355: case XML_TOK_IGNORE_SECT:
3356: if (defaultHandler)
3357: reportDefault(parser, enc, s, next);
3358: *startPtr = next;
3359: *nextPtr = next;
3360: if (ps_parsing == XML_FINISHED)
3361: return XML_ERROR_ABORTED;
3362: else
3363: return XML_ERROR_NONE;
3364: case XML_TOK_INVALID:
3365: *eventPP = next;
3366: return XML_ERROR_INVALID_TOKEN;
3367: case XML_TOK_PARTIAL_CHAR:
3368: if (haveMore) {
3369: *nextPtr = s;
3370: return XML_ERROR_NONE;
3371: }
3372: return XML_ERROR_PARTIAL_CHAR;
3373: case XML_TOK_PARTIAL:
3374: case XML_TOK_NONE:
3375: if (haveMore) {
3376: *nextPtr = s;
3377: return XML_ERROR_NONE;
3378: }
3379: return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3380: default:
3381: *eventPP = next;
3382: return XML_ERROR_UNEXPECTED_STATE;
3383: }
3384: /* not reached */
3385: }
3386:
3387: #endif /* XML_DTD */
3388:
3389: static enum XML_Error
3390: initializeEncoding(XML_Parser parser)
3391: {
3392: const char *s;
3393: #ifdef XML_UNICODE
3394: char encodingBuf[128];
3395: if (!protocolEncodingName)
3396: s = NULL;
3397: else {
3398: int i;
3399: for (i = 0; protocolEncodingName[i]; i++) {
3400: if (i == sizeof(encodingBuf) - 1
3401: || (protocolEncodingName[i] & ~0x7f) != 0) {
3402: encodingBuf[0] = '\0';
3403: break;
3404: }
3405: encodingBuf[i] = (char)protocolEncodingName[i];
3406: }
3407: encodingBuf[i] = '\0';
3408: s = encodingBuf;
3409: }
3410: #else
3411: s = protocolEncodingName;
3412: #endif
3413: if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3414: return XML_ERROR_NONE;
3415: return handleUnknownEncoding(parser, protocolEncodingName);
3416: }
3417:
3418: static enum XML_Error
3419: processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3420: const char *s, const char *next)
3421: {
3422: const char *encodingName = NULL;
3423: const XML_Char *storedEncName = NULL;
3424: const ENCODING *newEncoding = NULL;
3425: const char *version = NULL;
3426: const char *versionend;
3427: const XML_Char *storedversion = NULL;
3428: int standalone = -1;
3429: if (!(ns
3430: ? XmlParseXmlDeclNS
3431: : XmlParseXmlDecl)(isGeneralTextEntity,
3432: encoding,
3433: s,
3434: next,
3435: &eventPtr,
3436: &version,
3437: &versionend,
3438: &encodingName,
3439: &newEncoding,
3440: &standalone)) {
3441: if (isGeneralTextEntity)
3442: return XML_ERROR_TEXT_DECL;
3443: else
3444: return XML_ERROR_XML_DECL;
3445: }
3446: if (!isGeneralTextEntity && standalone == 1) {
3447: _dtd->standalone = XML_TRUE;
3448: #ifdef XML_DTD
3449: if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3450: paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3451: #endif /* XML_DTD */
3452: }
3453: if (xmlDeclHandler) {
3454: if (encodingName != NULL) {
3455: storedEncName = poolStoreString(&temp2Pool,
3456: encoding,
3457: encodingName,
3458: encodingName
3459: + XmlNameLength(encoding, encodingName));
3460: if (!storedEncName)
3461: return XML_ERROR_NO_MEMORY;
3462: poolFinish(&temp2Pool);
3463: }
3464: if (version) {
3465: storedversion = poolStoreString(&temp2Pool,
3466: encoding,
3467: version,
3468: versionend - encoding->minBytesPerChar);
3469: if (!storedversion)
3470: return XML_ERROR_NO_MEMORY;
3471: }
3472: xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3473: }
3474: else if (defaultHandler)
3475: reportDefault(parser, encoding, s, next);
3476: if (protocolEncodingName == NULL) {
3477: if (newEncoding) {
3478: if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3479: eventPtr = encodingName;
3480: return XML_ERROR_INCORRECT_ENCODING;
3481: }
3482: encoding = newEncoding;
3483: }
3484: else if (encodingName) {
3485: enum XML_Error result;
3486: if (!storedEncName) {
3487: storedEncName = poolStoreString(
3488: &temp2Pool, encoding, encodingName,
3489: encodingName + XmlNameLength(encoding, encodingName));
3490: if (!storedEncName)
3491: return XML_ERROR_NO_MEMORY;
3492: }
3493: result = handleUnknownEncoding(parser, storedEncName);
3494: poolClear(&temp2Pool);
3495: if (result == XML_ERROR_UNKNOWN_ENCODING)
3496: eventPtr = encodingName;
3497: return result;
3498: }
3499: }
3500:
3501: if (storedEncName || storedversion)
3502: poolClear(&temp2Pool);
3503:
3504: return XML_ERROR_NONE;
3505: }
3506:
3507: static enum XML_Error
3508: handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3509: {
3510: if (unknownEncodingHandler) {
3511: XML_Encoding info;
3512: int i;
3513: for (i = 0; i < 256; i++)
3514: info.map[i] = -1;
3515: info.convert = NULL;
3516: info.data = NULL;
3517: info.release = NULL;
3518: if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3519: &info)) {
3520: ENCODING *enc;
3521: unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3522: if (!unknownEncodingMem) {
3523: if (info.release)
3524: info.release(info.data);
3525: return XML_ERROR_NO_MEMORY;
3526: }
3527: enc = (ns
3528: ? XmlInitUnknownEncodingNS
3529: : XmlInitUnknownEncoding)(unknownEncodingMem,
3530: info.map,
3531: info.convert,
3532: info.data);
3533: if (enc) {
3534: unknownEncodingData = info.data;
3535: unknownEncodingRelease = info.release;
3536: encoding = enc;
3537: return XML_ERROR_NONE;
3538: }
3539: }
3540: if (info.release != NULL)
3541: info.release(info.data);
3542: }
3543: return XML_ERROR_UNKNOWN_ENCODING;
3544: }
3545:
3546: static enum XML_Error PTRCALL
3547: prologInitProcessor(XML_Parser parser,
3548: const char *s,
3549: const char *end,
3550: const char **nextPtr)
3551: {
3552: enum XML_Error result = initializeEncoding(parser);
3553: if (result != XML_ERROR_NONE)
3554: return result;
3555: processor = prologProcessor;
3556: return prologProcessor(parser, s, end, nextPtr);
3557: }
3558:
3559: #ifdef XML_DTD
3560:
3561: static enum XML_Error PTRCALL
3562: externalParEntInitProcessor(XML_Parser parser,
3563: const char *s,
3564: const char *end,
3565: const char **nextPtr)
3566: {
3567: enum XML_Error result = initializeEncoding(parser);
3568: if (result != XML_ERROR_NONE)
3569: return result;
3570:
3571: /* we know now that XML_Parse(Buffer) has been called,
3572: so we consider the external parameter entity read */
3573: _dtd->paramEntityRead = XML_TRUE;
3574:
3575: if (prologState.inEntityValue) {
3576: processor = entityValueInitProcessor;
3577: return entityValueInitProcessor(parser, s, end, nextPtr);
3578: }
3579: else {
3580: processor = externalParEntProcessor;
3581: return externalParEntProcessor(parser, s, end, nextPtr);
3582: }
3583: }
3584:
3585: static enum XML_Error PTRCALL
3586: entityValueInitProcessor(XML_Parser parser,
3587: const char *s,
3588: const char *end,
3589: const char **nextPtr)
3590: {
3591: int tok;
3592: const char *start = s;
3593: const char *next = start;
3594: eventPtr = start;
3595:
1.1.1.2 ! misho 3596: for (;;) {
1.1 misho 3597: tok = XmlPrologTok(encoding, start, end, &next);
3598: eventEndPtr = next;
3599: if (tok <= 0) {
3600: if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3601: *nextPtr = s;
3602: return XML_ERROR_NONE;
3603: }
3604: switch (tok) {
3605: case XML_TOK_INVALID:
3606: return XML_ERROR_INVALID_TOKEN;
3607: case XML_TOK_PARTIAL:
3608: return XML_ERROR_UNCLOSED_TOKEN;
3609: case XML_TOK_PARTIAL_CHAR:
3610: return XML_ERROR_PARTIAL_CHAR;
3611: case XML_TOK_NONE: /* start == end */
3612: default:
3613: break;
3614: }
3615: /* found end of entity value - can store it now */
3616: return storeEntityValue(parser, encoding, s, end);
3617: }
3618: else if (tok == XML_TOK_XML_DECL) {
3619: enum XML_Error result;
3620: result = processXmlDecl(parser, 0, start, next);
3621: if (result != XML_ERROR_NONE)
3622: return result;
3623: switch (ps_parsing) {
1.1.1.2 ! misho 3624: case XML_SUSPENDED:
1.1 misho 3625: *nextPtr = next;
3626: return XML_ERROR_NONE;
3627: case XML_FINISHED:
3628: return XML_ERROR_ABORTED;
3629: default:
3630: *nextPtr = next;
3631: }
3632: /* stop scanning for text declaration - we found one */
3633: processor = entityValueProcessor;
3634: return entityValueProcessor(parser, next, end, nextPtr);
3635: }
3636: /* If we are at the end of the buffer, this would cause XmlPrologTok to
3637: return XML_TOK_NONE on the next call, which would then cause the
3638: function to exit with *nextPtr set to s - that is what we want for other
3639: tokens, but not for the BOM - we would rather like to skip it;
3640: then, when this routine is entered the next time, XmlPrologTok will
3641: return XML_TOK_INVALID, since the BOM is still in the buffer
3642: */
3643: else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3644: *nextPtr = next;
3645: return XML_ERROR_NONE;
3646: }
3647: start = next;
3648: eventPtr = start;
3649: }
3650: }
3651:
3652: static enum XML_Error PTRCALL
3653: externalParEntProcessor(XML_Parser parser,
3654: const char *s,
3655: const char *end,
3656: const char **nextPtr)
3657: {
3658: const char *next = s;
3659: int tok;
3660:
3661: tok = XmlPrologTok(encoding, s, end, &next);
3662: if (tok <= 0) {
3663: if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3664: *nextPtr = s;
3665: return XML_ERROR_NONE;
3666: }
3667: switch (tok) {
3668: case XML_TOK_INVALID:
3669: return XML_ERROR_INVALID_TOKEN;
3670: case XML_TOK_PARTIAL:
3671: return XML_ERROR_UNCLOSED_TOKEN;
3672: case XML_TOK_PARTIAL_CHAR:
3673: return XML_ERROR_PARTIAL_CHAR;
3674: case XML_TOK_NONE: /* start == end */
3675: default:
3676: break;
3677: }
3678: }
3679: /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3680: However, when parsing an external subset, doProlog will not accept a BOM
3681: as valid, and report a syntax error, so we have to skip the BOM
3682: */
3683: else if (tok == XML_TOK_BOM) {
3684: s = next;
3685: tok = XmlPrologTok(encoding, s, end, &next);
3686: }
3687:
3688: processor = prologProcessor;
1.1.1.2 ! misho 3689: return doProlog(parser, encoding, s, end, tok, next,
1.1 misho 3690: nextPtr, (XML_Bool)!ps_finalBuffer);
3691: }
3692:
3693: static enum XML_Error PTRCALL
3694: entityValueProcessor(XML_Parser parser,
3695: const char *s,
3696: const char *end,
3697: const char **nextPtr)
3698: {
3699: const char *start = s;
3700: const char *next = s;
3701: const ENCODING *enc = encoding;
3702: int tok;
3703:
3704: for (;;) {
3705: tok = XmlPrologTok(enc, start, end, &next);
3706: if (tok <= 0) {
3707: if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3708: *nextPtr = s;
3709: return XML_ERROR_NONE;
3710: }
3711: switch (tok) {
3712: case XML_TOK_INVALID:
3713: return XML_ERROR_INVALID_TOKEN;
3714: case XML_TOK_PARTIAL:
3715: return XML_ERROR_UNCLOSED_TOKEN;
3716: case XML_TOK_PARTIAL_CHAR:
3717: return XML_ERROR_PARTIAL_CHAR;
3718: case XML_TOK_NONE: /* start == end */
3719: default:
3720: break;
3721: }
3722: /* found end of entity value - can store it now */
3723: return storeEntityValue(parser, enc, s, end);
3724: }
3725: start = next;
3726: }
3727: }
3728:
3729: #endif /* XML_DTD */
3730:
3731: static enum XML_Error PTRCALL
3732: prologProcessor(XML_Parser parser,
3733: const char *s,
3734: const char *end,
3735: const char **nextPtr)
3736: {
3737: const char *next = s;
3738: int tok = XmlPrologTok(encoding, s, end, &next);
1.1.1.2 ! misho 3739: return doProlog(parser, encoding, s, end, tok, next,
1.1 misho 3740: nextPtr, (XML_Bool)!ps_finalBuffer);
3741: }
3742:
3743: static enum XML_Error
3744: doProlog(XML_Parser parser,
3745: const ENCODING *enc,
3746: const char *s,
3747: const char *end,
3748: int tok,
3749: const char *next,
3750: const char **nextPtr,
3751: XML_Bool haveMore)
3752: {
3753: #ifdef XML_DTD
3754: static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3755: #endif /* XML_DTD */
1.1.1.2 ! misho 3756: static const XML_Char atypeCDATA[] =
1.1 misho 3757: { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3758: static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3759: static const XML_Char atypeIDREF[] =
3760: { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3761: static const XML_Char atypeIDREFS[] =
3762: { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3763: static const XML_Char atypeENTITY[] =
3764: { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3765: static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3766: ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3767: static const XML_Char atypeNMTOKEN[] = {
3768: ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3769: static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3770: ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3771: static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3772: ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3773: static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3774: static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3775:
3776: /* save one level of indirection */
1.1.1.2 ! misho 3777: DTD * const dtd = _dtd;
1.1 misho 3778:
3779: const char **eventPP;
3780: const char **eventEndPP;
3781: enum XML_Content_Quant quant;
3782:
3783: if (enc == encoding) {
3784: eventPP = &eventPtr;
3785: eventEndPP = &eventEndPtr;
3786: }
3787: else {
3788: eventPP = &(openInternalEntities->internalEventPtr);
3789: eventEndPP = &(openInternalEntities->internalEventEndPtr);
3790: }
3791:
3792: for (;;) {
3793: int role;
3794: XML_Bool handleDefault = XML_TRUE;
3795: *eventPP = s;
3796: *eventEndPP = next;
3797: if (tok <= 0) {
3798: if (haveMore && tok != XML_TOK_INVALID) {
3799: *nextPtr = s;
3800: return XML_ERROR_NONE;
3801: }
3802: switch (tok) {
3803: case XML_TOK_INVALID:
3804: *eventPP = next;
3805: return XML_ERROR_INVALID_TOKEN;
3806: case XML_TOK_PARTIAL:
3807: return XML_ERROR_UNCLOSED_TOKEN;
3808: case XML_TOK_PARTIAL_CHAR:
3809: return XML_ERROR_PARTIAL_CHAR;
1.1.1.2 ! misho 3810: case -XML_TOK_PROLOG_S:
! 3811: tok = -tok;
! 3812: break;
1.1 misho 3813: case XML_TOK_NONE:
3814: #ifdef XML_DTD
3815: /* for internal PE NOT referenced between declarations */
3816: if (enc != encoding && !openInternalEntities->betweenDecl) {
3817: *nextPtr = s;
3818: return XML_ERROR_NONE;
3819: }
3820: /* WFC: PE Between Declarations - must check that PE contains
3821: complete markup, not only for external PEs, but also for
3822: internal PEs if the reference occurs between declarations.
3823: */
3824: if (isParamEntity || enc != encoding) {
3825: if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3826: == XML_ROLE_ERROR)
3827: return XML_ERROR_INCOMPLETE_PE;
3828: *nextPtr = s;
3829: return XML_ERROR_NONE;
3830: }
3831: #endif /* XML_DTD */
3832: return XML_ERROR_NO_ELEMENTS;
3833: default:
3834: tok = -tok;
3835: next = end;
3836: break;
3837: }
3838: }
3839: role = XmlTokenRole(&prologState, tok, s, next, enc);
3840: switch (role) {
3841: case XML_ROLE_XML_DECL:
3842: {
3843: enum XML_Error result = processXmlDecl(parser, 0, s, next);
3844: if (result != XML_ERROR_NONE)
3845: return result;
3846: enc = encoding;
3847: handleDefault = XML_FALSE;
3848: }
3849: break;
3850: case XML_ROLE_DOCTYPE_NAME:
3851: if (startDoctypeDeclHandler) {
3852: doctypeName = poolStoreString(&tempPool, enc, s, next);
3853: if (!doctypeName)
3854: return XML_ERROR_NO_MEMORY;
3855: poolFinish(&tempPool);
3856: doctypePubid = NULL;
3857: handleDefault = XML_FALSE;
3858: }
3859: doctypeSysid = NULL; /* always initialize to NULL */
3860: break;
3861: case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3862: if (startDoctypeDeclHandler) {
3863: startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3864: doctypePubid, 1);
3865: doctypeName = NULL;
3866: poolClear(&tempPool);
3867: handleDefault = XML_FALSE;
3868: }
3869: break;
3870: #ifdef XML_DTD
3871: case XML_ROLE_TEXT_DECL:
3872: {
3873: enum XML_Error result = processXmlDecl(parser, 1, s, next);
3874: if (result != XML_ERROR_NONE)
3875: return result;
3876: enc = encoding;
3877: handleDefault = XML_FALSE;
3878: }
3879: break;
3880: #endif /* XML_DTD */
3881: case XML_ROLE_DOCTYPE_PUBLIC_ID:
3882: #ifdef XML_DTD
3883: useForeignDTD = XML_FALSE;
1.1.1.2 ! misho 3884: declEntity = (ENTITY *)lookup(parser,
! 3885: &dtd->paramEntities,
1.1 misho 3886: externalSubsetName,
3887: sizeof(ENTITY));
3888: if (!declEntity)
3889: return XML_ERROR_NO_MEMORY;
3890: #endif /* XML_DTD */
3891: dtd->hasParamEntityRefs = XML_TRUE;
3892: if (startDoctypeDeclHandler) {
1.1.1.2 ! misho 3893: XML_Char *pubId;
1.1 misho 3894: if (!XmlIsPublicId(enc, s, next, eventPP))
3895: return XML_ERROR_PUBLICID;
1.1.1.2 ! misho 3896: pubId = poolStoreString(&tempPool, enc,
! 3897: s + enc->minBytesPerChar,
! 3898: next - enc->minBytesPerChar);
! 3899: if (!pubId)
1.1 misho 3900: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 3901: normalizePublicId(pubId);
1.1 misho 3902: poolFinish(&tempPool);
1.1.1.2 ! misho 3903: doctypePubid = pubId;
1.1 misho 3904: handleDefault = XML_FALSE;
3905: goto alreadyChecked;
3906: }
3907: /* fall through */
3908: case XML_ROLE_ENTITY_PUBLIC_ID:
3909: if (!XmlIsPublicId(enc, s, next, eventPP))
3910: return XML_ERROR_PUBLICID;
3911: alreadyChecked:
3912: if (dtd->keepProcessing && declEntity) {
3913: XML_Char *tem = poolStoreString(&dtd->pool,
3914: enc,
3915: s + enc->minBytesPerChar,
3916: next - enc->minBytesPerChar);
3917: if (!tem)
3918: return XML_ERROR_NO_MEMORY;
3919: normalizePublicId(tem);
3920: declEntity->publicId = tem;
3921: poolFinish(&dtd->pool);
3922: if (entityDeclHandler)
3923: handleDefault = XML_FALSE;
3924: }
3925: break;
3926: case XML_ROLE_DOCTYPE_CLOSE:
3927: if (doctypeName) {
3928: startDoctypeDeclHandler(handlerArg, doctypeName,
3929: doctypeSysid, doctypePubid, 0);
3930: poolClear(&tempPool);
3931: handleDefault = XML_FALSE;
3932: }
3933: /* doctypeSysid will be non-NULL in the case of a previous
3934: XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3935: was not set, indicating an external subset
3936: */
3937: #ifdef XML_DTD
3938: if (doctypeSysid || useForeignDTD) {
3939: XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3940: dtd->hasParamEntityRefs = XML_TRUE;
3941: if (paramEntityParsing && externalEntityRefHandler) {
1.1.1.2 ! misho 3942: ENTITY *entity = (ENTITY *)lookup(parser,
! 3943: &dtd->paramEntities,
1.1 misho 3944: externalSubsetName,
3945: sizeof(ENTITY));
3946: if (!entity)
3947: return XML_ERROR_NO_MEMORY;
3948: if (useForeignDTD)
3949: entity->base = curBase;
3950: dtd->paramEntityRead = XML_FALSE;
3951: if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3952: 0,
3953: entity->base,
3954: entity->systemId,
3955: entity->publicId))
3956: return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3957: if (dtd->paramEntityRead) {
1.1.1.2 ! misho 3958: if (!dtd->standalone &&
! 3959: notStandaloneHandler &&
1.1 misho 3960: !notStandaloneHandler(handlerArg))
3961: return XML_ERROR_NOT_STANDALONE;
3962: }
3963: /* if we didn't read the foreign DTD then this means that there
3964: is no external subset and we must reset dtd->hasParamEntityRefs
3965: */
3966: else if (!doctypeSysid)
3967: dtd->hasParamEntityRefs = hadParamEntityRefs;
3968: /* end of DTD - no need to update dtd->keepProcessing */
3969: }
3970: useForeignDTD = XML_FALSE;
3971: }
3972: #endif /* XML_DTD */
3973: if (endDoctypeDeclHandler) {
3974: endDoctypeDeclHandler(handlerArg);
3975: handleDefault = XML_FALSE;
3976: }
3977: break;
3978: case XML_ROLE_INSTANCE_START:
3979: #ifdef XML_DTD
3980: /* if there is no DOCTYPE declaration then now is the
3981: last chance to read the foreign DTD
3982: */
3983: if (useForeignDTD) {
3984: XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3985: dtd->hasParamEntityRefs = XML_TRUE;
3986: if (paramEntityParsing && externalEntityRefHandler) {
1.1.1.2 ! misho 3987: ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
1.1 misho 3988: externalSubsetName,
3989: sizeof(ENTITY));
3990: if (!entity)
3991: return XML_ERROR_NO_MEMORY;
3992: entity->base = curBase;
3993: dtd->paramEntityRead = XML_FALSE;
3994: if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3995: 0,
3996: entity->base,
3997: entity->systemId,
3998: entity->publicId))
3999: return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4000: if (dtd->paramEntityRead) {
4001: if (!dtd->standalone &&
4002: notStandaloneHandler &&
4003: !notStandaloneHandler(handlerArg))
4004: return XML_ERROR_NOT_STANDALONE;
4005: }
4006: /* if we didn't read the foreign DTD then this means that there
4007: is no external subset and we must reset dtd->hasParamEntityRefs
4008: */
4009: else
4010: dtd->hasParamEntityRefs = hadParamEntityRefs;
4011: /* end of DTD - no need to update dtd->keepProcessing */
4012: }
4013: }
4014: #endif /* XML_DTD */
4015: processor = contentProcessor;
4016: return contentProcessor(parser, s, end, nextPtr);
4017: case XML_ROLE_ATTLIST_ELEMENT_NAME:
4018: declElementType = getElementType(parser, enc, s, next);
4019: if (!declElementType)
4020: return XML_ERROR_NO_MEMORY;
4021: goto checkAttListDeclHandler;
4022: case XML_ROLE_ATTRIBUTE_NAME:
4023: declAttributeId = getAttributeId(parser, enc, s, next);
4024: if (!declAttributeId)
4025: return XML_ERROR_NO_MEMORY;
4026: declAttributeIsCdata = XML_FALSE;
4027: declAttributeType = NULL;
4028: declAttributeIsId = XML_FALSE;
4029: goto checkAttListDeclHandler;
4030: case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4031: declAttributeIsCdata = XML_TRUE;
4032: declAttributeType = atypeCDATA;
4033: goto checkAttListDeclHandler;
4034: case XML_ROLE_ATTRIBUTE_TYPE_ID:
4035: declAttributeIsId = XML_TRUE;
4036: declAttributeType = atypeID;
4037: goto checkAttListDeclHandler;
4038: case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4039: declAttributeType = atypeIDREF;
4040: goto checkAttListDeclHandler;
4041: case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4042: declAttributeType = atypeIDREFS;
4043: goto checkAttListDeclHandler;
4044: case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4045: declAttributeType = atypeENTITY;
4046: goto checkAttListDeclHandler;
4047: case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4048: declAttributeType = atypeENTITIES;
4049: goto checkAttListDeclHandler;
4050: case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4051: declAttributeType = atypeNMTOKEN;
4052: goto checkAttListDeclHandler;
4053: case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4054: declAttributeType = atypeNMTOKENS;
4055: checkAttListDeclHandler:
4056: if (dtd->keepProcessing && attlistDeclHandler)
4057: handleDefault = XML_FALSE;
4058: break;
4059: case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4060: case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4061: if (dtd->keepProcessing && attlistDeclHandler) {
4062: const XML_Char *prefix;
4063: if (declAttributeType) {
4064: prefix = enumValueSep;
4065: }
4066: else {
4067: prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4068: ? notationPrefix
4069: : enumValueStart);
4070: }
4071: if (!poolAppendString(&tempPool, prefix))
4072: return XML_ERROR_NO_MEMORY;
4073: if (!poolAppend(&tempPool, enc, s, next))
4074: return XML_ERROR_NO_MEMORY;
4075: declAttributeType = tempPool.start;
4076: handleDefault = XML_FALSE;
4077: }
4078: break;
4079: case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4080: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4081: if (dtd->keepProcessing) {
4082: if (!defineAttribute(declElementType, declAttributeId,
4083: declAttributeIsCdata, declAttributeIsId,
4084: 0, parser))
4085: return XML_ERROR_NO_MEMORY;
4086: if (attlistDeclHandler && declAttributeType) {
4087: if (*declAttributeType == XML_T(ASCII_LPAREN)
4088: || (*declAttributeType == XML_T(ASCII_N)
4089: && declAttributeType[1] == XML_T(ASCII_O))) {
4090: /* Enumerated or Notation type */
4091: if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4092: || !poolAppendChar(&tempPool, XML_T('\0')))
4093: return XML_ERROR_NO_MEMORY;
4094: declAttributeType = tempPool.start;
4095: poolFinish(&tempPool);
4096: }
4097: *eventEndPP = s;
4098: attlistDeclHandler(handlerArg, declElementType->name,
4099: declAttributeId->name, declAttributeType,
4100: 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4101: poolClear(&tempPool);
4102: handleDefault = XML_FALSE;
4103: }
4104: }
4105: break;
4106: case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4107: case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4108: if (dtd->keepProcessing) {
4109: const XML_Char *attVal;
4110: enum XML_Error result =
4111: storeAttributeValue(parser, enc, declAttributeIsCdata,
4112: s + enc->minBytesPerChar,
4113: next - enc->minBytesPerChar,
4114: &dtd->pool);
4115: if (result)
4116: return result;
4117: attVal = poolStart(&dtd->pool);
4118: poolFinish(&dtd->pool);
4119: /* ID attributes aren't allowed to have a default */
4120: if (!defineAttribute(declElementType, declAttributeId,
4121: declAttributeIsCdata, XML_FALSE, attVal, parser))
4122: return XML_ERROR_NO_MEMORY;
4123: if (attlistDeclHandler && declAttributeType) {
4124: if (*declAttributeType == XML_T(ASCII_LPAREN)
4125: || (*declAttributeType == XML_T(ASCII_N)
4126: && declAttributeType[1] == XML_T(ASCII_O))) {
4127: /* Enumerated or Notation type */
4128: if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4129: || !poolAppendChar(&tempPool, XML_T('\0')))
4130: return XML_ERROR_NO_MEMORY;
4131: declAttributeType = tempPool.start;
4132: poolFinish(&tempPool);
4133: }
4134: *eventEndPP = s;
4135: attlistDeclHandler(handlerArg, declElementType->name,
4136: declAttributeId->name, declAttributeType,
4137: attVal,
4138: role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4139: poolClear(&tempPool);
4140: handleDefault = XML_FALSE;
4141: }
4142: }
4143: break;
4144: case XML_ROLE_ENTITY_VALUE:
4145: if (dtd->keepProcessing) {
4146: enum XML_Error result = storeEntityValue(parser, enc,
4147: s + enc->minBytesPerChar,
4148: next - enc->minBytesPerChar);
4149: if (declEntity) {
4150: declEntity->textPtr = poolStart(&dtd->entityValuePool);
4151: declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4152: poolFinish(&dtd->entityValuePool);
4153: if (entityDeclHandler) {
4154: *eventEndPP = s;
4155: entityDeclHandler(handlerArg,
4156: declEntity->name,
4157: declEntity->is_param,
4158: declEntity->textPtr,
4159: declEntity->textLen,
4160: curBase, 0, 0, 0);
4161: handleDefault = XML_FALSE;
4162: }
4163: }
4164: else
4165: poolDiscard(&dtd->entityValuePool);
4166: if (result != XML_ERROR_NONE)
4167: return result;
4168: }
4169: break;
4170: case XML_ROLE_DOCTYPE_SYSTEM_ID:
4171: #ifdef XML_DTD
4172: useForeignDTD = XML_FALSE;
4173: #endif /* XML_DTD */
4174: dtd->hasParamEntityRefs = XML_TRUE;
4175: if (startDoctypeDeclHandler) {
4176: doctypeSysid = poolStoreString(&tempPool, enc,
4177: s + enc->minBytesPerChar,
4178: next - enc->minBytesPerChar);
4179: if (doctypeSysid == NULL)
4180: return XML_ERROR_NO_MEMORY;
4181: poolFinish(&tempPool);
4182: handleDefault = XML_FALSE;
4183: }
4184: #ifdef XML_DTD
4185: else
4186: /* use externalSubsetName to make doctypeSysid non-NULL
4187: for the case where no startDoctypeDeclHandler is set */
4188: doctypeSysid = externalSubsetName;
4189: #endif /* XML_DTD */
4190: if (!dtd->standalone
4191: #ifdef XML_DTD
4192: && !paramEntityParsing
4193: #endif /* XML_DTD */
4194: && notStandaloneHandler
4195: && !notStandaloneHandler(handlerArg))
4196: return XML_ERROR_NOT_STANDALONE;
4197: #ifndef XML_DTD
4198: break;
4199: #else /* XML_DTD */
4200: if (!declEntity) {
1.1.1.2 ! misho 4201: declEntity = (ENTITY *)lookup(parser,
! 4202: &dtd->paramEntities,
1.1 misho 4203: externalSubsetName,
4204: sizeof(ENTITY));
4205: if (!declEntity)
4206: return XML_ERROR_NO_MEMORY;
4207: declEntity->publicId = NULL;
4208: }
4209: /* fall through */
4210: #endif /* XML_DTD */
4211: case XML_ROLE_ENTITY_SYSTEM_ID:
4212: if (dtd->keepProcessing && declEntity) {
4213: declEntity->systemId = poolStoreString(&dtd->pool, enc,
4214: s + enc->minBytesPerChar,
4215: next - enc->minBytesPerChar);
4216: if (!declEntity->systemId)
4217: return XML_ERROR_NO_MEMORY;
4218: declEntity->base = curBase;
4219: poolFinish(&dtd->pool);
4220: if (entityDeclHandler)
4221: handleDefault = XML_FALSE;
4222: }
4223: break;
4224: case XML_ROLE_ENTITY_COMPLETE:
4225: if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4226: *eventEndPP = s;
4227: entityDeclHandler(handlerArg,
4228: declEntity->name,
4229: declEntity->is_param,
4230: 0,0,
4231: declEntity->base,
4232: declEntity->systemId,
4233: declEntity->publicId,
4234: 0);
4235: handleDefault = XML_FALSE;
4236: }
4237: break;
4238: case XML_ROLE_ENTITY_NOTATION_NAME:
4239: if (dtd->keepProcessing && declEntity) {
4240: declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4241: if (!declEntity->notation)
4242: return XML_ERROR_NO_MEMORY;
4243: poolFinish(&dtd->pool);
4244: if (unparsedEntityDeclHandler) {
4245: *eventEndPP = s;
4246: unparsedEntityDeclHandler(handlerArg,
4247: declEntity->name,
4248: declEntity->base,
4249: declEntity->systemId,
4250: declEntity->publicId,
4251: declEntity->notation);
4252: handleDefault = XML_FALSE;
4253: }
4254: else if (entityDeclHandler) {
4255: *eventEndPP = s;
4256: entityDeclHandler(handlerArg,
4257: declEntity->name,
4258: 0,0,0,
4259: declEntity->base,
4260: declEntity->systemId,
4261: declEntity->publicId,
4262: declEntity->notation);
4263: handleDefault = XML_FALSE;
4264: }
4265: }
4266: break;
4267: case XML_ROLE_GENERAL_ENTITY_NAME:
4268: {
4269: if (XmlPredefinedEntityName(enc, s, next)) {
4270: declEntity = NULL;
4271: break;
4272: }
4273: if (dtd->keepProcessing) {
4274: const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4275: if (!name)
4276: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 4277: declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
1.1 misho 4278: sizeof(ENTITY));
4279: if (!declEntity)
4280: return XML_ERROR_NO_MEMORY;
4281: if (declEntity->name != name) {
4282: poolDiscard(&dtd->pool);
4283: declEntity = NULL;
4284: }
4285: else {
4286: poolFinish(&dtd->pool);
4287: declEntity->publicId = NULL;
4288: declEntity->is_param = XML_FALSE;
4289: /* if we have a parent parser or are reading an internal parameter
4290: entity, then the entity declaration is not considered "internal"
4291: */
4292: declEntity->is_internal = !(parentParser || openInternalEntities);
4293: if (entityDeclHandler)
4294: handleDefault = XML_FALSE;
4295: }
4296: }
4297: else {
4298: poolDiscard(&dtd->pool);
4299: declEntity = NULL;
4300: }
4301: }
4302: break;
4303: case XML_ROLE_PARAM_ENTITY_NAME:
4304: #ifdef XML_DTD
4305: if (dtd->keepProcessing) {
4306: const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4307: if (!name)
4308: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 4309: declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
1.1 misho 4310: name, sizeof(ENTITY));
4311: if (!declEntity)
4312: return XML_ERROR_NO_MEMORY;
4313: if (declEntity->name != name) {
4314: poolDiscard(&dtd->pool);
4315: declEntity = NULL;
4316: }
4317: else {
4318: poolFinish(&dtd->pool);
4319: declEntity->publicId = NULL;
4320: declEntity->is_param = XML_TRUE;
4321: /* if we have a parent parser or are reading an internal parameter
4322: entity, then the entity declaration is not considered "internal"
4323: */
4324: declEntity->is_internal = !(parentParser || openInternalEntities);
4325: if (entityDeclHandler)
4326: handleDefault = XML_FALSE;
4327: }
4328: }
4329: else {
4330: poolDiscard(&dtd->pool);
4331: declEntity = NULL;
4332: }
4333: #else /* not XML_DTD */
4334: declEntity = NULL;
4335: #endif /* XML_DTD */
4336: break;
4337: case XML_ROLE_NOTATION_NAME:
4338: declNotationPublicId = NULL;
4339: declNotationName = NULL;
4340: if (notationDeclHandler) {
4341: declNotationName = poolStoreString(&tempPool, enc, s, next);
4342: if (!declNotationName)
4343: return XML_ERROR_NO_MEMORY;
4344: poolFinish(&tempPool);
4345: handleDefault = XML_FALSE;
4346: }
4347: break;
4348: case XML_ROLE_NOTATION_PUBLIC_ID:
4349: if (!XmlIsPublicId(enc, s, next, eventPP))
4350: return XML_ERROR_PUBLICID;
4351: if (declNotationName) { /* means notationDeclHandler != NULL */
4352: XML_Char *tem = poolStoreString(&tempPool,
4353: enc,
4354: s + enc->minBytesPerChar,
4355: next - enc->minBytesPerChar);
4356: if (!tem)
4357: return XML_ERROR_NO_MEMORY;
4358: normalizePublicId(tem);
4359: declNotationPublicId = tem;
4360: poolFinish(&tempPool);
4361: handleDefault = XML_FALSE;
4362: }
4363: break;
4364: case XML_ROLE_NOTATION_SYSTEM_ID:
4365: if (declNotationName && notationDeclHandler) {
4366: const XML_Char *systemId
4367: = poolStoreString(&tempPool, enc,
4368: s + enc->minBytesPerChar,
4369: next - enc->minBytesPerChar);
4370: if (!systemId)
4371: return XML_ERROR_NO_MEMORY;
4372: *eventEndPP = s;
4373: notationDeclHandler(handlerArg,
4374: declNotationName,
4375: curBase,
4376: systemId,
4377: declNotationPublicId);
4378: handleDefault = XML_FALSE;
4379: }
4380: poolClear(&tempPool);
4381: break;
4382: case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4383: if (declNotationPublicId && notationDeclHandler) {
4384: *eventEndPP = s;
4385: notationDeclHandler(handlerArg,
4386: declNotationName,
4387: curBase,
4388: 0,
4389: declNotationPublicId);
4390: handleDefault = XML_FALSE;
4391: }
4392: poolClear(&tempPool);
4393: break;
4394: case XML_ROLE_ERROR:
4395: switch (tok) {
4396: case XML_TOK_PARAM_ENTITY_REF:
4397: /* PE references in internal subset are
1.1.1.2 ! misho 4398: not allowed within declarations. */
1.1 misho 4399: return XML_ERROR_PARAM_ENTITY_REF;
4400: case XML_TOK_XML_DECL:
4401: return XML_ERROR_MISPLACED_XML_PI;
4402: default:
4403: return XML_ERROR_SYNTAX;
4404: }
4405: #ifdef XML_DTD
4406: case XML_ROLE_IGNORE_SECT:
4407: {
4408: enum XML_Error result;
4409: if (defaultHandler)
4410: reportDefault(parser, enc, s, next);
4411: handleDefault = XML_FALSE;
4412: result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4413: if (result != XML_ERROR_NONE)
4414: return result;
4415: else if (!next) {
4416: processor = ignoreSectionProcessor;
4417: return result;
4418: }
4419: }
4420: break;
4421: #endif /* XML_DTD */
4422: case XML_ROLE_GROUP_OPEN:
4423: if (prologState.level >= groupSize) {
4424: if (groupSize) {
4425: char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4426: if (temp == NULL)
4427: return XML_ERROR_NO_MEMORY;
4428: groupConnector = temp;
4429: if (dtd->scaffIndex) {
4430: int *temp = (int *)REALLOC(dtd->scaffIndex,
4431: groupSize * sizeof(int));
4432: if (temp == NULL)
4433: return XML_ERROR_NO_MEMORY;
4434: dtd->scaffIndex = temp;
4435: }
4436: }
4437: else {
4438: groupConnector = (char *)MALLOC(groupSize = 32);
4439: if (!groupConnector)
4440: return XML_ERROR_NO_MEMORY;
4441: }
4442: }
4443: groupConnector[prologState.level] = 0;
4444: if (dtd->in_eldecl) {
4445: int myindex = nextScaffoldPart(parser);
4446: if (myindex < 0)
4447: return XML_ERROR_NO_MEMORY;
4448: dtd->scaffIndex[dtd->scaffLevel] = myindex;
4449: dtd->scaffLevel++;
4450: dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4451: if (elementDeclHandler)
4452: handleDefault = XML_FALSE;
4453: }
4454: break;
4455: case XML_ROLE_GROUP_SEQUENCE:
4456: if (groupConnector[prologState.level] == ASCII_PIPE)
4457: return XML_ERROR_SYNTAX;
4458: groupConnector[prologState.level] = ASCII_COMMA;
4459: if (dtd->in_eldecl && elementDeclHandler)
4460: handleDefault = XML_FALSE;
4461: break;
4462: case XML_ROLE_GROUP_CHOICE:
4463: if (groupConnector[prologState.level] == ASCII_COMMA)
4464: return XML_ERROR_SYNTAX;
4465: if (dtd->in_eldecl
4466: && !groupConnector[prologState.level]
4467: && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4468: != XML_CTYPE_MIXED)
4469: ) {
4470: dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4471: = XML_CTYPE_CHOICE;
4472: if (elementDeclHandler)
4473: handleDefault = XML_FALSE;
4474: }
4475: groupConnector[prologState.level] = ASCII_PIPE;
4476: break;
4477: case XML_ROLE_PARAM_ENTITY_REF:
4478: #ifdef XML_DTD
4479: case XML_ROLE_INNER_PARAM_ENTITY_REF:
4480: dtd->hasParamEntityRefs = XML_TRUE;
4481: if (!paramEntityParsing)
4482: dtd->keepProcessing = dtd->standalone;
4483: else {
4484: const XML_Char *name;
4485: ENTITY *entity;
4486: name = poolStoreString(&dtd->pool, enc,
4487: s + enc->minBytesPerChar,
4488: next - enc->minBytesPerChar);
4489: if (!name)
4490: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 4491: entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
1.1 misho 4492: poolDiscard(&dtd->pool);
4493: /* first, determine if a check for an existing declaration is needed;
4494: if yes, check that the entity exists, and that it is internal,
4495: otherwise call the skipped entity handler
4496: */
4497: if (prologState.documentEntity &&
4498: (dtd->standalone
4499: ? !openInternalEntities
4500: : !dtd->hasParamEntityRefs)) {
4501: if (!entity)
4502: return XML_ERROR_UNDEFINED_ENTITY;
4503: else if (!entity->is_internal)
4504: return XML_ERROR_ENTITY_DECLARED_IN_PE;
4505: }
4506: else if (!entity) {
4507: dtd->keepProcessing = dtd->standalone;
4508: /* cannot report skipped entities in declarations */
4509: if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4510: skippedEntityHandler(handlerArg, name, 1);
4511: handleDefault = XML_FALSE;
4512: }
4513: break;
4514: }
4515: if (entity->open)
4516: return XML_ERROR_RECURSIVE_ENTITY_REF;
4517: if (entity->textPtr) {
4518: enum XML_Error result;
1.1.1.2 ! misho 4519: XML_Bool betweenDecl =
1.1 misho 4520: (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4521: result = processInternalEntity(parser, entity, betweenDecl);
4522: if (result != XML_ERROR_NONE)
4523: return result;
4524: handleDefault = XML_FALSE;
4525: break;
4526: }
4527: if (externalEntityRefHandler) {
4528: dtd->paramEntityRead = XML_FALSE;
4529: entity->open = XML_TRUE;
4530: if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4531: 0,
4532: entity->base,
4533: entity->systemId,
4534: entity->publicId)) {
4535: entity->open = XML_FALSE;
4536: return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4537: }
4538: entity->open = XML_FALSE;
4539: handleDefault = XML_FALSE;
4540: if (!dtd->paramEntityRead) {
4541: dtd->keepProcessing = dtd->standalone;
4542: break;
4543: }
4544: }
4545: else {
4546: dtd->keepProcessing = dtd->standalone;
4547: break;
4548: }
4549: }
4550: #endif /* XML_DTD */
4551: if (!dtd->standalone &&
4552: notStandaloneHandler &&
4553: !notStandaloneHandler(handlerArg))
4554: return XML_ERROR_NOT_STANDALONE;
4555: break;
4556:
4557: /* Element declaration stuff */
4558:
4559: case XML_ROLE_ELEMENT_NAME:
4560: if (elementDeclHandler) {
4561: declElementType = getElementType(parser, enc, s, next);
4562: if (!declElementType)
4563: return XML_ERROR_NO_MEMORY;
4564: dtd->scaffLevel = 0;
4565: dtd->scaffCount = 0;
4566: dtd->in_eldecl = XML_TRUE;
4567: handleDefault = XML_FALSE;
4568: }
4569: break;
4570:
4571: case XML_ROLE_CONTENT_ANY:
4572: case XML_ROLE_CONTENT_EMPTY:
4573: if (dtd->in_eldecl) {
4574: if (elementDeclHandler) {
4575: XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4576: if (!content)
4577: return XML_ERROR_NO_MEMORY;
4578: content->quant = XML_CQUANT_NONE;
4579: content->name = NULL;
4580: content->numchildren = 0;
4581: content->children = NULL;
4582: content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4583: XML_CTYPE_ANY :
4584: XML_CTYPE_EMPTY);
4585: *eventEndPP = s;
4586: elementDeclHandler(handlerArg, declElementType->name, content);
4587: handleDefault = XML_FALSE;
4588: }
4589: dtd->in_eldecl = XML_FALSE;
4590: }
4591: break;
4592:
4593: case XML_ROLE_CONTENT_PCDATA:
4594: if (dtd->in_eldecl) {
4595: dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4596: = XML_CTYPE_MIXED;
4597: if (elementDeclHandler)
4598: handleDefault = XML_FALSE;
4599: }
4600: break;
4601:
4602: case XML_ROLE_CONTENT_ELEMENT:
4603: quant = XML_CQUANT_NONE;
4604: goto elementContent;
4605: case XML_ROLE_CONTENT_ELEMENT_OPT:
4606: quant = XML_CQUANT_OPT;
4607: goto elementContent;
4608: case XML_ROLE_CONTENT_ELEMENT_REP:
4609: quant = XML_CQUANT_REP;
4610: goto elementContent;
4611: case XML_ROLE_CONTENT_ELEMENT_PLUS:
4612: quant = XML_CQUANT_PLUS;
4613: elementContent:
4614: if (dtd->in_eldecl) {
4615: ELEMENT_TYPE *el;
4616: const XML_Char *name;
4617: int nameLen;
4618: const char *nxt = (quant == XML_CQUANT_NONE
4619: ? next
4620: : next - enc->minBytesPerChar);
4621: int myindex = nextScaffoldPart(parser);
4622: if (myindex < 0)
4623: return XML_ERROR_NO_MEMORY;
4624: dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4625: dtd->scaffold[myindex].quant = quant;
4626: el = getElementType(parser, enc, s, nxt);
4627: if (!el)
4628: return XML_ERROR_NO_MEMORY;
4629: name = el->name;
4630: dtd->scaffold[myindex].name = name;
4631: nameLen = 0;
4632: for (; name[nameLen++]; );
4633: dtd->contentStringLen += nameLen;
4634: if (elementDeclHandler)
4635: handleDefault = XML_FALSE;
4636: }
4637: break;
4638:
4639: case XML_ROLE_GROUP_CLOSE:
4640: quant = XML_CQUANT_NONE;
4641: goto closeGroup;
4642: case XML_ROLE_GROUP_CLOSE_OPT:
4643: quant = XML_CQUANT_OPT;
4644: goto closeGroup;
4645: case XML_ROLE_GROUP_CLOSE_REP:
4646: quant = XML_CQUANT_REP;
4647: goto closeGroup;
4648: case XML_ROLE_GROUP_CLOSE_PLUS:
4649: quant = XML_CQUANT_PLUS;
4650: closeGroup:
4651: if (dtd->in_eldecl) {
4652: if (elementDeclHandler)
4653: handleDefault = XML_FALSE;
4654: dtd->scaffLevel--;
4655: dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4656: if (dtd->scaffLevel == 0) {
4657: if (!handleDefault) {
4658: XML_Content *model = build_model(parser);
4659: if (!model)
4660: return XML_ERROR_NO_MEMORY;
4661: *eventEndPP = s;
4662: elementDeclHandler(handlerArg, declElementType->name, model);
4663: }
4664: dtd->in_eldecl = XML_FALSE;
4665: dtd->contentStringLen = 0;
4666: }
4667: }
4668: break;
4669: /* End element declaration stuff */
4670:
4671: case XML_ROLE_PI:
4672: if (!reportProcessingInstruction(parser, enc, s, next))
4673: return XML_ERROR_NO_MEMORY;
4674: handleDefault = XML_FALSE;
4675: break;
4676: case XML_ROLE_COMMENT:
4677: if (!reportComment(parser, enc, s, next))
4678: return XML_ERROR_NO_MEMORY;
4679: handleDefault = XML_FALSE;
4680: break;
4681: case XML_ROLE_NONE:
4682: switch (tok) {
4683: case XML_TOK_BOM:
4684: handleDefault = XML_FALSE;
4685: break;
4686: }
4687: break;
4688: case XML_ROLE_DOCTYPE_NONE:
4689: if (startDoctypeDeclHandler)
4690: handleDefault = XML_FALSE;
4691: break;
4692: case XML_ROLE_ENTITY_NONE:
4693: if (dtd->keepProcessing && entityDeclHandler)
4694: handleDefault = XML_FALSE;
4695: break;
4696: case XML_ROLE_NOTATION_NONE:
4697: if (notationDeclHandler)
4698: handleDefault = XML_FALSE;
4699: break;
4700: case XML_ROLE_ATTLIST_NONE:
4701: if (dtd->keepProcessing && attlistDeclHandler)
4702: handleDefault = XML_FALSE;
4703: break;
4704: case XML_ROLE_ELEMENT_NONE:
4705: if (elementDeclHandler)
4706: handleDefault = XML_FALSE;
4707: break;
4708: } /* end of big switch */
4709:
4710: if (handleDefault && defaultHandler)
4711: reportDefault(parser, enc, s, next);
4712:
4713: switch (ps_parsing) {
1.1.1.2 ! misho 4714: case XML_SUSPENDED:
1.1 misho 4715: *nextPtr = next;
4716: return XML_ERROR_NONE;
4717: case XML_FINISHED:
4718: return XML_ERROR_ABORTED;
4719: default:
4720: s = next;
4721: tok = XmlPrologTok(enc, s, end, &next);
4722: }
4723: }
4724: /* not reached */
4725: }
4726:
4727: static enum XML_Error PTRCALL
4728: epilogProcessor(XML_Parser parser,
4729: const char *s,
4730: const char *end,
4731: const char **nextPtr)
4732: {
4733: processor = epilogProcessor;
4734: eventPtr = s;
4735: for (;;) {
4736: const char *next = NULL;
4737: int tok = XmlPrologTok(encoding, s, end, &next);
4738: eventEndPtr = next;
4739: switch (tok) {
4740: /* report partial linebreak - it might be the last token */
4741: case -XML_TOK_PROLOG_S:
4742: if (defaultHandler) {
4743: reportDefault(parser, encoding, s, next);
4744: if (ps_parsing == XML_FINISHED)
4745: return XML_ERROR_ABORTED;
4746: }
4747: *nextPtr = next;
4748: return XML_ERROR_NONE;
4749: case XML_TOK_NONE:
4750: *nextPtr = s;
4751: return XML_ERROR_NONE;
4752: case XML_TOK_PROLOG_S:
4753: if (defaultHandler)
4754: reportDefault(parser, encoding, s, next);
4755: break;
4756: case XML_TOK_PI:
4757: if (!reportProcessingInstruction(parser, encoding, s, next))
4758: return XML_ERROR_NO_MEMORY;
4759: break;
4760: case XML_TOK_COMMENT:
4761: if (!reportComment(parser, encoding, s, next))
4762: return XML_ERROR_NO_MEMORY;
4763: break;
4764: case XML_TOK_INVALID:
4765: eventPtr = next;
4766: return XML_ERROR_INVALID_TOKEN;
4767: case XML_TOK_PARTIAL:
4768: if (!ps_finalBuffer) {
4769: *nextPtr = s;
4770: return XML_ERROR_NONE;
4771: }
4772: return XML_ERROR_UNCLOSED_TOKEN;
4773: case XML_TOK_PARTIAL_CHAR:
4774: if (!ps_finalBuffer) {
4775: *nextPtr = s;
4776: return XML_ERROR_NONE;
4777: }
4778: return XML_ERROR_PARTIAL_CHAR;
4779: default:
4780: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4781: }
4782: eventPtr = s = next;
4783: switch (ps_parsing) {
1.1.1.2 ! misho 4784: case XML_SUSPENDED:
1.1 misho 4785: *nextPtr = next;
4786: return XML_ERROR_NONE;
4787: case XML_FINISHED:
4788: return XML_ERROR_ABORTED;
4789: default: ;
4790: }
4791: }
4792: }
4793:
4794: static enum XML_Error
4795: processInternalEntity(XML_Parser parser, ENTITY *entity,
4796: XML_Bool betweenDecl)
4797: {
4798: const char *textStart, *textEnd;
4799: const char *next;
4800: enum XML_Error result;
4801: OPEN_INTERNAL_ENTITY *openEntity;
4802:
4803: if (freeInternalEntities) {
4804: openEntity = freeInternalEntities;
4805: freeInternalEntities = openEntity->next;
4806: }
4807: else {
4808: openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4809: if (!openEntity)
4810: return XML_ERROR_NO_MEMORY;
4811: }
4812: entity->open = XML_TRUE;
4813: entity->processed = 0;
4814: openEntity->next = openInternalEntities;
4815: openInternalEntities = openEntity;
4816: openEntity->entity = entity;
4817: openEntity->startTagLevel = tagLevel;
4818: openEntity->betweenDecl = betweenDecl;
4819: openEntity->internalEventPtr = NULL;
4820: openEntity->internalEventEndPtr = NULL;
4821: textStart = (char *)entity->textPtr;
4822: textEnd = (char *)(entity->textPtr + entity->textLen);
4823:
4824: #ifdef XML_DTD
4825: if (entity->is_param) {
4826: int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
1.1.1.2 ! misho 4827: result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
1.1 misho 4828: next, &next, XML_FALSE);
4829: }
1.1.1.2 ! misho 4830: else
1.1 misho 4831: #endif /* XML_DTD */
1.1.1.2 ! misho 4832: result = doContent(parser, tagLevel, internalEncoding, textStart,
1.1 misho 4833: textEnd, &next, XML_FALSE);
4834:
4835: if (result == XML_ERROR_NONE) {
4836: if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4837: entity->processed = (int)(next - textStart);
4838: processor = internalEntityProcessor;
4839: }
4840: else {
4841: entity->open = XML_FALSE;
4842: openInternalEntities = openEntity->next;
4843: /* put openEntity back in list of free instances */
4844: openEntity->next = freeInternalEntities;
4845: freeInternalEntities = openEntity;
4846: }
4847: }
4848: return result;
4849: }
4850:
4851: static enum XML_Error PTRCALL
4852: internalEntityProcessor(XML_Parser parser,
4853: const char *s,
4854: const char *end,
4855: const char **nextPtr)
4856: {
4857: ENTITY *entity;
4858: const char *textStart, *textEnd;
4859: const char *next;
4860: enum XML_Error result;
4861: OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4862: if (!openEntity)
4863: return XML_ERROR_UNEXPECTED_STATE;
4864:
4865: entity = openEntity->entity;
4866: textStart = ((char *)entity->textPtr) + entity->processed;
4867: textEnd = (char *)(entity->textPtr + entity->textLen);
4868:
4869: #ifdef XML_DTD
4870: if (entity->is_param) {
4871: int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
1.1.1.2 ! misho 4872: result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
1.1 misho 4873: next, &next, XML_FALSE);
4874: }
4875: else
4876: #endif /* XML_DTD */
1.1.1.2 ! misho 4877: result = doContent(parser, openEntity->startTagLevel, internalEncoding,
! 4878: textStart, textEnd, &next, XML_FALSE);
1.1 misho 4879:
4880: if (result != XML_ERROR_NONE)
4881: return result;
4882: else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4883: entity->processed = (int)(next - (char *)entity->textPtr);
4884: return result;
4885: }
4886: else {
4887: entity->open = XML_FALSE;
4888: openInternalEntities = openEntity->next;
4889: /* put openEntity back in list of free instances */
4890: openEntity->next = freeInternalEntities;
4891: freeInternalEntities = openEntity;
4892: }
4893:
4894: #ifdef XML_DTD
4895: if (entity->is_param) {
4896: int tok;
4897: processor = prologProcessor;
4898: tok = XmlPrologTok(encoding, s, end, &next);
1.1.1.2 ! misho 4899: return doProlog(parser, encoding, s, end, tok, next, nextPtr,
1.1 misho 4900: (XML_Bool)!ps_finalBuffer);
4901: }
4902: else
4903: #endif /* XML_DTD */
4904: {
4905: processor = contentProcessor;
4906: /* see externalEntityContentProcessor vs contentProcessor */
4907: return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
1.1.1.2 ! misho 4908: nextPtr, (XML_Bool)!ps_finalBuffer);
! 4909: }
1.1 misho 4910: }
4911:
4912: static enum XML_Error PTRCALL
4913: errorProcessor(XML_Parser parser,
4914: const char *s,
4915: const char *end,
4916: const char **nextPtr)
4917: {
4918: return errorCode;
4919: }
4920:
4921: static enum XML_Error
4922: storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4923: const char *ptr, const char *end,
4924: STRING_POOL *pool)
4925: {
4926: enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4927: end, pool);
4928: if (result)
4929: return result;
4930: if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4931: poolChop(pool);
4932: if (!poolAppendChar(pool, XML_T('\0')))
4933: return XML_ERROR_NO_MEMORY;
4934: return XML_ERROR_NONE;
4935: }
4936:
4937: static enum XML_Error
4938: appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4939: const char *ptr, const char *end,
4940: STRING_POOL *pool)
4941: {
4942: DTD * const dtd = _dtd; /* save one level of indirection */
4943: for (;;) {
4944: const char *next;
4945: int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4946: switch (tok) {
4947: case XML_TOK_NONE:
4948: return XML_ERROR_NONE;
4949: case XML_TOK_INVALID:
4950: if (enc == encoding)
4951: eventPtr = next;
4952: return XML_ERROR_INVALID_TOKEN;
4953: case XML_TOK_PARTIAL:
4954: if (enc == encoding)
4955: eventPtr = ptr;
4956: return XML_ERROR_INVALID_TOKEN;
4957: case XML_TOK_CHAR_REF:
4958: {
4959: XML_Char buf[XML_ENCODE_MAX];
4960: int i;
4961: int n = XmlCharRefNumber(enc, ptr);
4962: if (n < 0) {
4963: if (enc == encoding)
4964: eventPtr = ptr;
4965: return XML_ERROR_BAD_CHAR_REF;
4966: }
4967: if (!isCdata
4968: && n == 0x20 /* space */
4969: && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4970: break;
4971: n = XmlEncode(n, (ICHAR *)buf);
4972: if (!n) {
4973: if (enc == encoding)
4974: eventPtr = ptr;
4975: return XML_ERROR_BAD_CHAR_REF;
4976: }
4977: for (i = 0; i < n; i++) {
4978: if (!poolAppendChar(pool, buf[i]))
4979: return XML_ERROR_NO_MEMORY;
4980: }
4981: }
4982: break;
4983: case XML_TOK_DATA_CHARS:
4984: if (!poolAppend(pool, enc, ptr, next))
4985: return XML_ERROR_NO_MEMORY;
4986: break;
4987: case XML_TOK_TRAILING_CR:
4988: next = ptr + enc->minBytesPerChar;
4989: /* fall through */
4990: case XML_TOK_ATTRIBUTE_VALUE_S:
4991: case XML_TOK_DATA_NEWLINE:
4992: if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4993: break;
4994: if (!poolAppendChar(pool, 0x20))
4995: return XML_ERROR_NO_MEMORY;
4996: break;
4997: case XML_TOK_ENTITY_REF:
4998: {
4999: const XML_Char *name;
5000: ENTITY *entity;
5001: char checkEntityDecl;
5002: XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5003: ptr + enc->minBytesPerChar,
5004: next - enc->minBytesPerChar);
5005: if (ch) {
5006: if (!poolAppendChar(pool, ch))
5007: return XML_ERROR_NO_MEMORY;
5008: break;
5009: }
5010: name = poolStoreString(&temp2Pool, enc,
5011: ptr + enc->minBytesPerChar,
5012: next - enc->minBytesPerChar);
5013: if (!name)
5014: return XML_ERROR_NO_MEMORY;
1.1.1.2 ! misho 5015: entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
1.1 misho 5016: poolDiscard(&temp2Pool);
5017: /* First, determine if a check for an existing declaration is needed;
5018: if yes, check that the entity exists, and that it is internal.
5019: */
5020: if (pool == &dtd->pool) /* are we called from prolog? */
5021: checkEntityDecl =
5022: #ifdef XML_DTD
5023: prologState.documentEntity &&
5024: #endif /* XML_DTD */
5025: (dtd->standalone
5026: ? !openInternalEntities
5027: : !dtd->hasParamEntityRefs);
5028: else /* if (pool == &tempPool): we are called from content */
5029: checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5030: if (checkEntityDecl) {
5031: if (!entity)
5032: return XML_ERROR_UNDEFINED_ENTITY;
5033: else if (!entity->is_internal)
5034: return XML_ERROR_ENTITY_DECLARED_IN_PE;
5035: }
5036: else if (!entity) {
5037: /* Cannot report skipped entity here - see comments on
5038: skippedEntityHandler.
5039: if (skippedEntityHandler)
5040: skippedEntityHandler(handlerArg, name, 0);
5041: */
5042: /* Cannot call the default handler because this would be
5043: out of sync with the call to the startElementHandler.
5044: if ((pool == &tempPool) && defaultHandler)
5045: reportDefault(parser, enc, ptr, next);
5046: */
5047: break;
5048: }
5049: if (entity->open) {
5050: if (enc == encoding)
5051: eventPtr = ptr;
5052: return XML_ERROR_RECURSIVE_ENTITY_REF;
5053: }
5054: if (entity->notation) {
5055: if (enc == encoding)
5056: eventPtr = ptr;
5057: return XML_ERROR_BINARY_ENTITY_REF;
5058: }
5059: if (!entity->textPtr) {
5060: if (enc == encoding)
5061: eventPtr = ptr;
1.1.1.2 ! misho 5062: return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
1.1 misho 5063: }
5064: else {
5065: enum XML_Error result;
5066: const XML_Char *textEnd = entity->textPtr + entity->textLen;
5067: entity->open = XML_TRUE;
5068: result = appendAttributeValue(parser, internalEncoding, isCdata,
5069: (char *)entity->textPtr,
5070: (char *)textEnd, pool);
5071: entity->open = XML_FALSE;
5072: if (result)
5073: return result;
5074: }
5075: }
5076: break;
5077: default:
5078: if (enc == encoding)
5079: eventPtr = ptr;
5080: return XML_ERROR_UNEXPECTED_STATE;
5081: }
5082: ptr = next;
5083: }
5084: /* not reached */
5085: }
5086:
5087: static enum XML_Error
5088: storeEntityValue(XML_Parser parser,
5089: const ENCODING *enc,
5090: const char *entityTextPtr,
5091: const char *entityTextEnd)
5092: {
5093: DTD * const dtd = _dtd; /* save one level of indirection */
5094: STRING_POOL *pool = &(dtd->entityValuePool);
5095: enum XML_Error result = XML_ERROR_NONE;
5096: #ifdef XML_DTD
5097: int oldInEntityValue = prologState.inEntityValue;
5098: prologState.inEntityValue = 1;
5099: #endif /* XML_DTD */
5100: /* never return Null for the value argument in EntityDeclHandler,
5101: since this would indicate an external entity; therefore we
5102: have to make sure that entityValuePool.start is not null */
5103: if (!pool->blocks) {
5104: if (!poolGrow(pool))
5105: return XML_ERROR_NO_MEMORY;
5106: }
5107:
5108: for (;;) {
5109: const char *next;
5110: int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5111: switch (tok) {
5112: case XML_TOK_PARAM_ENTITY_REF:
5113: #ifdef XML_DTD
5114: if (isParamEntity || enc != encoding) {
5115: const XML_Char *name;
5116: ENTITY *entity;
5117: name = poolStoreString(&tempPool, enc,
5118: entityTextPtr + enc->minBytesPerChar,
5119: next - enc->minBytesPerChar);
5120: if (!name) {
5121: result = XML_ERROR_NO_MEMORY;
5122: goto endEntityValue;
5123: }
1.1.1.2 ! misho 5124: entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
1.1 misho 5125: poolDiscard(&tempPool);
5126: if (!entity) {
5127: /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5128: /* cannot report skipped entity here - see comments on
5129: skippedEntityHandler
5130: if (skippedEntityHandler)
5131: skippedEntityHandler(handlerArg, name, 0);
5132: */
5133: dtd->keepProcessing = dtd->standalone;
5134: goto endEntityValue;
5135: }
5136: if (entity->open) {
5137: if (enc == encoding)
5138: eventPtr = entityTextPtr;
5139: result = XML_ERROR_RECURSIVE_ENTITY_REF;
5140: goto endEntityValue;
5141: }
5142: if (entity->systemId) {
5143: if (externalEntityRefHandler) {
5144: dtd->paramEntityRead = XML_FALSE;
5145: entity->open = XML_TRUE;
5146: if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5147: 0,
5148: entity->base,
5149: entity->systemId,
5150: entity->publicId)) {
5151: entity->open = XML_FALSE;
5152: result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5153: goto endEntityValue;
5154: }
5155: entity->open = XML_FALSE;
5156: if (!dtd->paramEntityRead)
5157: dtd->keepProcessing = dtd->standalone;
5158: }
5159: else
5160: dtd->keepProcessing = dtd->standalone;
5161: }
5162: else {
5163: entity->open = XML_TRUE;
5164: result = storeEntityValue(parser,
5165: internalEncoding,
5166: (char *)entity->textPtr,
5167: (char *)(entity->textPtr
5168: + entity->textLen));
5169: entity->open = XML_FALSE;
5170: if (result)
5171: goto endEntityValue;
5172: }
5173: break;
5174: }
5175: #endif /* XML_DTD */
5176: /* In the internal subset, PE references are not legal
5177: within markup declarations, e.g entity values in this case. */
5178: eventPtr = entityTextPtr;
5179: result = XML_ERROR_PARAM_ENTITY_REF;
5180: goto endEntityValue;
5181: case XML_TOK_NONE:
5182: result = XML_ERROR_NONE;
5183: goto endEntityValue;
5184: case XML_TOK_ENTITY_REF:
5185: case XML_TOK_DATA_CHARS:
5186: if (!poolAppend(pool, enc, entityTextPtr, next)) {
5187: result = XML_ERROR_NO_MEMORY;
5188: goto endEntityValue;
5189: }
5190: break;
5191: case XML_TOK_TRAILING_CR:
5192: next = entityTextPtr + enc->minBytesPerChar;
5193: /* fall through */
5194: case XML_TOK_DATA_NEWLINE:
5195: if (pool->end == pool->ptr && !poolGrow(pool)) {
5196: result = XML_ERROR_NO_MEMORY;
5197: goto endEntityValue;
5198: }
5199: *(pool->ptr)++ = 0xA;
5200: break;
5201: case XML_TOK_CHAR_REF:
5202: {
5203: XML_Char buf[XML_ENCODE_MAX];
5204: int i;
5205: int n = XmlCharRefNumber(enc, entityTextPtr);
5206: if (n < 0) {
5207: if (enc == encoding)
5208: eventPtr = entityTextPtr;
5209: result = XML_ERROR_BAD_CHAR_REF;
5210: goto endEntityValue;
5211: }
5212: n = XmlEncode(n, (ICHAR *)buf);
5213: if (!n) {
5214: if (enc == encoding)
5215: eventPtr = entityTextPtr;
5216: result = XML_ERROR_BAD_CHAR_REF;
5217: goto endEntityValue;
5218: }
5219: for (i = 0; i < n; i++) {
5220: if (pool->end == pool->ptr && !poolGrow(pool)) {
5221: result = XML_ERROR_NO_MEMORY;
5222: goto endEntityValue;
5223: }
5224: *(pool->ptr)++ = buf[i];
5225: }
5226: }
5227: break;
5228: case XML_TOK_PARTIAL:
5229: if (enc == encoding)
5230: eventPtr = entityTextPtr;
5231: result = XML_ERROR_INVALID_TOKEN;
5232: goto endEntityValue;
5233: case XML_TOK_INVALID:
5234: if (enc == encoding)
5235: eventPtr = next;
5236: result = XML_ERROR_INVALID_TOKEN;
5237: goto endEntityValue;
5238: default:
5239: if (enc == encoding)
5240: eventPtr = entityTextPtr;
5241: result = XML_ERROR_UNEXPECTED_STATE;
5242: goto endEntityValue;
5243: }
5244: entityTextPtr = next;
5245: }
5246: endEntityValue:
5247: #ifdef XML_DTD
5248: prologState.inEntityValue = oldInEntityValue;
5249: #endif /* XML_DTD */
5250: return result;
5251: }
5252:
5253: static void FASTCALL
5254: normalizeLines(XML_Char *s)
5255: {
5256: XML_Char *p;
5257: for (;; s++) {
5258: if (*s == XML_T('\0'))
5259: return;
5260: if (*s == 0xD)
5261: break;
5262: }
5263: p = s;
5264: do {
5265: if (*s == 0xD) {
5266: *p++ = 0xA;
5267: if (*++s == 0xA)
5268: s++;
5269: }
5270: else
5271: *p++ = *s++;
5272: } while (*s);
5273: *p = XML_T('\0');
5274: }
5275:
5276: static int
5277: reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5278: const char *start, const char *end)
5279: {
5280: const XML_Char *target;
5281: XML_Char *data;
5282: const char *tem;
5283: if (!processingInstructionHandler) {
5284: if (defaultHandler)
5285: reportDefault(parser, enc, start, end);
5286: return 1;
5287: }
5288: start += enc->minBytesPerChar * 2;
5289: tem = start + XmlNameLength(enc, start);
5290: target = poolStoreString(&tempPool, enc, start, tem);
5291: if (!target)
5292: return 0;
5293: poolFinish(&tempPool);
5294: data = poolStoreString(&tempPool, enc,
5295: XmlSkipS(enc, tem),
5296: end - enc->minBytesPerChar*2);
5297: if (!data)
5298: return 0;
5299: normalizeLines(data);
5300: processingInstructionHandler(handlerArg, target, data);
5301: poolClear(&tempPool);
5302: return 1;
5303: }
5304:
5305: static int
5306: reportComment(XML_Parser parser, const ENCODING *enc,
5307: const char *start, const char *end)
5308: {
5309: XML_Char *data;
5310: if (!commentHandler) {
5311: if (defaultHandler)
5312: reportDefault(parser, enc, start, end);
5313: return 1;
5314: }
5315: data = poolStoreString(&tempPool,
5316: enc,
5317: start + enc->minBytesPerChar * 4,
5318: end - enc->minBytesPerChar * 3);
5319: if (!data)
5320: return 0;
5321: normalizeLines(data);
5322: commentHandler(handlerArg, data);
5323: poolClear(&tempPool);
5324: return 1;
5325: }
5326:
5327: static void
5328: reportDefault(XML_Parser parser, const ENCODING *enc,
5329: const char *s, const char *end)
5330: {
5331: if (MUST_CONVERT(enc, s)) {
5332: const char **eventPP;
5333: const char **eventEndPP;
5334: if (enc == encoding) {
5335: eventPP = &eventPtr;
5336: eventEndPP = &eventEndPtr;
5337: }
5338: else {
5339: eventPP = &(openInternalEntities->internalEventPtr);
5340: eventEndPP = &(openInternalEntities->internalEventEndPtr);
5341: }
5342: do {
5343: ICHAR *dataPtr = (ICHAR *)dataBuf;
5344: XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5345: *eventEndPP = s;
5346: defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5347: *eventPP = s;
5348: } while (s != end);
5349: }
5350: else
5351: defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5352: }
5353:
5354:
5355: static int
5356: defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5357: XML_Bool isId, const XML_Char *value, XML_Parser parser)
5358: {
5359: DEFAULT_ATTRIBUTE *att;
5360: if (value || isId) {
5361: /* The handling of default attributes gets messed up if we have
5362: a default which duplicates a non-default. */
5363: int i;
5364: for (i = 0; i < type->nDefaultAtts; i++)
5365: if (attId == type->defaultAtts[i].id)
5366: return 1;
5367: if (isId && !type->idAtt && !attId->xmlns)
5368: type->idAtt = attId;
5369: }
5370: if (type->nDefaultAtts == type->allocDefaultAtts) {
5371: if (type->allocDefaultAtts == 0) {
5372: type->allocDefaultAtts = 8;
5373: type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5374: * sizeof(DEFAULT_ATTRIBUTE));
5375: if (!type->defaultAtts)
5376: return 0;
5377: }
5378: else {
5379: DEFAULT_ATTRIBUTE *temp;
5380: int count = type->allocDefaultAtts * 2;
5381: temp = (DEFAULT_ATTRIBUTE *)
5382: REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5383: if (temp == NULL)
5384: return 0;
5385: type->allocDefaultAtts = count;
5386: type->defaultAtts = temp;
5387: }
5388: }
5389: att = type->defaultAtts + type->nDefaultAtts;
5390: att->id = attId;
5391: att->value = value;
5392: att->isCdata = isCdata;
5393: if (!isCdata)
5394: attId->maybeTokenized = XML_TRUE;
5395: type->nDefaultAtts += 1;
5396: return 1;
5397: }
5398:
5399: static int
5400: setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5401: {
5402: DTD * const dtd = _dtd; /* save one level of indirection */
5403: const XML_Char *name;
5404: for (name = elementType->name; *name; name++) {
5405: if (*name == XML_T(ASCII_COLON)) {
5406: PREFIX *prefix;
5407: const XML_Char *s;
5408: for (s = elementType->name; s != name; s++) {
5409: if (!poolAppendChar(&dtd->pool, *s))
5410: return 0;
5411: }
5412: if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5413: return 0;
1.1.1.2 ! misho 5414: prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
1.1 misho 5415: sizeof(PREFIX));
5416: if (!prefix)
5417: return 0;
5418: if (prefix->name == poolStart(&dtd->pool))
5419: poolFinish(&dtd->pool);
5420: else
5421: poolDiscard(&dtd->pool);
5422: elementType->prefix = prefix;
5423:
5424: }
5425: }
5426: return 1;
5427: }
5428:
5429: static ATTRIBUTE_ID *
5430: getAttributeId(XML_Parser parser, const ENCODING *enc,
5431: const char *start, const char *end)
5432: {
5433: DTD * const dtd = _dtd; /* save one level of indirection */
5434: ATTRIBUTE_ID *id;
5435: const XML_Char *name;
5436: if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5437: return NULL;
5438: name = poolStoreString(&dtd->pool, enc, start, end);
5439: if (!name)
5440: return NULL;
5441: /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5442: ++name;
1.1.1.2 ! misho 5443: id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
1.1 misho 5444: if (!id)
5445: return NULL;
5446: if (id->name != name)
5447: poolDiscard(&dtd->pool);
5448: else {
5449: poolFinish(&dtd->pool);
5450: if (!ns)
5451: ;
5452: else if (name[0] == XML_T(ASCII_x)
5453: && name[1] == XML_T(ASCII_m)
5454: && name[2] == XML_T(ASCII_l)
5455: && name[3] == XML_T(ASCII_n)
5456: && name[4] == XML_T(ASCII_s)
5457: && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5458: if (name[5] == XML_T('\0'))
5459: id->prefix = &dtd->defaultPrefix;
5460: else
1.1.1.2 ! misho 5461: id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
1.1 misho 5462: id->xmlns = XML_TRUE;
5463: }
5464: else {
5465: int i;
5466: for (i = 0; name[i]; i++) {
5467: /* attributes without prefix are *not* in the default namespace */
5468: if (name[i] == XML_T(ASCII_COLON)) {
5469: int j;
5470: for (j = 0; j < i; j++) {
5471: if (!poolAppendChar(&dtd->pool, name[j]))
5472: return NULL;
5473: }
5474: if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5475: return NULL;
1.1.1.2 ! misho 5476: id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
1.1 misho 5477: sizeof(PREFIX));
5478: if (id->prefix->name == poolStart(&dtd->pool))
5479: poolFinish(&dtd->pool);
5480: else
5481: poolDiscard(&dtd->pool);
5482: break;
5483: }
5484: }
5485: }
5486: }
5487: return id;
5488: }
5489:
5490: #define CONTEXT_SEP XML_T(ASCII_FF)
5491:
5492: static const XML_Char *
5493: getContext(XML_Parser parser)
5494: {
5495: DTD * const dtd = _dtd; /* save one level of indirection */
5496: HASH_TABLE_ITER iter;
5497: XML_Bool needSep = XML_FALSE;
5498:
5499: if (dtd->defaultPrefix.binding) {
5500: int i;
5501: int len;
5502: if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5503: return NULL;
5504: len = dtd->defaultPrefix.binding->uriLen;
5505: if (namespaceSeparator)
5506: len--;
5507: for (i = 0; i < len; i++)
5508: if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5509: return NULL;
5510: needSep = XML_TRUE;
5511: }
5512:
5513: hashTableIterInit(&iter, &(dtd->prefixes));
5514: for (;;) {
5515: int i;
5516: int len;
5517: const XML_Char *s;
5518: PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5519: if (!prefix)
5520: break;
5521: if (!prefix->binding)
5522: continue;
5523: if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5524: return NULL;
5525: for (s = prefix->name; *s; s++)
5526: if (!poolAppendChar(&tempPool, *s))
5527: return NULL;
5528: if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5529: return NULL;
5530: len = prefix->binding->uriLen;
5531: if (namespaceSeparator)
5532: len--;
5533: for (i = 0; i < len; i++)
5534: if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5535: return NULL;
5536: needSep = XML_TRUE;
5537: }
5538:
5539:
5540: hashTableIterInit(&iter, &(dtd->generalEntities));
5541: for (;;) {
5542: const XML_Char *s;
5543: ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5544: if (!e)
5545: break;
5546: if (!e->open)
5547: continue;
5548: if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5549: return NULL;
5550: for (s = e->name; *s; s++)
5551: if (!poolAppendChar(&tempPool, *s))
5552: return 0;
5553: needSep = XML_TRUE;
5554: }
5555:
5556: if (!poolAppendChar(&tempPool, XML_T('\0')))
5557: return NULL;
5558: return tempPool.start;
5559: }
5560:
5561: static XML_Bool
5562: setContext(XML_Parser parser, const XML_Char *context)
5563: {
5564: DTD * const dtd = _dtd; /* save one level of indirection */
5565: const XML_Char *s = context;
5566:
5567: while (*context != XML_T('\0')) {
5568: if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5569: ENTITY *e;
5570: if (!poolAppendChar(&tempPool, XML_T('\0')))
5571: return XML_FALSE;
1.1.1.2 ! misho 5572: e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
1.1 misho 5573: if (e)
5574: e->open = XML_TRUE;
5575: if (*s != XML_T('\0'))
5576: s++;
5577: context = s;
5578: poolDiscard(&tempPool);
5579: }
5580: else if (*s == XML_T(ASCII_EQUALS)) {
5581: PREFIX *prefix;
5582: if (poolLength(&tempPool) == 0)
5583: prefix = &dtd->defaultPrefix;
5584: else {
5585: if (!poolAppendChar(&tempPool, XML_T('\0')))
5586: return XML_FALSE;
1.1.1.2 ! misho 5587: prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
1.1 misho 5588: sizeof(PREFIX));
5589: if (!prefix)
5590: return XML_FALSE;
5591: if (prefix->name == poolStart(&tempPool)) {
5592: prefix->name = poolCopyString(&dtd->pool, prefix->name);
5593: if (!prefix->name)
5594: return XML_FALSE;
5595: }
5596: poolDiscard(&tempPool);
5597: }
5598: for (context = s + 1;
5599: *context != CONTEXT_SEP && *context != XML_T('\0');
5600: context++)
5601: if (!poolAppendChar(&tempPool, *context))
5602: return XML_FALSE;
5603: if (!poolAppendChar(&tempPool, XML_T('\0')))
5604: return XML_FALSE;
5605: if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5606: &inheritedBindings) != XML_ERROR_NONE)
5607: return XML_FALSE;
5608: poolDiscard(&tempPool);
5609: if (*context != XML_T('\0'))
5610: ++context;
5611: s = context;
5612: }
5613: else {
5614: if (!poolAppendChar(&tempPool, *s))
5615: return XML_FALSE;
5616: s++;
5617: }
5618: }
5619: return XML_TRUE;
5620: }
5621:
5622: static void FASTCALL
5623: normalizePublicId(XML_Char *publicId)
5624: {
5625: XML_Char *p = publicId;
5626: XML_Char *s;
5627: for (s = publicId; *s; s++) {
5628: switch (*s) {
5629: case 0x20:
5630: case 0xD:
5631: case 0xA:
5632: if (p != publicId && p[-1] != 0x20)
5633: *p++ = 0x20;
5634: break;
5635: default:
5636: *p++ = *s;
5637: }
5638: }
5639: if (p != publicId && p[-1] == 0x20)
5640: --p;
5641: *p = XML_T('\0');
5642: }
5643:
5644: static DTD *
5645: dtdCreate(const XML_Memory_Handling_Suite *ms)
5646: {
5647: DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5648: if (p == NULL)
5649: return p;
5650: poolInit(&(p->pool), ms);
5651: poolInit(&(p->entityValuePool), ms);
5652: hashTableInit(&(p->generalEntities), ms);
5653: hashTableInit(&(p->elementTypes), ms);
5654: hashTableInit(&(p->attributeIds), ms);
5655: hashTableInit(&(p->prefixes), ms);
5656: #ifdef XML_DTD
5657: p->paramEntityRead = XML_FALSE;
5658: hashTableInit(&(p->paramEntities), ms);
5659: #endif /* XML_DTD */
5660: p->defaultPrefix.name = NULL;
5661: p->defaultPrefix.binding = NULL;
5662:
5663: p->in_eldecl = XML_FALSE;
5664: p->scaffIndex = NULL;
5665: p->scaffold = NULL;
5666: p->scaffLevel = 0;
5667: p->scaffSize = 0;
5668: p->scaffCount = 0;
5669: p->contentStringLen = 0;
5670:
5671: p->keepProcessing = XML_TRUE;
5672: p->hasParamEntityRefs = XML_FALSE;
5673: p->standalone = XML_FALSE;
5674: return p;
5675: }
5676:
5677: static void
5678: dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5679: {
5680: HASH_TABLE_ITER iter;
5681: hashTableIterInit(&iter, &(p->elementTypes));
5682: for (;;) {
5683: ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5684: if (!e)
5685: break;
5686: if (e->allocDefaultAtts != 0)
5687: ms->free_fcn(e->defaultAtts);
5688: }
5689: hashTableClear(&(p->generalEntities));
5690: #ifdef XML_DTD
5691: p->paramEntityRead = XML_FALSE;
5692: hashTableClear(&(p->paramEntities));
5693: #endif /* XML_DTD */
5694: hashTableClear(&(p->elementTypes));
5695: hashTableClear(&(p->attributeIds));
5696: hashTableClear(&(p->prefixes));
5697: poolClear(&(p->pool));
5698: poolClear(&(p->entityValuePool));
5699: p->defaultPrefix.name = NULL;
5700: p->defaultPrefix.binding = NULL;
5701:
5702: p->in_eldecl = XML_FALSE;
5703:
5704: ms->free_fcn(p->scaffIndex);
5705: p->scaffIndex = NULL;
5706: ms->free_fcn(p->scaffold);
5707: p->scaffold = NULL;
5708:
5709: p->scaffLevel = 0;
5710: p->scaffSize = 0;
5711: p->scaffCount = 0;
5712: p->contentStringLen = 0;
5713:
5714: p->keepProcessing = XML_TRUE;
5715: p->hasParamEntityRefs = XML_FALSE;
5716: p->standalone = XML_FALSE;
5717: }
5718:
5719: static void
5720: dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5721: {
5722: HASH_TABLE_ITER iter;
5723: hashTableIterInit(&iter, &(p->elementTypes));
5724: for (;;) {
5725: ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5726: if (!e)
5727: break;
5728: if (e->allocDefaultAtts != 0)
5729: ms->free_fcn(e->defaultAtts);
5730: }
5731: hashTableDestroy(&(p->generalEntities));
5732: #ifdef XML_DTD
5733: hashTableDestroy(&(p->paramEntities));
5734: #endif /* XML_DTD */
5735: hashTableDestroy(&(p->elementTypes));
5736: hashTableDestroy(&(p->attributeIds));
5737: hashTableDestroy(&(p->prefixes));
5738: poolDestroy(&(p->pool));
5739: poolDestroy(&(p->entityValuePool));
5740: if (isDocEntity) {
5741: ms->free_fcn(p->scaffIndex);
5742: ms->free_fcn(p->scaffold);
5743: }
5744: ms->free_fcn(p);
5745: }
5746:
5747: /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5748: The new DTD has already been initialized.
5749: */
5750: static int
1.1.1.2 ! misho 5751: dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
1.1 misho 5752: {
5753: HASH_TABLE_ITER iter;
5754:
5755: /* Copy the prefix table. */
5756:
5757: hashTableIterInit(&iter, &(oldDtd->prefixes));
5758: for (;;) {
5759: const XML_Char *name;
5760: const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5761: if (!oldP)
5762: break;
5763: name = poolCopyString(&(newDtd->pool), oldP->name);
5764: if (!name)
5765: return 0;
1.1.1.2 ! misho 5766: if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
1.1 misho 5767: return 0;
5768: }
5769:
5770: hashTableIterInit(&iter, &(oldDtd->attributeIds));
5771:
5772: /* Copy the attribute id table. */
5773:
5774: for (;;) {
5775: ATTRIBUTE_ID *newA;
5776: const XML_Char *name;
5777: const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5778:
5779: if (!oldA)
5780: break;
5781: /* Remember to allocate the scratch byte before the name. */
5782: if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5783: return 0;
5784: name = poolCopyString(&(newDtd->pool), oldA->name);
5785: if (!name)
5786: return 0;
5787: ++name;
1.1.1.2 ! misho 5788: newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
1.1 misho 5789: sizeof(ATTRIBUTE_ID));
5790: if (!newA)
5791: return 0;
5792: newA->maybeTokenized = oldA->maybeTokenized;
5793: if (oldA->prefix) {
5794: newA->xmlns = oldA->xmlns;
5795: if (oldA->prefix == &oldDtd->defaultPrefix)
5796: newA->prefix = &newDtd->defaultPrefix;
5797: else
1.1.1.2 ! misho 5798: newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
1.1 misho 5799: oldA->prefix->name, 0);
5800: }
5801: }
5802:
5803: /* Copy the element type table. */
5804:
5805: hashTableIterInit(&iter, &(oldDtd->elementTypes));
5806:
5807: for (;;) {
5808: int i;
5809: ELEMENT_TYPE *newE;
5810: const XML_Char *name;
5811: const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5812: if (!oldE)
5813: break;
5814: name = poolCopyString(&(newDtd->pool), oldE->name);
5815: if (!name)
5816: return 0;
1.1.1.2 ! misho 5817: newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
1.1 misho 5818: sizeof(ELEMENT_TYPE));
5819: if (!newE)
5820: return 0;
5821: if (oldE->nDefaultAtts) {
5822: newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5823: ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5824: if (!newE->defaultAtts) {
5825: ms->free_fcn(newE);
5826: return 0;
5827: }
5828: }
5829: if (oldE->idAtt)
5830: newE->idAtt = (ATTRIBUTE_ID *)
1.1.1.2 ! misho 5831: lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
1.1 misho 5832: newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5833: if (oldE->prefix)
1.1.1.2 ! misho 5834: newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
1.1 misho 5835: oldE->prefix->name, 0);
5836: for (i = 0; i < newE->nDefaultAtts; i++) {
5837: newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
1.1.1.2 ! misho 5838: lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
1.1 misho 5839: newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5840: if (oldE->defaultAtts[i].value) {
5841: newE->defaultAtts[i].value
5842: = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5843: if (!newE->defaultAtts[i].value)
5844: return 0;
5845: }
5846: else
5847: newE->defaultAtts[i].value = NULL;
5848: }
5849: }
5850:
5851: /* Copy the entity tables. */
1.1.1.2 ! misho 5852: if (!copyEntityTable(oldParser,
! 5853: &(newDtd->generalEntities),
1.1 misho 5854: &(newDtd->pool),
5855: &(oldDtd->generalEntities)))
5856: return 0;
5857:
5858: #ifdef XML_DTD
1.1.1.2 ! misho 5859: if (!copyEntityTable(oldParser,
! 5860: &(newDtd->paramEntities),
1.1 misho 5861: &(newDtd->pool),
5862: &(oldDtd->paramEntities)))
5863: return 0;
5864: newDtd->paramEntityRead = oldDtd->paramEntityRead;
5865: #endif /* XML_DTD */
5866:
5867: newDtd->keepProcessing = oldDtd->keepProcessing;
5868: newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5869: newDtd->standalone = oldDtd->standalone;
5870:
5871: /* Don't want deep copying for scaffolding */
5872: newDtd->in_eldecl = oldDtd->in_eldecl;
5873: newDtd->scaffold = oldDtd->scaffold;
5874: newDtd->contentStringLen = oldDtd->contentStringLen;
5875: newDtd->scaffSize = oldDtd->scaffSize;
5876: newDtd->scaffLevel = oldDtd->scaffLevel;
5877: newDtd->scaffIndex = oldDtd->scaffIndex;
5878:
5879: return 1;
5880: } /* End dtdCopy */
5881:
5882: static int
1.1.1.2 ! misho 5883: copyEntityTable(XML_Parser oldParser,
! 5884: HASH_TABLE *newTable,
1.1 misho 5885: STRING_POOL *newPool,
5886: const HASH_TABLE *oldTable)
5887: {
5888: HASH_TABLE_ITER iter;
5889: const XML_Char *cachedOldBase = NULL;
5890: const XML_Char *cachedNewBase = NULL;
5891:
5892: hashTableIterInit(&iter, oldTable);
5893:
5894: for (;;) {
5895: ENTITY *newE;
5896: const XML_Char *name;
5897: const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5898: if (!oldE)
5899: break;
5900: name = poolCopyString(newPool, oldE->name);
5901: if (!name)
5902: return 0;
1.1.1.2 ! misho 5903: newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
1.1 misho 5904: if (!newE)
5905: return 0;
5906: if (oldE->systemId) {
5907: const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5908: if (!tem)
5909: return 0;
5910: newE->systemId = tem;
5911: if (oldE->base) {
5912: if (oldE->base == cachedOldBase)
5913: newE->base = cachedNewBase;
5914: else {
5915: cachedOldBase = oldE->base;
5916: tem = poolCopyString(newPool, cachedOldBase);
5917: if (!tem)
5918: return 0;
5919: cachedNewBase = newE->base = tem;
5920: }
5921: }
5922: if (oldE->publicId) {
5923: tem = poolCopyString(newPool, oldE->publicId);
5924: if (!tem)
5925: return 0;
5926: newE->publicId = tem;
5927: }
5928: }
5929: else {
5930: const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5931: oldE->textLen);
5932: if (!tem)
5933: return 0;
5934: newE->textPtr = tem;
5935: newE->textLen = oldE->textLen;
5936: }
5937: if (oldE->notation) {
5938: const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5939: if (!tem)
5940: return 0;
5941: newE->notation = tem;
5942: }
5943: newE->is_param = oldE->is_param;
5944: newE->is_internal = oldE->is_internal;
5945: }
5946: return 1;
5947: }
5948:
5949: #define INIT_POWER 6
5950:
5951: static XML_Bool FASTCALL
5952: keyeq(KEY s1, KEY s2)
5953: {
5954: for (; *s1 == *s2; s1++, s2++)
5955: if (*s1 == 0)
5956: return XML_TRUE;
5957: return XML_FALSE;
5958: }
5959:
5960: static unsigned long FASTCALL
1.1.1.2 ! misho 5961: hash(XML_Parser parser, KEY s)
1.1 misho 5962: {
1.1.1.2 ! misho 5963: unsigned long h = hash_secret_salt;
1.1 misho 5964: while (*s)
5965: h = CHAR_HASH(h, *s++);
5966: return h;
5967: }
5968:
5969: static NAMED *
1.1.1.2 ! misho 5970: lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
1.1 misho 5971: {
5972: size_t i;
5973: if (table->size == 0) {
5974: size_t tsize;
5975: if (!createSize)
5976: return NULL;
5977: table->power = INIT_POWER;
5978: /* table->size is a power of 2 */
5979: table->size = (size_t)1 << INIT_POWER;
5980: tsize = table->size * sizeof(NAMED *);
5981: table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5982: if (!table->v) {
5983: table->size = 0;
5984: return NULL;
5985: }
5986: memset(table->v, 0, tsize);
1.1.1.2 ! misho 5987: i = hash(parser, name) & ((unsigned long)table->size - 1);
1.1 misho 5988: }
5989: else {
1.1.1.2 ! misho 5990: unsigned long h = hash(parser, name);
1.1 misho 5991: unsigned long mask = (unsigned long)table->size - 1;
5992: unsigned char step = 0;
5993: i = h & mask;
5994: while (table->v[i]) {
5995: if (keyeq(name, table->v[i]->name))
5996: return table->v[i];
5997: if (!step)
5998: step = PROBE_STEP(h, mask, table->power);
5999: i < step ? (i += table->size - step) : (i -= step);
6000: }
6001: if (!createSize)
6002: return NULL;
6003:
6004: /* check for overflow (table is half full) */
6005: if (table->used >> (table->power - 1)) {
6006: unsigned char newPower = table->power + 1;
6007: size_t newSize = (size_t)1 << newPower;
6008: unsigned long newMask = (unsigned long)newSize - 1;
6009: size_t tsize = newSize * sizeof(NAMED *);
6010: NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6011: if (!newV)
6012: return NULL;
6013: memset(newV, 0, tsize);
6014: for (i = 0; i < table->size; i++)
6015: if (table->v[i]) {
1.1.1.2 ! misho 6016: unsigned long newHash = hash(parser, table->v[i]->name);
1.1 misho 6017: size_t j = newHash & newMask;
6018: step = 0;
6019: while (newV[j]) {
6020: if (!step)
6021: step = PROBE_STEP(newHash, newMask, newPower);
6022: j < step ? (j += newSize - step) : (j -= step);
6023: }
6024: newV[j] = table->v[i];
6025: }
6026: table->mem->free_fcn(table->v);
6027: table->v = newV;
6028: table->power = newPower;
6029: table->size = newSize;
6030: i = h & newMask;
6031: step = 0;
6032: while (table->v[i]) {
6033: if (!step)
6034: step = PROBE_STEP(h, newMask, newPower);
6035: i < step ? (i += newSize - step) : (i -= step);
6036: }
6037: }
6038: }
6039: table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6040: if (!table->v[i])
6041: return NULL;
6042: memset(table->v[i], 0, createSize);
6043: table->v[i]->name = name;
6044: (table->used)++;
6045: return table->v[i];
6046: }
6047:
6048: static void FASTCALL
6049: hashTableClear(HASH_TABLE *table)
6050: {
6051: size_t i;
6052: for (i = 0; i < table->size; i++) {
6053: table->mem->free_fcn(table->v[i]);
6054: table->v[i] = NULL;
6055: }
6056: table->used = 0;
6057: }
6058:
6059: static void FASTCALL
6060: hashTableDestroy(HASH_TABLE *table)
6061: {
6062: size_t i;
6063: for (i = 0; i < table->size; i++)
6064: table->mem->free_fcn(table->v[i]);
6065: table->mem->free_fcn(table->v);
6066: }
6067:
6068: static void FASTCALL
6069: hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6070: {
6071: p->power = 0;
6072: p->size = 0;
6073: p->used = 0;
6074: p->v = NULL;
6075: p->mem = ms;
6076: }
6077:
6078: static void FASTCALL
6079: hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6080: {
6081: iter->p = table->v;
6082: iter->end = iter->p + table->size;
6083: }
6084:
6085: static NAMED * FASTCALL
6086: hashTableIterNext(HASH_TABLE_ITER *iter)
6087: {
6088: while (iter->p != iter->end) {
6089: NAMED *tem = *(iter->p)++;
6090: if (tem)
6091: return tem;
6092: }
6093: return NULL;
6094: }
6095:
6096: static void FASTCALL
6097: poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6098: {
6099: pool->blocks = NULL;
6100: pool->freeBlocks = NULL;
6101: pool->start = NULL;
6102: pool->ptr = NULL;
6103: pool->end = NULL;
6104: pool->mem = ms;
6105: }
6106:
6107: static void FASTCALL
6108: poolClear(STRING_POOL *pool)
6109: {
6110: if (!pool->freeBlocks)
6111: pool->freeBlocks = pool->blocks;
6112: else {
6113: BLOCK *p = pool->blocks;
6114: while (p) {
6115: BLOCK *tem = p->next;
6116: p->next = pool->freeBlocks;
6117: pool->freeBlocks = p;
6118: p = tem;
6119: }
6120: }
6121: pool->blocks = NULL;
6122: pool->start = NULL;
6123: pool->ptr = NULL;
6124: pool->end = NULL;
6125: }
6126:
6127: static void FASTCALL
6128: poolDestroy(STRING_POOL *pool)
6129: {
6130: BLOCK *p = pool->blocks;
6131: while (p) {
6132: BLOCK *tem = p->next;
6133: pool->mem->free_fcn(p);
6134: p = tem;
6135: }
6136: p = pool->freeBlocks;
6137: while (p) {
6138: BLOCK *tem = p->next;
6139: pool->mem->free_fcn(p);
6140: p = tem;
6141: }
6142: }
6143:
6144: static XML_Char *
6145: poolAppend(STRING_POOL *pool, const ENCODING *enc,
6146: const char *ptr, const char *end)
6147: {
6148: if (!pool->ptr && !poolGrow(pool))
6149: return NULL;
6150: for (;;) {
6151: XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6152: if (ptr == end)
6153: break;
6154: if (!poolGrow(pool))
6155: return NULL;
6156: }
6157: return pool->start;
6158: }
6159:
6160: static const XML_Char * FASTCALL
6161: poolCopyString(STRING_POOL *pool, const XML_Char *s)
6162: {
6163: do {
6164: if (!poolAppendChar(pool, *s))
6165: return NULL;
6166: } while (*s++);
6167: s = pool->start;
6168: poolFinish(pool);
6169: return s;
6170: }
6171:
6172: static const XML_Char *
6173: poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6174: {
6175: if (!pool->ptr && !poolGrow(pool))
6176: return NULL;
6177: for (; n > 0; --n, s++) {
6178: if (!poolAppendChar(pool, *s))
6179: return NULL;
6180: }
6181: s = pool->start;
6182: poolFinish(pool);
6183: return s;
6184: }
6185:
6186: static const XML_Char * FASTCALL
6187: poolAppendString(STRING_POOL *pool, const XML_Char *s)
6188: {
6189: while (*s) {
6190: if (!poolAppendChar(pool, *s))
6191: return NULL;
6192: s++;
6193: }
6194: return pool->start;
6195: }
6196:
6197: static XML_Char *
6198: poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6199: const char *ptr, const char *end)
6200: {
6201: if (!poolAppend(pool, enc, ptr, end))
6202: return NULL;
6203: if (pool->ptr == pool->end && !poolGrow(pool))
6204: return NULL;
6205: *(pool->ptr)++ = 0;
6206: return pool->start;
6207: }
6208:
6209: static XML_Bool FASTCALL
6210: poolGrow(STRING_POOL *pool)
6211: {
6212: if (pool->freeBlocks) {
6213: if (pool->start == 0) {
6214: pool->blocks = pool->freeBlocks;
6215: pool->freeBlocks = pool->freeBlocks->next;
6216: pool->blocks->next = NULL;
6217: pool->start = pool->blocks->s;
6218: pool->end = pool->start + pool->blocks->size;
6219: pool->ptr = pool->start;
6220: return XML_TRUE;
6221: }
6222: if (pool->end - pool->start < pool->freeBlocks->size) {
6223: BLOCK *tem = pool->freeBlocks->next;
6224: pool->freeBlocks->next = pool->blocks;
6225: pool->blocks = pool->freeBlocks;
6226: pool->freeBlocks = tem;
6227: memcpy(pool->blocks->s, pool->start,
6228: (pool->end - pool->start) * sizeof(XML_Char));
6229: pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6230: pool->start = pool->blocks->s;
6231: pool->end = pool->start + pool->blocks->size;
6232: return XML_TRUE;
6233: }
6234: }
6235: if (pool->blocks && pool->start == pool->blocks->s) {
6236: int blockSize = (int)(pool->end - pool->start)*2;
1.1.1.2 ! misho 6237: BLOCK *temp = (BLOCK *)
1.1 misho 6238: pool->mem->realloc_fcn(pool->blocks,
6239: (offsetof(BLOCK, s)
6240: + blockSize * sizeof(XML_Char)));
1.1.1.2 ! misho 6241: if (temp == NULL)
1.1 misho 6242: return XML_FALSE;
1.1.1.2 ! misho 6243: pool->blocks = temp;
1.1 misho 6244: pool->blocks->size = blockSize;
6245: pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6246: pool->start = pool->blocks->s;
6247: pool->end = pool->start + blockSize;
6248: }
6249: else {
6250: BLOCK *tem;
6251: int blockSize = (int)(pool->end - pool->start);
6252: if (blockSize < INIT_BLOCK_SIZE)
6253: blockSize = INIT_BLOCK_SIZE;
6254: else
6255: blockSize *= 2;
6256: tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6257: + blockSize * sizeof(XML_Char));
6258: if (!tem)
6259: return XML_FALSE;
6260: tem->size = blockSize;
6261: tem->next = pool->blocks;
6262: pool->blocks = tem;
6263: if (pool->ptr != pool->start)
6264: memcpy(tem->s, pool->start,
6265: (pool->ptr - pool->start) * sizeof(XML_Char));
6266: pool->ptr = tem->s + (pool->ptr - pool->start);
6267: pool->start = tem->s;
6268: pool->end = tem->s + blockSize;
6269: }
6270: return XML_TRUE;
6271: }
6272:
6273: static int FASTCALL
6274: nextScaffoldPart(XML_Parser parser)
6275: {
6276: DTD * const dtd = _dtd; /* save one level of indirection */
6277: CONTENT_SCAFFOLD * me;
6278: int next;
6279:
6280: if (!dtd->scaffIndex) {
6281: dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6282: if (!dtd->scaffIndex)
6283: return -1;
6284: dtd->scaffIndex[0] = 0;
6285: }
6286:
6287: if (dtd->scaffCount >= dtd->scaffSize) {
6288: CONTENT_SCAFFOLD *temp;
6289: if (dtd->scaffold) {
6290: temp = (CONTENT_SCAFFOLD *)
6291: REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6292: if (temp == NULL)
6293: return -1;
6294: dtd->scaffSize *= 2;
6295: }
6296: else {
6297: temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6298: * sizeof(CONTENT_SCAFFOLD));
6299: if (temp == NULL)
6300: return -1;
6301: dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6302: }
6303: dtd->scaffold = temp;
6304: }
6305: next = dtd->scaffCount++;
6306: me = &dtd->scaffold[next];
6307: if (dtd->scaffLevel) {
6308: CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6309: if (parent->lastchild) {
6310: dtd->scaffold[parent->lastchild].nextsib = next;
6311: }
6312: if (!parent->childcnt)
6313: parent->firstchild = next;
6314: parent->lastchild = next;
6315: parent->childcnt++;
6316: }
6317: me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6318: return next;
6319: }
6320:
6321: static void
6322: build_node(XML_Parser parser,
6323: int src_node,
6324: XML_Content *dest,
6325: XML_Content **contpos,
6326: XML_Char **strpos)
6327: {
6328: DTD * const dtd = _dtd; /* save one level of indirection */
6329: dest->type = dtd->scaffold[src_node].type;
6330: dest->quant = dtd->scaffold[src_node].quant;
6331: if (dest->type == XML_CTYPE_NAME) {
6332: const XML_Char *src;
6333: dest->name = *strpos;
6334: src = dtd->scaffold[src_node].name;
6335: for (;;) {
6336: *(*strpos)++ = *src;
6337: if (!*src)
6338: break;
6339: src++;
6340: }
6341: dest->numchildren = 0;
6342: dest->children = NULL;
6343: }
6344: else {
6345: unsigned int i;
6346: int cn;
6347: dest->numchildren = dtd->scaffold[src_node].childcnt;
6348: dest->children = *contpos;
6349: *contpos += dest->numchildren;
6350: for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6351: i < dest->numchildren;
6352: i++, cn = dtd->scaffold[cn].nextsib) {
6353: build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6354: }
6355: dest->name = NULL;
6356: }
6357: }
6358:
6359: static XML_Content *
6360: build_model (XML_Parser parser)
6361: {
6362: DTD * const dtd = _dtd; /* save one level of indirection */
6363: XML_Content *ret;
6364: XML_Content *cpos;
6365: XML_Char * str;
6366: int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6367: + (dtd->contentStringLen * sizeof(XML_Char)));
6368:
6369: ret = (XML_Content *)MALLOC(allocsize);
6370: if (!ret)
6371: return NULL;
6372:
6373: str = (XML_Char *) (&ret[dtd->scaffCount]);
6374: cpos = &ret[1];
6375:
6376: build_node(parser, 0, ret, &cpos, &str);
6377: return ret;
6378: }
6379:
6380: static ELEMENT_TYPE *
6381: getElementType(XML_Parser parser,
6382: const ENCODING *enc,
6383: const char *ptr,
6384: const char *end)
6385: {
6386: DTD * const dtd = _dtd; /* save one level of indirection */
6387: const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6388: ELEMENT_TYPE *ret;
6389:
6390: if (!name)
6391: return NULL;
1.1.1.2 ! misho 6392: ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
1.1 misho 6393: if (!ret)
6394: return NULL;
6395: if (ret->name != name)
6396: poolDiscard(&dtd->pool);
6397: else {
6398: poolFinish(&dtd->pool);
6399: if (!setElementTypePrefix(parser, ret))
6400: return NULL;
6401: }
6402: return ret;
6403: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>