source: trunk/src/xmldecl.c @ 162

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

Fix WhiteSpace? processing for EBCDIC as well as ASCII.

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 "xml_error.h"
16#include "multiliteral.h"
17#include "bytelex.h"
18#include "xmlmodel.h"
19
20template <CodeUnit_Base C>
21XML_Decl_Parser<C>::XML_Decl_Parser(Byteplex * b){
22        byteplex = b;
23        buffer_base_pos = 0;
24        x8data = (unsigned char *) byteplex->x8data;
25}
26
27template <CodeUnit_Base C>
28XML_Decl_Parser<C>::~XML_Decl_Parser(){
29}
30
31template <CodeUnit_Base C>
32inline int XML_Decl_Parser<C>::AbsPos() const {
33        return  buffer_base_pos + buffer_rel_pos;
34}
35
36template <CodeUnit_Base C>
37inline unsigned char * XML_Decl_Parser<C>::cur() const {
38        return &x8data[buffer_rel_pos];
39}
40
41template <CodeUnit_Base C>
42inline void XML_Decl_Parser<C>::Advance(int n) {
43        buffer_rel_pos += n;
44        if (buffer_rel_pos >= BYTEPLEX_SIZE) {
45                 byteplex->AdvanceInputBuffer(BYTEPLEX_SIZE);
46        }
47}
48
49template <CodeUnit_Base C>
50inline void XML_Decl_Parser<C>::Scan_WS() {
51        while (at_WhiteSpace_10<C>(cur())) Advance(1);
52}
53
54template <CodeUnit_Base C>
55inline void XML_Decl_Parser<C>::ScanToQuote() {
56        int quote_start_pos = buffer_rel_pos;   
57        while (!AtQuote<C>(cur())) buffer_rel_pos+=1;
58        if (buffer_rel_pos >= BYTEPLEX_SIZE) {
59                byteplex->AdvanceInputBuffer(quote_start_pos);
60                buffer_rel_pos -= quote_start_pos;
61                buffer_base_pos += quote_start_pos;
62                while (!AtQuote<C>(cur())) buffer_rel_pos+=1;
63                if (buffer_rel_pos >= BYTEPLEX_SIZE) {
64                        ImplementationLimitError("Encoding name exceeds BYTEPLEX_SIZE");
65                }
66        }
67}
68
69template <CodeUnit_Base C>
70int XML_Decl_Parser<C>::EncodingAction(Entity_Info *e, int start_pos, int end_pos) {
71        e->encoding = (unsigned char *) malloc(end_pos-start_pos+1);
72        memcpy(e->encoding, &x8data[start_pos-buffer_base_pos], end_pos - start_pos);
73        e->encoding[end_pos - start_pos] = '\0';
74}
75//
76template <CodeUnit_Base C>
77void XML_Decl_Parser<C>::ReadXMLInfo(Entity_Info *e) {
78        e->version = no_XML_version_value;
79        e->has_encoding_decl = false;
80        e->standalone = Standalone_no_value;
81        buffer_rel_pos = e->BOM_units;
82        // It is possible that there is no XML declaration.
83        if (!at_XmlDecl_start<C>(cur())) {
84                e->content_start = AbsPos();
85                return;
86        }
87        // Otherwise, the XML declaration exists and must have
88        // at least version information.
89        Advance(6);
90        Scan_WS();
91        if (!at_version<C>(cur())) DeclarationError(AbsPos());
92        Advance(7);
93        Scan_WS();
94        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
95        Advance(1);
96        Scan_WS();
97        if (at_1_0<C>(cur())) e->version = XML_1_0;
98        else if (at_1_1<C>(cur())) e->version = XML_1_1;
99        else DeclarationError(AbsPos());
100        Advance(5);
101        if (at_PI_End<C>(cur())) {
102                e->content_start = AbsPos()+2;
103                return;
104        }
105        if (!at_WhiteSpace_10<C>(cur())) DeclarationError(AbsPos());
106        Scan_WS();
107        if (at_encoding<C>(cur())) {
108                e->has_encoding_decl = true;
109                Advance(8);
110                Scan_WS();
111                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
112                Advance(1);
113                Scan_WS();
114                if (AtQuote<C>(cur())) {
115                        unsigned char quoteCh = cur()[0];
116                        Advance(1);
117                        int encoding_start_pos = AbsPos();
118                        ScanToQuote();
119                        if (cur()[0] != quoteCh) DeclarationError(AbsPos());
120                        EncodingAction(e, encoding_start_pos, AbsPos());
121                }
122                else DeclarationError(AbsPos());
123                Advance(1);
124                if (at_PI_End<C>(cur())) {
125                        e->content_start = AbsPos()+2;
126                        return;
127                }
128                if (!at_WhiteSpace_10<C>(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); e->standalone = Standalone_yes;}
138                else if (at_no<C>(cur())) {Advance(4); e->standalone = Standalone_no;}
139                else DeclarationError(AbsPos());
140                Scan_WS();
141        }
142        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
143        e->content_start = 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>
151void XML_Decl_Parser<C>::ReadTextDeclaration(Entity_Info *e) {
152        e->version = no_XML_version_value;
153        e->has_encoding_decl = false;
154        e->standalone = Standalone_no_value;
155        buffer_rel_pos = e->BOM_units;
156        // It is possible that there is no XML declaration.
157        if (!at_XmlDecl_start<C>(cur())) {
158                e->content_start = AbsPos();
159                return;
160        }
161        // Otherwise, the text declaration exists and may have
162        // version information.
163        Advance(6);
164        Scan_WS();
165        if (at_version<C>(cur())) {
166                Advance(7);
167                Scan_WS();
168                if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
169                Advance(1);
170                Scan_WS();
171                if (at_1_0<C>(cur())) e->version = XML_1_0;
172                else if (at_1_1<C>(cur())) e->version = XML_1_1;
173                else DeclarationError(AbsPos());
174                Advance(5);
175                // Must have whitespace character before declaration.
176                if (!at_WhiteSpace_10<C>(cur())) DeclarationError(AbsPos());
177                Scan_WS();
178        }
179        if (!at_encoding<C>(cur())) DeclarationError(AbsPos());
180        e->has_encoding_decl = true;
181        Advance(8);
182        Scan_WS();
183        if (!AtChar<C,'='>(cur())) DeclarationError(AbsPos());
184        Advance(1);
185        Scan_WS();
186        if (AtQuote<C>(cur())) {
187                unsigned char quoteCh = cur()[0];
188                Advance(1);
189                int encoding_start_pos = AbsPos();
190                ScanToQuote();
191                if (cur()[0] != quoteCh) DeclarationError(AbsPos());
192                EncodingAction(e, encoding_start_pos, AbsPos());
193        }
194        else DeclarationError(AbsPos());
195        Advance(1);
196        Scan_WS();
197        if (!at_PI_End<C>(cur())) DeclarationError(AbsPos());
198        e->content_start = AbsPos()+2;
199}
200
Note: See TracBrowser for help on using the repository browser.