1
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2
See the file COPYING for copying permission.
6
#include <string.h> /* memset(), memcpy() */
8
#define XML_BUILDING_EXPAT 1
10
#ifdef COMPILED_FROM_DSP
11
#include "winconfig.h"
12
#elif defined(MACOS_CLASSIC)
13
#include "macconfig.h"
15
#ifdef HAVE_EXPAT_CONFIG_H
16
#include <expat_config.h>
18
#endif /* ndef COMPILED_FROM_DSP */
23
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
24
#define XmlConvert XmlUtf16Convert
25
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
26
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
27
#define XmlEncode XmlUtf16Encode
28
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
29
typedef unsigned short ICHAR;
31
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
32
#define XmlConvert XmlUtf8Convert
33
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
34
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
35
#define XmlEncode XmlUtf8Encode
36
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
43
#define XmlInitEncodingNS XmlInitEncoding
44
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
45
#undef XmlGetInternalEncodingNS
46
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
47
#define XmlParseXmlDeclNS XmlParseXmlDecl
53
#ifdef XML_UNICODE_WCHAR_T
54
#define XML_T(x) (const wchar_t)x
55
#define XML_L(x) L ## x
57
#define XML_T(x) (const unsigned short)x
68
/* Round up n to be a multiple of sz, where sz is a power of 2. */
69
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
71
/* Handle the case where memmove() doesn't exist. */
74
#define memmove(d,s,l) bcopy((s),(d),(l))
76
#error memmove does not exist on this platform, nor is a substitute available
77
#endif /* HAVE_BCOPY */
78
#endif /* HAVE_MEMMOVE */
84
typedef const XML_Char *KEY;
95
const XML_Memory_Handling_Suite *mem;
98
/* Basic character hash algorithm, taken from Python's string hash:
99
h = h * 1000003 ^ character, the constant being a prime number.
103
#define CHAR_HASH(h, c) \
104
(((h) * 0xF4243) ^ (unsigned short)(c))
106
#define CHAR_HASH(h, c) \
107
(((h) * 0xF4243) ^ (unsigned char)(c))
110
/* For probing (after a collision) we need a step size relative prime
111
to the hash table size, which is a power of 2. We use double-hashing,
112
since we can calculate a second hash value cheaply by taking those bits
113
of the first hash value that were discarded (masked out) when the table
114
index was calculated: index = hash & mask, where mask = table->size - 1.
115
We limit the maximum step size to table->size / 4 (mask >> 2) and make
116
it odd, since odd numbers are always relative prime to a power of 2.
118
#define SECOND_HASH(hash, mask, power) \
119
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
120
#define PROBE_STEP(hash, mask, power) \
121
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
128
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
129
#define INIT_DATA_BUF_SIZE 1024
130
#define INIT_ATTS_SIZE 16
131
#define INIT_ATTS_VERSION 0xFFFFFFFF
132
#define INIT_BLOCK_SIZE 1024
133
#define INIT_BUFFER_SIZE 1024
135
#define EXPAND_SPARE 24
137
typedef struct binding {
138
struct prefix *prefix;
139
struct binding *nextTagBinding;
140
struct binding *prevPrefixBinding;
141
const struct attribute_id *attId;
147
typedef struct prefix {
148
const XML_Char *name;
154
const XML_Char *localPart;
155
const XML_Char *prefix;
161
/* TAG represents an open element.
162
The name of the element is stored in both the document and API
163
encodings. The memory buffer 'buf' is a separately-allocated
164
memory area which stores the name. During the XML_Parse()/
165
XMLParseBuffer() when the element is open, the memory for the 'raw'
166
version of the name (in the document encoding) is shared with the
167
document buffer. If the element is open across calls to
168
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
169
contain the 'raw' name as well.
171
A parser re-uses these structures, maintaining a list of allocated
172
TAG objects in a free list.
175
struct tag *parent; /* parent of this element */
176
const char *rawName; /* tagName in the original encoding */
178
TAG_NAME name; /* tagName in the API encoding */
179
char *buf; /* buffer for name components */
180
char *bufEnd; /* end of the buffer */
185
const XML_Char *name;
186
const XML_Char *textPtr;
188
const XML_Char *systemId;
189
const XML_Char *base;
190
const XML_Char *publicId;
191
const XML_Char *notation;
194
XML_Bool is_internal; /* true if declared in internal subset outside PE */
198
enum XML_Content_Type type;
199
enum XML_Content_Quant quant;
200
const XML_Char * name;
207
#define INIT_SCAFFOLD_ELEMENTS 32
209
typedef struct block {
221
const XML_Memory_Handling_Suite *mem;
224
/* The XML_Char before the name is used to determine whether
225
an attribute has been specified. */
226
typedef struct attribute_id {
229
XML_Bool maybeTokenized;
234
const ATTRIBUTE_ID *id;
236
const XML_Char *value;
240
unsigned long version;
242
const XML_Char *uriName;
246
const XML_Char *name;
248
const ATTRIBUTE_ID *idAtt;
250
int allocDefaultAtts;
251
DEFAULT_ATTRIBUTE *defaultAtts;
255
HASH_TABLE generalEntities;
256
HASH_TABLE elementTypes;
257
HASH_TABLE attributeIds;
260
STRING_POOL entityValuePool;
261
/* false once a parameter entity reference has been skipped */
262
XML_Bool keepProcessing;
263
/* true once an internal or external PE reference has been encountered;
264
this includes the reference to an external subset */
265
XML_Bool hasParamEntityRefs;
268
/* indicates if external PE has been read */
269
XML_Bool paramEntityRead;
270
HASH_TABLE paramEntities;
272
PREFIX defaultPrefix;
273
/* === scaffolding for building content model === */
275
CONTENT_SCAFFOLD *scaffold;
276
unsigned contentStringLen;
283
typedef struct open_internal_entity {
284
const char *internalEventPtr;
285
const char *internalEventEndPtr;
286
struct open_internal_entity *next;
288
} OPEN_INTERNAL_ENTITY;
290
typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
293
const char **endPtr);
295
static Processor prologProcessor;
296
static Processor prologInitProcessor;
297
static Processor contentProcessor;
298
static Processor cdataSectionProcessor;
300
static Processor ignoreSectionProcessor;
301
static Processor externalParEntProcessor;
302
static Processor externalParEntInitProcessor;
303
static Processor entityValueProcessor;
304
static Processor entityValueInitProcessor;
306
static Processor epilogProcessor;
307
static Processor errorProcessor;
308
static Processor externalEntityInitProcessor;
309
static Processor externalEntityInitProcessor2;
310
static Processor externalEntityInitProcessor3;
311
static Processor externalEntityContentProcessor;
313
static enum XML_Error
314
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
315
static enum XML_Error
316
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
317
const char *, const char *);
318
static enum XML_Error
319
initializeEncoding(XML_Parser parser);
320
static enum XML_Error
321
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
322
const char *end, int tok, const char *next, const char **nextPtr);
323
static enum XML_Error
324
processInternalParamEntity(XML_Parser parser, ENTITY *entity);
325
static enum XML_Error
326
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
327
const char *start, const char *end, const char **endPtr);
328
static enum XML_Error
329
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
330
const char *end, const char **nextPtr);
332
static enum XML_Error
333
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
334
const char *end, const char **nextPtr);
337
static enum XML_Error
338
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
339
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
340
static enum XML_Error
341
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
342
const XML_Char *uri, BINDING **bindingsPtr);
344
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
345
XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
347
static enum XML_Error
348
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
349
const char *, const char *, STRING_POOL *);
350
static enum XML_Error
351
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
352
const char *, const char *, STRING_POOL *);
353
static ATTRIBUTE_ID *
354
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
357
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
358
static enum XML_Error
359
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
362
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
363
const char *start, const char *end);
365
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
368
reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
371
static const XML_Char * getContext(XML_Parser parser);
373
setContext(XML_Parser parser, const XML_Char *context);
375
static void FASTCALL normalizePublicId(XML_Char *s);
377
static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
378
/* do not call if parentParser != NULL */
379
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
381
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
383
dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
385
copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
388
lookup(HASH_TABLE *table, KEY name, size_t createSize);
390
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
391
static void FASTCALL hashTableClear(HASH_TABLE *);
392
static void FASTCALL hashTableDestroy(HASH_TABLE *);
394
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
395
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
398
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
399
static void FASTCALL poolClear(STRING_POOL *);
400
static void FASTCALL poolDestroy(STRING_POOL *);
402
poolAppend(STRING_POOL *pool, const ENCODING *enc,
403
const char *ptr, const char *end);
405
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
406
const char *ptr, const char *end);
407
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
408
static const XML_Char * FASTCALL
409
poolCopyString(STRING_POOL *pool, const XML_Char *s);
410
static const XML_Char *
411
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
412
static const XML_Char * FASTCALL
413
poolAppendString(STRING_POOL *pool, const XML_Char *s);
415
static int FASTCALL nextScaffoldPart(XML_Parser parser);
416
static XML_Content * build_model(XML_Parser parser);
417
static ELEMENT_TYPE *
418
getElementType(XML_Parser parser, const ENCODING *enc,
419
const char *ptr, const char *end);
422
parserCreate(const XML_Char *encodingName,
423
const XML_Memory_Handling_Suite *memsuite,
424
const XML_Char *nameSep,
427
parserInit(XML_Parser parser, const XML_Char *encodingName);
429
#define poolStart(pool) ((pool)->start)
430
#define poolEnd(pool) ((pool)->ptr)
431
#define poolLength(pool) ((pool)->ptr - (pool)->start)
432
#define poolChop(pool) ((void)--(pool->ptr))
433
#define poolLastChar(pool) (((pool)->ptr)[-1])
434
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
435
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
436
#define poolAppendChar(pool, c) \
437
(((pool)->ptr == (pool)->end && !poolGrow(pool)) \
439
: ((*((pool)->ptr)++ = c), 1))
441
struct XML_ParserStruct {
442
/* The first member must be userData so that the XML_GetUserData
447
const XML_Memory_Handling_Suite m_mem;
448
/* first character to be parsed */
449
const char *m_bufferPtr;
450
/* past last character to be parsed */
452
/* allocated end of buffer */
453
const char *m_bufferLim;
454
long m_parseEndByteIndex;
455
const char *m_parseEndPtr;
457
XML_Char *m_dataBufEnd;
458
XML_StartElementHandler m_startElementHandler;
459
XML_EndElementHandler m_endElementHandler;
460
XML_CharacterDataHandler m_characterDataHandler;
461
XML_ProcessingInstructionHandler m_processingInstructionHandler;
462
XML_CommentHandler m_commentHandler;
463
XML_StartCdataSectionHandler m_startCdataSectionHandler;
464
XML_EndCdataSectionHandler m_endCdataSectionHandler;
465
XML_DefaultHandler m_defaultHandler;
466
XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
467
XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
468
XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
469
XML_NotationDeclHandler m_notationDeclHandler;
470
XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
471
XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
472
XML_NotStandaloneHandler m_notStandaloneHandler;
473
XML_ExternalEntityRefHandler m_externalEntityRefHandler;
474
XML_Parser m_externalEntityRefHandlerArg;
475
XML_SkippedEntityHandler m_skippedEntityHandler;
476
XML_UnknownEncodingHandler m_unknownEncodingHandler;
477
XML_ElementDeclHandler m_elementDeclHandler;
478
XML_AttlistDeclHandler m_attlistDeclHandler;
479
XML_EntityDeclHandler m_entityDeclHandler;
480
XML_XmlDeclHandler m_xmlDeclHandler;
481
const ENCODING *m_encoding;
482
INIT_ENCODING m_initEncoding;
483
const ENCODING *m_internalEncoding;
484
const XML_Char *m_protocolEncodingName;
486
XML_Bool m_ns_triplets;
487
void *m_unknownEncodingMem;
488
void *m_unknownEncodingData;
489
void *m_unknownEncodingHandlerData;
490
void (*m_unknownEncodingRelease)(void *);
491
PROLOG_STATE m_prologState;
492
Processor *m_processor;
493
enum XML_Error m_errorCode;
494
const char *m_eventPtr;
495
const char *m_eventEndPtr;
496
const char *m_positionPtr;
497
OPEN_INTERNAL_ENTITY *m_openInternalEntities;
498
XML_Bool m_defaultExpandInternalEntities;
500
ENTITY *m_declEntity;
501
const XML_Char *m_doctypeName;
502
const XML_Char *m_doctypeSysid;
503
const XML_Char *m_doctypePubid;
504
const XML_Char *m_declAttributeType;
505
const XML_Char *m_declNotationName;
506
const XML_Char *m_declNotationPublicId;
507
ELEMENT_TYPE *m_declElementType;
508
ATTRIBUTE_ID *m_declAttributeId;
509
XML_Bool m_declAttributeIsCdata;
510
XML_Bool m_declAttributeIsId;
512
const XML_Char *m_curBase;
515
BINDING *m_inheritedBindings;
516
BINDING *m_freeBindingList;
518
int m_nSpecifiedAtts;
522
unsigned long m_nsAttsVersion;
523
unsigned char m_nsAttsPower;
525
STRING_POOL m_tempPool;
526
STRING_POOL m_temp2Pool;
527
char *m_groupConnector;
528
unsigned int m_groupSize;
529
XML_Char m_namespaceSeparator;
530
XML_Parser m_parentParser;
532
XML_Bool m_isParamEntity;
533
XML_Bool m_useForeignDTD;
534
enum XML_ParamEntityParsing m_paramEntityParsing;
538
#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
539
#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
540
#define FREE(p) (parser->m_mem.free_fcn((p)))
542
#define userData (parser->m_userData)
543
#define handlerArg (parser->m_handlerArg)
544
#define startElementHandler (parser->m_startElementHandler)
545
#define endElementHandler (parser->m_endElementHandler)
546
#define characterDataHandler (parser->m_characterDataHandler)
547
#define processingInstructionHandler \
548
(parser->m_processingInstructionHandler)
549
#define commentHandler (parser->m_commentHandler)
550
#define startCdataSectionHandler \
551
(parser->m_startCdataSectionHandler)
552
#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
553
#define defaultHandler (parser->m_defaultHandler)
554
#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
555
#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
556
#define unparsedEntityDeclHandler \
557
(parser->m_unparsedEntityDeclHandler)
558
#define notationDeclHandler (parser->m_notationDeclHandler)
559
#define startNamespaceDeclHandler \
560
(parser->m_startNamespaceDeclHandler)
561
#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
562
#define notStandaloneHandler (parser->m_notStandaloneHandler)
563
#define externalEntityRefHandler \
564
(parser->m_externalEntityRefHandler)
565
#define externalEntityRefHandlerArg \
566
(parser->m_externalEntityRefHandlerArg)
567
#define internalEntityRefHandler \
568
(parser->m_internalEntityRefHandler)
569
#define skippedEntityHandler (parser->m_skippedEntityHandler)
570
#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
571
#define elementDeclHandler (parser->m_elementDeclHandler)
572
#define attlistDeclHandler (parser->m_attlistDeclHandler)
573
#define entityDeclHandler (parser->m_entityDeclHandler)
574
#define xmlDeclHandler (parser->m_xmlDeclHandler)
575
#define encoding (parser->m_encoding)
576
#define initEncoding (parser->m_initEncoding)
577
#define internalEncoding (parser->m_internalEncoding)
578
#define unknownEncodingMem (parser->m_unknownEncodingMem)
579
#define unknownEncodingData (parser->m_unknownEncodingData)
580
#define unknownEncodingHandlerData \
581
(parser->m_unknownEncodingHandlerData)
582
#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
583
#define protocolEncodingName (parser->m_protocolEncodingName)
584
#define ns (parser->m_ns)
585
#define ns_triplets (parser->m_ns_triplets)
586
#define prologState (parser->m_prologState)
587
#define processor (parser->m_processor)
588
#define errorCode (parser->m_errorCode)
589
#define eventPtr (parser->m_eventPtr)
590
#define eventEndPtr (parser->m_eventEndPtr)
591
#define positionPtr (parser->m_positionPtr)
592
#define position (parser->m_position)
593
#define openInternalEntities (parser->m_openInternalEntities)
594
#define defaultExpandInternalEntities \
595
(parser->m_defaultExpandInternalEntities)
596
#define tagLevel (parser->m_tagLevel)
597
#define buffer (parser->m_buffer)
598
#define bufferPtr (parser->m_bufferPtr)
599
#define bufferEnd (parser->m_bufferEnd)
600
#define parseEndByteIndex (parser->m_parseEndByteIndex)
601
#define parseEndPtr (parser->m_parseEndPtr)
602
#define bufferLim (parser->m_bufferLim)
603
#define dataBuf (parser->m_dataBuf)
604
#define dataBufEnd (parser->m_dataBufEnd)
605
#define _dtd (parser->m_dtd)
606
#define curBase (parser->m_curBase)
607
#define declEntity (parser->m_declEntity)
608
#define doctypeName (parser->m_doctypeName)
609
#define doctypeSysid (parser->m_doctypeSysid)
610
#define doctypePubid (parser->m_doctypePubid)
611
#define declAttributeType (parser->m_declAttributeType)
612
#define declNotationName (parser->m_declNotationName)
613
#define declNotationPublicId (parser->m_declNotationPublicId)
614
#define declElementType (parser->m_declElementType)
615
#define declAttributeId (parser->m_declAttributeId)
616
#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
617
#define declAttributeIsId (parser->m_declAttributeIsId)
618
#define freeTagList (parser->m_freeTagList)
619
#define freeBindingList (parser->m_freeBindingList)
620
#define inheritedBindings (parser->m_inheritedBindings)
621
#define tagStack (parser->m_tagStack)
622
#define atts (parser->m_atts)
623
#define attsSize (parser->m_attsSize)
624
#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
625
#define idAttIndex (parser->m_idAttIndex)
626
#define nsAtts (parser->m_nsAtts)
627
#define nsAttsVersion (parser->m_nsAttsVersion)
628
#define nsAttsPower (parser->m_nsAttsPower)
629
#define tempPool (parser->m_tempPool)
630
#define temp2Pool (parser->m_temp2Pool)
631
#define groupConnector (parser->m_groupConnector)
632
#define groupSize (parser->m_groupSize)
633
#define namespaceSeparator (parser->m_namespaceSeparator)
634
#define parentParser (parser->m_parentParser)
636
#define isParamEntity (parser->m_isParamEntity)
637
#define useForeignDTD (parser->m_useForeignDTD)
638
#define paramEntityParsing (parser->m_paramEntityParsing)
647
(processor != externalParEntInitProcessor) \
649
(processor != externalEntityInitProcessor)) \
651
(processor != prologInitProcessor))
656
(processor != externalEntityInitProcessor) \
658
(processor != prologInitProcessor))
662
XML_ParserCreate(const XML_Char *encodingName)
664
return XML_ParserCreate_MM(encodingName, NULL, NULL);
668
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
672
return XML_ParserCreate_MM(encodingName, NULL, tmp);
675
static const XML_Char implicitContext[] = {
676
'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
677
'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
678
'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
679
'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
683
XML_ParserCreate_MM(const XML_Char *encodingName,
684
const XML_Memory_Handling_Suite *memsuite,
685
const XML_Char *nameSep)
687
XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
688
if (parser != NULL && ns) {
689
/* implicit context only set for root parser, since child
690
parsers (i.e. external entity parsers) will inherit it
692
if (!setContext(parser, implicitContext)) {
693
XML_ParserFree(parser);
701
parserCreate(const XML_Char *encodingName,
702
const XML_Memory_Handling_Suite *memsuite,
703
const XML_Char *nameSep,
709
XML_Memory_Handling_Suite *mtemp;
710
parser = (XML_Parser)
711
memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
712
if (parser != NULL) {
713
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
714
mtemp->malloc_fcn = memsuite->malloc_fcn;
715
mtemp->realloc_fcn = memsuite->realloc_fcn;
716
mtemp->free_fcn = memsuite->free_fcn;
720
XML_Memory_Handling_Suite *mtemp;
721
parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
722
if (parser != NULL) {
723
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
724
mtemp->malloc_fcn = malloc;
725
mtemp->realloc_fcn = realloc;
726
mtemp->free_fcn = free;
736
attsSize = INIT_ATTS_SIZE;
737
atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
742
dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
743
if (dataBuf == NULL) {
748
dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
753
_dtd = dtdCreate(&parser->m_mem);
762
freeBindingList = NULL;
766
groupConnector = NULL;
768
unknownEncodingHandler = NULL;
769
unknownEncodingHandlerData = NULL;
771
namespaceSeparator = '!';
773
ns_triplets = XML_FALSE;
779
poolInit(&tempPool, &(parser->m_mem));
780
poolInit(&temp2Pool, &(parser->m_mem));
781
parserInit(parser, encodingName);
783
if (encodingName && !protocolEncodingName) {
784
XML_ParserFree(parser);
790
internalEncoding = XmlGetInternalEncodingNS();
791
namespaceSeparator = *nameSep;
794
internalEncoding = XmlGetInternalEncoding();
801
parserInit(XML_Parser parser, const XML_Char *encodingName)
803
processor = prologInitProcessor;
804
XmlPrologStateInit(&prologState);
805
protocolEncodingName = (encodingName != NULL
806
? poolCopyString(&tempPool, encodingName)
809
XmlInitEncoding(&initEncoding, &encoding, 0);
812
startElementHandler = NULL;
813
endElementHandler = NULL;
814
characterDataHandler = NULL;
815
processingInstructionHandler = NULL;
816
commentHandler = NULL;
817
startCdataSectionHandler = NULL;
818
endCdataSectionHandler = NULL;
819
defaultHandler = NULL;
820
startDoctypeDeclHandler = NULL;
821
endDoctypeDeclHandler = NULL;
822
unparsedEntityDeclHandler = NULL;
823
notationDeclHandler = NULL;
824
startNamespaceDeclHandler = NULL;
825
endNamespaceDeclHandler = NULL;
826
notStandaloneHandler = NULL;
827
externalEntityRefHandler = NULL;
828
externalEntityRefHandlerArg = parser;
829
skippedEntityHandler = NULL;
830
elementDeclHandler = NULL;
831
attlistDeclHandler = NULL;
832
entityDeclHandler = NULL;
833
xmlDeclHandler = NULL;
836
parseEndByteIndex = 0;
838
declElementType = NULL;
839
declAttributeId = NULL;
844
declAttributeType = NULL;
845
declNotationName = NULL;
846
declNotationPublicId = NULL;
847
declAttributeIsCdata = XML_FALSE;
848
declAttributeIsId = XML_FALSE;
849
memset(&position, 0, sizeof(POSITION));
850
errorCode = XML_ERROR_NONE;
854
openInternalEntities = 0;
855
defaultExpandInternalEntities = XML_TRUE;
858
inheritedBindings = NULL;
860
unknownEncodingMem = NULL;
861
unknownEncodingRelease = NULL;
862
unknownEncodingData = NULL;
865
isParamEntity = XML_FALSE;
866
useForeignDTD = XML_FALSE;
867
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
871
/* moves list of bindings to freeBindingList */
873
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
876
BINDING *b = bindings;
877
bindings = bindings->nextTagBinding;
878
b->nextTagBinding = freeBindingList;
884
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
889
/* move tagStack to freeTagList */
894
tag->parent = freeTagList;
895
moveToFreeBindingList(parser, tag->bindings);
896
tag->bindings = NULL;
899
moveToFreeBindingList(parser, inheritedBindings);
900
FREE(unknownEncodingMem);
901
if (unknownEncodingRelease)
902
unknownEncodingRelease(unknownEncodingData);
903
poolClear(&tempPool);
904
poolClear(&temp2Pool);
905
parserInit(parser, encodingName);
906
dtdReset(_dtd, &parser->m_mem);
907
return setContext(parser, implicitContext);
910
enum XML_Status XMLCALL
911
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
913
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
914
XXX There's no way for the caller to determine which of the
915
XXX possible error cases caused the XML_STATUS_ERROR return.
918
return XML_STATUS_ERROR;
919
if (encodingName == NULL)
920
protocolEncodingName = NULL;
922
protocolEncodingName = poolCopyString(&tempPool, encodingName);
923
if (!protocolEncodingName)
924
return XML_STATUS_ERROR;
926
return XML_STATUS_OK;
930
XML_ExternalEntityParserCreate(XML_Parser oldParser,
931
const XML_Char *context,
932
const XML_Char *encodingName)
934
XML_Parser parser = oldParser;
937
XML_StartElementHandler oldStartElementHandler = startElementHandler;
938
XML_EndElementHandler oldEndElementHandler = endElementHandler;
939
XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
940
XML_ProcessingInstructionHandler oldProcessingInstructionHandler
941
= processingInstructionHandler;
942
XML_CommentHandler oldCommentHandler = commentHandler;
943
XML_StartCdataSectionHandler oldStartCdataSectionHandler
944
= startCdataSectionHandler;
945
XML_EndCdataSectionHandler oldEndCdataSectionHandler
946
= endCdataSectionHandler;
947
XML_DefaultHandler oldDefaultHandler = defaultHandler;
948
XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
949
= unparsedEntityDeclHandler;
950
XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
951
XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
952
= startNamespaceDeclHandler;
953
XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
954
= endNamespaceDeclHandler;
955
XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
956
XML_ExternalEntityRefHandler oldExternalEntityRefHandler
957
= externalEntityRefHandler;
958
XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
959
XML_UnknownEncodingHandler oldUnknownEncodingHandler
960
= unknownEncodingHandler;
961
XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
962
XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
963
XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
964
XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
965
ELEMENT_TYPE * oldDeclElementType = declElementType;
967
void *oldUserData = userData;
968
void *oldHandlerArg = handlerArg;
969
XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
970
XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
972
enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
973
int oldInEntityValue = prologState.inEntityValue;
975
XML_Bool oldns_triplets = ns_triplets;
982
/* Note that the magical uses of the pre-processor to make field
983
access look more like C++ require that `parser' be overwritten
984
here. This makes this function more painful to follow than it
989
*tmp = namespaceSeparator;
990
parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
993
parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
999
startElementHandler = oldStartElementHandler;
1000
endElementHandler = oldEndElementHandler;
1001
characterDataHandler = oldCharacterDataHandler;
1002
processingInstructionHandler = oldProcessingInstructionHandler;
1003
commentHandler = oldCommentHandler;
1004
startCdataSectionHandler = oldStartCdataSectionHandler;
1005
endCdataSectionHandler = oldEndCdataSectionHandler;
1006
defaultHandler = oldDefaultHandler;
1007
unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1008
notationDeclHandler = oldNotationDeclHandler;
1009
startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1010
endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1011
notStandaloneHandler = oldNotStandaloneHandler;
1012
externalEntityRefHandler = oldExternalEntityRefHandler;
1013
skippedEntityHandler = oldSkippedEntityHandler;
1014
unknownEncodingHandler = oldUnknownEncodingHandler;
1015
elementDeclHandler = oldElementDeclHandler;
1016
attlistDeclHandler = oldAttlistDeclHandler;
1017
entityDeclHandler = oldEntityDeclHandler;
1018
xmlDeclHandler = oldXmlDeclHandler;
1019
declElementType = oldDeclElementType;
1020
userData = oldUserData;
1021
if (oldUserData == oldHandlerArg)
1022
handlerArg = userData;
1024
handlerArg = parser;
1025
if (oldExternalEntityRefHandlerArg != oldParser)
1026
externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1027
defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1028
ns_triplets = oldns_triplets;
1029
parentParser = oldParser;
1031
paramEntityParsing = oldParamEntityParsing;
1032
prologState.inEntityValue = oldInEntityValue;
1034
#endif /* XML_DTD */
1035
if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1036
|| !setContext(parser, context)) {
1037
XML_ParserFree(parser);
1040
processor = externalEntityInitProcessor;
1044
/* The DTD instance referenced by _dtd is shared between the document's
1045
root parser and external PE parsers, therefore one does not need to
1046
call setContext. In addition, one also *must* not call setContext,
1047
because this would overwrite existing prefix->binding pointers in
1048
_dtd with ones that get destroyed with the external PE parser.
1049
This would leave those prefixes with dangling pointers.
1051
isParamEntity = XML_TRUE;
1052
XmlPrologStateInitExternalEntity(&prologState);
1053
processor = externalParEntInitProcessor;
1055
#endif /* XML_DTD */
1059
static void FASTCALL
1060
destroyBindings(BINDING *bindings, XML_Parser parser)
1063
BINDING *b = bindings;
1066
bindings = b->nextTagBinding;
1073
XML_ParserFree(XML_Parser parser)
1077
if (tagStack == NULL) {
1078
if (freeTagList == NULL)
1080
tagStack = freeTagList;
1084
tagStack = tagStack->parent;
1086
destroyBindings(p->bindings, parser);
1089
destroyBindings(freeBindingList, parser);
1090
destroyBindings(inheritedBindings, parser);
1091
poolDestroy(&tempPool);
1092
poolDestroy(&temp2Pool);
1094
/* external parameter entity parsers share the DTD structure
1095
parser->m_dtd with the root parser, so we must not destroy it
1097
if (!isParamEntity && _dtd)
1100
#endif /* XML_DTD */
1101
dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1103
FREE(groupConnector);
1107
FREE(unknownEncodingMem);
1108
if (unknownEncodingRelease)
1109
unknownEncodingRelease(unknownEncodingData);
1114
XML_UseParserAsHandlerArg(XML_Parser parser)
1116
handlerArg = parser;
1119
enum XML_Error XMLCALL
1120
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1123
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1125
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1126
useForeignDTD = useDTD;
1127
return XML_ERROR_NONE;
1129
return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1134
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1136
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1139
ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1143
XML_SetUserData(XML_Parser parser, void *p)
1145
if (handlerArg == userData)
1146
handlerArg = userData = p;
1151
enum XML_Status XMLCALL
1152
XML_SetBase(XML_Parser parser, const XML_Char *p)
1155
p = poolCopyString(&_dtd->pool, p);
1157
return XML_STATUS_ERROR;
1162
return XML_STATUS_OK;
1165
const XML_Char * XMLCALL
1166
XML_GetBase(XML_Parser parser)
1172
XML_GetSpecifiedAttributeCount(XML_Parser parser)
1174
return nSpecifiedAtts;
1178
XML_GetIdAttributeIndex(XML_Parser parser)
1184
XML_SetElementHandler(XML_Parser parser,
1185
XML_StartElementHandler start,
1186
XML_EndElementHandler end)
1188
startElementHandler = start;
1189
endElementHandler = end;
1193
XML_SetStartElementHandler(XML_Parser parser,
1194
XML_StartElementHandler start) {
1195
startElementHandler = start;
1199
XML_SetEndElementHandler(XML_Parser parser,
1200
XML_EndElementHandler end) {
1201
endElementHandler = end;
1205
XML_SetCharacterDataHandler(XML_Parser parser,
1206
XML_CharacterDataHandler handler)
1208
characterDataHandler = handler;
1212
XML_SetProcessingInstructionHandler(XML_Parser parser,
1213
XML_ProcessingInstructionHandler handler)
1215
processingInstructionHandler = handler;
1219
XML_SetCommentHandler(XML_Parser parser,
1220
XML_CommentHandler handler)
1222
commentHandler = handler;
1226
XML_SetCdataSectionHandler(XML_Parser parser,
1227
XML_StartCdataSectionHandler start,
1228
XML_EndCdataSectionHandler end)
1230
startCdataSectionHandler = start;
1231
endCdataSectionHandler = end;
1235
XML_SetStartCdataSectionHandler(XML_Parser parser,
1236
XML_StartCdataSectionHandler start) {
1237
startCdataSectionHandler = start;
1241
XML_SetEndCdataSectionHandler(XML_Parser parser,
1242
XML_EndCdataSectionHandler end) {
1243
endCdataSectionHandler = end;
1247
XML_SetDefaultHandler(XML_Parser parser,
1248
XML_DefaultHandler handler)
1250
defaultHandler = handler;
1251
defaultExpandInternalEntities = XML_FALSE;
1255
XML_SetDefaultHandlerExpand(XML_Parser parser,
1256
XML_DefaultHandler handler)
1258
defaultHandler = handler;
1259
defaultExpandInternalEntities = XML_TRUE;
1263
XML_SetDoctypeDeclHandler(XML_Parser parser,
1264
XML_StartDoctypeDeclHandler start,
1265
XML_EndDoctypeDeclHandler end)
1267
startDoctypeDeclHandler = start;
1268
endDoctypeDeclHandler = end;
1272
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1273
XML_StartDoctypeDeclHandler start) {
1274
startDoctypeDeclHandler = start;
1278
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1279
XML_EndDoctypeDeclHandler end) {
1280
endDoctypeDeclHandler = end;
1284
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1285
XML_UnparsedEntityDeclHandler handler)
1287
unparsedEntityDeclHandler = handler;
1291
XML_SetNotationDeclHandler(XML_Parser parser,
1292
XML_NotationDeclHandler handler)
1294
notationDeclHandler = handler;
1298
XML_SetNamespaceDeclHandler(XML_Parser parser,
1299
XML_StartNamespaceDeclHandler start,
1300
XML_EndNamespaceDeclHandler end)
1302
startNamespaceDeclHandler = start;
1303
endNamespaceDeclHandler = end;
1307
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1308
XML_StartNamespaceDeclHandler start) {
1309
startNamespaceDeclHandler = start;
1313
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1314
XML_EndNamespaceDeclHandler end) {
1315
endNamespaceDeclHandler = end;
1319
XML_SetNotStandaloneHandler(XML_Parser parser,
1320
XML_NotStandaloneHandler handler)
1322
notStandaloneHandler = handler;
1326
XML_SetExternalEntityRefHandler(XML_Parser parser,
1327
XML_ExternalEntityRefHandler handler)
1329
externalEntityRefHandler = handler;
1333
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1336
externalEntityRefHandlerArg = (XML_Parser)arg;
1338
externalEntityRefHandlerArg = parser;
1342
XML_SetSkippedEntityHandler(XML_Parser parser,
1343
XML_SkippedEntityHandler handler)
1345
skippedEntityHandler = handler;
1349
XML_SetUnknownEncodingHandler(XML_Parser parser,
1350
XML_UnknownEncodingHandler handler,
1353
unknownEncodingHandler = handler;
1354
unknownEncodingHandlerData = data;
1358
XML_SetElementDeclHandler(XML_Parser parser,
1359
XML_ElementDeclHandler eldecl)
1361
elementDeclHandler = eldecl;
1365
XML_SetAttlistDeclHandler(XML_Parser parser,
1366
XML_AttlistDeclHandler attdecl)
1368
attlistDeclHandler = attdecl;
1372
XML_SetEntityDeclHandler(XML_Parser parser,
1373
XML_EntityDeclHandler handler)
1375
entityDeclHandler = handler;
1379
XML_SetXmlDeclHandler(XML_Parser parser,
1380
XML_XmlDeclHandler handler) {
1381
xmlDeclHandler = handler;
1385
XML_SetParamEntityParsing(XML_Parser parser,
1386
enum XML_ParamEntityParsing peParsing)
1388
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1392
paramEntityParsing = peParsing;
1395
return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1399
enum XML_Status XMLCALL
1400
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1404
return XML_STATUS_OK;
1405
positionPtr = bufferPtr;
1406
errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1407
if (errorCode == XML_ERROR_NONE)
1408
return XML_STATUS_OK;
1409
eventEndPtr = eventPtr;
1410
processor = errorProcessor;
1411
return XML_STATUS_ERROR;
1413
#ifndef XML_CONTEXT_BYTES
1414
else if (bufferPtr == bufferEnd) {
1417
parseEndByteIndex += len;
1420
errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1421
if (errorCode == XML_ERROR_NONE)
1422
return XML_STATUS_OK;
1423
eventEndPtr = eventPtr;
1424
processor = errorProcessor;
1425
return XML_STATUS_ERROR;
1427
errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1428
if (errorCode != XML_ERROR_NONE) {
1429
eventEndPtr = eventPtr;
1430
processor = errorProcessor;
1431
return XML_STATUS_ERROR;
1433
XmlUpdatePosition(encoding, positionPtr, end, &position);
1435
nLeftOver = s + len - end;
1437
if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1438
/* FIXME avoid integer overflow */
1440
temp = (buffer == NULL
1441
? (char *)MALLOC(len * 2)
1442
: (char *)REALLOC(buffer, len * 2));
1444
errorCode = XML_ERROR_NO_MEMORY;
1445
return XML_STATUS_ERROR;
1449
errorCode = XML_ERROR_NO_MEMORY;
1450
eventPtr = eventEndPtr = NULL;
1451
processor = errorProcessor;
1452
return XML_STATUS_ERROR;
1454
bufferLim = buffer + len * 2;
1456
memcpy(buffer, end, nLeftOver);
1458
bufferEnd = buffer + nLeftOver;
1460
return XML_STATUS_OK;
1462
#endif /* not defined XML_CONTEXT_BYTES */
1464
void *buff = XML_GetBuffer(parser, len);
1466
return XML_STATUS_ERROR;
1468
memcpy(buff, s, len);
1469
return XML_ParseBuffer(parser, len, isFinal);
1474
enum XML_Status XMLCALL
1475
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1477
const char *start = bufferPtr;
1478
positionPtr = start;
1480
parseEndByteIndex += len;
1481
errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1482
isFinal ? (const char **)NULL : &bufferPtr);
1483
if (errorCode == XML_ERROR_NONE) {
1485
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1486
positionPtr = bufferPtr;
1488
return XML_STATUS_OK;
1491
eventEndPtr = eventPtr;
1492
processor = errorProcessor;
1493
return XML_STATUS_ERROR;
1498
XML_GetBuffer(XML_Parser parser, int len)
1500
if (len > bufferLim - bufferEnd) {
1501
/* FIXME avoid integer overflow */
1502
int neededSize = len + (bufferEnd - bufferPtr);
1503
#ifdef XML_CONTEXT_BYTES
1504
int keep = bufferPtr - buffer;
1506
if (keep > XML_CONTEXT_BYTES)
1507
keep = XML_CONTEXT_BYTES;
1509
#endif /* defined XML_CONTEXT_BYTES */
1510
if (neededSize <= bufferLim - buffer) {
1511
#ifdef XML_CONTEXT_BYTES
1512
if (keep < bufferPtr - buffer) {
1513
int offset = (bufferPtr - buffer) - keep;
1514
memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1515
bufferEnd -= offset;
1516
bufferPtr -= offset;
1519
memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1520
bufferEnd = buffer + (bufferEnd - bufferPtr);
1522
#endif /* not defined XML_CONTEXT_BYTES */
1526
int bufferSize = bufferLim - bufferPtr;
1527
if (bufferSize == 0)
1528
bufferSize = INIT_BUFFER_SIZE;
1531
} while (bufferSize < neededSize);
1532
newBuf = (char *)MALLOC(bufferSize);
1534
errorCode = XML_ERROR_NO_MEMORY;
1537
bufferLim = newBuf + bufferSize;
1538
#ifdef XML_CONTEXT_BYTES
1540
int keep = bufferPtr - buffer;
1541
if (keep > XML_CONTEXT_BYTES)
1542
keep = XML_CONTEXT_BYTES;
1543
memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1546
bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1547
bufferPtr = buffer + keep;
1550
bufferEnd = newBuf + (bufferEnd - bufferPtr);
1551
bufferPtr = buffer = newBuf;
1555
memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1558
bufferEnd = newBuf + (bufferEnd - bufferPtr);
1559
bufferPtr = buffer = newBuf;
1560
#endif /* not defined XML_CONTEXT_BYTES */
1566
enum XML_Error XMLCALL
1567
XML_GetErrorCode(XML_Parser parser)
1573
XML_GetCurrentByteIndex(XML_Parser parser)
1576
return parseEndByteIndex - (parseEndPtr - eventPtr);
1581
XML_GetCurrentByteCount(XML_Parser parser)
1583
if (eventEndPtr && eventPtr)
1584
return eventEndPtr - eventPtr;
1588
const char * XMLCALL
1589
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1591
#ifdef XML_CONTEXT_BYTES
1592
if (eventPtr && buffer) {
1593
*offset = eventPtr - buffer;
1594
*size = bufferEnd - buffer;
1597
#endif /* defined XML_CONTEXT_BYTES */
1602
XML_GetCurrentLineNumber(XML_Parser parser)
1605
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1606
positionPtr = eventPtr;
1608
return position.lineNumber + 1;
1612
XML_GetCurrentColumnNumber(XML_Parser parser)
1615
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1616
positionPtr = eventPtr;
1618
return position.columnNumber;
1622
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1628
XML_MemMalloc(XML_Parser parser, size_t size)
1630
return MALLOC(size);
1634
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1636
return REALLOC(ptr, size);
1640
XML_MemFree(XML_Parser parser, void *ptr)
1646
XML_DefaultCurrent(XML_Parser parser)
1648
if (defaultHandler) {
1649
if (openInternalEntities)
1650
reportDefault(parser,
1652
openInternalEntities->internalEventPtr,
1653
openInternalEntities->internalEventEndPtr);
1655
reportDefault(parser, encoding, eventPtr, eventEndPtr);
1659
const XML_LChar * XMLCALL
1660
XML_ErrorString(enum XML_Error code)
1662
static const XML_LChar *message[] = {
1664
XML_L("out of memory"),
1665
XML_L("syntax error"),
1666
XML_L("no element found"),
1667
XML_L("not well-formed (invalid token)"),
1668
XML_L("unclosed token"),
1669
XML_L("partial character"),
1670
XML_L("mismatched tag"),
1671
XML_L("duplicate attribute"),
1672
XML_L("junk after document element"),
1673
XML_L("illegal parameter entity reference"),
1674
XML_L("undefined entity"),
1675
XML_L("recursive entity reference"),
1676
XML_L("asynchronous entity"),
1677
XML_L("reference to invalid character number"),
1678
XML_L("reference to binary entity"),
1679
XML_L("reference to external entity in attribute"),
1680
XML_L("xml declaration not at start of external entity"),
1681
XML_L("unknown encoding"),
1682
XML_L("encoding specified in XML declaration is incorrect"),
1683
XML_L("unclosed CDATA section"),
1684
XML_L("error in processing external entity reference"),
1685
XML_L("document is not standalone"),
1686
XML_L("unexpected parser state - please send a bug report"),
1687
XML_L("entity declared in parameter entity"),
1688
XML_L("requested feature requires XML_DTD support in Expat"),
1689
XML_L("cannot change setting once parsing has begun"),
1690
XML_L("unbound prefix")
1692
if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1693
return message[code];
1697
const XML_LChar * XMLCALL
1698
XML_ExpatVersion(void) {
1700
/* V1 is used to string-ize the version number. However, it would
1701
string-ize the actual version macro *names* unless we get them
1702
substituted before being passed to V1. CPP is defined to expand
1703
a macro, then rescan for more expansions. Thus, we use V2 to expand
1704
the version macros, then CPP will expand the resulting V1() macro
1705
with the correct numerals. */
1706
/* ### I'm assuming cpp is portable in this respect... */
1708
#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1709
#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1711
return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1717
XML_Expat_Version XMLCALL
1718
XML_ExpatVersionInfo(void)
1720
XML_Expat_Version version;
1722
version.major = XML_MAJOR_VERSION;
1723
version.minor = XML_MINOR_VERSION;
1724
version.micro = XML_MICRO_VERSION;
1729
const XML_Feature * XMLCALL
1730
XML_GetFeatureList(void)
1732
static XML_Feature features[] = {
1733
{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 0},
1734
{XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 0},
1736
{XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
1738
#ifdef XML_UNICODE_WCHAR_T
1739
{XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
1742
{XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
1744
#ifdef XML_CONTEXT_BYTES
1745
{XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1749
{XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
1751
{XML_FEATURE_END, NULL, 0}
1754
features[0].value = sizeof(XML_Char);
1755
features[1].value = sizeof(XML_LChar);
1759
/* Initially tag->rawName always points into the parse buffer;
1760
for those TAG instances opened while the current parse buffer was
1761
processed, and not yet closed, we need to store tag->rawName in a more
1762
permanent location, since the parse buffer is about to be discarded.
1765
storeRawNames(XML_Parser parser)
1767
TAG *tag = tagStack;
1770
int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1771
char *rawNameBuf = tag->buf + nameLen;
1772
/* Stop if already stored. Since tagStack is a stack, we can stop
1773
at the first entry that has already been copied; everything
1774
below it in the stack is already been accounted for in a
1775
previous call to this function.
1777
if (tag->rawName == rawNameBuf)
1779
/* For re-use purposes we need to ensure that the
1780
size of tag->buf is a multiple of sizeof(XML_Char).
1782
bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1783
if (bufSize > tag->bufEnd - tag->buf) {
1784
char *temp = (char *)REALLOC(tag->buf, bufSize);
1787
/* if tag->name.str points to tag->buf (only when namespace
1788
processing is off) then we have to update it
1790
if (tag->name.str == (XML_Char *)tag->buf)
1791
tag->name.str = (XML_Char *)temp;
1792
/* if tag->name.localPart is set (when namespace processing is on)
1793
then update it as well, since it will always point into tag->buf
1795
if (tag->name.localPart)
1796
tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1797
(XML_Char *)tag->buf);
1799
tag->bufEnd = temp + bufSize;
1800
rawNameBuf = temp + nameLen;
1802
memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1803
tag->rawName = rawNameBuf;
1809
static enum XML_Error PTRCALL
1810
contentProcessor(XML_Parser parser,
1813
const char **endPtr)
1815
enum XML_Error result =
1816
doContent(parser, 0, encoding, start, end, endPtr);
1817
if (result != XML_ERROR_NONE)
1819
if (!storeRawNames(parser))
1820
return XML_ERROR_NO_MEMORY;
1824
static enum XML_Error PTRCALL
1825
externalEntityInitProcessor(XML_Parser parser,
1828
const char **endPtr)
1830
enum XML_Error result = initializeEncoding(parser);
1831
if (result != XML_ERROR_NONE)
1833
processor = externalEntityInitProcessor2;
1834
return externalEntityInitProcessor2(parser, start, end, endPtr);
1837
static enum XML_Error PTRCALL
1838
externalEntityInitProcessor2(XML_Parser parser,
1841
const char **endPtr)
1843
const char *next = start; /* XmlContentTok doesn't always set the last arg */
1844
int tok = XmlContentTok(encoding, start, end, &next);
1847
/* If we are at the end of the buffer, this would cause the next stage,
1848
i.e. externalEntityInitProcessor3, to pass control directly to
1849
doContent (by detecting XML_TOK_NONE) without processing any xml text
1850
declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1852
if (next == end && endPtr) {
1854
return XML_ERROR_NONE;
1858
case XML_TOK_PARTIAL:
1861
return XML_ERROR_NONE;
1864
return XML_ERROR_UNCLOSED_TOKEN;
1865
case XML_TOK_PARTIAL_CHAR:
1868
return XML_ERROR_NONE;
1871
return XML_ERROR_PARTIAL_CHAR;
1873
processor = externalEntityInitProcessor3;
1874
return externalEntityInitProcessor3(parser, start, end, endPtr);
1877
static enum XML_Error PTRCALL
1878
externalEntityInitProcessor3(XML_Parser parser,
1881
const char **endPtr)
1883
const char *next = start; /* XmlContentTok doesn't always set the last arg */
1884
int tok = XmlContentTok(encoding, start, end, &next);
1886
case XML_TOK_XML_DECL:
1888
enum XML_Error result = processXmlDecl(parser, 1, start, next);
1889
if (result != XML_ERROR_NONE)
1894
case XML_TOK_PARTIAL:
1897
return XML_ERROR_NONE;
1900
return XML_ERROR_UNCLOSED_TOKEN;
1901
case XML_TOK_PARTIAL_CHAR:
1904
return XML_ERROR_NONE;
1907
return XML_ERROR_PARTIAL_CHAR;
1909
processor = externalEntityContentProcessor;
1911
return externalEntityContentProcessor(parser, start, end, endPtr);
1914
static enum XML_Error PTRCALL
1915
externalEntityContentProcessor(XML_Parser parser,
1918
const char **endPtr)
1920
enum XML_Error result =
1921
doContent(parser, 1, encoding, start, end, endPtr);
1922
if (result != XML_ERROR_NONE)
1924
if (!storeRawNames(parser))
1925
return XML_ERROR_NO_MEMORY;
1929
static enum XML_Error
1930
doContent(XML_Parser parser,
1932
const ENCODING *enc,
1935
const char **nextPtr)
1937
DTD * const dtd = _dtd; /* save one level of indirection */
1938
const char **eventPP;
1939
const char **eventEndPP;
1940
if (enc == encoding) {
1941
eventPP = &eventPtr;
1942
eventEndPP = &eventEndPtr;
1945
eventPP = &(openInternalEntities->internalEventPtr);
1946
eventEndPP = &(openInternalEntities->internalEventEndPtr);
1950
const char *next = s; /* XmlContentTok doesn't always set the last arg */
1951
int tok = XmlContentTok(enc, s, end, &next);
1954
case XML_TOK_TRAILING_CR:
1957
return XML_ERROR_NONE;
1960
if (characterDataHandler) {
1962
characterDataHandler(handlerArg, &c, 1);
1964
else if (defaultHandler)
1965
reportDefault(parser, enc, s, end);
1966
if (startTagLevel == 0)
1967
return XML_ERROR_NO_ELEMENTS;
1968
if (tagLevel != startTagLevel)
1969
return XML_ERROR_ASYNC_ENTITY;
1970
return XML_ERROR_NONE;
1974
return XML_ERROR_NONE;
1976
if (startTagLevel > 0) {
1977
if (tagLevel != startTagLevel)
1978
return XML_ERROR_ASYNC_ENTITY;
1979
return XML_ERROR_NONE;
1981
return XML_ERROR_NO_ELEMENTS;
1982
case XML_TOK_INVALID:
1984
return XML_ERROR_INVALID_TOKEN;
1985
case XML_TOK_PARTIAL:
1988
return XML_ERROR_NONE;
1990
return XML_ERROR_UNCLOSED_TOKEN;
1991
case XML_TOK_PARTIAL_CHAR:
1994
return XML_ERROR_NONE;
1996
return XML_ERROR_PARTIAL_CHAR;
1997
case XML_TOK_ENTITY_REF:
1999
const XML_Char *name;
2001
XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2002
s + enc->minBytesPerChar,
2003
next - enc->minBytesPerChar);
2005
if (characterDataHandler)
2006
characterDataHandler(handlerArg, &ch, 1);
2007
else if (defaultHandler)
2008
reportDefault(parser, enc, s, next);
2011
name = poolStoreString(&dtd->pool, enc,
2012
s + enc->minBytesPerChar,
2013
next - enc->minBytesPerChar);
2015
return XML_ERROR_NO_MEMORY;
2016
entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2017
poolDiscard(&dtd->pool);
2018
/* First, determine if a check for an existing declaration is needed;
2019
if yes, check that the entity exists, and that it is internal,
2020
otherwise call the skipped entity or default handler.
2022
if (!dtd->hasParamEntityRefs || dtd->standalone) {
2024
return XML_ERROR_UNDEFINED_ENTITY;
2025
else if (!entity->is_internal)
2026
return XML_ERROR_ENTITY_DECLARED_IN_PE;
2029
if (skippedEntityHandler)
2030
skippedEntityHandler(handlerArg, name, 0);
2031
else if (defaultHandler)
2032
reportDefault(parser, enc, s, next);
2036
return XML_ERROR_RECURSIVE_ENTITY_REF;
2037
if (entity->notation)
2038
return XML_ERROR_BINARY_ENTITY_REF;
2039
if (entity->textPtr) {
2040
enum XML_Error result;
2041
OPEN_INTERNAL_ENTITY openEntity;
2042
if (!defaultExpandInternalEntities) {
2043
if (skippedEntityHandler)
2044
skippedEntityHandler(handlerArg, entity->name, 0);
2045
else if (defaultHandler)
2046
reportDefault(parser, enc, s, next);
2049
entity->open = XML_TRUE;
2050
openEntity.next = openInternalEntities;
2051
openInternalEntities = &openEntity;
2052
openEntity.entity = entity;
2053
openEntity.internalEventPtr = NULL;
2054
openEntity.internalEventEndPtr = NULL;
2055
result = doContent(parser,
2058
(char *)entity->textPtr,
2059
(char *)(entity->textPtr + entity->textLen),
2061
entity->open = XML_FALSE;
2062
openInternalEntities = openEntity.next;
2066
else if (externalEntityRefHandler) {
2067
const XML_Char *context;
2068
entity->open = XML_TRUE;
2069
context = getContext(parser);
2070
entity->open = XML_FALSE;
2072
return XML_ERROR_NO_MEMORY;
2073
if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
2078
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2079
poolDiscard(&tempPool);
2081
else if (defaultHandler)
2082
reportDefault(parser, enc, s, next);
2085
case XML_TOK_START_TAG_NO_ATTS:
2087
case XML_TOK_START_TAG_WITH_ATTS:
2090
enum XML_Error result;
2094
freeTagList = freeTagList->parent;
2097
tag = (TAG *)MALLOC(sizeof(TAG));
2099
return XML_ERROR_NO_MEMORY;
2100
tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2103
return XML_ERROR_NO_MEMORY;
2105
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2107
tag->bindings = NULL;
2108
tag->parent = tagStack;
2110
tag->name.localPart = NULL;
2111
tag->name.prefix = NULL;
2112
tag->rawName = s + enc->minBytesPerChar;
2113
tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2116
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2117
const char *fromPtr = tag->rawName;
2118
toPtr = (XML_Char *)tag->buf;
2123
&fromPtr, rawNameEnd,
2124
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2125
convLen = toPtr - (XML_Char *)tag->buf;
2126
if (fromPtr == rawNameEnd) {
2127
tag->name.strLen = convLen;
2130
bufSize = (tag->bufEnd - tag->buf) << 1;
2132
char *temp = (char *)REALLOC(tag->buf, bufSize);
2134
return XML_ERROR_NO_MEMORY;
2136
tag->bufEnd = temp + bufSize;
2137
toPtr = (XML_Char *)temp + convLen;
2141
tag->name.str = (XML_Char *)tag->buf;
2142
*toPtr = XML_T('\0');
2143
result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2146
if (startElementHandler)
2147
startElementHandler(handlerArg, tag->name.str,
2148
(const XML_Char **)atts);
2149
else if (defaultHandler)
2150
reportDefault(parser, enc, s, next);
2151
poolClear(&tempPool);
2154
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2156
case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2158
const char *rawName = s + enc->minBytesPerChar;
2159
enum XML_Error result;
2160
BINDING *bindings = NULL;
2161
XML_Bool noElmHandlers = XML_TRUE;
2163
name.str = poolStoreString(&tempPool, enc, rawName,
2164
rawName + XmlNameLength(enc, rawName));
2166
return XML_ERROR_NO_MEMORY;
2167
poolFinish(&tempPool);
2168
result = storeAtts(parser, enc, s, &name, &bindings);
2171
poolFinish(&tempPool);
2172
if (startElementHandler) {
2173
startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2174
noElmHandlers = XML_FALSE;
2176
if (endElementHandler) {
2177
if (startElementHandler)
2178
*eventPP = *eventEndPP;
2179
endElementHandler(handlerArg, name.str);
2180
noElmHandlers = XML_FALSE;
2182
if (noElmHandlers && defaultHandler)
2183
reportDefault(parser, enc, s, next);
2184
poolClear(&tempPool);
2186
BINDING *b = bindings;
2187
if (endNamespaceDeclHandler)
2188
endNamespaceDeclHandler(handlerArg, b->prefix->name);
2189
bindings = bindings->nextTagBinding;
2190
b->nextTagBinding = freeBindingList;
2191
freeBindingList = b;
2192
b->prefix->binding = b->prevPrefixBinding;
2196
return epilogProcessor(parser, next, end, nextPtr);
2198
case XML_TOK_END_TAG:
2199
if (tagLevel == startTagLevel)
2200
return XML_ERROR_ASYNC_ENTITY;
2203
const char *rawName;
2204
TAG *tag = tagStack;
2205
tagStack = tag->parent;
2206
tag->parent = freeTagList;
2208
rawName = s + enc->minBytesPerChar*2;
2209
len = XmlNameLength(enc, rawName);
2210
if (len != tag->rawNameLength
2211
|| memcmp(tag->rawName, rawName, len) != 0) {
2213
return XML_ERROR_TAG_MISMATCH;
2216
if (endElementHandler) {
2217
const XML_Char *localPart;
2218
const XML_Char *prefix;
2220
localPart = tag->name.localPart;
2221
if (ns && localPart) {
2222
/* localPart and prefix may have been overwritten in
2223
tag->name.str, since this points to the binding->uri
2224
buffer which gets re-used; so we have to add them again
2226
uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2227
/* don't need to check for space - already done in storeAtts() */
2228
while (*localPart) *uri++ = *localPart++;
2229
prefix = (XML_Char *)tag->name.prefix;
2230
if (ns_triplets && prefix) {
2231
*uri++ = namespaceSeparator;
2232
while (*prefix) *uri++ = *prefix++;
2236
endElementHandler(handlerArg, tag->name.str);
2238
else if (defaultHandler)
2239
reportDefault(parser, enc, s, next);
2240
while (tag->bindings) {
2241
BINDING *b = tag->bindings;
2242
if (endNamespaceDeclHandler)
2243
endNamespaceDeclHandler(handlerArg, b->prefix->name);
2244
tag->bindings = tag->bindings->nextTagBinding;
2245
b->nextTagBinding = freeBindingList;
2246
freeBindingList = b;
2247
b->prefix->binding = b->prevPrefixBinding;
2250
return epilogProcessor(parser, next, end, nextPtr);
2253
case XML_TOK_CHAR_REF:
2255
int n = XmlCharRefNumber(enc, s);
2257
return XML_ERROR_BAD_CHAR_REF;
2258
if (characterDataHandler) {
2259
XML_Char buf[XML_ENCODE_MAX];
2260
characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2262
else if (defaultHandler)
2263
reportDefault(parser, enc, s, next);
2266
case XML_TOK_XML_DECL:
2267
return XML_ERROR_MISPLACED_XML_PI;
2268
case XML_TOK_DATA_NEWLINE:
2269
if (characterDataHandler) {
2271
characterDataHandler(handlerArg, &c, 1);
2273
else if (defaultHandler)
2274
reportDefault(parser, enc, s, next);
2276
case XML_TOK_CDATA_SECT_OPEN:
2278
enum XML_Error result;
2279
if (startCdataSectionHandler)
2280
startCdataSectionHandler(handlerArg);
2282
/* Suppose you doing a transformation on a document that involves
2283
changing only the character data. You set up a defaultHandler
2284
and a characterDataHandler. The defaultHandler simply copies
2285
characters through. The characterDataHandler does the
2286
transformation and writes the characters out escaping them as
2287
necessary. This case will fail to work if we leave out the
2288
following two lines (because & and < inside CDATA sections will
2289
be incorrectly escaped).
2291
However, now we have a start/endCdataSectionHandler, so it seems
2292
easier to let the user deal with this.
2294
else if (characterDataHandler)
2295
characterDataHandler(handlerArg, dataBuf, 0);
2297
else if (defaultHandler)
2298
reportDefault(parser, enc, s, next);
2299
result = doCdataSection(parser, enc, &next, end, nextPtr);
2301
processor = cdataSectionProcessor;
2306
case XML_TOK_TRAILING_RSQB:
2309
return XML_ERROR_NONE;
2311
if (characterDataHandler) {
2312
if (MUST_CONVERT(enc, s)) {
2313
ICHAR *dataPtr = (ICHAR *)dataBuf;
2314
XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2315
characterDataHandler(handlerArg, dataBuf,
2316
dataPtr - (ICHAR *)dataBuf);
2319
characterDataHandler(handlerArg,
2321
(XML_Char *)end - (XML_Char *)s);
2323
else if (defaultHandler)
2324
reportDefault(parser, enc, s, end);
2325
if (startTagLevel == 0) {
2327
return XML_ERROR_NO_ELEMENTS;
2329
if (tagLevel != startTagLevel) {
2331
return XML_ERROR_ASYNC_ENTITY;
2333
return XML_ERROR_NONE;
2334
case XML_TOK_DATA_CHARS:
2335
if (characterDataHandler) {
2336
if (MUST_CONVERT(enc, s)) {
2338
ICHAR *dataPtr = (ICHAR *)dataBuf;
2339
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2341
characterDataHandler(handlerArg, dataBuf,
2342
dataPtr - (ICHAR *)dataBuf);
2349
characterDataHandler(handlerArg,
2351
(XML_Char *)next - (XML_Char *)s);
2353
else if (defaultHandler)
2354
reportDefault(parser, enc, s, next);
2357
if (!reportProcessingInstruction(parser, enc, s, next))
2358
return XML_ERROR_NO_MEMORY;
2360
case XML_TOK_COMMENT:
2361
if (!reportComment(parser, enc, s, next))
2362
return XML_ERROR_NO_MEMORY;
2366
reportDefault(parser, enc, s, next);
2369
*eventPP = s = next;
2374
/* Precondition: all arguments must be non-NULL;
2376
- normalize attributes
2377
- check attributes for well-formedness
2378
- generate namespace aware attribute names (URI, prefix)
2379
- build list of attributes for startElementHandler
2380
- default attributes
2381
- process namespace declarations (check and report them)
2382
- generate namespace aware element name (URI, prefix)
2384
static enum XML_Error
2385
storeAtts(XML_Parser parser, const ENCODING *enc,
2386
const char *attStr, TAG_NAME *tagNamePtr,
2387
BINDING **bindingsPtr)
2389
DTD * const dtd = _dtd; /* save one level of indirection */
2390
ELEMENT_TYPE *elementType;
2392
const XML_Char **appAtts; /* the attribute list for the application */
2400
const XML_Char *localPart;
2402
/* lookup the element type name */
2403
elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2405
const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2407
return XML_ERROR_NO_MEMORY;
2408
elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2409
sizeof(ELEMENT_TYPE));
2411
return XML_ERROR_NO_MEMORY;
2412
if (ns && !setElementTypePrefix(parser, elementType))
2413
return XML_ERROR_NO_MEMORY;
2415
nDefaultAtts = elementType->nDefaultAtts;
2417
/* get the attributes from the tokenizer */
2418
n = XmlGetAttributes(enc, attStr, attsSize, atts);
2419
if (n + nDefaultAtts > attsSize) {
2420
int oldAttsSize = attsSize;
2422
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2423
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2425
return XML_ERROR_NO_MEMORY;
2427
if (n > oldAttsSize)
2428
XmlGetAttributes(enc, attStr, n, atts);
2431
appAtts = (const XML_Char **)atts;
2432
for (i = 0; i < n; i++) {
2433
/* add the name and value to the attribute list */
2434
ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
2436
+ XmlNameLength(enc, atts[i].name));
2438
return XML_ERROR_NO_MEMORY;
2439
/* Detect duplicate attributes by their QNames. This does not work when
2440
namespace processing is turned on and different prefixes for the same
2441
namespace are used. For this case we have a check further down.
2443
if ((attId->name)[-1]) {
2444
if (enc == encoding)
2445
eventPtr = atts[i].name;
2446
return XML_ERROR_DUPLICATE_ATTRIBUTE;
2448
(attId->name)[-1] = 1;
2449
appAtts[attIndex++] = attId->name;
2450
if (!atts[i].normalized) {
2451
enum XML_Error result;
2452
XML_Bool isCdata = XML_TRUE;
2454
/* figure out whether declared as other than CDATA */
2455
if (attId->maybeTokenized) {
2457
for (j = 0; j < nDefaultAtts; j++) {
2458
if (attId == elementType->defaultAtts[j].id) {
2459
isCdata = elementType->defaultAtts[j].isCdata;
2465
/* normalize the attribute value */
2466
result = storeAttributeValue(parser, enc, isCdata,
2467
atts[i].valuePtr, atts[i].valueEnd,
2471
appAtts[attIndex] = poolStart(&tempPool);
2472
poolFinish(&tempPool);
2475
/* the value did not need normalizing */
2476
appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2478
if (appAtts[attIndex] == 0)
2479
return XML_ERROR_NO_MEMORY;
2480
poolFinish(&tempPool);
2482
/* handle prefixed attribute names */
2483
if (attId->prefix) {
2485
/* deal with namespace declarations here */
2486
enum XML_Error result = addBinding(parser, attId->prefix, attId,
2487
appAtts[attIndex], bindingsPtr);
2493
/* deal with other prefixed names later */
2496
(attId->name)[-1] = 2;
2503
/* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2504
nSpecifiedAtts = attIndex;
2505
if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2506
for (i = 0; i < attIndex; i += 2)
2507
if (appAtts[i] == elementType->idAtt->name) {
2515
/* do attribute defaulting */
2516
for (i = 0; i < nDefaultAtts; i++) {
2517
const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2518
if (!(da->id->name)[-1] && da->value) {
2519
if (da->id->prefix) {
2520
if (da->id->xmlns) {
2521
enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2522
da->value, bindingsPtr);
2527
(da->id->name)[-1] = 2;
2529
appAtts[attIndex++] = da->id->name;
2530
appAtts[attIndex++] = da->value;
2534
(da->id->name)[-1] = 1;
2535
appAtts[attIndex++] = da->id->name;
2536
appAtts[attIndex++] = da->value;
2540
appAtts[attIndex] = 0;
2542
/* expand prefixed attribute names, check for duplicates,
2543
and clear flags that say whether attributes were specified */
2546
int j; /* hash table index */
2547
unsigned long version = nsAttsVersion;
2548
int nsAttsSize = (int)1 << nsAttsPower;
2549
/* size of hash table must be at least 2 * (# of prefixed attributes) */
2550
if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2552
/* hash table size must also be a power of 2 and >= 8 */
2553
while (nPrefixes >> nsAttsPower++);
2554
if (nsAttsPower < 3)
2556
nsAttsSize = (int)1 << nsAttsPower;
2557
temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2559
return XML_ERROR_NO_MEMORY;
2561
version = 0; /* force re-initialization of nsAtts hash table */
2563
/* using a version flag saves us from initializing nsAtts every time */
2564
if (!version) { /* initialize version flags when version wraps around */
2565
version = INIT_ATTS_VERSION;
2566
for (j = nsAttsSize; j != 0; )
2567
nsAtts[--j].version = version;
2569
nsAttsVersion = --version;
2571
/* expand prefixed names and check for duplicates */
2572
for (; i < attIndex; i += 2) {
2573
const XML_Char *s = appAtts[i];
2574
if (s[-1] == 2) { /* prefixed */
2577
unsigned long uriHash = 0;
2578
((XML_Char *)s)[-1] = 0; /* clear flag */
2579
id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2580
b = id->prefix->binding;
2582
return XML_ERROR_UNBOUND_PREFIX;
2584
/* as we expand the name we also calculate its hash value */
2585
for (j = 0; j < b->uriLen; j++) {
2586
const XML_Char c = b->uri[j];
2587
if (!poolAppendChar(&tempPool, c))
2588
return XML_ERROR_NO_MEMORY;
2589
uriHash = CHAR_HASH(uriHash, c);
2591
while (*s++ != XML_T(':'))
2593
do { /* copies null terminator */
2594
const XML_Char c = *s;
2595
if (!poolAppendChar(&tempPool, *s))
2596
return XML_ERROR_NO_MEMORY;
2597
uriHash = CHAR_HASH(uriHash, c);
2600
{ /* Check hash table for duplicate of expanded name (uriName).
2601
Derived from code in lookup(HASH_TABLE *table, ...).
2603
unsigned char step = 0;
2604
unsigned long mask = nsAttsSize - 1;
2605
j = uriHash & mask; /* index into hash table */
2606
while (nsAtts[j].version == version) {
2607
/* for speed we compare stored hash values first */
2608
if (uriHash == nsAtts[j].hash) {
2609
const XML_Char *s1 = poolStart(&tempPool);
2610
const XML_Char *s2 = nsAtts[j].uriName;
2611
/* s1 is null terminated, but not s2 */
2612
for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2614
return XML_ERROR_DUPLICATE_ATTRIBUTE;
2617
step = PROBE_STEP(uriHash, mask, nsAttsPower);
2618
j < step ? ( j += nsAttsSize - step) : (j -= step);
2622
if (ns_triplets) { /* append namespace separator and prefix */
2623
tempPool.ptr[-1] = namespaceSeparator;
2624
s = b->prefix->name;
2626
if (!poolAppendChar(&tempPool, *s))
2627
return XML_ERROR_NO_MEMORY;
2631
/* store expanded name in attribute list */
2632
s = poolStart(&tempPool);
2633
poolFinish(&tempPool);
2636
/* fill empty slot with new version, uriName and hash value */
2637
nsAtts[j].version = version;
2638
nsAtts[j].hash = uriHash;
2639
nsAtts[j].uriName = s;
2644
else /* not prefixed */
2645
((XML_Char *)s)[-1] = 0; /* clear flag */
2648
/* clear flags for the remaining attributes */
2649
for (; i < attIndex; i += 2)
2650
((XML_Char *)(appAtts[i]))[-1] = 0;
2651
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2652
binding->attId->name[-1] = 0;
2655
return XML_ERROR_NONE;
2657
/* expand the element type name */
2658
if (elementType->prefix) {
2659
binding = elementType->prefix->binding;
2661
return XML_ERROR_UNBOUND_PREFIX;
2662
localPart = tagNamePtr->str;
2663
while (*localPart++ != XML_T(':'))
2666
else if (dtd->defaultPrefix.binding) {
2667
binding = dtd->defaultPrefix.binding;
2668
localPart = tagNamePtr->str;
2671
return XML_ERROR_NONE;
2673
if (ns_triplets && binding->prefix->name) {
2674
for (; binding->prefix->name[prefixLen++];)
2677
tagNamePtr->localPart = localPart;
2678
tagNamePtr->uriLen = binding->uriLen;
2679
tagNamePtr->prefix = binding->prefix->name;
2680
tagNamePtr->prefixLen = prefixLen;
2681
for (i = 0; localPart[i++];)
2683
n = i + binding->uriLen + prefixLen;
2684
if (n > binding->uriAlloc) {
2686
uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2688
return XML_ERROR_NO_MEMORY;
2689
binding->uriAlloc = n + EXPAND_SPARE;
2690
memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2691
for (p = tagStack; p; p = p->parent)
2692
if (p->name.str == binding->uri)
2697
uri = binding->uri + binding->uriLen;
2698
memcpy(uri, localPart, i * sizeof(XML_Char));
2700
uri = uri + (i - 1);
2701
if (namespaceSeparator)
2702
*uri = namespaceSeparator;
2703
memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2705
tagNamePtr->str = binding->uri;
2706
return XML_ERROR_NONE;
2709
/* addBinding() overwrites the value of prefix->binding without checking.
2710
Therefore one must keep track of the old value outside of addBinding().
2712
static enum XML_Error
2713
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2714
const XML_Char *uri, BINDING **bindingsPtr)
2719
/* empty string is only valid when there is no prefix per XML NS 1.0 */
2720
if (*uri == XML_T('\0') && prefix->name)
2721
return XML_ERROR_SYNTAX;
2723
for (len = 0; uri[len]; len++)
2725
if (namespaceSeparator)
2727
if (freeBindingList) {
2728
b = freeBindingList;
2729
if (len > b->uriAlloc) {
2730
XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2731
sizeof(XML_Char) * (len + EXPAND_SPARE));
2733
return XML_ERROR_NO_MEMORY;
2735
b->uriAlloc = len + EXPAND_SPARE;
2737
freeBindingList = b->nextTagBinding;
2740
b = (BINDING *)MALLOC(sizeof(BINDING));
2742
return XML_ERROR_NO_MEMORY;
2743
b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2746
return XML_ERROR_NO_MEMORY;
2748
b->uriAlloc = len + EXPAND_SPARE;
2751
memcpy(b->uri, uri, len * sizeof(XML_Char));
2752
if (namespaceSeparator)
2753
b->uri[len - 1] = namespaceSeparator;
2756
b->prevPrefixBinding = prefix->binding;
2757
/* NULL binding when default namespace undeclared */
2758
if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2759
prefix->binding = NULL;
2761
prefix->binding = b;
2762
b->nextTagBinding = *bindingsPtr;
2764
if (startNamespaceDeclHandler)
2765
startNamespaceDeclHandler(handlerArg, prefix->name,
2766
prefix->binding ? uri : 0);
2767
return XML_ERROR_NONE;
2770
/* The idea here is to avoid using stack for each CDATA section when
2771
the whole file is parsed with one call.
2773
static enum XML_Error PTRCALL
2774
cdataSectionProcessor(XML_Parser parser,
2777
const char **endPtr)
2779
enum XML_Error result = doCdataSection(parser, encoding, &start,
2782
if (parentParser) { /* we are parsing an external entity */
2783
processor = externalEntityContentProcessor;
2784
return externalEntityContentProcessor(parser, start, end, endPtr);
2787
processor = contentProcessor;
2788
return contentProcessor(parser, start, end, endPtr);
2794
/* startPtr gets set to non-null is the section is closed, and to null if
2795
the section is not yet closed.
2797
static enum XML_Error
2798
doCdataSection(XML_Parser parser,
2799
const ENCODING *enc,
2800
const char **startPtr,
2802
const char **nextPtr)
2804
const char *s = *startPtr;
2805
const char **eventPP;
2806
const char **eventEndPP;
2807
if (enc == encoding) {
2808
eventPP = &eventPtr;
2810
eventEndPP = &eventEndPtr;
2813
eventPP = &(openInternalEntities->internalEventPtr);
2814
eventEndPP = &(openInternalEntities->internalEventEndPtr);
2820
int tok = XmlCdataSectionTok(enc, s, end, &next);
2823
case XML_TOK_CDATA_SECT_CLOSE:
2824
if (endCdataSectionHandler)
2825
endCdataSectionHandler(handlerArg);
2827
/* see comment under XML_TOK_CDATA_SECT_OPEN */
2828
else if (characterDataHandler)
2829
characterDataHandler(handlerArg, dataBuf, 0);
2831
else if (defaultHandler)
2832
reportDefault(parser, enc, s, next);
2834
return XML_ERROR_NONE;
2835
case XML_TOK_DATA_NEWLINE:
2836
if (characterDataHandler) {
2838
characterDataHandler(handlerArg, &c, 1);
2840
else if (defaultHandler)
2841
reportDefault(parser, enc, s, next);
2843
case XML_TOK_DATA_CHARS:
2844
if (characterDataHandler) {
2845
if (MUST_CONVERT(enc, s)) {
2847
ICHAR *dataPtr = (ICHAR *)dataBuf;
2848
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2850
characterDataHandler(handlerArg, dataBuf,
2851
dataPtr - (ICHAR *)dataBuf);
2858
characterDataHandler(handlerArg,
2860
(XML_Char *)next - (XML_Char *)s);
2862
else if (defaultHandler)
2863
reportDefault(parser, enc, s, next);
2865
case XML_TOK_INVALID:
2867
return XML_ERROR_INVALID_TOKEN;
2868
case XML_TOK_PARTIAL_CHAR:
2871
return XML_ERROR_NONE;
2873
return XML_ERROR_PARTIAL_CHAR;
2874
case XML_TOK_PARTIAL:
2878
return XML_ERROR_NONE;
2880
return XML_ERROR_UNCLOSED_CDATA_SECTION;
2883
return XML_ERROR_UNEXPECTED_STATE;
2885
*eventPP = s = next;
2892
/* The idea here is to avoid using stack for each IGNORE section when
2893
the whole file is parsed with one call.
2895
static enum XML_Error PTRCALL
2896
ignoreSectionProcessor(XML_Parser parser,
2899
const char **endPtr)
2901
enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2904
processor = prologProcessor;
2905
return prologProcessor(parser, start, end, endPtr);
2910
/* startPtr gets set to non-null is the section is closed, and to null
2911
if the section is not yet closed.
2913
static enum XML_Error
2914
doIgnoreSection(XML_Parser parser,
2915
const ENCODING *enc,
2916
const char **startPtr,
2918
const char **nextPtr)
2922
const char *s = *startPtr;
2923
const char **eventPP;
2924
const char **eventEndPP;
2925
if (enc == encoding) {
2926
eventPP = &eventPtr;
2928
eventEndPP = &eventEndPtr;
2931
eventPP = &(openInternalEntities->internalEventPtr);
2932
eventEndPP = &(openInternalEntities->internalEventEndPtr);
2936
tok = XmlIgnoreSectionTok(enc, s, end, &next);
2939
case XML_TOK_IGNORE_SECT:
2941
reportDefault(parser, enc, s, next);
2943
return XML_ERROR_NONE;
2944
case XML_TOK_INVALID:
2946
return XML_ERROR_INVALID_TOKEN;
2947
case XML_TOK_PARTIAL_CHAR:
2950
return XML_ERROR_NONE;
2952
return XML_ERROR_PARTIAL_CHAR;
2953
case XML_TOK_PARTIAL:
2957
return XML_ERROR_NONE;
2959
return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2962
return XML_ERROR_UNEXPECTED_STATE;
2967
#endif /* XML_DTD */
2969
static enum XML_Error
2970
initializeEncoding(XML_Parser parser)
2974
char encodingBuf[128];
2975
if (!protocolEncodingName)
2979
for (i = 0; protocolEncodingName[i]; i++) {
2980
if (i == sizeof(encodingBuf) - 1
2981
|| (protocolEncodingName[i] & ~0x7f) != 0) {
2982
encodingBuf[0] = '\0';
2985
encodingBuf[i] = (char)protocolEncodingName[i];
2987
encodingBuf[i] = '\0';
2991
s = protocolEncodingName;
2993
if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2994
return XML_ERROR_NONE;
2995
return handleUnknownEncoding(parser, protocolEncodingName);
2998
static enum XML_Error
2999
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3000
const char *s, const char *next)
3002
const char *encodingName = NULL;
3003
const XML_Char *storedEncName = NULL;
3004
const ENCODING *newEncoding = NULL;
3005
const char *version = NULL;
3006
const char *versionend;
3007
const XML_Char *storedversion = NULL;
3008
int standalone = -1;
3011
: XmlParseXmlDecl)(isGeneralTextEntity,
3021
return XML_ERROR_SYNTAX;
3022
if (!isGeneralTextEntity && standalone == 1) {
3023
_dtd->standalone = XML_TRUE;
3025
if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3026
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3027
#endif /* XML_DTD */
3029
if (xmlDeclHandler) {
3030
if (encodingName != NULL) {
3031
storedEncName = poolStoreString(&temp2Pool,
3035
+ XmlNameLength(encoding, encodingName));
3037
return XML_ERROR_NO_MEMORY;
3038
poolFinish(&temp2Pool);
3041
storedversion = poolStoreString(&temp2Pool,
3044
versionend - encoding->minBytesPerChar);
3046
return XML_ERROR_NO_MEMORY;
3048
xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3050
else if (defaultHandler)
3051
reportDefault(parser, encoding, s, next);
3052
if (protocolEncodingName == NULL) {
3054
if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3055
eventPtr = encodingName;
3056
return XML_ERROR_INCORRECT_ENCODING;
3058
encoding = newEncoding;
3060
else if (encodingName) {
3061
enum XML_Error result;
3062
if (!storedEncName) {
3063
storedEncName = poolStoreString(
3064
&temp2Pool, encoding, encodingName,
3065
encodingName + XmlNameLength(encoding, encodingName));
3067
return XML_ERROR_NO_MEMORY;
3069
result = handleUnknownEncoding(parser, storedEncName);
3070
poolClear(&temp2Pool);
3071
if (result == XML_ERROR_UNKNOWN_ENCODING)
3072
eventPtr = encodingName;
3077
if (storedEncName || storedversion)
3078
poolClear(&temp2Pool);
3080
return XML_ERROR_NONE;
3083
static enum XML_Error
3084
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3086
if (unknownEncodingHandler) {
3089
for (i = 0; i < 256; i++)
3091
info.convert = NULL;
3093
info.release = NULL;
3094
if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3097
unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3098
if (!unknownEncodingMem) {
3100
info.release(info.data);
3101
return XML_ERROR_NO_MEMORY;
3104
? XmlInitUnknownEncodingNS
3105
: XmlInitUnknownEncoding)(unknownEncodingMem,
3110
unknownEncodingData = info.data;
3111
unknownEncodingRelease = info.release;
3113
return XML_ERROR_NONE;
3116
if (info.release != NULL)
3117
info.release(info.data);
3119
return XML_ERROR_UNKNOWN_ENCODING;
3122
static enum XML_Error PTRCALL
3123
prologInitProcessor(XML_Parser parser,
3126
const char **nextPtr)
3128
enum XML_Error result = initializeEncoding(parser);
3129
if (result != XML_ERROR_NONE)
3131
processor = prologProcessor;
3132
return prologProcessor(parser, s, end, nextPtr);
3137
static enum XML_Error PTRCALL
3138
externalParEntInitProcessor(XML_Parser parser,
3141
const char **nextPtr)
3143
enum XML_Error result = initializeEncoding(parser);
3144
if (result != XML_ERROR_NONE)
3147
/* we know now that XML_Parse(Buffer) has been called,
3148
so we consider the external parameter entity read */
3149
_dtd->paramEntityRead = XML_TRUE;
3151
if (prologState.inEntityValue) {
3152
processor = entityValueInitProcessor;
3153
return entityValueInitProcessor(parser, s, end, nextPtr);
3156
processor = externalParEntProcessor;
3157
return externalParEntProcessor(parser, s, end, nextPtr);
3161
static enum XML_Error PTRCALL
3162
entityValueInitProcessor(XML_Parser parser,
3165
const char **nextPtr)
3167
const char *start = s;
3168
const char *next = s;
3172
tok = XmlPrologTok(encoding, start, end, &next);
3174
if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3176
return XML_ERROR_NONE;
3179
case XML_TOK_INVALID:
3180
return XML_ERROR_INVALID_TOKEN;
3181
case XML_TOK_PARTIAL:
3182
return XML_ERROR_UNCLOSED_TOKEN;
3183
case XML_TOK_PARTIAL_CHAR:
3184
return XML_ERROR_PARTIAL_CHAR;
3185
case XML_TOK_NONE: /* start == end */
3189
return storeEntityValue(parser, encoding, s, end);
3191
else if (tok == XML_TOK_XML_DECL) {
3192
enum XML_Error result = processXmlDecl(parser, 0, start, next);
3193
if (result != XML_ERROR_NONE)
3195
if (nextPtr) *nextPtr = next;
3196
/* stop scanning for text declaration - we found one */
3197
processor = entityValueProcessor;
3198
return entityValueProcessor(parser, next, end, nextPtr);
3200
/* If we are at the end of the buffer, this would cause XmlPrologTok to
3201
return XML_TOK_NONE on the next call, which would then cause the
3202
function to exit with *nextPtr set to s - that is what we want for other
3203
tokens, but not for the BOM - we would rather like to skip it;
3204
then, when this routine is entered the next time, XmlPrologTok will
3205
return XML_TOK_INVALID, since the BOM is still in the buffer
3207
else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3209
return XML_ERROR_NONE;
3215
static enum XML_Error PTRCALL
3216
externalParEntProcessor(XML_Parser parser,
3219
const char **nextPtr)
3221
const char *start = s;
3222
const char *next = s;
3225
tok = XmlPrologTok(encoding, start, end, &next);
3227
if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3229
return XML_ERROR_NONE;
3232
case XML_TOK_INVALID:
3233
return XML_ERROR_INVALID_TOKEN;
3234
case XML_TOK_PARTIAL:
3235
return XML_ERROR_UNCLOSED_TOKEN;
3236
case XML_TOK_PARTIAL_CHAR:
3237
return XML_ERROR_PARTIAL_CHAR;
3238
case XML_TOK_NONE: /* start == end */
3243
/* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3244
However, when parsing an external subset, doProlog will not accept a BOM
3245
as valid, and report a syntax error, so we have to skip the BOM
3247
else if (tok == XML_TOK_BOM) {
3249
tok = XmlPrologTok(encoding, s, end, &next);
3252
processor = prologProcessor;
3253
return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3256
static enum XML_Error PTRCALL
3257
entityValueProcessor(XML_Parser parser,
3260
const char **nextPtr)
3262
const char *start = s;
3263
const char *next = s;
3264
const ENCODING *enc = encoding;
3268
tok = XmlPrologTok(enc, start, end, &next);
3270
if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3272
return XML_ERROR_NONE;
3275
case XML_TOK_INVALID:
3276
return XML_ERROR_INVALID_TOKEN;
3277
case XML_TOK_PARTIAL:
3278
return XML_ERROR_UNCLOSED_TOKEN;
3279
case XML_TOK_PARTIAL_CHAR:
3280
return XML_ERROR_PARTIAL_CHAR;
3281
case XML_TOK_NONE: /* start == end */
3285
return storeEntityValue(parser, enc, s, end);
3291
#endif /* XML_DTD */
3293
static enum XML_Error PTRCALL
3294
prologProcessor(XML_Parser parser,
3297
const char **nextPtr)
3299
const char *next = s;
3300
int tok = XmlPrologTok(encoding, s, end, &next);
3301
return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3304
static enum XML_Error
3305
doProlog(XML_Parser parser,
3306
const ENCODING *enc,
3311
const char **nextPtr)
3314
static const XML_Char externalSubsetName[] = { '#' , '\0' };
3315
#endif /* XML_DTD */
3316
static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3317
static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3318
static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3319
static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3320
static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3321
static const XML_Char atypeENTITIES[] =
3322
{ 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3323
static const XML_Char atypeNMTOKEN[] = {
3324
'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3325
static const XML_Char atypeNMTOKENS[] = {
3326
'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3327
static const XML_Char notationPrefix[] = {
3328
'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3329
static const XML_Char enumValueSep[] = { '|', '\0' };
3330
static const XML_Char enumValueStart[] = { '(', '\0' };
3332
DTD * const dtd = _dtd; /* save one level of indirection */
3334
const char **eventPP;
3335
const char **eventEndPP;
3336
enum XML_Content_Quant quant;
3338
if (enc == encoding) {
3339
eventPP = &eventPtr;
3340
eventEndPP = &eventEndPtr;
3343
eventPP = &(openInternalEntities->internalEventPtr);
3344
eventEndPP = &(openInternalEntities->internalEventEndPtr);
3348
XML_Bool handleDefault = XML_TRUE;
3352
if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3354
return XML_ERROR_NONE;
3357
case XML_TOK_INVALID:
3359
return XML_ERROR_INVALID_TOKEN;
3360
case XML_TOK_PARTIAL:
3361
return XML_ERROR_UNCLOSED_TOKEN;
3362
case XML_TOK_PARTIAL_CHAR:
3363
return XML_ERROR_PARTIAL_CHAR;
3366
if (enc != encoding)
3367
return XML_ERROR_NONE;
3368
if (isParamEntity) {
3369
if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3371
return XML_ERROR_SYNTAX;
3372
return XML_ERROR_NONE;
3374
#endif /* XML_DTD */
3375
return XML_ERROR_NO_ELEMENTS;
3382
role = XmlTokenRole(&prologState, tok, s, next, enc);
3384
case XML_ROLE_XML_DECL:
3386
enum XML_Error result = processXmlDecl(parser, 0, s, next);
3387
if (result != XML_ERROR_NONE)
3390
handleDefault = XML_FALSE;
3393
case XML_ROLE_DOCTYPE_NAME:
3394
if (startDoctypeDeclHandler) {
3395
doctypeName = poolStoreString(&tempPool, enc, s, next);
3397
return XML_ERROR_NO_MEMORY;
3398
poolFinish(&tempPool);
3399
doctypePubid = NULL;
3400
handleDefault = XML_FALSE;
3402
doctypeSysid = NULL; /* always initialize to NULL */
3404
case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3405
if (startDoctypeDeclHandler) {
3406
startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3409
poolClear(&tempPool);
3410
handleDefault = XML_FALSE;
3414
case XML_ROLE_TEXT_DECL:
3416
enum XML_Error result = processXmlDecl(parser, 1, s, next);
3417
if (result != XML_ERROR_NONE)
3420
handleDefault = XML_FALSE;
3423
#endif /* XML_DTD */
3424
case XML_ROLE_DOCTYPE_PUBLIC_ID:
3426
useForeignDTD = XML_FALSE;
3427
#endif /* XML_DTD */
3428
dtd->hasParamEntityRefs = XML_TRUE;
3429
if (startDoctypeDeclHandler) {
3430
doctypePubid = poolStoreString(&tempPool, enc,
3431
s + enc->minBytesPerChar,
3432
next - enc->minBytesPerChar);
3434
return XML_ERROR_NO_MEMORY;
3435
poolFinish(&tempPool);
3436
handleDefault = XML_FALSE;
3439
declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3443
return XML_ERROR_NO_MEMORY;
3444
#endif /* XML_DTD */
3446
case XML_ROLE_ENTITY_PUBLIC_ID:
3447
if (!XmlIsPublicId(enc, s, next, eventPP))
3448
return XML_ERROR_SYNTAX;
3449
if (dtd->keepProcessing && declEntity) {
3450
XML_Char *tem = poolStoreString(&dtd->pool,
3452
s + enc->minBytesPerChar,
3453
next - enc->minBytesPerChar);
3455
return XML_ERROR_NO_MEMORY;
3456
normalizePublicId(tem);
3457
declEntity->publicId = tem;
3458
poolFinish(&dtd->pool);
3459
if (entityDeclHandler)
3460
handleDefault = XML_FALSE;
3463
case XML_ROLE_DOCTYPE_CLOSE:
3465
startDoctypeDeclHandler(handlerArg, doctypeName,
3466
doctypeSysid, doctypePubid, 0);
3467
poolClear(&tempPool);
3468
handleDefault = XML_FALSE;
3470
/* doctypeSysid will be non-NULL in the case of a previous
3471
XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3472
was not set, indicating an external subset
3475
if (doctypeSysid || useForeignDTD) {
3476
dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3477
if (paramEntityParsing && externalEntityRefHandler) {
3478
ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3482
return XML_ERROR_NO_MEMORY;
3484
entity->base = curBase;
3485
dtd->paramEntityRead = XML_FALSE;
3486
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3491
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3492
if (dtd->paramEntityRead &&
3494
notStandaloneHandler &&
3495
!notStandaloneHandler(handlerArg))
3496
return XML_ERROR_NOT_STANDALONE;
3497
/* end of DTD - no need to update dtd->keepProcessing */
3499
useForeignDTD = XML_FALSE;
3501
#endif /* XML_DTD */
3502
if (endDoctypeDeclHandler) {
3503
endDoctypeDeclHandler(handlerArg);
3504
handleDefault = XML_FALSE;
3507
case XML_ROLE_INSTANCE_START:
3509
/* if there is no DOCTYPE declaration then now is the
3510
last chance to read the foreign DTD
3512
if (useForeignDTD) {
3513
dtd->hasParamEntityRefs = XML_TRUE;
3514
if (paramEntityParsing && externalEntityRefHandler) {
3515
ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3519
return XML_ERROR_NO_MEMORY;
3520
entity->base = curBase;
3521
dtd->paramEntityRead = XML_FALSE;
3522
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3527
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3528
if (dtd->paramEntityRead &&
3530
notStandaloneHandler &&
3531
!notStandaloneHandler(handlerArg))
3532
return XML_ERROR_NOT_STANDALONE;
3533
/* end of DTD - no need to update dtd->keepProcessing */
3536
#endif /* XML_DTD */
3537
processor = contentProcessor;
3538
return contentProcessor(parser, s, end, nextPtr);
3539
case XML_ROLE_ATTLIST_ELEMENT_NAME:
3540
declElementType = getElementType(parser, enc, s, next);
3541
if (!declElementType)
3542
return XML_ERROR_NO_MEMORY;
3543
goto checkAttListDeclHandler;
3544
case XML_ROLE_ATTRIBUTE_NAME:
3545
declAttributeId = getAttributeId(parser, enc, s, next);
3546
if (!declAttributeId)
3547
return XML_ERROR_NO_MEMORY;
3548
declAttributeIsCdata = XML_FALSE;
3549
declAttributeType = NULL;
3550
declAttributeIsId = XML_FALSE;
3551
goto checkAttListDeclHandler;
3552
case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
3553
declAttributeIsCdata = XML_TRUE;
3554
declAttributeType = atypeCDATA;
3555
goto checkAttListDeclHandler;
3556
case XML_ROLE_ATTRIBUTE_TYPE_ID:
3557
declAttributeIsId = XML_TRUE;
3558
declAttributeType = atypeID;
3559
goto checkAttListDeclHandler;
3560
case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
3561
declAttributeType = atypeIDREF;
3562
goto checkAttListDeclHandler;
3563
case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
3564
declAttributeType = atypeIDREFS;
3565
goto checkAttListDeclHandler;
3566
case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
3567
declAttributeType = atypeENTITY;
3568
goto checkAttListDeclHandler;
3569
case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
3570
declAttributeType = atypeENTITIES;
3571
goto checkAttListDeclHandler;
3572
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
3573
declAttributeType = atypeNMTOKEN;
3574
goto checkAttListDeclHandler;
3575
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
3576
declAttributeType = atypeNMTOKENS;
3577
checkAttListDeclHandler:
3578
if (dtd->keepProcessing && attlistDeclHandler)
3579
handleDefault = XML_FALSE;
3581
case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3582
case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
3583
if (dtd->keepProcessing && attlistDeclHandler) {
3584
const XML_Char *prefix;
3585
if (declAttributeType) {
3586
prefix = enumValueSep;
3589
prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3593
if (!poolAppendString(&tempPool, prefix))
3594
return XML_ERROR_NO_MEMORY;
3595
if (!poolAppend(&tempPool, enc, s, next))
3596
return XML_ERROR_NO_MEMORY;
3597
declAttributeType = tempPool.start;
3598
handleDefault = XML_FALSE;
3601
case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3602
case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
3603
if (dtd->keepProcessing) {
3604
if (!defineAttribute(declElementType, declAttributeId,
3605
declAttributeIsCdata, declAttributeIsId,
3607
return XML_ERROR_NO_MEMORY;
3608
if (attlistDeclHandler && declAttributeType) {
3609
if (*declAttributeType == XML_T('(')
3610
|| (*declAttributeType == XML_T('N')
3611
&& declAttributeType[1] == XML_T('O'))) {
3612
/* Enumerated or Notation type */
3613
if (!poolAppendChar(&tempPool, XML_T(')'))
3614
|| !poolAppendChar(&tempPool, XML_T('\0')))
3615
return XML_ERROR_NO_MEMORY;
3616
declAttributeType = tempPool.start;
3617
poolFinish(&tempPool);
3620
attlistDeclHandler(handlerArg, declElementType->name,
3621
declAttributeId->name, declAttributeType,
3622
0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3623
poolClear(&tempPool);
3624
handleDefault = XML_FALSE;
3628
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3629
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
3630
if (dtd->keepProcessing) {
3631
const XML_Char *attVal;
3632
enum XML_Error result =
3633
storeAttributeValue(parser, enc, declAttributeIsCdata,
3634
s + enc->minBytesPerChar,
3635
next - enc->minBytesPerChar,
3639
attVal = poolStart(&dtd->pool);
3640
poolFinish(&dtd->pool);
3641
/* ID attributes aren't allowed to have a default */
3642
if (!defineAttribute(declElementType, declAttributeId,
3643
declAttributeIsCdata, XML_FALSE, attVal, parser))
3644
return XML_ERROR_NO_MEMORY;
3645
if (attlistDeclHandler && declAttributeType) {
3646
if (*declAttributeType == XML_T('(')
3647
|| (*declAttributeType == XML_T('N')
3648
&& declAttributeType[1] == XML_T('O'))) {
3649
/* Enumerated or Notation type */
3650
if (!poolAppendChar(&tempPool, XML_T(')'))
3651
|| !poolAppendChar(&tempPool, XML_T('\0')))
3652
return XML_ERROR_NO_MEMORY;
3653
declAttributeType = tempPool.start;
3654
poolFinish(&tempPool);
3657
attlistDeclHandler(handlerArg, declElementType->name,
3658
declAttributeId->name, declAttributeType,
3660
role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3661
poolClear(&tempPool);
3662
handleDefault = XML_FALSE;
3666
case XML_ROLE_ENTITY_VALUE:
3667
if (dtd->keepProcessing) {
3668
enum XML_Error result = storeEntityValue(parser, enc,
3669
s + enc->minBytesPerChar,
3670
next - enc->minBytesPerChar);
3672
declEntity->textPtr = poolStart(&dtd->entityValuePool);
3673
declEntity->textLen = poolLength(&dtd->entityValuePool);
3674
poolFinish(&dtd->entityValuePool);
3675
if (entityDeclHandler) {
3677
entityDeclHandler(handlerArg,
3679
declEntity->is_param,
3680
declEntity->textPtr,
3681
declEntity->textLen,
3683
handleDefault = XML_FALSE;
3687
poolDiscard(&dtd->entityValuePool);
3688
if (result != XML_ERROR_NONE)
3692
case XML_ROLE_DOCTYPE_SYSTEM_ID:
3694
useForeignDTD = XML_FALSE;
3695
#endif /* XML_DTD */
3696
dtd->hasParamEntityRefs = XML_TRUE;
3697
if (startDoctypeDeclHandler) {
3698
doctypeSysid = poolStoreString(&tempPool, enc,
3699
s + enc->minBytesPerChar,
3700
next - enc->minBytesPerChar);
3701
if (doctypeSysid == NULL)
3702
return XML_ERROR_NO_MEMORY;
3703
poolFinish(&tempPool);
3704
handleDefault = XML_FALSE;
3708
/* use externalSubsetName to make doctypeSysid non-NULL
3709
for the case where no startDoctypeDeclHandler is set */
3710
doctypeSysid = externalSubsetName;
3711
#endif /* XML_DTD */
3712
if (!dtd->standalone
3714
&& !paramEntityParsing
3715
#endif /* XML_DTD */
3716
&& notStandaloneHandler
3717
&& !notStandaloneHandler(handlerArg))
3718
return XML_ERROR_NOT_STANDALONE;
3723
declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3727
return XML_ERROR_NO_MEMORY;
3728
declEntity->publicId = NULL;
3731
#endif /* XML_DTD */
3732
case XML_ROLE_ENTITY_SYSTEM_ID:
3733
if (dtd->keepProcessing && declEntity) {
3734
declEntity->systemId = poolStoreString(&dtd->pool, enc,
3735
s + enc->minBytesPerChar,
3736
next - enc->minBytesPerChar);
3737
if (!declEntity->systemId)
3738
return XML_ERROR_NO_MEMORY;
3739
declEntity->base = curBase;
3740
poolFinish(&dtd->pool);
3741
if (entityDeclHandler)
3742
handleDefault = XML_FALSE;
3745
case XML_ROLE_ENTITY_COMPLETE:
3746
if (dtd->keepProcessing && declEntity && entityDeclHandler) {
3748
entityDeclHandler(handlerArg,
3750
declEntity->is_param,
3753
declEntity->systemId,
3754
declEntity->publicId,
3756
handleDefault = XML_FALSE;
3759
case XML_ROLE_ENTITY_NOTATION_NAME:
3760
if (dtd->keepProcessing && declEntity) {
3761
declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
3762
if (!declEntity->notation)
3763
return XML_ERROR_NO_MEMORY;
3764
poolFinish(&dtd->pool);
3765
if (unparsedEntityDeclHandler) {
3767
unparsedEntityDeclHandler(handlerArg,
3770
declEntity->systemId,
3771
declEntity->publicId,
3772
declEntity->notation);
3773
handleDefault = XML_FALSE;
3775
else if (entityDeclHandler) {
3777
entityDeclHandler(handlerArg,
3781
declEntity->systemId,
3782
declEntity->publicId,
3783
declEntity->notation);
3784
handleDefault = XML_FALSE;
3788
case XML_ROLE_GENERAL_ENTITY_NAME:
3790
if (XmlPredefinedEntityName(enc, s, next)) {
3794
if (dtd->keepProcessing) {
3795
const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3797
return XML_ERROR_NO_MEMORY;
3798
declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
3801
return XML_ERROR_NO_MEMORY;
3802
if (declEntity->name != name) {
3803
poolDiscard(&dtd->pool);
3807
poolFinish(&dtd->pool);
3808
declEntity->publicId = NULL;
3809
declEntity->is_param = XML_FALSE;
3810
/* if we have a parent parser or are reading an internal parameter
3811
entity, then the entity declaration is not considered "internal"
3813
declEntity->is_internal = !(parentParser || openInternalEntities);
3814
if (entityDeclHandler)
3815
handleDefault = XML_FALSE;
3819
poolDiscard(&dtd->pool);
3824
case XML_ROLE_PARAM_ENTITY_NAME:
3826
if (dtd->keepProcessing) {
3827
const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3829
return XML_ERROR_NO_MEMORY;
3830
declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3831
name, sizeof(ENTITY));
3833
return XML_ERROR_NO_MEMORY;
3834
if (declEntity->name != name) {
3835
poolDiscard(&dtd->pool);
3839
poolFinish(&dtd->pool);
3840
declEntity->publicId = NULL;
3841
declEntity->is_param = XML_TRUE;
3842
/* if we have a parent parser or are reading an internal parameter
3843
entity, then the entity declaration is not considered "internal"
3845
declEntity->is_internal = !(parentParser || openInternalEntities);
3846
if (entityDeclHandler)
3847
handleDefault = XML_FALSE;
3851
poolDiscard(&dtd->pool);
3854
#else /* not XML_DTD */
3856
#endif /* XML_DTD */
3858
case XML_ROLE_NOTATION_NAME:
3859
declNotationPublicId = NULL;
3860
declNotationName = NULL;
3861
if (notationDeclHandler) {
3862
declNotationName = poolStoreString(&tempPool, enc, s, next);
3863
if (!declNotationName)
3864
return XML_ERROR_NO_MEMORY;
3865
poolFinish(&tempPool);
3866
handleDefault = XML_FALSE;
3869
case XML_ROLE_NOTATION_PUBLIC_ID:
3870
if (!XmlIsPublicId(enc, s, next, eventPP))
3871
return XML_ERROR_SYNTAX;
3872
if (declNotationName) { /* means notationDeclHandler != NULL */
3873
XML_Char *tem = poolStoreString(&tempPool,
3875
s + enc->minBytesPerChar,
3876
next - enc->minBytesPerChar);
3878
return XML_ERROR_NO_MEMORY;
3879
normalizePublicId(tem);
3880
declNotationPublicId = tem;
3881
poolFinish(&tempPool);
3882
handleDefault = XML_FALSE;
3885
case XML_ROLE_NOTATION_SYSTEM_ID:
3886
if (declNotationName && notationDeclHandler) {
3887
const XML_Char *systemId
3888
= poolStoreString(&tempPool, enc,
3889
s + enc->minBytesPerChar,
3890
next - enc->minBytesPerChar);
3892
return XML_ERROR_NO_MEMORY;
3894
notationDeclHandler(handlerArg,
3898
declNotationPublicId);
3899
handleDefault = XML_FALSE;
3901
poolClear(&tempPool);
3903
case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3904
if (declNotationPublicId && notationDeclHandler) {
3906
notationDeclHandler(handlerArg,
3910
declNotationPublicId);
3911
handleDefault = XML_FALSE;
3913
poolClear(&tempPool);
3915
case XML_ROLE_ERROR:
3917
case XML_TOK_PARAM_ENTITY_REF:
3918
return XML_ERROR_PARAM_ENTITY_REF;
3919
case XML_TOK_XML_DECL:
3920
return XML_ERROR_MISPLACED_XML_PI;
3922
return XML_ERROR_SYNTAX;
3925
case XML_ROLE_IGNORE_SECT:
3927
enum XML_Error result;
3929
reportDefault(parser, enc, s, next);
3930
handleDefault = XML_FALSE;
3931
result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3933
processor = ignoreSectionProcessor;
3938
#endif /* XML_DTD */
3939
case XML_ROLE_GROUP_OPEN:
3940
if (prologState.level >= groupSize) {
3942
char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
3944
return XML_ERROR_NO_MEMORY;
3945
groupConnector = temp;
3946
if (dtd->scaffIndex) {
3947
int *temp = (int *)REALLOC(dtd->scaffIndex,
3948
groupSize * sizeof(int));
3950
return XML_ERROR_NO_MEMORY;
3951
dtd->scaffIndex = temp;
3955
groupConnector = (char *)MALLOC(groupSize = 32);
3956
if (!groupConnector)
3957
return XML_ERROR_NO_MEMORY;
3960
groupConnector[prologState.level] = 0;
3961
if (dtd->in_eldecl) {
3962
int myindex = nextScaffoldPart(parser);
3964
return XML_ERROR_NO_MEMORY;
3965
dtd->scaffIndex[dtd->scaffLevel] = myindex;
3967
dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
3968
if (elementDeclHandler)
3969
handleDefault = XML_FALSE;
3972
case XML_ROLE_GROUP_SEQUENCE:
3973
if (groupConnector[prologState.level] == '|')
3974
return XML_ERROR_SYNTAX;
3975
groupConnector[prologState.level] = ',';
3976
if (dtd->in_eldecl && elementDeclHandler)
3977
handleDefault = XML_FALSE;
3979
case XML_ROLE_GROUP_CHOICE:
3980
if (groupConnector[prologState.level] == ',')
3981
return XML_ERROR_SYNTAX;
3983
&& !groupConnector[prologState.level]
3984
&& (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3987
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3989
if (elementDeclHandler)
3990
handleDefault = XML_FALSE;
3992
groupConnector[prologState.level] = '|';
3994
case XML_ROLE_PARAM_ENTITY_REF:
3996
case XML_ROLE_INNER_PARAM_ENTITY_REF:
3997
/* PE references in internal subset are
3998
not allowed within declarations */
3999
if (prologState.documentEntity &&
4000
role == XML_ROLE_INNER_PARAM_ENTITY_REF)
4001
return XML_ERROR_PARAM_ENTITY_REF;
4002
dtd->hasParamEntityRefs = XML_TRUE;
4003
if (!paramEntityParsing)
4004
dtd->keepProcessing = dtd->standalone;
4006
const XML_Char *name;
4008
name = poolStoreString(&dtd->pool, enc,
4009
s + enc->minBytesPerChar,
4010
next - enc->minBytesPerChar);
4012
return XML_ERROR_NO_MEMORY;
4013
entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4014
poolDiscard(&dtd->pool);
4015
/* first, determine if a check for an existing declaration is needed;
4016
if yes, check that the entity exists, and that it is internal,
4017
otherwise call the skipped entity handler
4019
if (prologState.documentEntity &&
4021
? !openInternalEntities
4022
: !dtd->hasParamEntityRefs)) {
4024
return XML_ERROR_UNDEFINED_ENTITY;
4025
else if (!entity->is_internal)
4026
return XML_ERROR_ENTITY_DECLARED_IN_PE;
4029
dtd->keepProcessing = dtd->standalone;
4030
/* cannot report skipped entities in declarations */
4031
if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4032
skippedEntityHandler(handlerArg, name, 1);
4033
handleDefault = XML_FALSE;
4038
return XML_ERROR_RECURSIVE_ENTITY_REF;
4039
if (entity->textPtr) {
4040
enum XML_Error result;
4041
result = processInternalParamEntity(parser, entity);
4042
if (result != XML_ERROR_NONE)
4044
handleDefault = XML_FALSE;
4047
if (externalEntityRefHandler) {
4048
dtd->paramEntityRead = XML_FALSE;
4049
entity->open = XML_TRUE;
4050
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4054
entity->publicId)) {
4055
entity->open = XML_FALSE;
4056
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4058
entity->open = XML_FALSE;
4059
handleDefault = XML_FALSE;
4060
if (!dtd->paramEntityRead) {
4061
dtd->keepProcessing = dtd->standalone;
4066
dtd->keepProcessing = dtd->standalone;
4070
#endif /* XML_DTD */
4071
if (!dtd->standalone &&
4072
notStandaloneHandler &&
4073
!notStandaloneHandler(handlerArg))
4074
return XML_ERROR_NOT_STANDALONE;
4077
/* Element declaration stuff */
4079
case XML_ROLE_ELEMENT_NAME:
4080
if (elementDeclHandler) {
4081
declElementType = getElementType(parser, enc, s, next);
4082
if (!declElementType)
4083
return XML_ERROR_NO_MEMORY;
4084
dtd->scaffLevel = 0;
4085
dtd->scaffCount = 0;
4086
dtd->in_eldecl = XML_TRUE;
4087
handleDefault = XML_FALSE;
4091
case XML_ROLE_CONTENT_ANY:
4092
case XML_ROLE_CONTENT_EMPTY:
4093
if (dtd->in_eldecl) {
4094
if (elementDeclHandler) {
4095
XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4097
return XML_ERROR_NO_MEMORY;
4098
content->quant = XML_CQUANT_NONE;
4099
content->name = NULL;
4100
content->numchildren = 0;
4101
content->children = NULL;
4102
content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4106
elementDeclHandler(handlerArg, declElementType->name, content);
4107
handleDefault = XML_FALSE;
4109
dtd->in_eldecl = XML_FALSE;
4113
case XML_ROLE_CONTENT_PCDATA:
4114
if (dtd->in_eldecl) {
4115
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4117
if (elementDeclHandler)
4118
handleDefault = XML_FALSE;
4122
case XML_ROLE_CONTENT_ELEMENT:
4123
quant = XML_CQUANT_NONE;
4124
goto elementContent;
4125
case XML_ROLE_CONTENT_ELEMENT_OPT:
4126
quant = XML_CQUANT_OPT;
4127
goto elementContent;
4128
case XML_ROLE_CONTENT_ELEMENT_REP:
4129
quant = XML_CQUANT_REP;
4130
goto elementContent;
4131
case XML_ROLE_CONTENT_ELEMENT_PLUS:
4132
quant = XML_CQUANT_PLUS;
4134
if (dtd->in_eldecl) {
4136
const XML_Char *name;
4138
const char *nxt = (quant == XML_CQUANT_NONE
4140
: next - enc->minBytesPerChar);
4141
int myindex = nextScaffoldPart(parser);
4143
return XML_ERROR_NO_MEMORY;
4144
dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4145
dtd->scaffold[myindex].quant = quant;
4146
el = getElementType(parser, enc, s, nxt);
4148
return XML_ERROR_NO_MEMORY;
4150
dtd->scaffold[myindex].name = name;
4152
for (; name[nameLen++]; );
4153
dtd->contentStringLen += nameLen;
4154
if (elementDeclHandler)
4155
handleDefault = XML_FALSE;
4159
case XML_ROLE_GROUP_CLOSE:
4160
quant = XML_CQUANT_NONE;
4162
case XML_ROLE_GROUP_CLOSE_OPT:
4163
quant = XML_CQUANT_OPT;
4165
case XML_ROLE_GROUP_CLOSE_REP:
4166
quant = XML_CQUANT_REP;
4168
case XML_ROLE_GROUP_CLOSE_PLUS:
4169
quant = XML_CQUANT_PLUS;
4171
if (dtd->in_eldecl) {
4172
if (elementDeclHandler)
4173
handleDefault = XML_FALSE;
4175
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4176
if (dtd->scaffLevel == 0) {
4177
if (!handleDefault) {
4178
XML_Content *model = build_model(parser);
4180
return XML_ERROR_NO_MEMORY;
4182
elementDeclHandler(handlerArg, declElementType->name, model);
4184
dtd->in_eldecl = XML_FALSE;
4185
dtd->contentStringLen = 0;
4189
/* End element declaration stuff */
4192
if (!reportProcessingInstruction(parser, enc, s, next))
4193
return XML_ERROR_NO_MEMORY;
4194
handleDefault = XML_FALSE;
4196
case XML_ROLE_COMMENT:
4197
if (!reportComment(parser, enc, s, next))
4198
return XML_ERROR_NO_MEMORY;
4199
handleDefault = XML_FALSE;
4204
handleDefault = XML_FALSE;
4208
case XML_ROLE_DOCTYPE_NONE:
4209
if (startDoctypeDeclHandler)
4210
handleDefault = XML_FALSE;
4212
case XML_ROLE_ENTITY_NONE:
4213
if (dtd->keepProcessing && entityDeclHandler)
4214
handleDefault = XML_FALSE;
4216
case XML_ROLE_NOTATION_NONE:
4217
if (notationDeclHandler)
4218
handleDefault = XML_FALSE;
4220
case XML_ROLE_ATTLIST_NONE:
4221
if (dtd->keepProcessing && attlistDeclHandler)
4222
handleDefault = XML_FALSE;
4224
case XML_ROLE_ELEMENT_NONE:
4225
if (elementDeclHandler)
4226
handleDefault = XML_FALSE;
4228
} /* end of big switch */
4230
if (handleDefault && defaultHandler)
4231
reportDefault(parser, enc, s, next);
4234
tok = XmlPrologTok(enc, s, end, &next);
4239
static enum XML_Error PTRCALL
4240
epilogProcessor(XML_Parser parser,
4243
const char **nextPtr)
4245
processor = epilogProcessor;
4248
const char *next = NULL;
4249
int tok = XmlPrologTok(encoding, s, end, &next);
4252
/* report partial linebreak - it might be the last token */
4253
case -XML_TOK_PROLOG_S:
4254
if (defaultHandler) {
4256
reportDefault(parser, encoding, s, next);
4260
return XML_ERROR_NONE;
4264
return XML_ERROR_NONE;
4265
case XML_TOK_PROLOG_S:
4267
reportDefault(parser, encoding, s, next);
4270
if (!reportProcessingInstruction(parser, encoding, s, next))
4271
return XML_ERROR_NO_MEMORY;
4273
case XML_TOK_COMMENT:
4274
if (!reportComment(parser, encoding, s, next))
4275
return XML_ERROR_NO_MEMORY;
4277
case XML_TOK_INVALID:
4279
return XML_ERROR_INVALID_TOKEN;
4280
case XML_TOK_PARTIAL:
4283
return XML_ERROR_NONE;
4285
return XML_ERROR_UNCLOSED_TOKEN;
4286
case XML_TOK_PARTIAL_CHAR:
4289
return XML_ERROR_NONE;
4291
return XML_ERROR_PARTIAL_CHAR;
4293
return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4295
eventPtr = s = next;
4301
static enum XML_Error
4302
processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4304
const char *s, *end, *next;
4306
enum XML_Error result;
4307
OPEN_INTERNAL_ENTITY openEntity;
4308
entity->open = XML_TRUE;
4309
openEntity.next = openInternalEntities;
4310
openInternalEntities = &openEntity;
4311
openEntity.entity = entity;
4312
openEntity.internalEventPtr = NULL;
4313
openEntity.internalEventEndPtr = NULL;
4314
s = (char *)entity->textPtr;
4315
end = (char *)(entity->textPtr + entity->textLen);
4316
tok = XmlPrologTok(internalEncoding, s, end, &next);
4317
result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
4318
entity->open = XML_FALSE;
4319
openInternalEntities = openEntity.next;
4323
#endif /* XML_DTD */
4325
static enum XML_Error PTRCALL
4326
errorProcessor(XML_Parser parser,
4329
const char **nextPtr)
4334
static enum XML_Error
4335
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4336
const char *ptr, const char *end,
4339
enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4343
if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4345
if (!poolAppendChar(pool, XML_T('\0')))
4346
return XML_ERROR_NO_MEMORY;
4347
return XML_ERROR_NONE;
4350
static enum XML_Error
4351
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4352
const char *ptr, const char *end,
4355
DTD * const dtd = _dtd; /* save one level of indirection */
4358
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4361
return XML_ERROR_NONE;
4362
case XML_TOK_INVALID:
4363
if (enc == encoding)
4365
return XML_ERROR_INVALID_TOKEN;
4366
case XML_TOK_PARTIAL:
4367
if (enc == encoding)
4369
return XML_ERROR_INVALID_TOKEN;
4370
case XML_TOK_CHAR_REF:
4372
XML_Char buf[XML_ENCODE_MAX];
4374
int n = XmlCharRefNumber(enc, ptr);
4376
if (enc == encoding)
4378
return XML_ERROR_BAD_CHAR_REF;
4381
&& n == 0x20 /* space */
4382
&& (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4384
n = XmlEncode(n, (ICHAR *)buf);
4386
if (enc == encoding)
4388
return XML_ERROR_BAD_CHAR_REF;
4390
for (i = 0; i < n; i++) {
4391
if (!poolAppendChar(pool, buf[i]))
4392
return XML_ERROR_NO_MEMORY;
4396
case XML_TOK_DATA_CHARS:
4397
if (!poolAppend(pool, enc, ptr, next))
4398
return XML_ERROR_NO_MEMORY;
4400
case XML_TOK_TRAILING_CR:
4401
next = ptr + enc->minBytesPerChar;
4403
case XML_TOK_ATTRIBUTE_VALUE_S:
4404
case XML_TOK_DATA_NEWLINE:
4405
if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4407
if (!poolAppendChar(pool, 0x20))
4408
return XML_ERROR_NO_MEMORY;
4410
case XML_TOK_ENTITY_REF:
4412
const XML_Char *name;
4414
char checkEntityDecl;
4415
XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4416
ptr + enc->minBytesPerChar,
4417
next - enc->minBytesPerChar);
4419
if (!poolAppendChar(pool, ch))
4420
return XML_ERROR_NO_MEMORY;
4423
name = poolStoreString(&temp2Pool, enc,
4424
ptr + enc->minBytesPerChar,
4425
next - enc->minBytesPerChar);
4427
return XML_ERROR_NO_MEMORY;
4428
entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4429
poolDiscard(&temp2Pool);
4430
/* first, determine if a check for an existing declaration is needed;
4431
if yes, check that the entity exists, and that it is internal,
4432
otherwise call the default handler (if called from content)
4434
if (pool == &dtd->pool) /* are we called from prolog? */
4437
prologState.documentEntity &&
4438
#endif /* XML_DTD */
4440
? !openInternalEntities
4441
: !dtd->hasParamEntityRefs);
4442
else /* if (pool == &tempPool): we are called from content */
4443
checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4444
if (checkEntityDecl) {
4446
return XML_ERROR_UNDEFINED_ENTITY;
4447
else if (!entity->is_internal)
4448
return XML_ERROR_ENTITY_DECLARED_IN_PE;
4451
/* cannot report skipped entity here - see comments on
4452
skippedEntityHandler
4453
if (skippedEntityHandler)
4454
skippedEntityHandler(handlerArg, name, 0);
4456
if ((pool == &tempPool) && defaultHandler)
4457
reportDefault(parser, enc, ptr, next);
4461
if (enc == encoding)
4463
return XML_ERROR_RECURSIVE_ENTITY_REF;
4465
if (entity->notation) {
4466
if (enc == encoding)
4468
return XML_ERROR_BINARY_ENTITY_REF;
4470
if (!entity->textPtr) {
4471
if (enc == encoding)
4473
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4476
enum XML_Error result;
4477
const XML_Char *textEnd = entity->textPtr + entity->textLen;
4478
entity->open = XML_TRUE;
4479
result = appendAttributeValue(parser, internalEncoding, isCdata,
4480
(char *)entity->textPtr,
4481
(char *)textEnd, pool);
4482
entity->open = XML_FALSE;
4489
if (enc == encoding)
4491
return XML_ERROR_UNEXPECTED_STATE;
4498
static enum XML_Error
4499
storeEntityValue(XML_Parser parser,
4500
const ENCODING *enc,
4501
const char *entityTextPtr,
4502
const char *entityTextEnd)
4504
DTD * const dtd = _dtd; /* save one level of indirection */
4505
STRING_POOL *pool = &(dtd->entityValuePool);
4506
enum XML_Error result = XML_ERROR_NONE;
4508
int oldInEntityValue = prologState.inEntityValue;
4509
prologState.inEntityValue = 1;
4510
#endif /* XML_DTD */
4511
/* never return Null for the value argument in EntityDeclHandler,
4512
since this would indicate an external entity; therefore we
4513
have to make sure that entityValuePool.start is not null */
4514
if (!pool->blocks) {
4515
if (!poolGrow(pool))
4516
return XML_ERROR_NO_MEMORY;
4521
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4523
case XML_TOK_PARAM_ENTITY_REF:
4525
if (isParamEntity || enc != encoding) {
4526
const XML_Char *name;
4528
name = poolStoreString(&tempPool, enc,
4529
entityTextPtr + enc->minBytesPerChar,
4530
next - enc->minBytesPerChar);
4532
result = XML_ERROR_NO_MEMORY;
4533
goto endEntityValue;
4535
entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4536
poolDiscard(&tempPool);
4538
/* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4539
/* cannot report skipped entity here - see comments on
4540
skippedEntityHandler
4541
if (skippedEntityHandler)
4542
skippedEntityHandler(handlerArg, name, 0);
4544
dtd->keepProcessing = dtd->standalone;
4545
goto endEntityValue;
4548
if (enc == encoding)
4549
eventPtr = entityTextPtr;
4550
result = XML_ERROR_RECURSIVE_ENTITY_REF;
4551
goto endEntityValue;
4553
if (entity->systemId) {
4554
if (externalEntityRefHandler) {
4555
dtd->paramEntityRead = XML_FALSE;
4556
entity->open = XML_TRUE;
4557
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4561
entity->publicId)) {
4562
entity->open = XML_FALSE;
4563
result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4564
goto endEntityValue;
4566
entity->open = XML_FALSE;
4567
if (!dtd->paramEntityRead)
4568
dtd->keepProcessing = dtd->standalone;
4571
dtd->keepProcessing = dtd->standalone;
4574
entity->open = XML_TRUE;
4575
result = storeEntityValue(parser,
4577
(char *)entity->textPtr,
4578
(char *)(entity->textPtr
4579
+ entity->textLen));
4580
entity->open = XML_FALSE;
4582
goto endEntityValue;
4586
#endif /* XML_DTD */
4587
/* in the internal subset, PE references are not legal
4588
within markup declarations, e.g entity values in this case */
4589
eventPtr = entityTextPtr;
4590
result = XML_ERROR_PARAM_ENTITY_REF;
4591
goto endEntityValue;
4593
result = XML_ERROR_NONE;
4594
goto endEntityValue;
4595
case XML_TOK_ENTITY_REF:
4596
case XML_TOK_DATA_CHARS:
4597
if (!poolAppend(pool, enc, entityTextPtr, next)) {
4598
result = XML_ERROR_NO_MEMORY;
4599
goto endEntityValue;
4602
case XML_TOK_TRAILING_CR:
4603
next = entityTextPtr + enc->minBytesPerChar;
4605
case XML_TOK_DATA_NEWLINE:
4606
if (pool->end == pool->ptr && !poolGrow(pool)) {
4607
result = XML_ERROR_NO_MEMORY;
4608
goto endEntityValue;
4610
*(pool->ptr)++ = 0xA;
4612
case XML_TOK_CHAR_REF:
4614
XML_Char buf[XML_ENCODE_MAX];
4616
int n = XmlCharRefNumber(enc, entityTextPtr);
4618
if (enc == encoding)
4619
eventPtr = entityTextPtr;
4620
result = XML_ERROR_BAD_CHAR_REF;
4621
goto endEntityValue;
4623
n = XmlEncode(n, (ICHAR *)buf);
4625
if (enc == encoding)
4626
eventPtr = entityTextPtr;
4627
result = XML_ERROR_BAD_CHAR_REF;
4628
goto endEntityValue;
4630
for (i = 0; i < n; i++) {
4631
if (pool->end == pool->ptr && !poolGrow(pool)) {
4632
result = XML_ERROR_NO_MEMORY;
4633
goto endEntityValue;
4635
*(pool->ptr)++ = buf[i];
4639
case XML_TOK_PARTIAL:
4640
if (enc == encoding)
4641
eventPtr = entityTextPtr;
4642
result = XML_ERROR_INVALID_TOKEN;
4643
goto endEntityValue;
4644
case XML_TOK_INVALID:
4645
if (enc == encoding)
4647
result = XML_ERROR_INVALID_TOKEN;
4648
goto endEntityValue;
4650
if (enc == encoding)
4651
eventPtr = entityTextPtr;
4652
result = XML_ERROR_UNEXPECTED_STATE;
4653
goto endEntityValue;
4655
entityTextPtr = next;
4659
prologState.inEntityValue = oldInEntityValue;
4660
#endif /* XML_DTD */
4664
static void FASTCALL
4665
normalizeLines(XML_Char *s)
4669
if (*s == XML_T('\0'))
4688
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4689
const char *start, const char *end)
4691
const XML_Char *target;
4694
if (!processingInstructionHandler) {
4696
reportDefault(parser, enc, start, end);
4699
start += enc->minBytesPerChar * 2;
4700
tem = start + XmlNameLength(enc, start);
4701
target = poolStoreString(&tempPool, enc, start, tem);
4704
poolFinish(&tempPool);
4705
data = poolStoreString(&tempPool, enc,
4707
end - enc->minBytesPerChar*2);
4710
normalizeLines(data);
4711
processingInstructionHandler(handlerArg, target, data);
4712
poolClear(&tempPool);
4717
reportComment(XML_Parser parser, const ENCODING *enc,
4718
const char *start, const char *end)
4721
if (!commentHandler) {
4723
reportDefault(parser, enc, start, end);
4726
data = poolStoreString(&tempPool,
4728
start + enc->minBytesPerChar * 4,
4729
end - enc->minBytesPerChar * 3);
4732
normalizeLines(data);
4733
commentHandler(handlerArg, data);
4734
poolClear(&tempPool);
4739
reportDefault(XML_Parser parser, const ENCODING *enc,
4740
const char *s, const char *end)
4742
if (MUST_CONVERT(enc, s)) {
4743
const char **eventPP;
4744
const char **eventEndPP;
4745
if (enc == encoding) {
4746
eventPP = &eventPtr;
4747
eventEndPP = &eventEndPtr;
4750
eventPP = &(openInternalEntities->internalEventPtr);
4751
eventEndPP = &(openInternalEntities->internalEventEndPtr);
4754
ICHAR *dataPtr = (ICHAR *)dataBuf;
4755
XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4757
defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4762
defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4767
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4768
XML_Bool isId, const XML_Char *value, XML_Parser parser)
4770
DEFAULT_ATTRIBUTE *att;
4771
if (value || isId) {
4772
/* The handling of default attributes gets messed up if we have
4773
a default which duplicates a non-default. */
4775
for (i = 0; i < type->nDefaultAtts; i++)
4776
if (attId == type->defaultAtts[i].id)
4778
if (isId && !type->idAtt && !attId->xmlns)
4779
type->idAtt = attId;
4781
if (type->nDefaultAtts == type->allocDefaultAtts) {
4782
if (type->allocDefaultAtts == 0) {
4783
type->allocDefaultAtts = 8;
4784
type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
4785
* sizeof(DEFAULT_ATTRIBUTE));
4786
if (!type->defaultAtts)
4790
DEFAULT_ATTRIBUTE *temp;
4791
int count = type->allocDefaultAtts * 2;
4792
temp = (DEFAULT_ATTRIBUTE *)
4793
REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4796
type->allocDefaultAtts = count;
4797
type->defaultAtts = temp;
4800
att = type->defaultAtts + type->nDefaultAtts;
4803
att->isCdata = isCdata;
4805
attId->maybeTokenized = XML_TRUE;
4806
type->nDefaultAtts += 1;
4811
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
4813
DTD * const dtd = _dtd; /* save one level of indirection */
4814
const XML_Char *name;
4815
for (name = elementType->name; *name; name++) {
4816
if (*name == XML_T(':')) {
4819
for (s = elementType->name; s != name; s++) {
4820
if (!poolAppendChar(&dtd->pool, *s))
4823
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4825
prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4829
if (prefix->name == poolStart(&dtd->pool))
4830
poolFinish(&dtd->pool);
4832
poolDiscard(&dtd->pool);
4833
elementType->prefix = prefix;
4840
static ATTRIBUTE_ID *
4841
getAttributeId(XML_Parser parser, const ENCODING *enc,
4842
const char *start, const char *end)
4844
DTD * const dtd = _dtd; /* save one level of indirection */
4846
const XML_Char *name;
4847
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4849
name = poolStoreString(&dtd->pool, enc, start, end);
4852
/* skip quotation mark - its storage will be re-used (like in name[-1]) */
4854
id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
4857
if (id->name != name)
4858
poolDiscard(&dtd->pool);
4860
poolFinish(&dtd->pool);
4863
else if (name[0] == XML_T('x')
4864
&& name[1] == XML_T('m')
4865
&& name[2] == XML_T('l')
4866
&& name[3] == XML_T('n')
4867
&& name[4] == XML_T('s')
4868
&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4869
if (name[5] == XML_T('\0'))
4870
id->prefix = &dtd->defaultPrefix;
4872
id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4873
id->xmlns = XML_TRUE;
4877
for (i = 0; name[i]; i++) {
4878
/* attributes without prefix are *not* in the default namespace */
4879
if (name[i] == XML_T(':')) {
4881
for (j = 0; j < i; j++) {
4882
if (!poolAppendChar(&dtd->pool, name[j]))
4885
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4887
id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4889
if (id->prefix->name == poolStart(&dtd->pool))
4890
poolFinish(&dtd->pool);
4892
poolDiscard(&dtd->pool);
4901
#define CONTEXT_SEP XML_T('\f')
4903
static const XML_Char *
4904
getContext(XML_Parser parser)
4906
DTD * const dtd = _dtd; /* save one level of indirection */
4907
HASH_TABLE_ITER iter;
4908
XML_Bool needSep = XML_FALSE;
4910
if (dtd->defaultPrefix.binding) {
4913
if (!poolAppendChar(&tempPool, XML_T('=')))
4915
len = dtd->defaultPrefix.binding->uriLen;
4916
if (namespaceSeparator != XML_T('\0'))
4918
for (i = 0; i < len; i++)
4919
if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4924
hashTableIterInit(&iter, &(dtd->prefixes));
4929
PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4932
if (!prefix->binding)
4934
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4936
for (s = prefix->name; *s; s++)
4937
if (!poolAppendChar(&tempPool, *s))
4939
if (!poolAppendChar(&tempPool, XML_T('=')))
4941
len = prefix->binding->uriLen;
4942
if (namespaceSeparator != XML_T('\0'))
4944
for (i = 0; i < len; i++)
4945
if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
4951
hashTableIterInit(&iter, &(dtd->generalEntities));
4954
ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4959
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4961
for (s = e->name; *s; s++)
4962
if (!poolAppendChar(&tempPool, *s))
4967
if (!poolAppendChar(&tempPool, XML_T('\0')))
4969
return tempPool.start;
4973
setContext(XML_Parser parser, const XML_Char *context)
4975
DTD * const dtd = _dtd; /* save one level of indirection */
4976
const XML_Char *s = context;
4978
while (*context != XML_T('\0')) {
4979
if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4981
if (!poolAppendChar(&tempPool, XML_T('\0')))
4983
e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
4986
if (*s != XML_T('\0'))
4989
poolDiscard(&tempPool);
4991
else if (*s == XML_T('=')) {
4993
if (poolLength(&tempPool) == 0)
4994
prefix = &dtd->defaultPrefix;
4996
if (!poolAppendChar(&tempPool, XML_T('\0')))
4998
prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5002
if (prefix->name == poolStart(&tempPool)) {
5003
prefix->name = poolCopyString(&dtd->pool, prefix->name);
5007
poolDiscard(&tempPool);
5009
for (context = s + 1;
5010
*context != CONTEXT_SEP && *context != XML_T('\0');
5012
if (!poolAppendChar(&tempPool, *context))
5014
if (!poolAppendChar(&tempPool, XML_T('\0')))
5016
if (addBinding(parser, prefix, 0, poolStart(&tempPool),
5017
&inheritedBindings) != XML_ERROR_NONE)
5019
poolDiscard(&tempPool);
5020
if (*context != XML_T('\0'))
5025
if (!poolAppendChar(&tempPool, *s))
5033
static void FASTCALL
5034
normalizePublicId(XML_Char *publicId)
5036
XML_Char *p = publicId;
5038
for (s = publicId; *s; s++) {
5043
if (p != publicId && p[-1] != 0x20)
5050
if (p != publicId && p[-1] == 0x20)
5056
dtdCreate(const XML_Memory_Handling_Suite *ms)
5058
DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5061
poolInit(&(p->pool), ms);
5063
poolInit(&(p->entityValuePool), ms);
5064
#endif /* XML_DTD */
5065
hashTableInit(&(p->generalEntities), ms);
5066
hashTableInit(&(p->elementTypes), ms);
5067
hashTableInit(&(p->attributeIds), ms);
5068
hashTableInit(&(p->prefixes), ms);
5070
p->paramEntityRead = XML_FALSE;
5071
hashTableInit(&(p->paramEntities), ms);
5072
#endif /* XML_DTD */
5073
p->defaultPrefix.name = NULL;
5074
p->defaultPrefix.binding = NULL;
5076
p->in_eldecl = XML_FALSE;
5077
p->scaffIndex = NULL;
5082
p->contentStringLen = 0;
5084
p->keepProcessing = XML_TRUE;
5085
p->hasParamEntityRefs = XML_FALSE;
5086
p->standalone = XML_FALSE;
5091
dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5093
HASH_TABLE_ITER iter;
5094
hashTableIterInit(&iter, &(p->elementTypes));
5096
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5099
if (e->allocDefaultAtts != 0)
5100
ms->free_fcn(e->defaultAtts);
5102
hashTableClear(&(p->generalEntities));
5104
p->paramEntityRead = XML_FALSE;
5105
hashTableClear(&(p->paramEntities));
5106
#endif /* XML_DTD */
5107
hashTableClear(&(p->elementTypes));
5108
hashTableClear(&(p->attributeIds));
5109
hashTableClear(&(p->prefixes));
5110
poolClear(&(p->pool));
5112
poolClear(&(p->entityValuePool));
5113
#endif /* XML_DTD */
5114
p->defaultPrefix.name = NULL;
5115
p->defaultPrefix.binding = NULL;
5117
p->in_eldecl = XML_FALSE;
5119
ms->free_fcn(p->scaffIndex);
5120
p->scaffIndex = NULL;
5121
ms->free_fcn(p->scaffold);
5127
p->contentStringLen = 0;
5129
p->keepProcessing = XML_TRUE;
5130
p->hasParamEntityRefs = XML_FALSE;
5131
p->standalone = XML_FALSE;
5135
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5137
HASH_TABLE_ITER iter;
5138
hashTableIterInit(&iter, &(p->elementTypes));
5140
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5143
if (e->allocDefaultAtts != 0)
5144
ms->free_fcn(e->defaultAtts);
5146
hashTableDestroy(&(p->generalEntities));
5148
hashTableDestroy(&(p->paramEntities));
5149
#endif /* XML_DTD */
5150
hashTableDestroy(&(p->elementTypes));
5151
hashTableDestroy(&(p->attributeIds));
5152
hashTableDestroy(&(p->prefixes));
5153
poolDestroy(&(p->pool));
5155
poolDestroy(&(p->entityValuePool));
5156
#endif /* XML_DTD */
5158
ms->free_fcn(p->scaffIndex);
5159
ms->free_fcn(p->scaffold);
5164
/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5165
The new DTD has already been initialized.
5168
dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5170
HASH_TABLE_ITER iter;
5172
/* Copy the prefix table. */
5174
hashTableIterInit(&iter, &(oldDtd->prefixes));
5176
const XML_Char *name;
5177
const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5180
name = poolCopyString(&(newDtd->pool), oldP->name);
5183
if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5187
hashTableIterInit(&iter, &(oldDtd->attributeIds));
5189
/* Copy the attribute id table. */
5193
const XML_Char *name;
5194
const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5198
/* Remember to allocate the scratch byte before the name. */
5199
if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5201
name = poolCopyString(&(newDtd->pool), oldA->name);
5205
newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5206
sizeof(ATTRIBUTE_ID));
5209
newA->maybeTokenized = oldA->maybeTokenized;
5211
newA->xmlns = oldA->xmlns;
5212
if (oldA->prefix == &oldDtd->defaultPrefix)
5213
newA->prefix = &newDtd->defaultPrefix;
5215
newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5216
oldA->prefix->name, 0);
5220
/* Copy the element type table. */
5222
hashTableIterInit(&iter, &(oldDtd->elementTypes));
5227
const XML_Char *name;
5228
const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5231
name = poolCopyString(&(newDtd->pool), oldE->name);
5234
newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5235
sizeof(ELEMENT_TYPE));
5238
if (oldE->nDefaultAtts) {
5239
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5240
ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5241
if (!newE->defaultAtts) {
5247
newE->idAtt = (ATTRIBUTE_ID *)
5248
lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5249
newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5251
newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5252
oldE->prefix->name, 0);
5253
for (i = 0; i < newE->nDefaultAtts; i++) {
5254
newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5255
lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5256
newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5257
if (oldE->defaultAtts[i].value) {
5258
newE->defaultAtts[i].value
5259
= poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5260
if (!newE->defaultAtts[i].value)
5264
newE->defaultAtts[i].value = NULL;
5268
/* Copy the entity tables. */
5269
if (!copyEntityTable(&(newDtd->generalEntities),
5271
&(oldDtd->generalEntities)))
5275
if (!copyEntityTable(&(newDtd->paramEntities),
5277
&(oldDtd->paramEntities)))
5279
newDtd->paramEntityRead = oldDtd->paramEntityRead;
5280
#endif /* XML_DTD */
5282
newDtd->keepProcessing = oldDtd->keepProcessing;
5283
newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5284
newDtd->standalone = oldDtd->standalone;
5286
/* Don't want deep copying for scaffolding */
5287
newDtd->in_eldecl = oldDtd->in_eldecl;
5288
newDtd->scaffold = oldDtd->scaffold;
5289
newDtd->contentStringLen = oldDtd->contentStringLen;
5290
newDtd->scaffSize = oldDtd->scaffSize;
5291
newDtd->scaffLevel = oldDtd->scaffLevel;
5292
newDtd->scaffIndex = oldDtd->scaffIndex;
5298
copyEntityTable(HASH_TABLE *newTable,
5299
STRING_POOL *newPool,
5300
const HASH_TABLE *oldTable)
5302
HASH_TABLE_ITER iter;
5303
const XML_Char *cachedOldBase = NULL;
5304
const XML_Char *cachedNewBase = NULL;
5306
hashTableIterInit(&iter, oldTable);
5310
const XML_Char *name;
5311
const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5314
name = poolCopyString(newPool, oldE->name);
5317
newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5320
if (oldE->systemId) {
5321
const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5324
newE->systemId = tem;
5326
if (oldE->base == cachedOldBase)
5327
newE->base = cachedNewBase;
5329
cachedOldBase = oldE->base;
5330
tem = poolCopyString(newPool, cachedOldBase);
5333
cachedNewBase = newE->base = tem;
5336
if (oldE->publicId) {
5337
tem = poolCopyString(newPool, oldE->publicId);
5340
newE->publicId = tem;
5344
const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5348
newE->textPtr = tem;
5349
newE->textLen = oldE->textLen;
5351
if (oldE->notation) {
5352
const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5355
newE->notation = tem;
5357
newE->is_param = oldE->is_param;
5358
newE->is_internal = oldE->is_internal;
5363
#define INIT_POWER 6
5365
static XML_Bool FASTCALL
5366
keyeq(KEY s1, KEY s2)
5368
for (; *s1 == *s2; s1++, s2++)
5374
static unsigned long FASTCALL
5377
unsigned long h = 0;
5379
h = CHAR_HASH(h, *s++);
5384
lookup(HASH_TABLE *table, KEY name, size_t createSize)
5387
if (table->size == 0) {
5391
table->power = INIT_POWER;
5392
/* table->size is a power of 2 */
5393
table->size = (size_t)1 << INIT_POWER;
5394
tsize = table->size * sizeof(NAMED *);
5395
table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5398
memset(table->v, 0, tsize);
5399
i = hash(name) & ((unsigned long)table->size - 1);
5402
unsigned long h = hash(name);
5403
unsigned long mask = (unsigned long)table->size - 1;
5404
unsigned char step = 0;
5406
while (table->v[i]) {
5407
if (keyeq(name, table->v[i]->name))
5410
step = PROBE_STEP(h, mask, table->power);
5411
i < step ? (i += table->size - step) : (i -= step);
5416
/* check for overflow (table is half full) */
5417
if (table->used >> (table->power - 1)) {
5418
unsigned char newPower = table->power + 1;
5419
size_t newSize = (size_t)1 << newPower;
5420
unsigned long newMask = (unsigned long)newSize - 1;
5421
size_t tsize = newSize * sizeof(NAMED *);
5422
NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
5425
memset(newV, 0, tsize);
5426
for (i = 0; i < table->size; i++)
5428
unsigned long newHash = hash(table->v[i]->name);
5429
size_t j = newHash & newMask;
5433
step = PROBE_STEP(newHash, newMask, newPower);
5434
j < step ? (j += newSize - step) : (j -= step);
5436
newV[j] = table->v[i];
5438
table->mem->free_fcn(table->v);
5440
table->power = newPower;
5441
table->size = newSize;
5444
while (table->v[i]) {
5446
step = PROBE_STEP(h, newMask, newPower);
5447
i < step ? (i += newSize - step) : (i -= step);
5451
table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
5454
memset(table->v[i], 0, createSize);
5455
table->v[i]->name = name;
5460
static void FASTCALL
5461
hashTableClear(HASH_TABLE *table)
5464
for (i = 0; i < table->size; i++) {
5465
table->mem->free_fcn(table->v[i]);
5471
static void FASTCALL
5472
hashTableDestroy(HASH_TABLE *table)
5475
for (i = 0; i < table->size; i++)
5476
table->mem->free_fcn(table->v[i]);
5477
table->mem->free_fcn(table->v);
5480
static void FASTCALL
5481
hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
5490
static void FASTCALL
5491
hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
5494
iter->end = iter->p + table->size;
5497
static NAMED * FASTCALL
5498
hashTableIterNext(HASH_TABLE_ITER *iter)
5500
while (iter->p != iter->end) {
5501
NAMED *tem = *(iter->p)++;
5508
static void FASTCALL
5509
poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
5511
pool->blocks = NULL;
5512
pool->freeBlocks = NULL;
5519
static void FASTCALL
5520
poolClear(STRING_POOL *pool)
5522
if (!pool->freeBlocks)
5523
pool->freeBlocks = pool->blocks;
5525
BLOCK *p = pool->blocks;
5527
BLOCK *tem = p->next;
5528
p->next = pool->freeBlocks;
5529
pool->freeBlocks = p;
5533
pool->blocks = NULL;
5539
static void FASTCALL
5540
poolDestroy(STRING_POOL *pool)
5542
BLOCK *p = pool->blocks;
5544
BLOCK *tem = p->next;
5545
pool->mem->free_fcn(p);
5548
p = pool->freeBlocks;
5550
BLOCK *tem = p->next;
5551
pool->mem->free_fcn(p);
5557
poolAppend(STRING_POOL *pool, const ENCODING *enc,
5558
const char *ptr, const char *end)
5560
if (!pool->ptr && !poolGrow(pool))
5563
XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5566
if (!poolGrow(pool))
5572
static const XML_Char * FASTCALL
5573
poolCopyString(STRING_POOL *pool, const XML_Char *s)
5576
if (!poolAppendChar(pool, *s))
5584
static const XML_Char *
5585
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
5587
if (!pool->ptr && !poolGrow(pool))
5589
for (; n > 0; --n, s++) {
5590
if (!poolAppendChar(pool, *s))
5598
static const XML_Char * FASTCALL
5599
poolAppendString(STRING_POOL *pool, const XML_Char *s)
5602
if (!poolAppendChar(pool, *s))
5610
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5611
const char *ptr, const char *end)
5613
if (!poolAppend(pool, enc, ptr, end))
5615
if (pool->ptr == pool->end && !poolGrow(pool))
5621
static XML_Bool FASTCALL
5622
poolGrow(STRING_POOL *pool)
5624
if (pool->freeBlocks) {
5625
if (pool->start == 0) {
5626
pool->blocks = pool->freeBlocks;
5627
pool->freeBlocks = pool->freeBlocks->next;
5628
pool->blocks->next = NULL;
5629
pool->start = pool->blocks->s;
5630
pool->end = pool->start + pool->blocks->size;
5631
pool->ptr = pool->start;
5634
if (pool->end - pool->start < pool->freeBlocks->size) {
5635
BLOCK *tem = pool->freeBlocks->next;
5636
pool->freeBlocks->next = pool->blocks;
5637
pool->blocks = pool->freeBlocks;
5638
pool->freeBlocks = tem;
5639
memcpy(pool->blocks->s, pool->start,
5640
(pool->end - pool->start) * sizeof(XML_Char));
5641
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5642
pool->start = pool->blocks->s;
5643
pool->end = pool->start + pool->blocks->size;
5647
if (pool->blocks && pool->start == pool->blocks->s) {
5648
int blockSize = (pool->end - pool->start)*2;
5649
pool->blocks = (BLOCK *)
5650
pool->mem->realloc_fcn(pool->blocks,
5652
+ blockSize * sizeof(XML_Char)));
5653
if (pool->blocks == NULL)
5655
pool->blocks->size = blockSize;
5656
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5657
pool->start = pool->blocks->s;
5658
pool->end = pool->start + blockSize;
5662
int blockSize = pool->end - pool->start;
5663
if (blockSize < INIT_BLOCK_SIZE)
5664
blockSize = INIT_BLOCK_SIZE;
5667
tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
5668
+ blockSize * sizeof(XML_Char));
5671
tem->size = blockSize;
5672
tem->next = pool->blocks;
5674
if (pool->ptr != pool->start)
5675
memcpy(tem->s, pool->start,
5676
(pool->ptr - pool->start) * sizeof(XML_Char));
5677
pool->ptr = tem->s + (pool->ptr - pool->start);
5678
pool->start = tem->s;
5679
pool->end = tem->s + blockSize;
5685
nextScaffoldPart(XML_Parser parser)
5687
DTD * const dtd = _dtd; /* save one level of indirection */
5688
CONTENT_SCAFFOLD * me;
5691
if (!dtd->scaffIndex) {
5692
dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5693
if (!dtd->scaffIndex)
5695
dtd->scaffIndex[0] = 0;
5698
if (dtd->scaffCount >= dtd->scaffSize) {
5699
CONTENT_SCAFFOLD *temp;
5700
if (dtd->scaffold) {
5701
temp = (CONTENT_SCAFFOLD *)
5702
REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5705
dtd->scaffSize *= 2;
5708
temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5709
* sizeof(CONTENT_SCAFFOLD));
5712
dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
5714
dtd->scaffold = temp;
5716
next = dtd->scaffCount++;
5717
me = &dtd->scaffold[next];
5718
if (dtd->scaffLevel) {
5719
CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
5720
if (parent->lastchild) {
5721
dtd->scaffold[parent->lastchild].nextsib = next;
5723
if (!parent->childcnt)
5724
parent->firstchild = next;
5725
parent->lastchild = next;
5728
me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5733
build_node(XML_Parser parser,
5736
XML_Content **contpos,
5739
DTD * const dtd = _dtd; /* save one level of indirection */
5740
dest->type = dtd->scaffold[src_node].type;
5741
dest->quant = dtd->scaffold[src_node].quant;
5742
if (dest->type == XML_CTYPE_NAME) {
5743
const XML_Char *src;
5744
dest->name = *strpos;
5745
src = dtd->scaffold[src_node].name;
5747
*(*strpos)++ = *src;
5752
dest->numchildren = 0;
5753
dest->children = NULL;
5758
dest->numchildren = dtd->scaffold[src_node].childcnt;
5759
dest->children = *contpos;
5760
*contpos += dest->numchildren;
5761
for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5762
i < dest->numchildren;
5763
i++, cn = dtd->scaffold[cn].nextsib) {
5764
build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5770
static XML_Content *
5771
build_model (XML_Parser parser)
5773
DTD * const dtd = _dtd; /* save one level of indirection */
5777
int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5778
+ (dtd->contentStringLen * sizeof(XML_Char)));
5780
ret = (XML_Content *)MALLOC(allocsize);
5784
str = (XML_Char *) (&ret[dtd->scaffCount]);
5787
build_node(parser, 0, ret, &cpos, &str);
5791
static ELEMENT_TYPE *
5792
getElementType(XML_Parser parser,
5793
const ENCODING *enc,
5797
DTD * const dtd = _dtd; /* save one level of indirection */
5798
const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
5803
ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5806
if (ret->name != name)
5807
poolDiscard(&dtd->pool);
5809
poolFinish(&dtd->pool);
5810
if (!setElementTypePrefix(parser, ret))