source: trunk/src/bytelex.h @ 124

Last change on this file since 124 was 124, checked in by lindanl, 11 years ago

Name checking and other well-formedness checking.

File size: 13.8 KB
Line 
1/*  bytelex.h - XML lexical recognizers for pseudo-ASCII or
2    EBCDIC-family byte streams
3    Copyright (c) 2008, Robert D. Cameron.
4    Licensed to the public under the Open Software License 3.0.
5    Licensed to International Characters, Inc., under the Academic
6    Free License 3.0.
7*/
8#ifndef BYTELEX_H
9#define BYTELEX_H
10
11#include "xmlmodel.h"
12#include "multiliteral.h"
13
14template<CodeUnit_Base C, unsigned char c>
15inline bool AtChar(unsigned char x8data[]) {
16  return x8data[0] == Ord<C, c>::value;
17}
18
19template<CodeUnit_Base C>
20inline bool AtQuote(unsigned char x8data[]) {
21  return (x8data[0] == Ord<C, '"'>::value) | (x8data[0] == Ord<C, '\''>::value);
22}
23
24// Whitespace recognition.  This varies between XML 1.0 and
25// XML 1.1, but only the XML 1.0 version is needed.
26// Specific ASCII/EBCDIC versions are hard-coded here, because
27// the Ord metafunction currently only works for printable characters.
28// Could be improved. 
29template<XML_version, CodeUnit_Base C>
30inline bool at_WhiteSpace(unsigned char x8data[]);
31
32// Workaround because we lack function partial specialization.
33template<CodeUnit_Base C>
34inline bool at_WhiteSpace_10(unsigned char x8data[]) {
35  unsigned char ch = x8data[0];
36  return (ch == Ord<C, ' '>::value) || 
37         (ch == LF<C>::value) || (ch == LF<C>::value) || (ch == HT<C>::value);
38}
39
40template<>
41inline bool at_WhiteSpace<XML_1_0, ASCII>(unsigned char x8data[]) {
42        return at_WhiteSpace_10<ASCII>(x8data);
43}
44
45template<>
46inline bool at_WhiteSpace<XML_1_0, EBCDIC>(unsigned char x8data[]) {
47        return at_WhiteSpace_10<EBCDIC>(x8data);
48}
49
50template<CodeUnit_Base C>
51inline bool at_EndTag_Start(unsigned char x8data[]) {
52  return s2int16(x8data) == c2int16<C, '<', '/'>::value;
53}
54
55template<CodeUnit_Base C>
56inline bool at_Comment_Start(unsigned char x8data[]) {
57  return s4int32(x8data) == c4int32<C, '<', '!', '-', '-'>::value;
58}
59
60template<CodeUnit_Base C>
61inline bool at_DoubleHyphen(unsigned char x8data[]) {
62  return s2int16(x8data) == c2int16<C, '-', '-'>::value;
63}
64
65template<CodeUnit_Base C>
66inline bool at_Comment_End(unsigned char x8data[]) {
67  return s3int32(x8data) == c3int32<C, '-', '-', '>'>::value;
68}
69
70template<CodeUnit_Base C>
71inline bool at_CDATA_Start(unsigned char x8data[]) {
72  return s8int64(x8data) == 
73         c8int64<C, '<', '!', '[', 'C', 'D', 'A', 'T', 'A'>::value;
74}
75
76template<CodeUnit_Base C>
77inline bool at_CDATA_End(unsigned char x8data[]) {
78  return s3int32(x8data) == c3int32<C, ']', ']', '>'>::value;
79}
80
81template<CodeUnit_Base C>
82inline bool at_PI_Start(unsigned char x8data[]) {
83  return s2int16(x8data) == c2int16<C, '<', '?'>::value;
84}
85
86template<CodeUnit_Base C>
87inline bool at_PI_End(unsigned char x8data[]) {
88  return s2int16(x8data) == c2int16<C, '?', '>'>::value;
89}
90
91template<CodeUnit_Base C>
92inline bool at_CharRef_Start(unsigned char x8data[]) {
93  return s2int16(x8data) == c2int16<C, '&', '#'>::value;
94}
95
96
97template<CodeUnit_Base C>
98inline bool at_EqualsQuote(unsigned char x8data[]) {
99  uint16_t EQ = s2int16(x8data);
100  return (EQ == c2int16<C, '=', '"'>::value) | (EQ == c2int16<C, '=', '\''>::value);
101}
102
103template<CodeUnit_Base C>
104inline bool at_xmlns(unsigned char x8data[]) {
105  return s5int64(x8data) == c5int64<C, 'x', 'm', 'l', 'n', 's'>::value; 
106}
107
108template<CodeUnit_Base C>
109inline bool at_EmptyElementDelim(unsigned char x8data[]) {
110  return s2int16(x8data) == c2int16<C, '/', '>'>::value;
111}
112
113template<CodeUnit_Base C>
114inline bool at_XmlDecl_start(unsigned char x8data[]) {
115  return (s5int64(x8data) == c5int64<C, '<', '?', 'x', 'm', 'l'>::value) &&
116         at_WhiteSpace<XML_1_0, C>(&x8data[5]);
117}
118
119template<CodeUnit_Base C>
120inline bool at_version(unsigned char x8data[]) {
121  return s7int64(x8data) == c7int64<C, 'v', 'e', 'r', 's', 'i', 'o', 'n'>::value;
122}
123
124template<CodeUnit_Base C>
125inline bool at_1_0(unsigned char x8data[]) {
126  return (s5int64(x8data) == c5int64<C, '"', '1', '.', '0', '"'>::value) ||
127         (s5int64(x8data) == c5int64<C, '\'', '1', '.', '0', '\''>::value);
128}
129
130template<CodeUnit_Base C>
131inline bool at_1_1(unsigned char x8data[]) {
132  return (s5int64(x8data) == c5int64<C, '"', '1', '.', '1', '"'>::value) ||
133         (s5int64(x8data) == c5int64<C, '\'', '1', '.', '1', '\''>::value);
134}
135
136template<CodeUnit_Base C>
137inline bool at_encoding(unsigned char x8data[]) {
138  return s8int64(x8data) == c8int64<C, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g'>::value;
139}
140
141template<CodeUnit_Base C>
142inline bool at_standalone(unsigned char x8data[]) {
143  return (s8int64(x8data) == c8int64<C, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o'>::value) &
144         (s2int16(&x8data[8]) == c2int16<C, 'n', 'e'>::value);
145}
146
147template<CodeUnit_Base C>
148inline bool at_yes(unsigned char x8data[]) {
149  return (s5int64(x8data) == c5int64<C, '"', 'y', 'e', 's', '"'>::value) |
150         (s5int64(x8data) == c5int64<C, '\'', 'y', 'e', 's', '\''>::value);
151}
152
153template<CodeUnit_Base C>
154inline bool at_no(unsigned char x8data[]) {
155  return (s4int32(x8data) == c4int32<C, '"', 'n', 'o', '"'>::value) |
156         (s4int32(x8data) == c4int32<C, '\'', 'n', 'o', '\''>::value);
157}
158
159template<CodeUnit_Base C>
160inline bool at_XxMmLll(unsigned char x8data[]) {
161  return caseless_comp<C, 'x', 'm', 'l'>(x8data);
162}
163
164/* The at_ElementTag_Start recognizer rules out '<!', '<?', '</'
165   combinations while returning true for '<' followed by any NameStrt
166   character.
167*/
168template<CodeUnit_Base C>
169inline bool at_ElementTag_Start(unsigned char x8data[]) {
170  return (x8data[0] == Ord<C, '<'>::value) & (x8data[1] != Ord<C, '!'>::value) &
171         (x8data[1] != Ord<C, '?'>::value) & (x8data[1] != Ord<C, '/'>::value);
172}
173
174/* The following ugly hack optimizes for ASCII. */
175template<>
176inline bool at_ElementTag_Start<ASCII>(unsigned char x8data[]) {
177  return (x8data[0] == Ord<ASCII, '<'>::value) &
178         ((x8data[1] & 0xE1) != 0x21);
179}
180
181
182inline bool at_UTF_8(unsigned char x8data[]) {
183  return caseless_comp<ASCII, 'u', 't', 'f', '-', '8'>(x8data);
184}
185
186inline bool at_UCS_2(unsigned char x8data[]) {
187  return caseless_comp<ASCII, 'u', 'c', 's', '-', '2'>(x8data);
188}
189
190inline bool at_UCS_4(unsigned char x8data[]) {
191  return caseless_comp<ASCII, 'u', 'c', 's', '-', '4'>(x8data);
192}
193
194inline bool at_UCS_2LE(unsigned char x8data[]) {
195  return caseless_comp<ASCII, 'u', 'c', 's', '-', '2', 'l', 'e'>(x8data);
196}
197
198inline bool at_UCS_2BE(unsigned char x8data[]) {
199  return caseless_comp<ASCII, 'u', 'c', 's', '-', '2', 'b', 'e'>(x8data);
200}
201
202inline bool at_UCS_4LE(unsigned char x8data[]) {
203  return caseless_comp<ASCII, 'u', 'c', 's', '-', '4', 'l', 'e'>(x8data);
204}
205
206inline bool at_UCS_4BE(unsigned char x8data[]) {
207  return caseless_comp<ASCII, 'u', 'c', 's', '-', '4', 'b', 'e'>(x8data);
208}
209
210inline bool at_UTF_16(unsigned char x8data[]) {
211  return caseless_comp<ASCII, 'u', 't', 'f', '-', '1', '6'>(x8data);
212}
213
214inline bool at_UTF_32(unsigned char x8data[]) {
215  return caseless_comp<ASCII, 'u', 't', 'f', '-', '3', '2'>(x8data);
216}
217
218inline bool at_UTF_16LE(unsigned char x8data[]) {
219  return caseless_comp<ASCII, 'u', 't', 'f', '-', '1', '6', 'l', 'e'>(x8data);
220}
221
222inline bool at_UTF_32LE(unsigned char x8data[]) {
223  return caseless_comp<ASCII, 'u', 't', 'f', '-', '3', '2', 'l', 'e'>(x8data);
224}
225
226inline bool at_UTF_16BE(unsigned char x8data[]) {
227  return caseless_comp<ASCII, 'u', 't', 'f', '-', '1', '6', 'b', 'e'>(x8data);
228}
229
230inline bool at_UTF_32BE(unsigned char x8data[]) {
231  return caseless_comp<ASCII, 'u', 't', 'f', '-', '3', '2', 'b', 'e'>(x8data);
232}
233
234inline bool at_ASCII(unsigned char x8data[]) {
235  return caseless_comp<ASCII, 'a', 's', 'c', 'i', 'i'>(x8data);
236}
237
238inline bool at_Latin1(unsigned char x8data[]) {
239  return caseless_comp<ASCII, 'l', 'a', 't', 'i', 'n', '1'>(x8data);
240}
241
242inline bool at_EBCDIC(unsigned char x8data[]) {
243  return caseless_comp<EBCDIC, 'e', 'b', 'c', 'd', 'i', 'c'>(x8data);
244}
245
246template<CodeUnit_Base C>
247inline bool at_DOCTYPE_start(unsigned char x8data[]) {
248        return s8int64(x8data) == c8int64<C, '<', '!','D', 'O', 'C', 'T', 'Y', 'P'>::value & AtChar<C,'E'>(&x8data[8]);
249}
250
251template<CodeUnit_Base C>
252inline bool at_SYSTEM(unsigned char x8data[]) {
253        return s6int64(x8data) == c6int64<C, 'S', 'Y', 'S', 'T', 'E', 'M'>::value;
254}
255
256template<CodeUnit_Base C>
257inline bool at_PUBLIC(unsigned char x8data[]) {
258        return s6int64(x8data) == c6int64<C, 'P', 'U', 'B', 'L', 'I', 'C'>::value;
259}
260
261template<CodeUnit_Base C>
262inline bool at_ELEMENT(unsigned char x8data[]) {
263        return s7int64(x8data) == c7int64<C, 'E', 'L', 'E', 'M', 'E', 'N', 'T'>::value;
264}
265
266template<CodeUnit_Base C>
267inline bool at_ATTLIST(unsigned char x8data[]) {
268        return s7int64(x8data) == c7int64<C, 'A', 'T', 'T', 'L', 'I', 'S', 'T'>::value;
269}
270
271template<CodeUnit_Base C>
272inline bool at_ENTITY(unsigned char x8data[]) {
273        return s6int64(x8data) == c6int64<C, 'E', 'N', 'T', 'I', 'T', 'Y'>::value;
274}
275
276template<CodeUnit_Base C>
277inline bool at_NOTATION(unsigned char x8data[]) {
278        return s8int64(x8data) == c8int64<C, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N'>::value;
279}
280
281template<CodeUnit_Base C>
282inline bool at_EMPTY(unsigned char x8data[]) {
283        return s5int64(x8data) == c5int64<C, 'E', 'M', 'P', 'T', 'Y'>::value;
284}
285
286template<CodeUnit_Base C>
287inline bool at_PCDATA(unsigned char x8data[]) {
288        return s7int64(x8data) == c7int64<C, '#', 'P', 'C', 'D', 'A', 'T', 'A'>::value;
289}
290
291template<CodeUnit_Base C>
292inline bool at_Para_star(unsigned char x8data[]) {
293        return s2int16(x8data) == c2int16<C, ')', '*'>::value;
294}
295
296template<CodeUnit_Base C>
297inline bool at_CDATA(unsigned char x8data[]) {
298        return s5int64(x8data) == c5int64<C, 'C', 'D', 'A', 'T', 'A'>::value;
299}
300
301template<CodeUnit_Base C>
302inline bool at_ID(unsigned char x8data[]) {
303        return s2int16(x8data) == c2int16<C, 'I', 'D'>::value;
304}
305
306template<CodeUnit_Base C>
307inline bool at_IDREF(unsigned char x8data[]) {
308        return s5int64(x8data) == c5int64<C, 'I', 'D', 'R', 'E', 'F'>::value;
309}
310
311template<CodeUnit_Base C>
312inline bool at_NDATA(unsigned char x8data[]) {
313        return s5int64(x8data) == c5int64<C, 'N', 'D', 'A', 'T', 'A'>::value;
314}
315
316template<CodeUnit_Base C>
317inline bool at_IDREFS(unsigned char x8data[]) {
318        return s6int64(x8data) == c6int64<C, 'I', 'D', 'R', 'E', 'F', 'S'>::value;
319}
320
321template<CodeUnit_Base C>
322inline bool at_ENTITIES(unsigned char x8data[]) {
323        return s8int64(x8data) == c8int64<C, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S'>::value;
324}
325
326template<CodeUnit_Base C>
327inline bool at_NMTOKEN(unsigned char x8data[]) {
328        return s7int64(x8data) == c7int64<C, 'N', 'M', 'T', 'O', 'K', 'E', 'N'>::value;
329}
330
331template<CodeUnit_Base C>
332inline bool at_NMTOKENS(unsigned char x8data[]) {
333        return s8int64(x8data) == c8int64<C, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S'>::value;
334}
335
336template<CodeUnit_Base C>
337inline bool at_REQUIRED(unsigned char x8data[]) {
338        return s8int64(x8data) == c8int64<C, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E'>::value
339          & AtChar<C,'D'>(&x8data[8]);
340}
341
342template<CodeUnit_Base C>
343inline bool at_IMPLIED(unsigned char x8data[]) {
344        return s8int64(x8data) == c8int64<C, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D'>::value;
345}
346
347template<CodeUnit_Base C>
348inline bool at_FIXED(unsigned char x8data[]) {
349        return s6int64(x8data) == c6int64<C, '#', 'F', 'I', 'X', 'E', 'D'>::value;
350}
351
352template<CodeUnit_Base C>
353inline bool at_ANY(unsigned char x8data[]) {
354        return s3int32(x8data) == c3int32<C, 'A', 'N', 'Y'>::value;
355}
356
357template<CodeUnit_Base C>
358inline bool at_INCLUDE(unsigned char x8data[]) {
359        return s7int64(x8data) == c7int64<C, 'I', 'N', 'C', 'L', 'U', 'D', 'E'>::value;
360}
361
362template<CodeUnit_Base C>
363inline bool at_IGNORE(unsigned char x8data[]) {
364        return s6int64(x8data) == c6int64<C, 'I', 'G', 'N', 'O', 'R', 'E'>::value;
365}
366
367template<CodeUnit_Base C>
368inline bool at_condSect_start(unsigned char x8data[]) {
369        return s3int32(x8data) == c3int32<C, '<', '!', '['>::value;
370}
371
372template<CodeUnit_Base C>
373inline bool at_xml(unsigned char x8data[]) { 
374  return (s4int32(x8data) == c4int32<C, '?', 'x', 'm', 'l'>::value);
375}
376
377template<CodeUnit_Base C>
378inline bool at_PubidChar(unsigned char x8data[]) {
379        switch (x8data[0]) {
380                case Ord<C, '0'>::value: case Ord<C, '1'>::value: 
381                case Ord<C, '2'>::value: case Ord<C, '3'>::value: 
382                case Ord<C, '4'>::value: case Ord<C, '5'>::value:
383                case Ord<C, '6'>::value: case Ord<C, '7'>::value:
384                case Ord<C, '8'>::value: case Ord<C, '9'>::value:
385                case Ord<C, 'A'>::value: case Ord<C, 'a'>::value:
386                case Ord<C, 'B'>::value: case Ord<C, 'b'>::value:
387                case Ord<C, 'C'>::value: case Ord<C, 'c'>::value:
388                case Ord<C, 'D'>::value: case Ord<C, 'd'>::value:
389                case Ord<C, 'E'>::value: case Ord<C, 'e'>::value:
390                case Ord<C, 'F'>::value: case Ord<C, 'f'>::value:
391                case Ord<C, 'G'>::value: case Ord<C, 'g'>::value:
392                case Ord<C, 'H'>::value: case Ord<C, 'h'>::value:
393                case Ord<C, 'I'>::value: case Ord<C, 'i'>::value:
394                case Ord<C, 'J'>::value: case Ord<C, 'j'>::value:
395                case Ord<C, 'K'>::value: case Ord<C, 'k'>::value:
396                case Ord<C, 'L'>::value: case Ord<C, 'l'>::value:
397                case Ord<C, 'M'>::value: case Ord<C, 'm'>::value:
398                case Ord<C, 'N'>::value: case Ord<C, 'n'>::value:
399                case Ord<C, 'O'>::value: case Ord<C, 'o'>::value:
400                case Ord<C, 'P'>::value: case Ord<C, 'p'>::value:
401                case Ord<C, 'Q'>::value: case Ord<C, 'q'>::value:
402                case Ord<C, 'R'>::value: case Ord<C, 'r'>::value:
403                case Ord<C, 'S'>::value: case Ord<C, 's'>::value:
404                case Ord<C, 'T'>::value: case Ord<C, 't'>::value:
405                case Ord<C, 'U'>::value: case Ord<C, 'u'>::value:
406                case Ord<C, 'V'>::value: case Ord<C, 'v'>::value:
407                case Ord<C, 'W'>::value: case Ord<C, 'w'>::value:
408                case Ord<C, 'X'>::value: case Ord<C, 'x'>::value:
409                case Ord<C, 'Y'>::value: case Ord<C, 'y'>::value:
410                case Ord<C, 'Z'>::value: case Ord<C, 'z'>::value:
411                case Ord<C, '-'>::value: case Ord<C, '\''>::value:
412                case Ord<C, '('>::value: case Ord<C, ')'>::value:
413                case Ord<C, '+'>::value: case Ord<C, ','>::value:
414                case Ord<C, '.'>::value: case Ord<C, '/'>::value:
415                case Ord<C, ':'>::value: case Ord<C, '='>::value:
416                case Ord<C, '?'>::value: case Ord<C, ';'>::value:
417                case Ord<C, '!'>::value: case Ord<C, '*'>::value:
418                case Ord<C, '#'>::value: case Ord<C, '@'>::value:
419                case Ord<C, '$'>::value: case Ord<C, '_'>::value:
420                case Ord<C, '%'>::value: case Ord<C, ' '>::value:
421                case CR<C>::value: case LF<C>::value:
422                        return true;
423                default: return false;
424        }
425}
426#endif
Note: See TracBrowser for help on using the repository browser.