source: trunk/src/symtab.c @ 174

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

Nmtokens.

File size: 14.7 KB
Line 
1#include "symtab.h"
2
3const int INIT_STRINGPOOL_SIZE = 4096;
4
5inline bool bit_test(unsigned char * bit_Map, int codepoint) {
6        return (bit_Map[codepoint/8] >> (7 - codepoint % 8)) & 1;
7}
8
9
10bool is_XML10_NameStrt_codepoint(int codepoint) {
11        switch (codepoint >> 12) {
12                case 0: return bit_test(NameStrt_XML10_0000_11FF, codepoint);
13                case 1: if (codepoint <= 0x11FF)
14                                return bit_test(NameStrt_XML10_0000_11FF, codepoint);
15                        else if (codepoint < 0x1E00) return false;
16                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
17                case 2: if (codepoint > 0x2182) return false;
18                        else return bit_test(NameStrt_XML10_2000_21FF, codepoint & 0x1FF);
19                case 3: if (codepoint > 0x312C) return false;
20                        else return bit_test(NameStrt_XML10_3000_31FF, codepoint & 0x1FF);
21                case 4: return codepoint >= 0x4E00;
22                case 5: case 6: case 7: case 8: return true;
23                case 9: return codepoint <= 0x9FA5;
24                case 0xA: return codepoint >= 0xAC00;
25                case 0xB: case 0xC: return true;
26                case 0xD: return codepoint <= 0xD7A3;
27                default: return false;
28        }
29}
30
31bool is_XML10_NameChar_codepoint(int codepoint) {
32        switch (codepoint >> 12) {
33                case 0: return bit_test(NameChar_XML10_0000_11FF, codepoint);
34                case 1: if (codepoint <= 0x11FF)
35                                return bit_test(NameChar_XML10_0000_11FF, codepoint);
36                        else if (codepoint < 0x1E00) return false;
37                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
38                case 2: if (codepoint > 0x2182) return false;
39                        else return bit_test(NameChar_XML10_2000_21FF, codepoint & 0x1FF);
40                case 3: if (codepoint > 0x312C) return false;
41                        else return bit_test(NameChar_XML10_3000_31FF, codepoint & 0x1FF);
42                case 4: return codepoint >= 0x4E00;
43                case 5: case 6: case 7: case 8: return true;
44                case 9: return codepoint <= 0x9FA5;
45                case 0xA:       return codepoint >= 0xAC00;
46                case 0xB: case 0xC: return true;
47                case 0xD: return codepoint <= 0xD7A3;
48                default: return false;
49        }
50}
51
52bool is_XML11_NameStrt_codepoint(int codepoint) {
53        if (likely(codepoint) <= 0x03FF) return bit_test(NameStrt_XML11_0000_03FF, codepoint);
54        else switch (codepoint >> 12) {
55                case 0: case 1: return true;
56                case 2: if (codepoint >= 0x2070) 
57                                if (codepoint <= 0x218F) return true;
58                                else return (codepoint >= 0x2C00) & (codepoint <= 0x2FEF);
59                        else return (codepoint >= 0x200C) & (codepoint <= 0x200D);
60                case 3: return codepoint >= 0x3001;
61                case 4: case 5: case 6: case 7: case 8: case 9: case 0xA: case 0xB: case 0xC: return true;
62                case 0xD: return codepoint <= 0xD7FF;
63                case 0xE: return false;
64                case 0xF: if (codepoint <= 0xFDCF) return codepoint >= 0xF900;
65                          else return (codepoint >= 0xFDF0) & (codepoint <= 0xFFFD);
66                default: return codepoint <= 0xEFFFF;
67        }
68}
69
70bool is_XML11_NameChar_codepoint(int codepoint) {
71        if (likely(codepoint) <= 0x03FF) return bit_test(NameChar_XML11_0000_03FF, codepoint);
72        else switch (codepoint >> 12) {
73                case 0: case 1: return true;
74                case 2: if (codepoint >= 0x2070) 
75                                if (codepoint <= 0x218F) return true;
76                                else return (codepoint >= 0x2C00) & (codepoint <= 0x2FEF);
77                        else if (codepoint <= 0x200D) return codepoint >= 0x200C;
78                        else return (codepoint == 0x203F) | (codepoint == 0x2040);
79                case 3: return codepoint >= 0x3001;
80                case 4: case 5: case 6: case 7: case 8: case 9: case 0xA: case 0xB: case 0xC: return true;
81                case 0xD: return codepoint <= 0xD7FF;
82                case 0xE: return false;
83                case 0xF: if (codepoint <= 0xFDCF) return codepoint >= 0xF900;
84                          else return (codepoint >= 0xFDF0) & (codepoint <= 0xFFFD);
85                default: return codepoint <= 0xEFFFF;
86        }
87}
88
89inline int XML_10_UTF8_NameStrt_bytes (unsigned char bytes[]) {
90        if (bytes[0] <= 0x7F) {
91                if (bit_test(NameStrt_XML10_0000_11FF, (int) bytes[0])) return 1;
92                else return 0;
93        }
94        else if (bytes[0] <= 0xDF) {
95                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
96                if (bit_test(NameStrt_XML10_0000_11FF, codepoint)) return 2;
97                else return 0;
98        }
99        else if (bytes[0] <= 0xEF) {
100                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
101                return is_XML10_NameStrt_codepoint(codepoint) ? 3 : 0;
102        }
103        else return 0;
104}
105
106inline int XML_10_UTF8_NameChar_bytes (unsigned char bytes[]) {
107        if (bytes[0] <= 0x7F) {
108                if (bit_test(NameChar_XML10_0000_11FF, (int) bytes[0])) return 1;
109                else return 0;
110        }
111        else if (bytes[0] <= 0xDF) {
112                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
113                if (bit_test(NameChar_XML10_0000_11FF, codepoint)) return 2;
114                else return 0;
115        }
116        else if (bytes[0] <= 0xEF) {
117                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
118                return is_XML10_NameChar_codepoint(codepoint) ? 3 : 0;
119        }
120        else return 0;
121}
122
123inline int XML_11_UTF8_NameStrt_bytes (unsigned char bytes[]) {
124        if (bytes[0] <= 0x7F) {
125                if (bit_test(NameStrt_XML11_0000_03FF, (int) bytes[0])) return 1;
126                else return 0;
127        }
128        else if (bytes[0] <= 0xDF) {
129                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
130                return is_XML11_NameStrt_codepoint(codepoint) ? 2 : 0;
131        }
132        else if (bytes[0] <= 0xEF) {
133                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
134                return is_XML11_NameStrt_codepoint(codepoint) ? 3 : 0;
135        }
136        else {
137                int codepoint = ((bytes[0] & 0x0F) << 18)| ((bytes[1] & 0x3F) << 12) | 
138                                ((bytes[2] & 0x3F) << 6) | (bytes[3] & 0x3F);
139                return is_XML11_NameStrt_codepoint(codepoint) ? 4 : 0;
140        }
141}
142
143inline int XML_11_UTF8_NameChar_bytes (unsigned char bytes[]) {
144        if (bytes[0] <= 0x7F) {
145                if (bit_test(NameChar_XML11_0000_03FF, (int) bytes[0])) return 1;
146                else return 0;
147        }
148        else if (bytes[0] <= 0xDF) {
149                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
150                return is_XML11_NameChar_codepoint(codepoint) ? 2 : 0;
151        }
152        else if (bytes[0] <= 0xEF) {
153                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
154                return is_XML11_NameChar_codepoint(codepoint) ? 3 : 0;
155        }
156        else {
157                int codepoint = ((bytes[0] & 0x0F) << 18)| ((bytes[1] & 0x3F) << 12) | 
158                                ((bytes[2] & 0x3F) << 6) | (bytes[3] & 0x3F);
159                return is_XML11_NameChar_codepoint(codepoint) ? 4 : 0;
160        }
161}
162
163bool is_XML10_UTF8_Name(char protoname[], int lgth) {
164        int valid_bytes = XML_10_UTF8_NameStrt_bytes((unsigned char *) protoname);
165        int pos = valid_bytes;
166        while ((valid_bytes > 0) & (pos < lgth)) {
167                valid_bytes = XML_10_UTF8_NameChar_bytes((unsigned char *) &protoname[pos]);
168                pos += valid_bytes;
169                 
170        }
171        /* Success requires that every byte sequence processed be valid
172           and that the total lgth processed be exactly that provided on
173           input. */
174         
175        return (valid_bytes > 0) & (pos == lgth);
176}
177
178bool is_XML11_UTF8_Name(char protoname[], int lgth) {
179        int valid_bytes = XML_11_UTF8_NameStrt_bytes((unsigned char *) protoname);
180        int pos = valid_bytes;
181        while ((valid_bytes > 0) & (pos < lgth)) {
182                valid_bytes = XML_11_UTF8_NameChar_bytes((unsigned char *) &protoname[pos]);
183                pos += valid_bytes;
184        }
185        /* Success requires that every byte sequence processed be valid
186           and that the total lgth processed be exactly that provided on
187           input. */
188        return (valid_bytes > 0) & (pos == lgth);
189}
190
191bool is_XML10_UTF8_Nmtoken(char prototoken[], int lgth) {
192        int valid_bytes = XML_10_UTF8_NameChar_bytes((unsigned char *) prototoken);
193        int pos = valid_bytes;
194        while ((valid_bytes > 0) & (pos < lgth)) {
195                valid_bytes = XML_10_UTF8_NameChar_bytes((unsigned char *) &prototoken[pos]);
196                pos += valid_bytes;
197                 
198        }
199        /* Success requires that every byte sequence processed be valid
200           and that the total lgth processed be exactly that provided on
201           input. */
202         
203        return (valid_bytes > 0) & (pos == lgth);
204}
205
206bool is_XML11_UTF8_Nmtoken(char prototoken[], int lgth) {
207        int valid_bytes = XML_11_UTF8_NameChar_bytes((unsigned char *) prototoken);
208        int pos = valid_bytes;
209        while ((valid_bytes > 0) & (pos < lgth)) {
210                valid_bytes = XML_11_UTF8_NameChar_bytes((unsigned char *) &prototoken[pos]);
211                pos += valid_bytes;
212        }
213        /* Success requires that every byte sequence processed be valid
214           and that the total lgth processed be exactly that provided on
215           input. */
216        return (valid_bytes > 0) & (pos == lgth);
217}
218
219int Symbol_Table::Insert_Name(char * name, int lgth) {
220//      char * s = copy_name(name,lgth);
221        char * s = pool->Insert(name,lgth);
222        UTF8NameMap[s]=++(globalNameCount);
223        Name_Data name_data;
224        name_data.name_string = s;
225        name_data.lgth = lgth;
226        UTF8NameTable.push_back(name_data);
227        return globalNameCount;
228}
229
230
231inline bool Verify_ASCII(char * name_ptr, int name_lgth) {
232        /* To verify that a name is ASCII, ensure that the high bit
233           of each byte is 0.  A SIMD compare can verify this for
234           up to sizeof(BytePack) bytes.  For less than 16 bytes,
235           first shift out bytes beyond the name length.  For more
236           than 16 bytes, form the logical "or" of the successive byte
237           packs together so that a high 1 bit in any byte is preserved
238           for the final SIMD test. */
239        BytePack b = sisd_load_unaligned((BytePack *) name_ptr);
240        if (name_lgth <= sizeof(BytePack)) {
241                /* Clear bytes beyond the length of the name. */
242                b = sisd_sfl(b, sisd_from_int(8 * (sizeof(BytePack) - name_lgth)));
243        } 
244        else {
245                int offset = name_lgth % sizeof(BytePack);
246                for (int i = offset; i < name_lgth; i += sizeof(BytePack)) {
247                        b = simd_or(sisd_load_unaligned((BytePack *) &name_ptr[i]),b);
248                }
249        }
250        return !simd_any_sign_bit_8(b);
251}
252
253
254/* ASCII_LookupOrInsert determines the nameID for any ASCII name
255from the global name table, inserting the name and allocating
256a nameID if necessary.  If the name is non-ASCII, 0 is returned. */
257
258inline int Symbol_Table::ASCII_Lookup_or_Insert_Name(char * name_ptr, int name_lgth) {
259
260        if (Verify_ASCII(name_ptr, name_lgth)) {
261                return UTF8_Lookup_or_Insert_Name(name_ptr, name_lgth);
262        }
263        return 0;
264}
265
266
267
268int Symbol_Table::UTF8_Lookup_or_Insert_Name(char * name, int lgth) {
269               
270        char delim = name[lgth];
271        name[lgth] = '\0';
272        int nameID = UTF8NameMap[name];
273        name[lgth] = delim;     
274       
275        if(nameID == 0){
276        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
277#ifdef EDITION5
278                if (!is_XML11_UTF8_Name(name,lgth))  {
279                        ShowSyntaxError(NT_Name);
280                        exit(-1);
281                }
282#endif
283#ifndef EDITION5
284                if (!is_XML10_UTF8_Name(name,lgth))  {
285                        if (version == XML_1_1) {
286                                if (!is_XML11_UTF8_Name(name,lgth))  {
287                                        ShowSyntaxError(NT_Name);
288                                        exit(-1);
289                                }
290                        }
291                        else {
292                                ShowSyntaxError(NT_Name);
293                                exit(-1);
294                        }
295                }
296#endif
297        #endif
298//              char * s = copy_name(name,lgth);
299                char * s = pool->Insert(name,lgth);
300                UTF8NameMap[s]=++(globalNameCount);
301                nameID = globalNameCount;
302                Name_Data name_data;
303                name_data.name_string = s;
304                name_data.lgth = lgth;
305                UTF8NameTable.push_back(name_data);
306//              UTF8NameTable.push_back(s);
307        }
308        return nameID;
309}
310
311//char * Symbol_Table::Get_UTF8_name(int nameID) {
312//      return  UTF8NameTable[nameID];
313//}
314
315char * Symbol_Table::Get_UTF8_name(int nameID) {
316        return  UTF8NameTable[nameID].name_string;
317}
318
319int Symbol_Table::Get_UTF8_lgth(int nameID) {
320        return  UTF8NameTable[nameID].lgth;
321}
322
323inline int Symbol_Table::ASCII_Lookup_or_Insert_Nmtoken(char * nmtoken_ptr, int name_lgth) {
324
325        if (Verify_ASCII(nmtoken_ptr, name_lgth)) {
326                return UTF8_Lookup_or_Insert_Nmtoken(nmtoken_ptr, name_lgth);
327        }
328        return 0;
329}
330
331
332int Symbol_Table::UTF8_Lookup_or_Insert_Nmtoken(char * nmtoken, int lgth) {
333               
334        char delim = nmtoken[lgth];
335        nmtoken[lgth] = '\0';
336        int nmtokenID = UTF8NmtokenMap[nmtoken];
337        nmtoken[lgth] = delim; 
338       
339        if(nmtokenID == 0){
340        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
341#ifdef EDITION5
342                if (!is_XML11_UTF8_Nmtoken(nmtoken,lgth))  {
343                        ShowSyntaxError(NT_Nmtoken);
344                        exit(-1);
345                }
346#endif
347#ifndef EDITION5
348                if (!is_XML10_UTF8_Nmtoken(nmtoken,lgth))  {
349                        if (version == XML_1_1) {
350                                if (!is_XML11_UTF8_Nmtoken(nmtoken,lgth))  {
351                                        ShowSyntaxError(NT_Nmtoken);
352                                        exit(-1);
353                                }
354                        }
355                        else {
356                                ShowSyntaxError(NT_Nmtoken);
357                                exit(-1);
358                        }
359                }
360#endif
361        #endif
362//              char * s = copy_name(name,lgth);
363                char * s = pool->Insert(nmtoken,lgth);
364                UTF8NmtokenMap[s]=++(globalNmtokenCount);
365                nmtokenID = globalNmtokenCount;
366                Name_Data nmtoken_data;
367                nmtoken_data.name_string = s;
368                nmtoken_data.lgth = lgth;
369                UTF8NmtokenTable.push_back(nmtoken_data);
370//              UTF8NameTable.push_back(s);
371        }
372        return nmtokenID;
373}
374
375
376
377
378char * Symbol_Table::Get_UTF8_nmtoken(int nmtokenID) {
379        return  UTF8NmtokenTable[nmtokenID].name_string;
380}
381
382int Symbol_Table::Get_UTF8_nmtoken_lgth(int nmtokenID) {
383        return  UTF8NmtokenTable[nmtokenID].lgth;
384}
385
386char * Symbol_Table::ReserveSymbolSpace(int u8_lgth) {
387        reserved = new char[u8_lgth+1];
388        reserved_lgth = u8_lgth;
389        return reserved;
390}
391
392int Symbol_Table::LookupOrInsertReserved(){             
393        int nameID = UTF8NameMap[reserved];
394        if(nameID == 0){
395        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
396                if (!is_XML10_UTF8_Name(reserved,reserved_lgth))  {
397                        ShowSyntaxError(NT_Name);
398                        exit(-1);
399                }
400        #endif
401                UTF8NameMap[reserved]=++(globalNameCount);
402                nameID = globalNameCount;
403                Name_Data name_data;
404                name_data.name_string = reserved;
405                name_data.lgth = reserved_lgth;
406                UTF8NameTable.push_back(name_data);
407//              UTF8NameTable.push_back(s);
408        }
409        else {
410                delete [] reserved;
411        }
412        return nameID;
413}
414
415int Symbol_Table::LookupOrInsertReserved_nmtoken(){             
416        int nmtokenID = UTF8NmtokenMap[reserved];
417        if(nmtokenID == 0){
418        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
419                if (!is_XML10_UTF8_Nmtoken(reserved,reserved_lgth))  {
420                        ShowSyntaxError(NT_Nmtoken);
421                        exit(-1);
422                }
423        #endif
424                UTF8NmtokenMap[reserved]=++(globalNmtokenCount);
425                nmtokenID = globalNmtokenCount;
426                Name_Data nmtoken_data;
427                nmtoken_data.name_string = reserved;
428                nmtoken_data.lgth = reserved_lgth;
429                UTF8NmtokenTable.push_back(nmtoken_data);
430        }
431        else {
432                delete [] reserved;
433        }
434        return nmtokenID;
435}
436
437Symbol_Table::Symbol_Table(){
438        globalNameCount = 0;
439        Name_Data name_data;
440        name_data.name_string = NULL;
441        name_data.lgth = 0;
442        UTF8NameTable.push_back(name_data);
443//      UTF8NameTable.push_back(NULL);
444/*      for (int i = 0; i < 5; i++) {
445                UTF8NameMap[predefined[i]] = ++(globalNameCount);
446                Name_Data name_data;
447                name_data.name_string = predefined[i];
448                name_data.lgth = strlen(predefined[i]);
449                UTF8NameTable.push_back(name_data);
450                printf("predefined name: %s, global name count: %d\n",predefined[i],globalNameCount);
451//              UTF8NameTable.push_back(predefined[i]);
452        }*/
453        pool = new StringPool;
454}
455
456
457StringPool::StringPool() {
458       buffer_capacity = INIT_STRINGPOOL_SIZE;
459       buffer_space_used = 0;
460       pool_buffers.push_back(new char [buffer_capacity]);
461}
462
463StringPool::~StringPool() {
464       vector<char * >::iterator i;
465       for (i = pool_buffers.begin(); i != pool_buffers.end(); i++) {
466               delete [] *i;
467       }
468}
469
470char * StringPool::Insert(char * s, int lgth) {
471       while (lgth + buffer_space_used >= buffer_capacity) {
472               buffer_capacity *= 2;
473               pool_buffers.push_back(new char [buffer_capacity]);
474               buffer_space_used = 0;
475       }
476       char * insertion_ptr = &pool_buffers.back()[buffer_space_used];
477       memcpy(insertion_ptr, s, lgth);
478       insertion_ptr[lgth] = '\0';
479       buffer_space_used += lgth + 1;
480       return insertion_ptr;
481}
482
483
484
Note: See TracBrowser for help on using the repository browser.