source: trunk/src/xmldecl.c @ 85

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

EncodingAction?: void return type; lgth calc.

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>
76void XML_Decl_Parser<C>::EncodingAction(Model_Info * m, int start_pos, int end_pos) {
77        int encoding_lgth = end_pos-start_pos;
78        m->encoding = (unsigned char *) malloc(encoding_lgth+1);
79        memcpy(m->encoding, &x8data[start_pos-buffer_base_pos], encoding_lgth);
80        m->encoding[encoding_lgth] = '\0';
81}
82//
83template <CodeUnit_Base C>
84int XML_Decl_Parser<C>::ReadXMLInfo(Model_Info * m) {
85        m->version = no_XML_version_value;
86        m->has_encoding_decl = false;
87        m->standalone = Standalone_no_value;
88        buffer_rel_pos = m->BOM_units;
89        // It is possible that there is no XML declaration.
90        if (!at_XmlDecl_start<C>(cur())) {
91                return AbsPos();
92        }
93        // Otherwise, the XML declaration exists and must have
94        // at least version information.
95        Advance(6);
96        Scan_WS();
97        if (!at_version<C>(cur())) DeclarationError(AbsPos());
98        Advance(7);
99        Scan_WS();
100        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
101        Advance(1);
102        Scan_WS();
103        if (at_1_0<C>(cur())) m->version = XML_1_0;
104        else if (at_1_1<C>(cur())) m->version = XML_1_1;
105        else DeclarationError(AbsPos());
106        Advance(5);
107        if (at_PI_End<C>(cur())) return AbsPos()+2;
108        if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
109        Scan_WS();
110        if (at_encoding<C>(cur())) {
111                m->has_encoding_decl = true;
112                Advance(8);
113                Scan_WS();
114                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
115                Advance(1);
116                Scan_WS();
117                if (AtQuote<C>(cur())) {
118                        unsigned char quoteCh = cur()[0];
119                        Advance(1);
120                        int encoding_start_pos = AbsPos();
121                        ScanToQuote();
122                        if (cur()[0] != quoteCh) DeclarationError(AbsPos());
123                        EncodingAction(m, encoding_start_pos, AbsPos());
124                }
125                else DeclarationError(AbsPos());
126                Advance(1);
127                if (at_PI_End<C>(cur())) return AbsPos()+2;
128                if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
129                Scan_WS();
130        }
131        if (at_standalone<C>(cur())) {
132                Advance(10);
133                Scan_WS();
134                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
135                Advance(1);
136                Scan_WS();
137                if (at_yes<C>(cur())) {Advance(5); m->standalone = Standalone_yes;}
138                else if (at_no<C>(cur())) {Advance(4); m->standalone = Standalone_no;}
139                else DeclarationError(AbsPos());
140                Scan_WS();
141        }
142        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
143        return AbsPos()+2;
144}
145
146// Similar to reading the XML_declaration of the document entity,
147// ReadTextDeclaration reads the text declaration of an external
148// parsed entity.  This is not really needed at present, for DTDless
149// processing.
150template <CodeUnit_Base C>
151int XML_Decl_Parser<C>::ReadTextDeclaration(Model_Info * m) {
152        m->version = no_XML_version_value;
153        m->has_encoding_decl = false;
154        m->standalone = Standalone_no_value;
155        buffer_rel_pos = m->BOM_units;
156        // It is possible that there is no XML declaration.
157        if (!at_XmlDecl_start<C>(cur())) {
158                return AbsPos();
159        }
160        // Otherwise, the text declaration exists and may have
161        // version information.
162        Advance(6);
163        Scan_WS();
164        if (at_version<C>(cur())) {
165                Advance(7);
166                Scan_WS();
167                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
168                Advance(1);
169                Scan_WS();
170                if (at_1_0<C>(cur())) m->version = XML_1_0;
171                else if (at_1_1<C>(cur())) m->version = XML_1_1;
172                else DeclarationError(AbsPos());
173                Advance(5);
174                // Must have whitespace character before declaration.
175                if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) DeclarationError(AbsPos());
176                Scan_WS();
177        }
178        if (!at_encoding<C>(cur())) DeclarationError(AbsPos());
179        m->has_encoding_decl = true;
180        Advance(8);
181        Scan_WS();
182        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
183        Advance(1);
184        Scan_WS();
185        if (AtQuote<C>(cur())) {
186                unsigned char quoteCh = cur()[0];
187                Advance(1);
188                int encoding_start_pos = AbsPos();
189                ScanToQuote();
190                if (cur()[0] != quoteCh) DeclarationError(AbsPos());
191                EncodingAction(m, encoding_start_pos, AbsPos());
192        }
193        else DeclarationError(AbsPos());
194        Advance(1);
195        Scan_WS();
196        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
197        return AbsPos()+2;
198}
199
Note: See TracBrowser for help on using the repository browser.