source: trunk/src/symtab.c @ 179

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

Templated SIMD Library - initial version

File size: 14.8 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#ifdef TEMPLATED_SIMD_LIB
251        return !simd_any_sign_bit<8>(b);
252#endif
253#ifndef TEMPLATED_SIMD_LIB
254        return !simd_any_sign_bit_8(b);
255#endif
256}
257
258
259/* ASCII_LookupOrInsert determines the nameID for any ASCII name
260from the global name table, inserting the name and allocating
261a nameID if necessary.  If the name is non-ASCII, 0 is returned. */
262
263inline int Symbol_Table::ASCII_Lookup_or_Insert_Name(char * name_ptr, int name_lgth) {
264
265        if (Verify_ASCII(name_ptr, name_lgth)) {
266                return UTF8_Lookup_or_Insert_Name(name_ptr, name_lgth);
267        }
268        return 0;
269}
270
271
272
273int Symbol_Table::UTF8_Lookup_or_Insert_Name(char * name, int lgth) {
274               
275        char delim = name[lgth];
276        name[lgth] = '\0';
277        int nameID = UTF8NameMap[name];
278        name[lgth] = delim;     
279       
280        if(nameID == 0){
281        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
282#ifdef EDITION5
283                if (!is_XML11_UTF8_Name(name,lgth))  {
284                        ShowSyntaxError(NT_Name);
285                        exit(-1);
286                }
287#endif
288#ifndef EDITION5
289                if (!is_XML10_UTF8_Name(name,lgth))  {
290                        if (version == XML_1_1) {
291                                if (!is_XML11_UTF8_Name(name,lgth))  {
292                                        ShowSyntaxError(NT_Name);
293                                        exit(-1);
294                                }
295                        }
296                        else {
297                                ShowSyntaxError(NT_Name);
298                                exit(-1);
299                        }
300                }
301#endif
302        #endif
303//              char * s = copy_name(name,lgth);
304                char * s = pool->Insert(name,lgth);
305                UTF8NameMap[s]=++(globalNameCount);
306                nameID = globalNameCount;
307                Name_Data name_data;
308                name_data.name_string = s;
309                name_data.lgth = lgth;
310                UTF8NameTable.push_back(name_data);
311//              UTF8NameTable.push_back(s);
312        }
313        return nameID;
314}
315
316//char * Symbol_Table::Get_UTF8_name(int nameID) {
317//      return  UTF8NameTable[nameID];
318//}
319
320char * Symbol_Table::Get_UTF8_name(int nameID) {
321        return  UTF8NameTable[nameID].name_string;
322}
323
324int Symbol_Table::Get_UTF8_lgth(int nameID) {
325        return  UTF8NameTable[nameID].lgth;
326}
327
328inline int Symbol_Table::ASCII_Lookup_or_Insert_Nmtoken(char * nmtoken_ptr, int name_lgth) {
329
330        if (Verify_ASCII(nmtoken_ptr, name_lgth)) {
331                return UTF8_Lookup_or_Insert_Nmtoken(nmtoken_ptr, name_lgth);
332        }
333        return 0;
334}
335
336
337int Symbol_Table::UTF8_Lookup_or_Insert_Nmtoken(char * nmtoken, int lgth) {
338               
339        char delim = nmtoken[lgth];
340        nmtoken[lgth] = '\0';
341        int nmtokenID = UTF8NmtokenMap[nmtoken];
342        nmtoken[lgth] = delim; 
343       
344        if(nmtokenID == 0){
345        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
346#ifdef EDITION5
347                if (!is_XML11_UTF8_Nmtoken(nmtoken,lgth))  {
348                        ShowSyntaxError(NT_Nmtoken);
349                        exit(-1);
350                }
351#endif
352#ifndef EDITION5
353                if (!is_XML10_UTF8_Nmtoken(nmtoken,lgth))  {
354                        if (version == XML_1_1) {
355                                if (!is_XML11_UTF8_Nmtoken(nmtoken,lgth))  {
356                                        ShowSyntaxError(NT_Nmtoken);
357                                        exit(-1);
358                                }
359                        }
360                        else {
361                                ShowSyntaxError(NT_Nmtoken);
362                                exit(-1);
363                        }
364                }
365#endif
366        #endif
367//              char * s = copy_name(name,lgth);
368                char * s = pool->Insert(nmtoken,lgth);
369                UTF8NmtokenMap[s]=++(globalNmtokenCount);
370                nmtokenID = globalNmtokenCount;
371                Name_Data nmtoken_data;
372                nmtoken_data.name_string = s;
373                nmtoken_data.lgth = lgth;
374                UTF8NmtokenTable.push_back(nmtoken_data);
375//              UTF8NameTable.push_back(s);
376        }
377        return nmtokenID;
378}
379
380
381
382
383char * Symbol_Table::Get_UTF8_nmtoken(int nmtokenID) {
384        return  UTF8NmtokenTable[nmtokenID].name_string;
385}
386
387int Symbol_Table::Get_UTF8_nmtoken_lgth(int nmtokenID) {
388        return  UTF8NmtokenTable[nmtokenID].lgth;
389}
390
391char * Symbol_Table::ReserveSymbolSpace(int u8_lgth) {
392        reserved = new char[u8_lgth+1];
393        reserved_lgth = u8_lgth;
394        return reserved;
395}
396
397int Symbol_Table::LookupOrInsertReserved(){             
398        int nameID = UTF8NameMap[reserved];
399        if(nameID == 0){
400        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
401                if (!is_XML10_UTF8_Name(reserved,reserved_lgth))  {
402                        ShowSyntaxError(NT_Name);
403                        exit(-1);
404                }
405        #endif
406                UTF8NameMap[reserved]=++(globalNameCount);
407                nameID = globalNameCount;
408                Name_Data name_data;
409                name_data.name_string = reserved;
410                name_data.lgth = reserved_lgth;
411                UTF8NameTable.push_back(name_data);
412//              UTF8NameTable.push_back(s);
413        }
414        else {
415                delete [] reserved;
416        }
417        return nameID;
418}
419
420int Symbol_Table::LookupOrInsertReserved_nmtoken(){             
421        int nmtokenID = UTF8NmtokenMap[reserved];
422        if(nmtokenID == 0){
423        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
424                if (!is_XML10_UTF8_Nmtoken(reserved,reserved_lgth))  {
425                        ShowSyntaxError(NT_Nmtoken);
426                        exit(-1);
427                }
428        #endif
429                UTF8NmtokenMap[reserved]=++(globalNmtokenCount);
430                nmtokenID = globalNmtokenCount;
431                Name_Data nmtoken_data;
432                nmtoken_data.name_string = reserved;
433                nmtoken_data.lgth = reserved_lgth;
434                UTF8NmtokenTable.push_back(nmtoken_data);
435        }
436        else {
437                delete [] reserved;
438        }
439        return nmtokenID;
440}
441
442Symbol_Table::Symbol_Table(){
443        globalNameCount = 0;
444        Name_Data name_data;
445        name_data.name_string = NULL;
446        name_data.lgth = 0;
447        UTF8NameTable.push_back(name_data);
448//      UTF8NameTable.push_back(NULL);
449/*      for (int i = 0; i < 5; i++) {
450                UTF8NameMap[predefined[i]] = ++(globalNameCount);
451                Name_Data name_data;
452                name_data.name_string = predefined[i];
453                name_data.lgth = strlen(predefined[i]);
454                UTF8NameTable.push_back(name_data);
455                printf("predefined name: %s, global name count: %d\n",predefined[i],globalNameCount);
456//              UTF8NameTable.push_back(predefined[i]);
457        }*/
458        pool = new StringPool;
459}
460
461
462StringPool::StringPool() {
463       buffer_capacity = INIT_STRINGPOOL_SIZE;
464       buffer_space_used = 0;
465       pool_buffers.push_back(new char [buffer_capacity]);
466}
467
468StringPool::~StringPool() {
469       vector<char * >::iterator i;
470       for (i = pool_buffers.begin(); i != pool_buffers.end(); i++) {
471               delete [] *i;
472       }
473}
474
475char * StringPool::Insert(char * s, int lgth) {
476       while (lgth + buffer_space_used >= buffer_capacity) {
477               buffer_capacity *= 2;
478               pool_buffers.push_back(new char [buffer_capacity]);
479               buffer_space_used = 0;
480       }
481       char * insertion_ptr = &pool_buffers.back()[buffer_space_used];
482       memcpy(insertion_ptr, s, lgth);
483       insertion_ptr[lgth] = '\0';
484       buffer_space_used += lgth + 1;
485       return insertion_ptr;
486}
487
488
489
Note: See TracBrowser for help on using the repository browser.