source: trunk/src/engine.c @ 188

Last change on this file since 188 was 188, checked in by cameron, 11 years ago

Unify ScanTo? routines

File size: 69.7 KB
Line 
1/*  engine.c - Parabix XML parsing engine.
2    Copyright (c) 2007, 2008, Robert D. Cameron and Dan Lin.
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters, Inc., under the Academic
5    Free License 3.0.
6*/
7
8#include "engine.h"
9#include "byteplex.h"
10#include "xmldecl.h"
11#include "bytelex.h"
12#include "bitlex.h"
13#include "contentmodel.h"
14#include "contentmodel.c"
15#include "xml_error.h"
16
17#include <assert.h>
18#include <stdlib.h>
19#include <errno.h>
20#include <string.h>
21#include <string>
22#include <iostream>
23using namespace std;
24       
25inline char * copy_string (unsigned char * s, int lgth){               
26        char * d = new char[lgth+1];
27        memcpy(d, (char *)s,lgth); 
28        d[lgth] = '\0'; 
29        return d;
30}
31
32inline char * cat_string (char * s1, char * s2, int lgth1, int lgth2){
33        char * s = new char[lgth1 + lgth2 + 1];
34        memcpy(s, s1,lgth1);
35        memcpy(&s[lgth1],s2,lgth2);
36        s[lgth1 + lgth2] = '\0';
37        return s;
38}
39       
40       
41       
42Parser_Interface * Parser_Interface::ParserFactory(char * filename) {
43       
44        int chars_read;
45        unsigned char signature[4];
46        FILE * infile;
47        infile = fopen(filename, "rb");
48        if (!infile) {
49                fprintf(stderr, "Error: cannot open %s for input.\n", filename);
50                exit(-1);
51        }
52        fread(signature,1,4,infile);
53        Entity_Info * e = new Entity_Info;
54        Model_Info * m = new Model_Info;
55        e->AnalyzeSignature(signature);
56        Byteplex * b = Byteplex::ByteplexFactory(e, infile);
57        b->InitializeBuffer(signature,4);
58        b->DoByteplex();
59        b->PreparePseudoASCII_Stream();
60       
61        if (e->code_unit_base == ASCII) {
62                XML_Decl_Parser<ASCII> decl_parser(b);
63                decl_parser.ReadXMLInfo(*e);
64                if (e->code_unit_size == SingleByte) {
65                        if (!(e->has_encoding_decl) || at_UTF_8(e->encoding))
66                                return new ParsingEngine< UTF8_Buffer>(e, m, b, false);         
67                        else return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, false);
68                }
69                else if (e->code_unit_size == DoubleByte) {
70                        return new ParsingEngine<U16_Buffer>(e, m, b, false);
71                }
72                else if (e->code_unit_size == QuadByte) {
73                        return new ParsingEngine<U32_Buffer>(e, m, b, false);
74                }
75        }
76        else /* if (e->code_unit_base == EBCDIC) */ {
77                XML_Decl_Parser<EBCDIC> decl_parser(b);
78                decl_parser.ReadXMLInfo(*e);
79                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, false);
80        }       
81}
82
83Parser_Interface * Parser_Interface::ParserFactory(char * filename, Model_Info * m) {
84       
85        int chars_read;
86        unsigned char signature[4];
87        FILE * infile;
88        infile = fopen(filename, "rb");
89        if (!infile) {
90                fprintf(stderr, "Error: cannot open %s for input.\n", filename);
91                exit(-1);
92        }
93        fread(signature,1,4,infile);
94        Entity_Info * e = new Entity_Info;
95        e->AnalyzeSignature(signature);
96        Byteplex * b = Byteplex::ByteplexFactory(e, infile);
97        b->InitializeBuffer(signature,4);
98        b->DoByteplex();
99        b->PreparePseudoASCII_Stream();
100        if (e->code_unit_base == ASCII) {
101                XML_Decl_Parser<ASCII> decl_parser(b);
102                decl_parser.ReadXMLInfo(*e);
103                if (e->code_unit_size == SingleByte) {
104                        return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, true);
105                }
106                else if (e->code_unit_size == DoubleByte) {
107                        return new ParsingEngine<U16_Buffer>(e, m, b, true);
108                }
109                else if (e->code_unit_size == QuadByte) {
110                        return new ParsingEngine<U32_Buffer>(e, m, b, true);
111                }
112        }
113        else /* if (e->code_unit_base == EBCDIC) */ {
114                XML_Decl_Parser<EBCDIC> decl_parser(b);
115                decl_parser.ReadXMLInfo(*e);
116                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, true);
117        }       
118}
119
120Parser_Interface * Parser_Interface::ParserFactory(char * byte_buffer, int byte_count, Entity_Info * e1, Model_Info * m){
121        Entity_Info * e = new Entity_Info;
122        e->BOM_units = 0;
123        e->code_unit_base=e1->code_unit_base;
124        e->code_unit_size=e1->code_unit_size;
125        e->version=e1->version;
126        e->encoding=e1->encoding;
127        e->content_start = 0;
128        Byteplex * b = Byteplex::ByteplexFactory(e, (unsigned char *) byte_buffer, byte_count);
129        b->DoByteplex();
130        b->PreparePseudoASCII_Stream();
131        if (e->code_unit_base == ASCII) {
132                if (e->code_unit_size == SingleByte) {
133                        return new ParsingEngine< X8_Buffer<ASCII> >(e, m, b, false);
134                }
135                else if (e->code_unit_size == DoubleByte) {
136                        return new ParsingEngine<U16_Buffer>(e, m, b, false);
137                }
138                else if (e->code_unit_size == QuadByte) {
139                        return new ParsingEngine<U32_Buffer>(e, m, b, false);
140                }
141        }
142        else /* if (e->code_unit_base == EBCDIC) */ {
143                return new ParsingEngine< X8_Buffer<EBCDIC> >(e, m, b, false);
144        }       
145}
146
147Parser_Interface::~Parser_Interface() {
148}
149
150
151bool Parser_Interface::has_ByteOrderMark() {
152        return entity_Info->BOM_units > 0;
153}
154
155XML_version Parser_Interface::get_version() {
156        return entity_Info->version;
157}
158
159XML_standalone Parser_Interface::standalone_status() {
160        return entity_Info->standalone;
161}
162
163bool Parser_Interface::has_EncodingDecl() {
164        return entity_Info->has_encoding_decl;
165}
166
167unsigned char * Parser_Interface::get_Encoding() {
168        return entity_Info->encoding;
169}
170
171template <class B>
172inline unsigned char * ParsingEngine<B>::GetCodeUnitPtr(int pos) {
173        int rel_pos = pos - buffer_base_pos;
174        return &((unsigned char *) (byteplex->src_buffer))[rel_pos * (int) B::Size];
175}
176
177template <>
178inline unsigned char * ParsingEngine<UTF8_Buffer>::GetCodeUnitPtr(int pos) {
179        int rel_pos = pos - buffer_base_pos;
180        return &((unsigned char *) (x8data))[rel_pos];
181}
182
183
184
185
186template <class B>
187ParsingEngine<B>::ParsingEngine(Entity_Info * e, Model_Info * m, Byteplex * b, bool is_external) : Parser_Interface () {
188        entity_Info = e;
189        model_info = m;
190        byteplex = b;
191
192//      m->symbol_table = new Symbol_Table();
193//      m->SimpleEntity("lt", "<");
194//      m->SimpleEntity("gt", ">");
195//      m->SimpleEntity("amp", "&");
196//      m->SimpleEntity("quot", "\"");
197//      m->SimpleEntity("apos", "'");   
198        m->symbol_table->version = e->version;
199
200        StrictWellFormedness=false;
201        LastAttOccurrence.assign(m->globalAttributeCount+1, 0);
202       
203       
204        bitplex = new Bitplex;
205        buf = (LexicalStreamSet *) simd_new(sizeof(LexicalStreamSet)/PACKSIZE);
206
207  /* Install sentinels for every lexical item stream*/
208#ifdef TEMPLATED_SIMD_LIB
209        BitBlock sentinel_value = simd<1>::constant<1>();
210#endif
211#ifndef TEMPLATED_SIMD_LIB
212        BitBlock sentinel_value = simd_const_1(1);
213#endif
214
215        for (int j = minLexicalItem; j < LexicalItemCount; j++) {
216                buf->item_stream[j][BUFFER_BLOCKS] = sentinel_value;
217        }
218
219        buffer_base_pos = 0;
220        buffer_rel_pos = e->content_start;
221        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
222        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
223        x8data = byteplex->x8data;
224        lexer = Lexer<B::Base>::LexerFactory(e, buf);
225        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
226        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
227}
228
229template <class B>
230ParsingEngine<B>::~ParsingEngine() {
231  // How do we do this?  model_info->~Model_Info();
232  entity_Info->~Entity_Info();
233  byteplex->~Byteplex();
234  bitplex->~Bitplex();
235  simd_delete((SIMD_type *) buf);
236  lexer->~Lexer_Interface();
237}
238
239template <class B>
240void ParsingEngine<B>::AdvanceBuffers(){
241#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
242        code_clocker->cc_start_interval();
243#endif
244
245        int advance_amt = text_or_markup_start - buffer_base_pos;
246        advance_amt &= -PACKSIZE; // maintain alignment
247        byteplex->AdvanceInputBuffer(advance_amt);
248        buffer_base_pos += advance_amt;
249        buffer_rel_pos -= advance_amt;
250        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
251        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
252#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
253        code_clocker->cc_start_interval();
254#endif
255        byteplex->DoByteplex();
256        byteplex->PreparePseudoASCII_Stream();
257#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
258        code_clocker->cc_end_interval(buffer_limit_pos);
259#endif
260#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
261        code_clocker->cc_start_interval();
262#endif
263        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
264#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
265        code_clocker->cc_end_interval(buffer_limit_pos);
266#endif
267        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
268#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
269        code_clocker->cc_end_interval(buffer_limit_pos);
270#endif
271
272}
273
274template <>
275void ParsingEngine<U16_Buffer>::AdvanceBuffers(){
276#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
277        code_clocker->cc_start_interval();
278#endif
279
280        int advance_amt = text_or_markup_start - buffer_base_pos;
281        advance_amt &= -PACKSIZE; // maintain alignment
282        byteplex->AdvanceInputBuffer(advance_amt);
283        buffer_base_pos += advance_amt;
284        buffer_rel_pos -= advance_amt;
285        buffer_limit_pos = min(BUFFER_SIZE, byteplex->units_in_buffer);
286        int blocks_in_buffer = (buffer_limit_pos + BLOCKSIZE - 1)/BLOCKSIZE;
287#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
288        code_clocker->cc_start_interval();
289#endif
290        byteplex->DoByteplex();
291        if (at_UTF_16(entity_Info->encoding)) ((U16_Buffer *) byteplex)->Validate_UTF16();
292        byteplex->PreparePseudoASCII_Stream();
293#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BYTEPLEX)
294        code_clocker->cc_end_interval(buffer_limit_pos);
295#endif
296#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
297        code_clocker->cc_start_interval();
298#endif
299        bitplex->TransposeToBitStreams(byteplex->x8data, blocks_in_buffer);
300#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == BITPLEX)
301        code_clocker->cc_end_interval(buffer_limit_pos);
302#endif
303        lexer->AnalyzeBuffer(bitplex->x8basis, buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
304#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == ADVANCE_BUFFERS)
305        code_clocker->cc_end_interval(buffer_limit_pos);
306#endif
307
308}
309
310template <class B>
311inline unsigned char * ParsingEngine<B>::cur() const {
312  return &((unsigned char *) x8data)[buffer_rel_pos];
313}
314
315template <class B>
316inline int ParsingEngine<B>::AbsPos() const {
317  return buffer_base_pos + buffer_rel_pos;
318}
319
320template <class B>
321inline int ParsingEngine<B>::LengthFrom(int start_pos) const {
322  return buffer_base_pos + buffer_rel_pos - start_pos;
323}
324
325
326
327template <class B>
328inline int ParsingEngine<B>::BufferRelPos() const {
329  return buffer_rel_pos;
330}
331
332
333template <class B>
334inline bool ParsingEngine<B>::at_EOF() const {
335  return (buffer_rel_pos >= buffer_limit_pos) && 
336         (buffer_limit_pos < BUFFER_SIZE);
337}
338
339//template <class B>
340//inline void ParsingEngine<B>::Advance(int n) {
341//      buffer_rel_pos += n;
342//  if (buffer_rel_pos >= BUFFER_SIZE) {       
343//      FinalizeBuffer_action();
344//      AdvanceBuffers();
345//  }
346//}
347
348#define Advance(n) \
349do {\
350        buffer_rel_pos += n; \
351        if (buffer_rel_pos >= BUFFER_SIZE) {    \
352                FinalizeBuffer_action();\
353        AdvanceBuffers();\
354        }\
355} while(0)
356
357
358template <class B> 
359void ParsingEngine<B>::AdjustBufferEndForIncompleteSequences() {
360}
361
362template <> 
363void ParsingEngine<UTF8_Buffer>::AdjustBufferEndForIncompleteSequences() {
364        if (*(cur()-1) >= 0xC0) buffer_rel_pos--;
365        else if (*(cur()-2) >= 0xE0) buffer_rel_pos -= 2;
366        else if (*(cur()-3) >= 0xF0) buffer_rel_pos -= 3;
367}
368
369template <> 
370void ParsingEngine<U16_Buffer>::AdjustBufferEndForIncompleteSequences() {
371        unsigned short last_u16_unit = *(GetCodeUnitPtr(AbsPos()-1));
372        if ((last_u16_unit >= 0xD800) & (last_u16_unit <= 0xDC00)) buffer_rel_pos--;
373}
374
375
376#ifndef OPTIMIZE_SHORT_SCAN
377
378/*
379#define ScanTo(item) \
380do {\
381  buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);\
382  while (buffer_rel_pos >= BUFFER_SIZE) {\
383        AdjustBufferEndForIncompleteSequences();\
384        FinalizeBuffer_action();\
385        AdvanceBuffers();\
386        buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);\
387  }\
388} while(0)
389*/
390
391
392#endif
393template <class B>
394inline void ParsingEngine<B>::ScanTo(int item) {
395        buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
396        while (buffer_rel_pos >= BUFFER_SIZE) {
397                AdjustBufferEndForIncompleteSequences();
398                FinalizeBuffer_action();
399                AdvanceBuffers();
400                buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
401        }
402}
403
404template <class B>
405inline void ParsingEngine<B>::ScanTextTo(int item) {
406        text_or_markup_start = AbsPos();
407        buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
408        while (buffer_rel_pos >= BUFFER_SIZE) {
409                AdjustBufferEndForIncompleteSequences();
410                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start), true);
411                text_or_markup_start = AbsPos();
412                FinalizeBuffer_action();
413                AdvanceBuffers();
414                buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
415        }
416}
417
418template <class B>
419void ParsingEngine<B>::WF_Error (XML_Constraint errCode) {
420        printf("Error at position %i in input.\n", AbsPos());
421        ShowConstraintError(errCode);
422        exit(-1);
423//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
424}
425       
426
427template <class B>
428void ParsingEngine<B>::Validity_Error (XML_Constraint errCode) {
429        printf("Error at position %i in input.\n", AbsPos());
430        ShowConstraintError(errCode);
431        exit(-1);
432//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
433}
434       
435template <class B>
436void ParsingEngine<B>::Syntax_Error (XML_NonTerminal errNT) {
437        printf("Error at position %i in input.\n", AbsPos());
438        ShowSyntaxError(errNT);
439        exit(-1);
440//      Error_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
441}
442       
443
444/* Parse a comment beginning "<!--" */
445template <class B>
446void ParsingEngine<B>::Parse_Comment() {
447
448        Advance(4); /* Skip "<!--". */
449        ScanTo(Hyphen);
450        while (!at_DoubleHyphen<B::Base>(cur())) {
451                if(at_EOF())
452                        Syntax_Error(NT_CDSect);
453                Advance(2); /* Skip hyphen-nonhyphen pair */
454                ScanTo(Hyphen); 
455        }
456        if (at_Comment_End<B::Base>(cur())) {
457                Advance(3); /* Skip "-->". */
458                Comment_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
459        }
460        else {
461                Advance(2);  /* "--" */
462                Syntax_Error(NT_Comment);
463        }
464}
465
466/* Parse an end tag beginning "</" */
467template <class B>
468inline void ParsingEngine<B>::Parse_EndTag() {
469        Advance(2); /* Skip "</". */
470        int nameID = Parse_Name();
471        if (AtChar<B::Base,'>'>(cur())) {
472                Advance(1);
473                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
474        }
475        else {
476                ScanTo(NonWS);
477                if (AtChar<B::Base,'>'>(cur())) {
478                        Advance(1);
479                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
480                }
481                else Syntax_Error(NT_ETag);
482        }
483}
484
485/* Parse a CDATA section beginning "<![CDATA". */
486template <class B>
487void ParsingEngine<B>::Parse_CDATA() {
488                Advance(8); /* Skip "<![CDATA". */
489        if (!AtChar<B::Base,'['>(cur())) {
490                Syntax_Error(NT_CDStart);
491        }
492        else { 
493                Advance(1);
494                CDATA_start_action(GetCodeUnitPtr(text_or_markup_start));
495                text_or_markup_start = AbsPos();
496                ScanTextTo(CD_End_check);
497                while (!at_CDATA_End<B::Base>(cur())) {
498                        if (at_EOF())
499                                Syntax_Error(NT_CDSect);
500                        Advance(1);
501                        ScanTextTo(CD_End_check);
502                }
503                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start), true);
504                Advance(3); /* Skip "]]>". */
505                CDATA_end_action(GetCodeUnitPtr(AbsPos()));
506        }
507}
508
509template <class B>
510void ParsingEngine<B>::Parse_EntityRef() {
511    Advance(1);  // skip "&"
512        int nameID = Parse_Name();  /* Name delimiter */
513    if (!AtChar<B::Base,';'>(cur())) {
514                Syntax_Error(NT_Reference);
515    }
516        else {
517                Advance(1);
518                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
519               
520                //      The following code will replace Reference_Action.
521                GEntity_info * this_info;
522                Parser_Interface * entity_parser;
523                int entityID = model_info->GlobalGEntityTable[nameID]; 
524                if (entityID == 0)
525                        WF_Error(wfErr_wf_entdeclared);
526                else{
527                        this_info = model_info->GEntityData[entityID-1];
528                        if (this_info->is_external){
529                               
530                        if (entity_Info->standalone != Standalone_no)
531                                WF_Error(wfErr_NoExternalRefs);
532                        else {
533                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
534                                        entity_parser->Parse_WF_Content();
535                                        if(!entity_parser->at_EOF())
536                                                Syntax_Error(NT_content);
537                                        entity_parser->~Parser_Interface();
538                        }
539                        }
540                        else {
541                                if (this_info->is_simple == true);
542//                                      printf("Entity is %s\n",this_info->ReplacementText);
543                                else{
544//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
545                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
546                                        entity_parser->Parse_WF_Content();
547                                        if(!entity_parser->at_EOF())
548                                                Syntax_Error(NT_content);
549                                        entity_parser->~Parser_Interface();
550                                }
551                        }
552                }
553               
554        }
555}
556
557template <class B>
558void ParsingEngine<B>::Parse_EntityRef_inMixed(symbol_set_t elems) {
559    Advance(1);  // skip "&"
560        int nameID = Parse_Name();  /* Name delimiter */
561    if (!AtChar<B::Base,';'>(cur())) {
562                Syntax_Error(NT_Reference);
563    }
564        else {
565                Advance(1);
566                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
567               
568                //      The following code will replace Reference_Action.
569                GEntity_info * this_info;
570                Parser_Interface * entity_parser;
571                int entityID = model_info->GlobalGEntityTable[nameID]; 
572                if (entityID == 0)
573                        WF_Error(wfErr_wf_entdeclared);
574                else{
575                        this_info = model_info->GEntityData[entityID-1];
576                        if (this_info->is_external){
577                               
578                        if (entity_Info->standalone != Standalone_no)
579                                WF_Error(wfErr_NoExternalRefs);
580                        else {
581                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
582                                        entity_parser->Parse_MixedContent(elems);
583                                        if(!entity_parser->at_EOF())
584                                                Syntax_Error(NT_content);
585                                        entity_parser->~Parser_Interface();
586                        }
587                        }
588                        else {
589                                if (this_info->is_simple == true);
590//                                      printf("Entity is %s\n",this_info->ReplacementText);
591                                else{
592//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
593                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
594                                        entity_parser->Parse_MixedContent(elems);
595                                        if(!entity_parser->at_EOF())
596                                                Syntax_Error(NT_content);
597                                        entity_parser->~Parser_Interface();
598                                }
599                        }
600                }
601               
602        }
603}
604
605template <class B>
606void ParsingEngine<B>::Parse_EntityRef_inAnyContent() {
607    Advance(1);  // skip "&"
608        int nameID = Parse_Name();  /* Name delimiter */
609    if (!AtChar<B::Base,';'>(cur())) {
610                Syntax_Error(NT_Reference);
611    }
612        else {
613                Advance(1);
614                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
615               
616                //      The following code will replace Reference_Action.
617                GEntity_info * this_info;
618                Parser_Interface * entity_parser;
619                int entityID = model_info->GlobalGEntityTable[nameID]; 
620                if (entityID == 0)
621                        WF_Error(wfErr_wf_entdeclared);
622                else{
623                        this_info = model_info->GEntityData[entityID-1];
624                        if (this_info->is_external){
625                               
626                        if (entity_Info->standalone != Standalone_no)
627                                WF_Error(wfErr_NoExternalRefs);
628                        else {
629                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
630                                        entity_parser->Parse_AnyContent();
631                                        if(!entity_parser->at_EOF())
632                                                Syntax_Error(NT_content);
633                                        entity_parser->~Parser_Interface();
634                        }
635                        }
636                        else {
637                                if (this_info->is_simple == true);
638//                                      printf("Entity is %s\n",this_info->ReplacementText);
639                                else{
640//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
641                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
642                                        entity_parser->Parse_AnyContent();
643                                        if(!entity_parser->at_EOF())
644                                                Syntax_Error(NT_content);
645                                        entity_parser->~Parser_Interface();
646                                }
647                        }
648                }
649               
650        }
651}
652
653template <class B>
654void ParsingEngine<B>::Parse_ValidEntityRef(CM_RegExp * cre, int & cur_state) {
655    Advance(1);  // skip "&"
656        int nameID = Parse_Name();  /* Name delimiter */
657    if (!AtChar<B::Base,';'>(cur())) {
658                Syntax_Error(NT_Reference);
659    }
660        else {
661                Advance(1);
662                Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
663               
664                //      The following code will replace Reference_Action.
665                GEntity_info * this_info;
666                Parser_Interface * entity_parser;
667                int entityID = model_info->GlobalGEntityTable[nameID]; 
668                if (entityID == 0)
669                        WF_Error(wfErr_wf_entdeclared);
670                else{
671                        this_info = model_info->GEntityData[entityID-1];
672                        if (this_info->is_external){
673                               
674                        if (entity_Info->standalone != Standalone_no)
675                                WF_Error(wfErr_NoExternalRefs);
676                        else {
677                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
678                                        entity_parser->Parse_ValidContent(cre, cur_state);
679                                        if(!entity_parser->at_EOF())
680                                                Syntax_Error(NT_content);
681                                        entity_parser->~Parser_Interface();
682                        }
683                        }
684                        else {
685                                if (this_info->is_simple == true);
686//                                      printf("Entity is %s\n",this_info->ReplacementText);
687                                else{
688//                                      printf("Not a simple text: %s\n",this_info->ReplacementText);
689                                        entity_parser = ParserFactory(this_info->ReplacementText, strlen(this_info->ReplacementText),entity_Info, model_info);
690                                        entity_parser->Parse_ValidContent(cre, cur_state);
691                                        if(!entity_parser->at_EOF())
692                                                Syntax_Error(NT_content);
693                                        entity_parser->~Parser_Interface();
694                                }
695                        }
696                }
697               
698        }
699}
700       
701template <class B>
702void ParsingEngine<B>::Parse_CharRef() {
703        Advance(2);  // skip "&#"
704        int ch_val = 0;
705        if (AtChar<B::Base,'x'>(cur())) {
706                Advance(1);
707                while(at_HexDigit<B::Base>(cur())){
708                        ch_val = HexVal<B::Base>(cur()[0]) + (ch_val<<4);
709                        if (ch_val> 0x10FFFF )
710                                WF_Error(wfErr_wf_Legalchar);
711                        Advance(1);
712                }
713        }
714        else {
715                while(at_Digit<B::Base>(cur())){
716                        ch_val = DigitVal<B::Base>(cur()[0]) + ch_val*10;
717                        if (ch_val> 0x10FFFF )
718                                WF_Error(wfErr_wf_Legalchar);
719                        Advance(1);
720                }
721        }
722        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF))
723                                WF_Error(wfErr_wf_Legalchar);   
724                else  if (entity_Info->version != XML_1_1)
725                        if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA)))
726                                WF_Error(wfErr_wf_Legalchar); 
727                               
728        if (!AtChar<B::Base,';'>(cur())) {
729                        Syntax_Error(NT_CharRef);
730        }
731                else {
732                        Advance(1);
733                        Reference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
734                }
735}
736
737template <class B>
738void ParsingEngine<B>::Parse_PI (){
739        int nameID;
740        Advance(2); /* Skip "<?". */
741        int target_start = AbsPos();
742        if (at_XxMmLll<B::Base>(cur())) {
743                nameID = Parse_Name();
744                if (AbsPos() - target_start == 3) Syntax_Error(NT_PI);
745        }
746        else nameID = Parse_Name();
747        PI_Target_action(GetCodeUnitPtr(target_start), LengthFrom(target_start));
748        if (!at_PI_End<B::Base>(cur())) requireWS();
749        ScanTo(QMark);
750        while (!at_PI_End<B::Base>(cur())) {
751                if(at_EOF())
752                        Syntax_Error(NT_PI);
753                Advance(1);
754                ScanTo(QMark);
755        }
756        Advance(2); /* Skip "?>". */
757        PI_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
758}
759 
760/* Parse a start or empty element tag. */
761template <class B>
762inline void ParsingEngine<B>::Parse_StartTag (){
763        int att_name_start;
764        int att_val_start;
765        int att_name_end, att_val_end;
766        unsigned char quoteCh;
767        Advance(1);
768        int nameID = Parse_Name();  /* Name delimiter: WS, "/" or ">" */
769        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
770        /* The following test optimizes the most common case of a
771        start tag with no attributes.  */
772        if (AtChar<B::Base,'>'>(cur())) {
773                Advance(1);
774                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
775        }
776        else {
777                ScanTo(NonWS);
778                if (AtChar<B::Base,'>'>(cur())) {
779                        Advance(1);
780                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
781                }
782                else if (at_EmptyElementDelim<B::Base>(cur())) {
783                        Advance(2);
784                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
785                }
786                else do {
787                        /* Must be an attribute-value pair or error. */
788                        att_name_start = AbsPos();
789                        int att_nameID = Parse_Name();
790                        att_name_end = AbsPos();
791               
792                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
793                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
794                        else {
795                                if (LastAttOccurrence[attID] > text_or_markup_start) {
796                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
797                                        break;
798                                }                       
799                        }
800                        LastAttOccurrence[attID] = att_name_start;
801                        /* The following optimized tests handle the frequently occurring
802                        case that there are no blanks on either side of the equals sign.
803                        In many cases, the very first test handles 100% of actual
804                        attribute-value pairs encountered. */
805                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
806                        else {
807                                ScanTo(NonWS);
808                                if (!AtChar<B::Base,'='>(cur())) {
809                                        Syntax_Error(NT_STag); 
810                                        break;
811                                }
812                                Advance(1);
813                                ScanTo(NonWS);
814                                if (!AtQuote<B::Base>(cur())) {
815                                        Syntax_Error(NT_STag); 
816                                        break;
817                                }
818                        }
819                        att_val_start = AbsPos()+1;
820                        Parse_AttValue();
821                        att_val_end = AbsPos()-1;
822                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
823                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
824                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
825                        }
826                        else {
827                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
828                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
829                        }
830                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
831                        if (AtChar<B::Base,'>'>(cur())) {
832                                Advance(1);
833                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
834                                break;
835                        }
836                        else if (at_EmptyElementDelim<B::Base>(cur())) {
837                                Advance(2);
838                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
839                                break;
840                        }
841                        ScanTo(NonWS);
842                        if (AtChar<B::Base,'>'>(cur())) {
843                                Advance(1);
844                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
845                                break;
846                        }
847                        else if (at_EmptyElementDelim<B::Base>(cur())) {
848                                Advance(2);
849                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
850                                break;
851                        }
852                        else if (AbsPos() == att_val_end + 1) { 
853                                /* No WS following att value */
854                                Syntax_Error(NT_STag);
855                                break;
856                        }
857                } while (1);
858        }
859}
860
861template <class B>
862inline void ParsingEngine<B>::text_if_nonnull_action(bool more){
863        if (AbsPos() > text_or_markup_start) {
864                Text_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start), more);
865                text_or_markup_start = AbsPos();
866        }
867}
868
869template <class B>
870void ParsingEngine<B>::Parse_WF_EndTag(int nameID) {
871        Advance(2);
872        int end_nameID = Parse_Name();
873        if(end_nameID != nameID)
874                WF_Error(wfErr_GIMatch);
875        if (AtChar<B::Base,'>'>(cur())) {
876                Advance(1);
877                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
878        }
879    else {
880                ScanTo(NonWS);
881                if (AtChar<B::Base,'>'>(cur())) {
882                        Advance(1);
883                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
884                }
885                else Syntax_Error(NT_ETag);
886    }
887}
888
889template <>
890void ParsingEngine<UTF8_Buffer>::Parse_WF_EndTag(int nameID) {
891        Advance(2); /* Skip "</". */
892       
893        int name_start = AbsPos();
894//      ScanTo(NameFollow);
895//      int lgth = AbsPos()-name_start;
896
897#if (not defined(OMISSION)) or ((OMISSION != END_TAG_MATCHING)  and (OMISSION != NAME_LOOKUP))
898        char * start_elem_name = model_info->symbol_table->Get_UTF8_name(nameID);
899        int lgth = model_info->symbol_table->Get_UTF8_lgth(nameID);
900        char * end_elem_name = &((char *) x8data)[buffer_rel_pos];
901       
902#ifdef TEMPLATED_SIMD_LIB       
903        BytePack byte_compare =  simd<8>::eq(sisd_load_unaligned((BytePack *) end_elem_name),
904                                                           sisd_load_unaligned((BytePack *) start_elem_name));
905#endif
906#ifndef TEMPLATED_SIMD_LIB     
907        BytePack byte_compare =  simd_eq_8(sisd_load_unaligned((BytePack *) end_elem_name),
908                                                           sisd_load_unaligned((BytePack *) start_elem_name));
909#endif
910        if (lgth < 16) {
911                int expected_bits = ~(-1 << lgth);
912            if ((_mm_movemask_epi8(byte_compare) & expected_bits) != expected_bits) {
913                        WF_Error(wfErr_GIMatch);
914            }
915        }
916        else {
917            /* Must compare with bytes beyond the first 16.  Set up to
918               compare 16 bytes at a time, with the first additional compare
919               overlapping with the first byte_compare. */
920            int pos = (lgth - 1) % PACKSIZE + 1;
921#ifdef TEMPLATED_SIMD_LIB
922            byte_compare =  simd_or(byte_compare, simd<8>::eq(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
923                                                                                        sisd_load_unaligned((BytePack *) &start_elem_name[pos])));
924#endif
925#ifndef TEMPLATED_SIMD_LIB
926            byte_compare =  simd_or(byte_compare, simd_eq_8(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
927                                                                                        sisd_load_unaligned((BytePack *) &start_elem_name[pos])));
928#endif
929            pos += 16;
930            while (pos < lgth) {
931                if (_mm_movemask_epi8(byte_compare) != 0xFFFF) {
932                        WF_Error(wfErr_GIMatch);
933                }
934#ifdef TEMPLATED_SIMD_LIB
935                byte_compare =  simd<8>::eq(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
936                                                  sisd_load_unaligned((BytePack *) &start_elem_name[pos]));
937#endif
938#ifndef TEMPLATED_SIMD_LIB
939                byte_compare =  simd_eq_8(sisd_load_unaligned((BytePack *) &end_elem_name[pos]),
940                                                  sisd_load_unaligned((BytePack *) &start_elem_name[pos]));
941#endif
942                pos += 16;
943            }
944            if (_mm_movemask_epi8(byte_compare) != 0xFFFF) {
945                        WF_Error(wfErr_GIMatch);
946            }
947        }
948        Advance(lgth);
949
950#endif
951#if defined(OMISSION) and ((OMISSION == END_TAG_MATCHING) or (OMISSION == NAME_LOOKUP))
952        ScanTo(NameFollow);
953#endif
954//      for(int i=0; i<lgth; i++) {
955//              if (start_elem_name[i] != end_elem_name[i])
956//                      WF_Error(wfErr_GIMatch);
957//      }
958//      if (start_elem_name[lgth] != '\0') WF_Error(wfErr_GIMatch);
959
960        if (AtChar<ASCII,'>'>(cur())) {
961                Advance(1);
962                EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
963        }
964    else {
965                ScanTo(NonWS);
966                if (AtChar<ASCII,'>'>(cur())) {
967                        Advance(1);
968                        EndTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
969                }
970                else Syntax_Error(NT_ETag);
971    }
972}
973/* Parse a valid start or empty element tag. */
974template <class B>
975int ParsingEngine<B>::Parse_WF_StartTag (bool& is_emptyStartTag){
976        int att_name_start;
977        int att_val_start;
978        int att_name_end, att_val_end;
979        unsigned char quoteCh;
980        Advance(1);
981       
982        #if (not defined(OMISSION)) or (OMISSION != NAME_LOOKUP)
983        int nameID = Parse_Name(); 
984        #endif
985        #if (defined(OMISSION)) and (OMISSION == NAME_LOOKUP)
986        ScanTo(NameFollow);
987        int nameID = 0;
988        #endif
989        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
990        /* The following test optimizes the most common case of a
991        start tag with no attributes.  */
992        if (AtChar<B::Base,'>'>(cur())) {
993                Advance(1);
994                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
995        }
996        else {
997                ScanTo(NonWS);
998                if (AtChar<B::Base,'>'>(cur())) {
999                        Advance(1);
1000                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1001                }
1002                else if (at_EmptyElementDelim<B::Base>(cur())) {
1003                        Advance(2);
1004                        is_emptyStartTag = true;
1005                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1006                }
1007                else do {
1008                        /* Must be an attribute-value pair or error. */
1009                        att_name_start = AbsPos();
1010                        #if (not defined(OMISSION)) or (OMISSION != NAME_LOOKUP)
1011                        int att_nameID = Parse_Name(); 
1012                        #endif
1013                        #if (defined(OMISSION)) and (OMISSION == NAME_LOOKUP)
1014                        ScanTo(NameFollow);
1015                        int att_nameID = 0;
1016                        #endif
1017            att_name_end = AbsPos();
1018                #if (not defined(OMISSION)) or ((OMISSION != ATTRIBUTE_UNIQUENESS) and (OMISSION != NAME_LOOKUP))
1019                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
1020                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
1021                        else {
1022                                if (LastAttOccurrence[attID] > text_or_markup_start) {
1023                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
1024                                        break;
1025                                }                       
1026                        }
1027                        LastAttOccurrence[attID] = att_name_start;
1028                 #endif
1029                        /* The following optimized tests handle the frequently occurring
1030                        case that there are no blanks on either side of the equals sign.
1031                        In many cases, the very first test handles 100% of actual
1032                        attribute-value pairs encountered. */
1033                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
1034                        else {
1035                                ScanTo(NonWS);
1036                                if (!AtChar<B::Base,'='>(cur())) {
1037                                        Syntax_Error(NT_STag); 
1038                                        break;
1039                                }
1040                                Advance(1);
1041                                ScanTo(NonWS);
1042                                if (!AtQuote<B::Base>(cur())) {
1043                                        Syntax_Error(NT_STag); 
1044                                        break;
1045                                }
1046                        }
1047                        att_val_start = AbsPos()+1;
1048                        Parse_AttValue();
1049                        att_val_end = AbsPos()-1;
1050                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
1051                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
1052                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
1053                        }
1054                        else {
1055                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
1056                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
1057                        }
1058                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
1059                        if (AtChar<B::Base,'>'>(cur())) {
1060                                Advance(1);
1061                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1062                                break;
1063                        }
1064                        else if (at_EmptyElementDelim<B::Base>(cur())) {
1065                                Advance(2);
1066                                is_emptyStartTag = true;       
1067                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1068                                break;
1069                        }
1070                        ScanTo(NonWS);
1071                        if (AtChar<B::Base,'>'>(cur())) {
1072                                Advance(1);
1073                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1074                                break;
1075                        }
1076                        else if (at_EmptyElementDelim<B::Base>(cur())) {
1077                                Advance(2);
1078                                is_emptyStartTag = true;
1079                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1080                                break;
1081                        }
1082                        else if (AbsPos() == att_val_end + 1) { 
1083                                /* No WS following att value */
1084                                Syntax_Error(NT_STag);
1085                                break;
1086                        }
1087                } while (1);
1088        }
1089        return nameID;
1090}
1091
1092
1093
1094template <class B>
1095void ParsingEngine<B>::Parse_WF_Element() {
1096        bool is_emptyStartTag = false;
1097        int nameID = Parse_WF_StartTag(is_emptyStartTag);
1098#ifdef DEBUG
1099        printf("Parse_Element: nameID = %d, is_emptyStartTag=%i\n",nameID, is_emptyStartTag);
1100#endif
1101        if (!is_emptyStartTag) {
1102                Parse_WF_Content();
1103                Parse_WF_EndTag(nameID);
1104        }
1105}
1106
1107
1108template <class B>
1109void ParsingEngine<B>::Parse_WF_Content() {
1110        do {
1111                text_or_markup_start = AbsPos();
1112                ScanTextTo(MarkupStart); /* '<', '&', or ']' for ']]>' test */
1113                if (at_ElementTag_Start<B::Base>(cur())) {
1114                        text_if_nonnull_action(false);
1115                        Parse_WF_Element();
1116                }
1117                else if (at_EndTag_Start<B::Base>(cur())) {
1118                        text_if_nonnull_action(false);
1119                        return;
1120                }
1121                else if (at_Comment_Start<B::Base>(cur())) {
1122                        text_if_nonnull_action(false);
1123                        Parse_Comment();
1124                }
1125                else if (at_CharRef_Start<B::Base>(cur())) {
1126                        text_if_nonnull_action(true);
1127                        Parse_CharRef();
1128                }
1129                else if (AtChar<B::Base,'&'>(cur())) {
1130                        text_if_nonnull_action(true);
1131                        Parse_EntityRef();
1132                }
1133                else if (at_CDATA_Start<B::Base>(cur())) {
1134                        text_if_nonnull_action(true);
1135                        Parse_CDATA();
1136                }
1137                else if (at_PI_Start<B::Base>(cur())) {
1138                        text_if_nonnull_action(false);
1139                        Parse_PI();
1140                }
1141                else if (at_CDATA_End<B::Base>(cur())) {
1142                        text_if_nonnull_action(true);
1143                        Advance(3);
1144                        Syntax_Error(NT_CharData);
1145                }
1146                else if (at_EOF()) {
1147                        text_if_nonnull_action(false);
1148                        return;
1149                }
1150                else if (AtChar<B::Base,'<'>(cur())) {
1151                        Syntax_Error(NT_markupdecl);
1152                }
1153                else {
1154                        Advance(1);
1155                        continue;
1156                }
1157        } while (1);
1158}
1159
1160
1161
1162template <class B>
1163void ParsingEngine<B>::ParseContent() {
1164        DocumentStart_action(); 
1165        bool is_emptyStartTag = false;
1166        do {
1167                text_or_markup_start = AbsPos();
1168                ScanTextTo(MarkupStart); /* '<', '&', or ']' for ']]>' test */
1169/*              if (AtChar<B::Base,'<'>(cur())) {
1170                        text_if_nonnull_action();
1171                        Parse_Markup<B>();
1172                }*/
1173                if (at_ElementTag_Start<B::Base>(cur())) {
1174                        text_if_nonnull_action(false);
1175                        Parse_StartTag();
1176                }
1177                else if (at_EndTag_Start<B::Base>(cur())) {
1178                        text_if_nonnull_action(false);
1179                        Parse_EndTag();
1180                }
1181                else if (at_Comment_Start<B::Base>(cur())) {
1182                        text_if_nonnull_action(false);
1183                        Parse_Comment();
1184                }
1185                else if (at_CharRef_Start<B::Base>(cur())) {
1186                        text_if_nonnull_action(true);
1187                        Parse_CharRef();
1188                }
1189                else if (AtChar<B::Base,'&'>(cur())) {
1190                        text_if_nonnull_action(true);
1191                        Parse_EntityRef();
1192                }
1193                else if (at_CDATA_Start<B::Base>(cur())) {
1194                        text_if_nonnull_action(true);
1195                        Parse_CDATA();
1196                }
1197                else if (at_PI_Start<B::Base>(cur())) {
1198                        text_if_nonnull_action(false);
1199                        Parse_PI();
1200                }
1201                else if (at_CDATA_End<B::Base>(cur())) {
1202                        text_if_nonnull_action(true);
1203                        Advance(3);
1204                        Syntax_Error(NT_CharData);
1205                }
1206                else if (at_EOF()) {
1207                        text_if_nonnull_action(false);
1208                        break;
1209                }
1210                else if (AtChar<B::Base,'<'>(cur())) {
1211                        Syntax_Error(NT_markupdecl);
1212                }
1213                else {
1214                        Advance(1);
1215                        continue;
1216                }
1217        } while (1);
1218        DocumentEnd_action();   
1219}
1220
1221
1222template <class B>
1223void ParsingEngine<B>::Parse_DocType (){
1224
1225        int old_abspos, start_pos;
1226        ScanTo(NonWS);
1227        start_pos = AbsPos();
1228       
1229        if (at_DOCTYPE_start<B::Base>(cur()))
1230        Advance(9);
1231        else{
1232//              printf("No Document definition!\n");
1233                return;
1234        }
1235        requireWS();
1236        int nameID = Parse_Name();
1237
1238        old_abspos = AbsPos(); 
1239    ScanTo(NonWS);
1240    if(at_SYSTEM<B::Base>(cur())||at_PUBLIC<B::Base>(cur())){
1241        model_info->has_external_DTD = true;
1242        if(old_abspos == AbsPos())
1243                Syntax_Error(NT_doctypedecl);
1244        Parse_ExternalID(model_info->external_DTD_systemLiteral, model_info->external_DTD_pubidLiteral);
1245        Parser_Interface * entity_parser;
1246        entity_parser = ParserFactory(model_info->external_DTD_systemLiteral, model_info);
1247                entity_parser->Parse_ExtSubsetDecl();
1248                entity_parser->~Parser_Interface();
1249    }
1250    else model_info->has_external_DTD = false;
1251    ScanTo(NonWS);     
1252
1253        if (AtChar<B::Base,'['>(cur())){
1254                Advance(1);
1255                Parse_IntSubset();
1256                if (AtChar<B::Base,']'>(cur()))
1257                        Advance(1);
1258                else
1259                Syntax_Error(NT_doctypedecl);
1260                ScanTo(NonWS);
1261        }
1262       
1263        if (AtChar<B::Base,'>'>(cur())){
1264                Advance(1); 
1265
1266                CRE_Seq * rslt = new CRE_Seq();
1267                rslt->subCMs.push_back(new CRE_Name(nameID));
1268                CM_RegExp * cre = new CM_RegExp();
1269                cre->content_re = rslt;         
1270               
1271                int id_count = cre->content_re->Set_IDs(0);
1272                cre->content_re->Set_First_Map();               
1273                symbol_set_t * transition_map = new symbol_set_t[id_count+1];
1274                cre->content_re->follow_map[0] = id_count+1;
1275               
1276                cre->content_re->Set_Follow_Map(transition_map);
1277                transition_map[0] = cre->content_re->first_map;
1278                if (cre->content_re->matches_empty)
1279                        transition_map[0][0]=id_count+1;
1280                       
1281                cre -> transition_map = transition_map;
1282               
1283                model_info->rootModel = cre;
1284               
1285                /* Check for notations that were used, but not defined by the end of the DTD. */
1286                #if (VALIDATION_MODE == ON)
1287                hash_map<int, int >::iterator j;
1288                for (j=model_info->GlobalNotationTable.begin(); j!=model_info->GlobalNotationTable.end(); j++) {
1289                        if (j->second == -1)
1290                                Validity_Error(vErr_notatn);
1291                }
1292                #endif
1293        }
1294        else
1295                Syntax_Error(NT_doctypedecl);   
1296}
1297
1298template <class B>
1299void ParsingEngine<B>::Parse_ExternalID (char *& systemLiteral, char *& pubidLiteral){
1300        int quot_start, lgth;
1301        if(at_SYSTEM<B::Base>(cur())){
1302                Advance(6);
1303                pubidLiteral = NULL;
1304                requireWS();
1305                if (!AtQuote<B::Base>(cur())) Syntax_Error(NT_ExternalID);
1306                quot_start = AbsPos()+1;
1307                Parse_SystemLiteral (); /*  SystemLiteral */
1308                lgth = AbsPos() - quot_start - 1;                       
1309                systemLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1310        }
1311        else if (at_PUBLIC<B::Base>(cur())){
1312                Advance(6);
1313                requireWS();
1314                if (!AtQuote<B::Base>(cur())) Syntax_Error(NT_ExternalID);
1315                quot_start = AbsPos()+1;
1316                Parse_PubidLiteral ();/*  PubidLiteral */
1317                lgth = AbsPos() - quot_start - 1;                       
1318                pubidLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1319                systemLiteral = NULL;
1320                if (AtChar<B::Base, '>'>(cur())) return;
1321                requireWS();
1322                if (AtQuote<B::Base>(cur())) {
1323                        quot_start = AbsPos()+1;       
1324                        Parse_SystemLiteral ();/*  SystemLiteral */
1325                        lgth = AbsPos() - quot_start - 1;                       
1326                        systemLiteral = copy_string(GetCodeUnitPtr(quot_start),lgth);
1327                }
1328        }
1329        else
1330                Syntax_Error(NT_ExternalID); 
1331}
1332
1333template <class B>
1334void ParsingEngine<B>::Parse_SystemLiteral (){
1335        unsigned char quoteCh;
1336        if(AtQuote<B::Base>(cur())){
1337                quoteCh = cur()[0];
1338                Advance(1);
1339        }       
1340        ScanTo(Quote);                 
1341        while (cur()[0] != quoteCh){
1342                if(at_EOF())
1343                        Syntax_Error(NT_SystemLiteral);
1344                Advance(1);
1345                ScanTo(Quote);
1346        }
1347        Advance(1);
1348}
1349
1350template <class B>
1351void ParsingEngine<B>::Parse_PubidLiteral (){
1352        unsigned char quoteCh;
1353        quoteCh = cur()[0];
1354        Advance(1);
1355        while (at_PubidChar<B::Base>(cur()) && (cur()[0] != quoteCh)) {
1356                Advance(1);
1357        }
1358        if (cur()[0] != quoteCh){
1359                Syntax_Error(NT_PubidLiteral);
1360        }
1361        Advance(1);
1362}
1363
1364template <class B>
1365void ParsingEngine<B>::Parse_IntSubset (){
1366       
1367        while(1){
1368                ScanTo(NonWS); 
1369                text_or_markup_start = AbsPos();
1370                if (AtChar<B::Base,'%'>(cur()))
1371                        Parse_PEReference();   
1372                else if (at_PI_Start<B::Base>(cur())) {
1373                        Parse_PI();
1374                }
1375                else if (at_Comment_Start<B::Base>(cur())) {
1376                        Parse_Comment();
1377                }
1378                else if (AtChar<B::Base,'<'>(cur())){
1379                        Advance(1);
1380                        if(AtChar<B::Base,'!'>(cur())){
1381                                Advance(1);
1382                                if (at_ELEMENT<B::Base>(cur()))
1383                                        Parse_Elementdecl();
1384                                else if (at_ATTLIST<B::Base>(cur()))
1385                                        Parse_AttlistDecl();
1386                                else if (at_ENTITY<B::Base>(cur()))
1387                                        Parse_Entitydecl();
1388                                else if (at_NOTATION<B::Base>(cur()))
1389                                        Parse_Notationdecl();
1390                                else {
1391                                        Syntax_Error(NT_markupdecl);           
1392                                }                                                               
1393                        }
1394                        else
1395                                Syntax_Error(NT_markupdecl); 
1396                }
1397                else if (AtChar<B::Base,']'>(cur())){
1398                        break;
1399                }
1400                else
1401                        Syntax_Error(NT_intSubset); 
1402        }
1403}
1404
1405
1406template <class B>
1407void ParsingEngine<B>::Parse_PEReference (){
1408
1409        Advance(1); /* Skip "%". */
1410        fprintf(stderr,"Parameter Reference has not been completed yet.\n");
1411        exit(-1);
1412        int nameID = Parse_Name(); 
1413        if (AtChar<B::Base,';'>(cur())) {
1414                Advance(1);
1415                PEReference_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
1416                PEntity_info * this_info;
1417                Parser_Interface * entity_parser;
1418                int entityID = model_info->GlobalPEntityTable[nameID]; 
1419                if (entityID == 0)
1420                        WF_Error(wfErr_wf_entdeclared);
1421                else{
1422                        this_info = model_info->PEntityData[entityID-1];
1423                        if (this_info->is_external){
1424                               
1425//                      if (entity_Info->standalone != Standalone_no)
1426//                              WF_Error(wfErr_NoExternalRefs);
1427//                      else {
1428                                        entity_parser = ParserFactory(this_info->systemLiteral, model_info);
1429                                        entity_parser->Parse_WF_Content();
1430                                        if(!entity_parser->at_EOF())
1431                                                Syntax_Error(NT_content);
1432                                        entity_parser->~Parser_Interface();
1433//                      }
1434                        }
1435                        else {
1436                        }
1437                }
1438        }
1439        else
1440                Syntax_Error(NT_PEReference);
1441}
1442
1443
1444template <class B>
1445void ParsingEngine<B>::Parse_Elementdecl (){
1446
1447        Advance(7); /* Skip "<!ELEMENT". */
1448
1449    requireWS();
1450        int nameID = Parse_Name();
1451        int elemID = model_info->getOrInsertGlobalElement(nameID);
1452
1453        requireWS();
1454        ContentModel * cm;
1455        /* Start parsing "contentspec"*/
1456        if (at_EMPTY<B::Base>(cur())) {
1457        Advance(5);
1458        cm = new CM_Empty();
1459        model_info->ContentModelData[nameID] = cm;
1460        }
1461    else if (at_ANY<B::Base>(cur())) {
1462        Advance(3);
1463        cm = new CM_Any();
1464        model_info->ContentModelData[nameID] = cm;
1465    }
1466    else {
1467        if (AtChar<B::Base,'('>(cur()))
1468                        Advance(1);
1469                ScanTo(NonWS);
1470                if (at_PCDATA<B::Base>(cur())){
1471                        cm = Parse_RemainingMixed();
1472                        model_info->ContentModelData[nameID] = cm;
1473                }
1474                else{
1475
1476                        CM_RegExp * cre = new CM_RegExp;
1477                        cre->content_re = Parse_RemainingChildren();
1478
1479                        int id_count = cre->content_re->Set_IDs(0);
1480                        cre->content_re->Set_First_Map();       
1481                        symbol_set_t * transition_map = new symbol_set_t[id_count+1];
1482                        cre->content_re->follow_map[0] = id_count+1;
1483                       
1484                        cre->content_re->Set_Follow_Map(transition_map);
1485                        transition_map[0] = cre->content_re->first_map;
1486                       
1487                        if (cre->content_re->matches_empty)
1488                                transition_map[0][0]=id_count+1;
1489                               
1490                        cre -> transition_map = transition_map;
1491                       
1492                        model_info->ContentModelData[nameID] = cre;
1493                        cm = cre;
1494                }                       
1495    }
1496    ScanTo(NonWS);   
1497
1498        if (AtChar<B::Base,'>'>(cur())) {
1499                Advance(1);
1500        }
1501        else
1502                Syntax_Error(NT_elementdecl);
1503}
1504template <class B>
1505ContentModel * ParsingEngine<B>::Parse_RemainingMixed (){
1506        CM_Mixed * r = new CM_Mixed();
1507        Advance(7);  /* Skip "#PCDATA". */
1508   
1509    if (AtChar<B::Base,')'>(cur())){
1510        if (AtChar<B::Base,'*'>(cur())) {
1511                Advance(2);
1512                }
1513                else {
1514                        Advance(1);
1515                }
1516    }
1517    else{
1518        ScanTo(NonWS);
1519        int k = 0;
1520        while (AtChar<B::Base,'|'>(cur())){
1521                        Advance(1);
1522                        ScanTo(NonWS);
1523                        int nameID = Parse_Name();
1524                        r->elements[nameID] = ++k;
1525                        ScanTo(NonWS);
1526                }
1527                if (at_Para_star<B::Base>(cur())) Advance(2);
1528                else {
1529                        Syntax_Error(NT_Mixed);
1530                        exit(-1);
1531        }
1532    }
1533    return r;
1534}
1535
1536
1537template <class B>
1538Content_RE * ParsingEngine<B>::Parse_RemainingChildren (){
1539        Content_RE * c1 = Parse_Cp();
1540        Content_RE * r = c1;
1541        ScanTo(NonWS);
1542        if(AtChar<B::Base,'|'>(cur())){
1543                CRE_Choice * rslt = new CRE_Choice;
1544                rslt->subCMs.push_back(c1);
1545                Advance(1);
1546                ScanTo(NonWS);
1547                rslt->subCMs.push_back(Parse_Cp());
1548                ScanTo(NonWS);
1549                while(!AtChar<B::Base,')'>(cur())){
1550                        if(AtChar<B::Base,'|'>(cur()))
1551                                Advance(1);
1552                        else
1553                                Syntax_Error(NT_children);
1554                        ScanTo(NonWS);
1555                        rslt->subCMs.push_back(Parse_Cp());
1556                        ScanTo(NonWS);
1557                }
1558                Advance(1);
1559                rslt->Compile();
1560                r = rslt;
1561        }
1562        else if(AtChar<B::Base,','>(cur())){
1563                CRE_Seq * rslt = new CRE_Seq;
1564                rslt->subCMs.push_back(c1);
1565                Advance(1);
1566                ScanTo(NonWS);
1567                rslt->subCMs.push_back(Parse_Cp());
1568                ScanTo(NonWS);
1569                while(!AtChar<B::Base,')'>(cur())){
1570                        if(AtChar<B::Base,','>(cur()))
1571                                Advance(1);
1572                        else
1573                                Syntax_Error(NT_children);
1574                        ScanTo(NonWS);
1575                        rslt->subCMs.push_back(Parse_Cp());
1576                        ScanTo(NonWS);
1577                }
1578                Advance(1);
1579                rslt->Compile();
1580                r = rslt;
1581        }       
1582        else if(AtChar<B::Base,')'>(cur())){
1583                Advance(1);
1584        }
1585        else
1586                Syntax_Error(NT_children);
1587               
1588        if (AtChar<B::Base,'?'>(cur())) {
1589                Advance(1);
1590                r = new CRE_Opt(r);
1591        }
1592        else if (AtChar<B::Base,'*'>(cur())) {
1593                Advance(1);
1594                r = new CRE_Star(r);
1595        }
1596        else if (AtChar<B::Base,'+'>(cur())) {
1597                Advance(1);
1598                r = new CRE_Plus(r);
1599        }
1600
1601        return r;
1602}
1603
1604template <class B>
1605Content_RE * ParsingEngine<B>::Parse_Cp (){
1606        if (AtChar<B::Base,'('>(cur())){
1607                Advance(1);
1608                ScanTo(NonWS);
1609                Parse_RemainingChildren();
1610        }
1611        else{
1612                int nameID = Parse_Name();
1613                CRE_Name * r = new CRE_Name(nameID);
1614
1615                if (AtChar<B::Base,'?'>(cur())) {
1616                        Advance(1);
1617                        return new CRE_Opt(r);
1618                }
1619                else if (AtChar<B::Base,'*'>(cur())) {
1620                        Advance(1);
1621                        return new CRE_Star(r);
1622                }
1623                else if (AtChar<B::Base,'+'>(cur())) {
1624                        Advance(1);
1625                        return new CRE_Plus(r);
1626                }
1627                else return r;
1628        }
1629}
1630
1631template <class B>
1632void ParsingEngine<B>::Parse_AttlistDecl (){
1633       
1634        int old_abspos;
1635       
1636        int name_start;
1637        int lgth;
1638       
1639        int elemID;
1640        int attID;
1641       
1642        Advance(7); /* Skip "ATTLIST. */
1643        requireWS();
1644       
1645        int nameID = Parse_Name();
1646        elemID = model_info->getOrInsertGlobalElement(nameID);
1647       
1648        old_abspos = AbsPos();
1649        ScanTo(NonWS);
1650        while(!AtChar<B::Base,'>'>(cur())) {
1651                if(old_abspos == AbsPos())
1652                Syntax_Error(NT_AttlistDecl);
1653               
1654                int att_nameID = Parse_Name();
1655               
1656                attID = model_info->getOrInsertGlobalAttName(att_nameID);
1657                if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
1658        ATT_info * this_info = new ATT_info;
1659        this_info->globalATT_id = attID;
1660        requireWS();
1661        if (at_CDATA<B::Base>(cur())){
1662                Advance(5);
1663                this_info->attType = CDATA_att;
1664        }
1665        else if(at_ID<B::Base>(cur())){
1666                Advance(2);
1667                this_info->attType = ID_att;
1668        }
1669        /* Make sure to check IDREFS before IDREF*/
1670        else if(at_IDREFS<B::Base>(cur())){
1671                Advance(6);
1672                this_info->attType = IDREFS_att;
1673        }
1674        else if(at_IDREF<B::Base>(cur())){
1675                Advance(5);
1676                this_info->attType = IDREF_att;
1677        }
1678        else if(at_ENTITY<B::Base>(cur())){
1679                Advance(6);
1680                this_info->attType = ENTITY_att;
1681        }
1682        else if(at_ENTITIES<B::Base>(cur())){
1683                Advance(8);
1684                this_info->attType = ENTITIES_att;
1685        }
1686        /* Make sure to check NMTOKENS before NMTOKEN*/
1687        else if(at_NMTOKENS<B::Base>(cur())){
1688                Advance(8);
1689                this_info->attType = NMTOKENS_att;
1690        }
1691        else if(at_NMTOKEN<B::Base>(cur())){
1692                Advance(7);
1693                this_info->attType = NMTOKEN_att;
1694        }
1695        else if(at_NOTATION<B::Base>(cur())){ /* NotationType = 'NOTATION' S Enumeration
1696                                                                         when Nmtoken = Name */
1697                Advance(8);
1698                        requireWS();
1699                Parse_Notation(this_info);
1700                this_info->attType = NOTATION_att;
1701        }
1702        else if(AtChar<B::Base,'('>(cur())){
1703                Parse_Enumeration(this_info);
1704                this_info->attType = enumeration_att;
1705        }
1706        else
1707                Syntax_Error(NT_AttlistDecl);
1708        requireWS();
1709        Parse_DefaultDecl(this_info);
1710
1711                ScanTo(NonWS);
1712                model_info->ElementAttributeData[elemID].push_back(this_info);
1713        }
1714
1715        Advance(1);
1716}
1717
1718template <class B>
1719void ParsingEngine<B>::Parse_Notation (ATT_info * this_info){
1720
1721        if(AtChar<B::Base,'('>(cur()))
1722                Advance(1);
1723        else
1724                Syntax_Error(NT_NotationType);
1725        ScanTo(NonWS);
1726       
1727    int notn_nameID = Parse_Name();
1728
1729        /*Notation name is not in the global table!*/
1730        if(model_info->GlobalNotationTable[notn_nameID]==0)
1731                model_info->GlobalNotationTable[notn_nameID] = -1;
1732       
1733        ScanTo(NonWS);
1734        while(AtChar<B::Base,'|'>(cur())){
1735                Advance(1);
1736                ScanTo(NonWS); 
1737                notn_nameID = Parse_Name();
1738                       
1739                if(model_info->GlobalNotationTable[notn_nameID]==0)
1740//                      Validity_Error(vErr_notatn);
1741                        model_info->GlobalNotationTable[notn_nameID] = -1;
1742                       
1743                ScanTo(NonWS);
1744        }
1745        if (AtChar<B::Base,')'>(cur())) 
1746                Advance(1);
1747        else
1748                Syntax_Error(NT_NotationType);
1749}
1750
1751template <class B>
1752void ParsingEngine<B>::Parse_Enumeration (ATT_info * this_info){
1753
1754        int enumCount=0;
1755        if(AtChar<B::Base,'('>(cur()))
1756                Advance(1);
1757        else
1758                Syntax_Error(NT_Enumeration);
1759        ScanTo(NonWS);
1760       
1761        int nmtokenID = Parse_Nmtoken();
1762       
1763        this_info->enumValues[nmtokenID]=++(enumCount);
1764       
1765        ScanTo(NonWS);
1766        while(AtChar<B::Base,'|'>(cur())){
1767                Advance(1);
1768                ScanTo(NonWS); 
1769                int nmtokenID = Parse_Nmtoken();
1770       
1771                int enumID = this_info->enumValues[nmtokenID];
1772                if(enumID==0){ 
1773                        this_info->enumValues[nmtokenID]=++(enumCount);
1774                        enumID = enumCount;
1775                }
1776                else if(!StrictWellFormedness){
1777                        Validity_Error(vErr_NoDuplicateTokens);
1778                }
1779                ScanTo(NonWS);
1780        }
1781        if (AtChar<B::Base,')'>(cur())) 
1782                Advance(1);
1783        else
1784                Syntax_Error(NT_Enumeration);
1785}
1786
1787template <class B>
1788void ParsingEngine<B>::Parse_DefaultDecl (ATT_info * this_info){
1789        if(at_REQUIRED<B::Base>(cur())){
1790                Advance(9);
1791                this_info->defaultKind = REQUIRED_att;
1792        }
1793        else if(at_IMPLIED<B::Base>(cur())){
1794                Advance(8);
1795                this_info->defaultKind = IMPLIED_att;
1796        }
1797        else {
1798                if(at_FIXED<B::Base>(cur())){
1799                        Advance(6);
1800                        requireWS();
1801                        this_info->defaultKind = FIXED_att;
1802                }
1803                else this_info->defaultKind = DEFAULT_att;
1804                if(AtQuote<B::Base>(cur())){
1805                        int quot_start = AbsPos()+1;
1806                        Parse_AttValue();
1807                        /* need to normalize */
1808                        this_info->defaultValueLgth = AbsPos() - quot_start - 1;
1809                       
1810                        this_info->defaultValue = new unsigned char[this_info->defaultValueLgth+1];
1811                        memcpy(this_info->defaultValue, GetCodeUnitPtr(quot_start),this_info->defaultValueLgth); 
1812                        this_info->defaultValue[this_info->defaultValueLgth] = '\0';
1813                        }
1814                else
1815                        Syntax_Error(NT_DefaultDecl);
1816        }
1817}
1818
1819template <class B>
1820void ParsingEngine<B>::Parse_Entitydecl (){
1821       
1822        int name_start;
1823        int quot_start;
1824        int lgth;
1825        int old_abspos;
1826        char * s;
1827       
1828        Advance(6); /* Skip "ENTITY. */
1829        requireWS();
1830       
1831        if (AtChar<B::Base,'%'>(cur())){
1832                Advance(1);
1833                requireWS();
1834               
1835                int nameID = Parse_Name();
1836                PEntity_info * this_info = new PEntity_info;
1837                int entityID = model_info->GlobalPEntityTable[nameID];
1838                if(entityID==0){       
1839                        model_info->GlobalPEntityTable[nameID]=++(model_info->globalPEntityCount);
1840                        entityID = model_info->globalPEntityCount;
1841                        this_info->globalPEntity_id = entityID;
1842                }
1843                else
1844                        printf("Warning: Entity definition already exist!\n");
1845       
1846                requireWS();
1847                if(AtQuote<B::Base>(cur())){
1848                Parse_PEntityValue(this_info);
1849                this_info->is_external = false;
1850        }
1851        else {
1852                Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1853                this_info->is_external = true;
1854                if (this_info->systemLiteral == NULL) Syntax_Error(NT_EntityDecl);
1855        }
1856        model_info->PEntityData.push_back(this_info);
1857        }
1858        else{
1859                int nameID = Parse_Name();
1860       
1861                GEntity_info * this_info = new GEntity_info();
1862                int entityID = model_info->GlobalGEntityTable[nameID];
1863                if(entityID==0){       
1864                        model_info->GlobalGEntityTable[nameID]=++(model_info->globalGEntityCount);
1865                        entityID = model_info->globalGEntityCount;
1866                        this_info->globalGEntity_id = entityID;
1867                }
1868                else
1869                        printf("Warning: Entity definition already exists!\n");
1870                       
1871                requireWS();
1872               
1873                if(AtQuote<B::Base>(cur())){
1874                Parse_GEntityValue(this_info);                 
1875                this_info->is_external = false;
1876        }
1877        else {
1878                Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1879                this_info->is_external = true;
1880                if (this_info->systemLiteral == NULL) Syntax_Error(NT_EntityDecl);
1881                        old_abspos = AbsPos();
1882                        ScanTo(NonWS);
1883                if(at_NDATA<B::Base>(cur())){
1884                        if(old_abspos == AbsPos())
1885                                Syntax_Error(NT_EntityDecl);
1886                        else
1887                                Advance(5);
1888                        requireWS();
1889                        name_start = AbsPos();
1890                        int nameID = Parse_Name();
1891                        lgth = AbsPos() - name_start;
1892                                this_info->NDataName = copy_string(GetCodeUnitPtr(name_start),lgth);
1893                }
1894                }
1895        model_info->GEntityData.push_back(this_info);
1896        }
1897        ScanTo(NonWS);
1898        if (AtChar<B::Base,'>'>(cur())){
1899                Advance(1);
1900        }
1901        else
1902                Syntax_Error(NT_EntityDecl);
1903}
1904
1905template <class B>
1906void ParsingEngine<B>::Parse_Notationdecl (){
1907
1908        int old_abspos;
1909        Advance(8); /* Skip "NOTATION. */
1910        requireWS();
1911       
1912        int nameID = Parse_Name();
1913
1914        int notationID = model_info->GlobalNotationTable[nameID];
1915        /* notationID == -1: used but not yet defined; == 0: new, > 0 prev. defined */
1916        if(notationID <= 0){   
1917                model_info->GlobalNotationTable[nameID]=++(model_info->globalNotationCount);
1918                notationID = model_info->globalNotationCount;
1919        }
1920        else /*Duplicate notation name!*/
1921                Validity_Error(vErr_NoDuplicateTokens);
1922        Notation_info * this_info = new Notation_info;
1923        ScanTo(NonWS);         
1924    Parse_ExternalID(this_info->systemLiteral, this_info->pubidLiteral);
1925        ScanTo(NonWS);
1926        if (AtChar<B::Base,'>'>(cur())) {
1927                Advance(1);
1928        }
1929        else
1930                Syntax_Error(NT_NotationDecl);
1931}
1932
1933template <class B>
1934void ParsingEngine<B>::requireWS(){
1935       
1936    int old_abspos = AbsPos(); 
1937    ScanTo(NonWS);
1938    if(old_abspos == AbsPos())
1939        Syntax_Error(NT_S);
1940}
1941
1942template <class B>
1943void ParsingEngine<B>::Parse_AttValue(){
1944       
1945        int     quoteCh = cur()[0];
1946        Advance(1); /* Skip " or ' */
1947
1948        ScanTo(Quote);                 
1949        while (cur()[0] != quoteCh){
1950                if (at_CharRef_Start<B::Base>(cur())){
1951                        Parse_CharRef();
1952                        ScanTo(Quote);
1953                }
1954                else if (AtChar<B::Base,'&'>(cur())){
1955                        Parse_EntityRef();
1956                        ScanTo(Quote);
1957                }
1958                else if (AtQuote<B::Base>(cur())) {
1959                        Advance(1);
1960                        ScanTo(Quote);
1961                }
1962                else /* if (AtChar<B::Base,'<'>(cur())) */
1963                        WF_Error(wfErr_CleanAttrVals);
1964        }
1965        Advance(1);
1966}
1967
1968template <class B>
1969void ParsingEngine<B>::Parse_GEntityValue(GEntity_info * this_info){
1970       
1971        int     quoteCh = cur()[0];
1972        Advance(1); /* Skip " or ' */
1973        this_info->is_simple = true;
1974        int quot_start = AbsPos();
1975        char * replText;
1976        ScanTo(Quote);         
1977        replText = copy_string(GetCodeUnitPtr(quot_start),AbsPos()-quot_start);
1978        while (cur()[0] != quoteCh){
1979                if (at_CharRef_Start<B::Base>(cur())){
1980                        strcat (replText,Replace_CharRef());
1981                        quot_start = AbsPos();
1982                        ScanTo(Quote);
1983                }
1984                else if (AtQuote<B::Base>(cur())) {
1985                        quot_start = AbsPos();
1986                        Advance(1);
1987                        ScanTo(Quote);
1988                }
1989                else if (at_EOF()) {
1990                        Syntax_Error(NT_EntityValue);
1991                }
1992                else { /* '<' or '&' found */
1993                        quot_start = AbsPos();
1994                        Advance(1);
1995                        ScanTo(Quote);
1996                        this_info->is_simple = false;                   
1997                }
1998                replText = cat_string (replText,(char *)GetCodeUnitPtr(quot_start), strlen(replText), AbsPos()-quot_start);
1999        }
2000        this_info->ReplacementText = replText;
2001        Advance(1);
2002}
2003
2004template <class B>
2005char * ParsingEngine<B>::Replace_EntityRef(bool& is_simple){
2006        Advance(1);
2007        int nameID = Parse_Name(); 
2008        if (AtChar<B::Base,';'>(cur()))
2009                Advance(1);
2010        else
2011                Syntax_Error(NT_EntityValue);
2012        int entityID = model_info->GlobalGEntityTable[nameID]; 
2013        if (entityID == 0)
2014                WF_Error(wfErr_wf_entdeclared);
2015        else{
2016                if (model_info->GEntityData[entityID-1]->is_simple == false)
2017                        is_simple = false;
2018                return model_info->GEntityData[entityID-1]->ReplacementText;
2019        }
2020       
2021}
2022
2023template <class B>
2024void ParsingEngine<B>::Parse_PEntityValue(PEntity_info * this_info){
2025        fprintf(stderr,"parsing of parameter entity value has not been completed yet.\n");
2026        exit(-1);
2027}
2028
2029template <class B>
2030char * ParsingEngine<B>::Replace_CharRef(){
2031        Advance(2);
2032        fprintf(stderr,"Replacement of Character Reference has not been completed yet.\n");
2033        exit(-1);
2034}
2035
2036template <class B>
2037void ParsingEngine<B>::Parse_Prolog(){
2038        ScanTo(NonWS);
2039        int old_pos = AbsPos();
2040        while (!at_DOCTYPE_start<B::Base>(cur())) {
2041                if (at_Comment_Start<B::Base>(cur())) 
2042                        Parse_Comment();
2043                else if (at_PI_Start<B::Base>(cur()))
2044                                Parse_PI();
2045                else{
2046                        Prolog_action(GetCodeUnitPtr(old_pos), LengthFrom(old_pos));
2047                        return;
2048                }
2049                ScanTo(NonWS);
2050        }
2051        Parse_DocType();
2052        ScanTo(NonWS);
2053        while(at_Comment_Start<B::Base>(cur()) || at_PI_Start<B::Base>(cur()) ){
2054                if (at_Comment_Start<B::Base>(cur()))
2055                        Parse_Comment();
2056                else 
2057                        Parse_PI();
2058                ScanTo(NonWS);
2059        }
2060        Prolog_action(GetCodeUnitPtr(old_pos), LengthFrom(old_pos));
2061}
2062
2063template <class B>
2064void ParsingEngine<B>::Parse_ExtSubsetDecl() {
2065        ScanTo(NonWS);
2066        int start_pos=AbsPos();
2067        while(!at_EOF()){
2068                if(at_condSect_start<B::Base>(cur())){         
2069                        Advance(3);
2070                        ScanTo(NonWS);
2071                        if (at_INCLUDE<B::Base>(cur())){
2072                                Advance(7);
2073                                ScanTo(NonWS);
2074                                if(AtChar<B::Base,'['>(cur())){
2075                                        Advance(1);
2076                                        Parse_ExtSubsetDecl();
2077                                        if(at_CDATA_End<B::Base>(cur()))
2078                                                Advance(3);
2079                                        else Syntax_Error(NT_includeSect);
2080                                }
2081                                else Syntax_Error(NT_includeSect);
2082                        }
2083                        else if (at_IGNORE<B::Base>(cur())){
2084                                Advance(6);
2085                                ScanTo(NonWS);         
2086                                if(AtChar<B::Base,'['>(cur())){
2087                                        int section_depth=1;
2088                                        Advance(1);
2089                                        while(!at_EOF()){
2090                                                ScanTextTo(MarkupStart);
2091                                                if(at_condSect_start<B::Base>(cur())){
2092                                                        Advance(3);
2093                                                        section_depth++;
2094                                                }
2095                                                else if(at_CDATA_End<B::Base>(cur())){
2096                                                        Advance(3);
2097                                                        section_depth--;
2098                                                }
2099                                                else
2100                                                        Advance(1);
2101                                                if(section_depth==0) return;                                   
2102                                        }
2103                                        Syntax_Error(NT_ignoreSectContents);   
2104                                }
2105                                else Syntax_Error(NT_ignoreSect);
2106                        }
2107                        else Syntax_Error(NT_conditionalSect);
2108                }
2109                else if (AtChar<B::Base,'%'>(cur()))
2110                        Parse_PEReference();   
2111                else if (at_PI_Start<B::Base>(cur())) {
2112                        Parse_PI();
2113                }
2114                else if (at_Comment_Start<B::Base>(cur())) {
2115                        Parse_Comment();
2116                }
2117                else if (AtChar<B::Base,'<'>(cur())){
2118                        Advance(1);
2119
2120                        if(AtChar<B::Base,'!'>(cur())){
2121                                Advance(1);
2122                                if(at_ELEMENT<B::Base>(cur()))
2123                                        Parse_Elementdecl();
2124                                else if(at_ATTLIST<B::Base>(cur()))
2125                                        Parse_AttlistDecl();
2126                                else if(at_ENTITY<B::Base>(cur()))
2127                                        Parse_Entitydecl();
2128                                else if(at_NOTATION<B::Base>(cur()))
2129                                        Parse_Notationdecl();                                   
2130                                else{
2131                                        Syntax_Error(NT_markupdecl);   
2132                                }                                                               
2133                        }
2134                        else
2135                                Syntax_Error(NT_markupdecl); 
2136                }
2137                else
2138                        Syntax_Error(NT_extSubsetDecl); 
2139                ScanTo(NonWS);
2140        }
2141        ExtSubsetDecl_action(GetCodeUnitPtr(start_pos), LengthFrom(start_pos));
2142}
2143
2144/* Parse a valid start or empty element tag. */
2145template <class B>
2146inline int ParsingEngine<B>::Parse_ValidStartTag (bool& is_emptyStartTag){
2147        int att_name_start;
2148        int att_val_start;
2149        int att_name_end, att_val_end;
2150        unsigned char quoteCh;
2151        Advance(1);
2152
2153        int nameID = Parse_Name(); 
2154        int elemID = model_info->GlobalElementTable[nameID];
2155        if(elemID==0)
2156                        Validity_Error(vErr_elementvalid);
2157       
2158        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
2159        /* The following test optimizes the most common case of a
2160        start tag with no attributes.  */
2161        if (AtChar<B::Base,'>'>(cur())) {
2162                Advance(1);
2163                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2164        }
2165        else {
2166                ScanTo(NonWS);
2167                if (AtChar<B::Base,'>'>(cur())) {
2168                        Advance(1);
2169                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2170                }
2171                else if (at_EmptyElementDelim<B::Base>(cur())) {
2172                        Advance(2);
2173                        is_emptyStartTag = true;
2174                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2175                }
2176                else do {
2177                        /* Must be an attribute-value pair or error. */
2178                        att_name_start = AbsPos();
2179                        int att_nameID = Parse_Name();
2180                        #if (not defined(OMISSION)) or (OMISSION != ATTRIBUTE_UNIQUENESS) 
2181                        int attID = model_info->getOrInsertGlobalAttName(att_nameID);
2182                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
2183                        else {
2184                                if (LastAttOccurrence[attID] > text_or_markup_start) {
2185                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
2186                                        break;
2187                                }                       
2188                        }
2189                        LastAttOccurrence[attID] = att_name_start;
2190                        #endif
2191                        /* The following optimized tests handle the frequently occurring
2192                        case that there are no blanks on either side of the equals sign.
2193                        In many cases, the very first test handles 100% of actual
2194                        attribute-value pairs encountered. */
2195                        if (at_EqualsQuote<B::Base>(cur())) Advance(1); 
2196                        else {
2197                                ScanTo(NonWS);
2198                                if (!AtChar<B::Base,'='>(cur())) {
2199                                        Syntax_Error(NT_STag); 
2200                                        break;
2201                                }
2202                                Advance(1); 
2203                                ScanTo(NonWS);
2204                                if (!AtQuote<B::Base>(cur())) {
2205                                        Syntax_Error(NT_STag); 
2206                                        break;
2207                                }
2208                        }
2209                        att_val_start = AbsPos()+1;
2210                        Parse_AttValue();
2211                        att_val_end = AbsPos()-1;
2212                        if (at_xmlns<B::Base>(cur()+att_name_start-AbsPos())) {
2213                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
2214                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
2215                        }
2216                        else {
2217                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
2218                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
2219                        }
2220                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
2221                        if (AtChar<B::Base,'>'>(cur())) {
2222                                Advance(1);
2223                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2224                                break;
2225                        }
2226                        else if (at_EmptyElementDelim<B::Base>(cur())) {
2227                                Advance(2);
2228                                is_emptyStartTag = true;       
2229                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2230                                break;
2231                        }
2232                        ScanTo(NonWS);
2233                        if (AtChar<B::Base,'>'>(cur())) {
2234                                Advance(1);
2235                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2236                                break;
2237                        }
2238                        else if (at_EmptyElementDelim<B::Base>(cur())) {
2239                                Advance(2);
2240                                is_emptyStartTag = true;
2241                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
2242                                break;
2243                        }
2244                        else if (AbsPos() == att_val_end + 1) { 
2245                                /* No WS following att value */
2246                                Syntax_Error(NT_STag);
2247                                break;
2248                        }
2249                } while (1);
2250        }
2251        return nameID;
2252}
2253
2254template <class B>
2255int ParsingEngine<B>::Parse_ValidElement() {
2256        bool is_emptyStartTag = false;
2257        int nameID = Parse_ValidStartTag(is_emptyStartTag);
2258#ifdef DEBUG
2259        printf("Parse_ValidElement: nameID = %d, name = %s, is_emptyStartTag=%i\n",nameID, model_info->symbol_table->Get_UTF8_name(nameID), is_emptyStartTag);
2260#endif
2261        ContentModel * cm = model_info->ContentModelData[nameID];
2262        switch (cm->cm_type) {
2263                case cm_Empty:
2264                        if (!is_emptyStartTag) {
2265                                if (at_EndTag_Start<B::Base>(cur())) {
2266                                        Parse_WF_EndTag(nameID);
2267                                }
2268                                else {
2269                                        Validity_Error(vErr_elementvalid);
2270                                }
2271                        }
2272                        break;
2273                case cm_Any:           
2274                        if (!is_emptyStartTag) {
2275                                Parse_AnyContent();
2276                                Parse_WF_EndTag(nameID);
2277                        }
2278                        break;
2279                case cm_Mixed:         
2280                        if (!is_emptyStartTag) {
2281                                Parse_MixedContent(((CM_Mixed *) cm)->elements);
2282                                Parse_WF_EndTag(nameID);
2283                        }
2284                        break;
2285                case cm_RegExp:
2286                        CM_RegExp * cre = (CM_RegExp *) cm;
2287                        int content_state = 0;
2288                        if (!is_emptyStartTag) {
2289                                Parse_ValidContent(cre, content_state);
2290                                #ifdef DEBUG
2291                                printf("Final content_state = %i, nameID = %i\n", content_state, nameID);
2292                                #endif
2293                                Parse_WF_EndTag(nameID);               
2294                        }
2295                        if (cre->transition_map[content_state][0]==0) {
2296                                Validity_Error(vErr_elementvalid);
2297                        }
2298        }
2299        return nameID;
2300}
2301
2302template <class B>
2303void ParsingEngine<B>::Parse_ValidContent(CM_RegExp * cre, int & cur_state) {
2304        do {
2305                ScanTo(NonWS);
2306                /* If non-null report WS  WS_action()? */
2307                text_or_markup_start = AbsPos();
2308                if (at_EndTag_Start<B::Base>(cur())) {
2309                        break;
2310                }
2311                else if (at_ElementTag_Start<B::Base>(cur())) {
2312                        int nameID = Parse_ValidElement();
2313#ifdef DEBUG
2314                        printf("Content model state transition %i", cur_state);
2315#endif
2316                        cur_state = cre->transition_map[cur_state][nameID];
2317#ifdef DEBUG
2318                        printf("-> %i\n", cur_state);
2319#endif
2320                }
2321                else if (at_Comment_Start<B::Base>(cur())) {
2322                        Parse_Comment();
2323                }
2324                else if (at_PI_Start<B::Base>(cur())) {
2325                        Parse_PI();
2326                }
2327                else if (AtChar<B::Base,'&'>(cur())) {
2328                        Parse_ValidEntityRef(cre, cur_state);
2329#ifdef DEBUG
2330                        printf("EntityRef complete, cur_state = %i\n", cur_state);
2331#endif
2332                       
2333                }
2334                else if (at_EOF()) {
2335                        break;
2336                }
2337                else if (AtChar<B::Base,'<'>(cur())) {
2338                        Syntax_Error(NT_markupdecl);
2339                }
2340                else {
2341                        Validity_Error(vErr_elementvalid);
2342                }
2343        } while(1);
2344}
2345
2346
2347template <class B>
2348void ParsingEngine<B>::Parse_AnyContent() {
2349        do {
2350                text_or_markup_start = AbsPos();
2351                ScanTextTo(MarkupStart); /* '<', '&', or ']' for ']]>' test */
2352                if (at_ElementTag_Start<B::Base>(cur())) {
2353                        text_if_nonnull_action(false);
2354                        int nameID = Parse_ValidElement();
2355                }
2356                else if (at_EndTag_Start<B::Base>(cur())) {
2357                        text_if_nonnull_action(false);
2358                        return;
2359                }
2360                else if (at_Comment_Start<B::Base>(cur())) {
2361                        text_if_nonnull_action(false);
2362                        Parse_Comment();
2363                }
2364                else if (at_CharRef_Start<B::Base>(cur())) {
2365                        text_if_nonnull_action(true);
2366                        Parse_CharRef();
2367                }
2368                else if (AtChar<B::Base,'&'>(cur())) {
2369                        text_if_nonnull_action(true);
2370                        Parse_EntityRef_inAnyContent();
2371                }
2372                else if (at_CDATA_Start<B::Base>(cur())) {
2373                        text_if_nonnull_action(true);
2374                        Parse_CDATA();
2375                }
2376                else if (at_PI_Start<B::Base>(cur())) {
2377                        text_if_nonnull_action(false);
2378                        Parse_PI();
2379                }
2380                else if (at_CDATA_End<B::Base>(cur())) {
2381                        text_if_nonnull_action(true);
2382                        Advance(3);
2383                        Syntax_Error(NT_CharData);
2384                }
2385                else if (at_EOF()) {
2386                        text_if_nonnull_action(false);
2387                        return;
2388                }
2389                else if (AtChar<B::Base,'<'>(cur())) {
2390                        Syntax_Error(NT_markupdecl);
2391                }
2392                else {
2393                        Advance(1);
2394                        continue;
2395                }
2396        } while (1);
2397}
2398template <class B>
2399void ParsingEngine<B>::Parse_MixedContent(symbol_set_t elems) {
2400        do {
2401                text_or_markup_start = AbsPos();
2402                ScanTextTo(MarkupStart); /* '<', '&', or ']' for ']]>' test */
2403/*              if (AtChar<B::Base,'<'>(cur())) {
2404                        text_if_nonnull_action();
2405                        Parse_Markup<B>();
2406                }*/
2407                if (at_ElementTag_Start<B::Base>(cur())) {
2408                        text_if_nonnull_action(false);
2409                        int nameID = Parse_ValidElement();
2410                        if (elems[nameID] == 0) {
2411                                Validity_Error(vErr_elementvalid);
2412                        }
2413                }
2414                else if (at_EndTag_Start<B::Base>(cur())) {
2415                        text_if_nonnull_action(false);
2416                        return;
2417                }
2418                else if (at_Comment_Start<B::Base>(cur())) {
2419                        text_if_nonnull_action(false);
2420                        Parse_Comment();
2421                }
2422                else if (at_CharRef_Start<B::Base>(cur())) {
2423                        text_if_nonnull_action(true);
2424                        Parse_CharRef();
2425                }
2426                else if (AtChar<B::Base,'&'>(cur())) {
2427                        text_if_nonnull_action(true);
2428                        Parse_EntityRef_inMixed(elems);
2429                }
2430                else if (at_CDATA_Start<B::Base>(cur())) {
2431                        text_if_nonnull_action(true);
2432                        Parse_CDATA();
2433                }
2434                else if (at_PI_Start<B::Base>(cur())) {
2435                        text_if_nonnull_action(false);
2436                        Parse_PI();
2437                }
2438                else if (at_CDATA_End<B::Base>(cur())) {
2439                        text_if_nonnull_action(true);
2440                        Advance(3);
2441                        Syntax_Error(NT_CharData);
2442                }
2443                else if (at_EOF()) {
2444                        text_if_nonnull_action(false);
2445                        return;
2446                }
2447                else if (AtChar<B::Base,'<'>(cur())) {
2448                        Syntax_Error(NT_markupdecl);
2449                }
2450                else {
2451                        Advance(1);
2452                        continue;
2453                }
2454        } while (1);
2455}
2456
2457
2458template <class B>
2459int ParsingEngine<B>::Parse_Name() {
2460        int name_pos = AbsPos();
2461        ScanTo(NameFollow);
2462        int lgth = AbsPos()-name_pos;
2463        int nameID = model_info->symbol_table->ASCII_Lookup_or_Insert_Name(&((char *) x8data)[buffer_rel_pos-lgth], lgth);
2464        if (nameID != 0) return nameID;
2465        else {
2466                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2467                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2468                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2469                return model_info->symbol_table->LookupOrInsertReserved();
2470        }
2471}
2472
2473template <>
2474int ParsingEngine< X8_Buffer<EBCDIC> >::Parse_Name() {
2475        int name_pos = AbsPos();
2476        ScanTo(NameFollow);
2477        int lgth = AbsPos()-name_pos;
2478//      int nameID = local_EBCDIC_table->Lookup_or_Insert(GetCodeUnitPtr(name_pos), lgth);
2479//      if (nameID != 0) return nameID;
2480//      else {
2481                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2482                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2483                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2484                return model_info->symbol_table->LookupOrInsertReserved();
2485//      }
2486}
2487
2488template <>
2489inline int ParsingEngine<UTF8_Buffer>::Parse_Name() {
2490        int name_pos = AbsPos();
2491        ScanTo(NameFollow);
2492        int lgth = AbsPos()-name_pos;
2493        return model_info->symbol_table->UTF8_Lookup_or_Insert_Name(&((char *)x8data)[buffer_rel_pos-lgth], lgth);
2494}
2495
2496template <class B>
2497int ParsingEngine<B>::Parse_Nmtoken() {
2498        int name_pos = AbsPos();
2499        ScanTo(NameFollow);
2500        int lgth = AbsPos()-name_pos;
2501        int nameID = model_info->symbol_table->ASCII_Lookup_or_Insert_Nmtoken(&((char *) x8data)[buffer_rel_pos-lgth], lgth);
2502        if (nameID != 0) return nameID;
2503        else {
2504                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2505                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2506                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2507                return model_info->symbol_table->LookupOrInsertReserved_nmtoken();
2508        }
2509}
2510
2511template <>
2512int ParsingEngine< X8_Buffer<EBCDIC> >::Parse_Nmtoken() {
2513        int name_pos = AbsPos();
2514        ScanTo(NameFollow);
2515        int lgth = AbsPos()-name_pos;
2516//      int nameID = local_EBCDIC_table->Lookup_or_Insert(GetCodeUnitPtr(name_pos), lgth);
2517//      if (nameID != 0) return nameID;
2518//      else {
2519                int u8_lgth = byteplex->UTF8_Length(name_pos, lgth);
2520                char * u8_ptr = model_info->symbol_table->ReserveSymbolSpace(u8_lgth);
2521                byteplex->to_UTF8(name_pos, lgth, u8_ptr);
2522                return model_info->symbol_table->LookupOrInsertReserved_nmtoken();
2523//      }
2524}
2525template <>
2526int ParsingEngine<UTF8_Buffer>::Parse_Nmtoken() {
2527        int name_pos = AbsPos();
2528        ScanTo(NameFollow);
2529        int lgth = AbsPos()-name_pos;
2530        return model_info->symbol_table->UTF8_Lookup_or_Insert_Nmtoken(&((char *)x8data)[buffer_rel_pos-lgth], lgth);
2531}
2532
2533template <class B>
2534void ParsingEngine<B>::Parse_DocumentContent() {
2535#if (VALIDATION_MODE == ON)
2536        int cur_state = 0;
2537        Parse_ValidContent(model_info->rootModel, cur_state);
2538        if (model_info->rootModel->transition_map[cur_state][0]==0) {
2539                Validity_Error(vErr_elementvalid);
2540        }
2541#endif
2542#if (VALIDATION_MODE == OFF)   
2543        Parse_WF_Element();
2544        ScanTo(NonWS);
2545        while(at_Comment_Start<B::Base>(cur()) || at_PI_Start<B::Base>(cur()) ){
2546                if (at_Comment_Start<B::Base>(cur()))
2547                        Parse_Comment();
2548                else 
2549                        Parse_PI();
2550                ScanTo(NonWS);
2551        }
2552        if (!at_EOF()) {
2553                Syntax_Error(NT_document);
2554        }       
2555#endif
2556}
2557
Note: See TracBrowser for help on using the repository browser.