SAX based XML parser

Dependents:   giken9_HTMLServer_Temp_Sample

Committer:
andrewbonney
Date:
Fri Apr 08 09:18:41 2011 +0000
Revision:
0:07919e3d6c56
Child:
1:e96b2af301dd

        

Who changed what in which revision?

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