source: trunk/src/symtab.c @ 160

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

Restructured character set architecture; StringPool? in symbol table.

File size: 11.3 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
191int Symbol_Table::Insert_Name(char * name, int lgth) {
192//      char * s = copy_name(name,lgth);
193        char * s = pool->Insert(name,lgth);
194        UTF8NameMap[s]=++(globalNameCount);
195        Name_Data name_data;
196        name_data.name_string = s;
197        name_data.lgth = lgth;
198        UTF8NameTable.push_back(name_data);
199        return globalNameCount;
200}
201
202
203inline bool Verify_ASCII(char * name_ptr, int name_lgth) {
204        /* To verify that a name is ASCII, ensure that the high bit
205           of each byte is 0.  A SIMD compare can verify this for
206           up to sizeof(BytePack) bytes.  For less than 16 bytes,
207           first shift out bytes beyond the name length.  For more
208           than 16 bytes, form the logical "or" of the successive byte
209           packs together so that a high 1 bit in any byte is preserved
210           for the final SIMD test. */
211        BytePack b = sisd_load_unaligned((BytePack *) name_ptr);
212        if (name_lgth <= sizeof(BytePack)) {
213                /* Clear bytes beyond the length of the name. */
214                b = sisd_sfl(b, sisd_from_int(8 * (sizeof(BytePack) - name_lgth)));
215        } 
216        else {
217                int offset = name_lgth % sizeof(BytePack);
218                for (int i = offset; i < name_lgth; i += sizeof(BytePack)) {
219                        b = simd_or(sisd_load_unaligned((BytePack *) &name_ptr[i]),b);
220                }
221        }
222        return !simd_any_sign_bit_8(b);
223}
224
225
226/* ASCII_LookupOrInsert determines the nameID for any ASCII name
227from the global name table, inserting the name and allocating
228a nameID if necessary.  If the name is non-ASCII, 0 is returned. */
229
230inline int Symbol_Table::ASCII_Lookup_or_Insert(char * name_ptr, int name_lgth) {
231        if (Verify_ASCII(name_ptr, name_lgth)) {
232                return UTF8_Lookup_or_Insert(name_ptr, name_lgth);
233        }
234        return 0;
235}
236
237
238
239int Symbol_Table::UTF8_Lookup_or_Insert(char * name, int lgth) {
240        char delim = name[lgth];
241        name[lgth] = '\0';
242        int nameID = UTF8NameMap[name];
243        name[lgth] = delim;     
244       
245        if(nameID == 0){
246        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
247                if (!is_XML11_UTF8_Name(name,lgth))  {
248                        ShowSyntaxError(NT_Name);
249                        exit(-1);
250                }
251        #endif
252//              char * s = copy_name(name,lgth);
253                char * s = pool->Insert(name,lgth);
254                UTF8NameMap[s]=++(globalNameCount);
255                nameID = globalNameCount;
256                Name_Data name_data;
257                name_data.name_string = s;
258                name_data.lgth = lgth;
259                UTF8NameTable.push_back(name_data);
260//              UTF8NameTable.push_back(s);
261        }
262        return nameID;
263}
264
265//char * Symbol_Table::Get_UTF8_name(int nameID) {
266//      return  UTF8NameTable[nameID];
267//}
268
269char * Symbol_Table::Get_UTF8_name(int nameID) {
270        return  UTF8NameTable[nameID].name_string;
271}
272
273int Symbol_Table::Get_UTF8_lgth(int nameID) {
274        return  UTF8NameTable[nameID].lgth;
275}
276
277char * Symbol_Table::ReserveSymbolSpace(int u8_lgth) {
278        reserved = new char[u8_lgth+1];
279        reserved_lgth = u8_lgth;
280        return reserved;
281}
282
283int Symbol_Table::LookupOrInsertReserved(){             
284        int nameID = UTF8NameMap[reserved];
285        if(nameID == 0){
286        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
287                if (!is_XML10_UTF8_Name(reserved,reserved_lgth))  {
288                        ShowSyntaxError(NT_Name);
289                        exit(-1);
290                }
291        #endif
292                UTF8NameMap[reserved]=++(globalNameCount);
293                nameID = globalNameCount;
294                Name_Data name_data;
295                name_data.name_string = reserved;
296                name_data.lgth = reserved_lgth;
297                UTF8NameTable.push_back(name_data);
298//              UTF8NameTable.push_back(s);
299        }
300        else {
301                delete [] reserved;
302        }
303        return nameID;
304}
305
306Symbol_Table::Symbol_Table(){
307        globalNameCount = 0;
308        Name_Data name_data;
309        name_data.name_string = NULL;
310        name_data.lgth = 0;
311        UTF8NameTable.push_back(name_data);
312//      UTF8NameTable.push_back(NULL);
313        for (int i = 0; i < 5; i++) {
314                UTF8NameMap[predefined[i]] = ++(globalNameCount);
315                Name_Data name_data;
316                name_data.name_string = predefined[i];
317                name_data.lgth = strlen(predefined[i]);
318                UTF8NameTable.push_back(name_data);
319//              UTF8NameTable.push_back(predefined[i]);
320        }
321        pool = new StringPool;
322}
323
324
325StringPool::StringPool() {
326       buffer_capacity = INIT_STRINGPOOL_SIZE;
327       buffer_space_used = 0;
328       pool_buffers.push_back(new char [buffer_capacity]);
329}
330
331StringPool::~StringPool() {
332       vector<char * >::iterator i;
333       for (i = pool_buffers.begin(); i != pool_buffers.end(); i++) {
334               delete [] *i;
335       }
336}
337
338char * StringPool::Insert(char * s, int lgth) {
339       while (lgth + buffer_space_used >= buffer_capacity) {
340               buffer_capacity *= 2;
341               pool_buffers.push_back(new char [buffer_capacity]);
342               buffer_space_used = 0;
343       }
344       char * insertion_ptr = &pool_buffers.back()[buffer_space_used];
345       memcpy(insertion_ptr, s, lgth);
346       insertion_ptr[lgth] = '\0';
347       buffer_space_used += lgth + 1;
348       return insertion_ptr;
349}
350
351
352
Note: See TracBrowser for help on using the repository browser.