source: trunk/src/xmldecl.c @ 78

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

Model Processor refactoring

File size: 5.6 KB
Line 
1/*  xmldecl.c - Parsing XML and Text Declarations.
2    Copyright (c) 2008, Robert D. Cameron.
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 <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/types.h>
12
13#include "byteplex.h"
14#include "xmldecl.h"
15#include "multiliteral.h"
16#include "bytelex.h"
17#include "xmlmodel.h"
18
19template <CodeUnit_Base C>
20XML_Decl_Parser<C>::XML_Decl_Parser(Byteplex * b){
21        byteplex = b;
22        buffer_base_pos = 0;
23        x8data = (unsigned char *) byteplex->x8data;
24}
25
26template <CodeUnit_Base C>
27XML_Decl_Parser<C>::~XML_Decl_Parser(){
28}
29
30template <CodeUnit_Base C>
31inline int XML_Decl_Parser<C>::AbsPos() const {
32        return  buffer_base_pos + buffer_rel_pos;
33}
34
35template <CodeUnit_Base C>
36inline unsigned char * XML_Decl_Parser<C>::cur() const {
37        return &x8data[buffer_rel_pos];
38}
39
40template <CodeUnit_Base C>
41inline void XML_Decl_Parser<C>::Advance(int n) {
42        buffer_rel_pos += n;
43        if (buffer_rel_pos >= BYTEPLEX_SIZE) {
44                 byteplex->AdvanceInputBuffer(BYTEPLEX_SIZE);
45        }
46}
47
48template <CodeUnit_Base C>
49inline void XML_Decl_Parser<C>::Scan_WS() {
50        while (at_WhiteSpace<XML_1_0, C>(cur())) Advance(1);
51}
52
53template <CodeUnit_Base C>
54inline void XML_Decl_Parser<C>::ScanToQuote() {
55        int quote_start_pos = buffer_rel_pos;   
56        while (!AtQuote<C>(cur())) buffer_rel_pos+=1;
57        if (buffer_rel_pos >= BYTEPLEX_SIZE) {
58                byteplex->AdvanceInputBuffer(quote_start_pos);
59                buffer_rel_pos -= quote_start_pos;
60                buffer_base_pos += quote_start_pos;
61                while (!AtQuote<C>(cur())) buffer_rel_pos+=1;
62                if (buffer_rel_pos >= BYTEPLEX_SIZE) {
63                        printf("Fatal implementation limit - encoding name exceeds BYTEPLEX_SIZE\n");
64                        exit(-1);
65                }
66        }
67}
68
69void DeclarationError(int pos) {
70        printf("Parsing error at position %i in XML or Text declaration.\n", pos);
71        exit(-1);
72}
73
74
75template <CodeUnit_Base C>
76int XML_Decl_Parser<C>::EncodingAction(Model_Info * m, int start_pos, int end_pos) {
77        m->encoding = (unsigned char *) malloc(end_pos-start_pos+1);
78        memcpy(m->encoding, &x8data[start_pos-buffer_base_pos], end_pos - start_pos);
79        m->encoding[end_pos] = '\0';
80}
81//
82template <CodeUnit_Base C>
83int XML_Decl_Parser<C>::ReadXMLInfo(Model_Info * m) {
84        m->version = no_XML_version_value;
85        m->has_encoding_decl = false;
86        m->standalone = Standalone_no_value;
87        buffer_rel_pos = m->BOM_units;
88        // It is possible that there is no XML declaration.
89        if (!at_XmlDecl_start<C>(cur())) {
90                return AbsPos();
91        }
92        // Otherwise, the XML declaration exists and must have
93        // at least version information.
94        Advance(6);
95        Scan_WS();
96        if (!at_version<C>(cur())) DeclarationError(AbsPos());
97        Advance(7);
98        Scan_WS();
99        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
100        Advance(1);
101        Scan_WS();
102        if (at_1_0<C>(cur())) m->version = XML_1_0;
103        else if (at_1_1<C>(cur())) m->version = XML_1_1;
104        else DeclarationError(AbsPos());
105        Advance(5);
106        if (at_PI_End<C>(cur())) return AbsPos()+2;
107        if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
108        Scan_WS();
109        if (at_encoding<C>(cur())) {
110                m->has_encoding_decl = true;
111                Advance(8);
112                Scan_WS();
113                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
114                Advance(1);
115                Scan_WS();
116                if (AtQuote<C>(cur())) {
117                        unsigned char quoteCh = cur()[0];
118                        Advance(1);
119                        int encoding_start_pos = AbsPos();
120                        ScanToQuote();
121                        if (cur()[0] != quoteCh) DeclarationError(AbsPos());
122                        EncodingAction(m, encoding_start_pos, AbsPos());
123                }
124                else DeclarationError(AbsPos());
125                Advance(1);
126                if (at_PI_End<C>(cur())) return AbsPos()+2;
127                if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
128                Scan_WS();
129        }
130        if (at_standalone<C>(cur())) {
131                Advance(10);
132                Scan_WS();
133                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
134                Advance(1);
135                Scan_WS();
136                if (at_yes<C>(cur())) {Advance(5); m->standalone = Standalone_yes;}
137                else if (at_no<C>(cur())) {Advance(4); m->standalone = Standalone_no;}
138                else DeclarationError(AbsPos());
139                Scan_WS();
140        }
141        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
142        return AbsPos()+2;
143}
144
145// Similar to reading the XML_declaration of the document entity,
146// ReadTextDeclaration reads the text declaration of an external
147// parsed entity.  This is not really needed at present, for DTDless
148// processing.
149template <CodeUnit_Base C>
150int XML_Decl_Parser<C>::ReadTextDeclaration(Model_Info * m) {
151        m->version = no_XML_version_value;
152        m->has_encoding_decl = false;
153        m->standalone = Standalone_no_value;
154        buffer_rel_pos = m->BOM_units;
155        // It is possible that there is no XML declaration.
156        if (!at_XmlDecl_start<C>(cur())) {
157                return AbsPos();
158        }
159        // Otherwise, the text declaration exists and may have
160        // version information.
161        Advance(6);
162        Scan_WS();
163        if (at_version<C>(cur())) {
164                Advance(7);
165                Scan_WS();
166                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
167                Advance(1);
168                Scan_WS();
169                if (at_1_0<C>(cur())) m->version = XML_1_0;
170                else if (at_1_1<C>(cur())) m->version = XML_1_1;
171                else DeclarationError(AbsPos());
172                Advance(5);
173                // Must have whitespace character before declaration.
174                if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
175                Scan_WS();
176        }
177        if (!at_encoding<C>(cur())) DeclarationError(AbsPos());
178        m->has_encoding_decl = true;
179        Advance(8);
180        Scan_WS();
181        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
182        Advance(1);
183        Scan_WS();
184        if (AtQuote<C>(cur())) {
185                unsigned char quoteCh = cur()[0];
186                Advance(1);
187                int encoding_start_pos = AbsPos();
188                ScanToQuote();
189                if (cur()[0] != quoteCh) DeclarationError(AbsPos());
190                EncodingAction(m, encoding_start_pos, AbsPos());
191        }
192        else DeclarationError(AbsPos());
193        Advance(1);
194        Scan_WS();
195        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
196        return AbsPos()+2;
197}
198
Note: See TracBrowser for help on using the repository browser.