source: trunk/src/symtab.c @ 173

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

End-tags for non UTF-8; predefined symbol fix; DTD parsing fixes.

File size: 11.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
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
232        if (Verify_ASCII(name_ptr, name_lgth)) {
233                return UTF8_Lookup_or_Insert(name_ptr, name_lgth);
234        }
235        return 0;
236}
237
238
239
240int Symbol_Table::UTF8_Lookup_or_Insert(char * name, int lgth) {
241               
242        char delim = name[lgth];
243        name[lgth] = '\0';
244        int nameID = UTF8NameMap[name];
245        name[lgth] = delim;     
246       
247        if(nameID == 0){
248        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
249#ifdef EDITION5
250                if (!is_XML11_UTF8_Name(name,lgth))  {
251                        ShowSyntaxError(NT_Name);
252                        exit(-1);
253                }
254#endif
255#ifndef EDITION5
256                if (!is_XML10_UTF8_Name(name,lgth))  {
257                        if (version == XML_1_1) {
258                                if (!is_XML11_UTF8_Name(name,lgth))  {
259                                        ShowSyntaxError(NT_Name);
260                                        exit(-1);
261                                }
262                        }
263                        else {
264                                ShowSyntaxError(NT_Name);
265                                exit(-1);
266                        }
267                }
268#endif
269        #endif
270//              char * s = copy_name(name,lgth);
271                char * s = pool->Insert(name,lgth);
272                UTF8NameMap[s]=++(globalNameCount);
273                nameID = globalNameCount;
274                Name_Data name_data;
275                name_data.name_string = s;
276                name_data.lgth = lgth;
277                UTF8NameTable.push_back(name_data);
278//              UTF8NameTable.push_back(s);
279        }
280        return nameID;
281}
282
283//char * Symbol_Table::Get_UTF8_name(int nameID) {
284//      return  UTF8NameTable[nameID];
285//}
286
287char * Symbol_Table::Get_UTF8_name(int nameID) {
288        return  UTF8NameTable[nameID].name_string;
289}
290
291int Symbol_Table::Get_UTF8_lgth(int nameID) {
292        return  UTF8NameTable[nameID].lgth;
293}
294
295char * Symbol_Table::ReserveSymbolSpace(int u8_lgth) {
296        reserved = new char[u8_lgth+1];
297        reserved_lgth = u8_lgth;
298        return reserved;
299}
300
301int Symbol_Table::LookupOrInsertReserved(){             
302        int nameID = UTF8NameMap[reserved];
303        if(nameID == 0){
304        #if (not defined(OMISSION)) or (OMISSION != NAME_VALIDATION)
305                if (!is_XML10_UTF8_Name(reserved,reserved_lgth))  {
306                        ShowSyntaxError(NT_Name);
307                        exit(-1);
308                }
309        #endif
310                UTF8NameMap[reserved]=++(globalNameCount);
311                nameID = globalNameCount;
312                Name_Data name_data;
313                name_data.name_string = reserved;
314                name_data.lgth = reserved_lgth;
315                UTF8NameTable.push_back(name_data);
316//              UTF8NameTable.push_back(s);
317        }
318        else {
319                delete [] reserved;
320        }
321        return nameID;
322}
323
324Symbol_Table::Symbol_Table(){
325        globalNameCount = 0;
326        Name_Data name_data;
327        name_data.name_string = NULL;
328        name_data.lgth = 0;
329        UTF8NameTable.push_back(name_data);
330//      UTF8NameTable.push_back(NULL);
331/*      for (int i = 0; i < 5; i++) {
332                UTF8NameMap[predefined[i]] = ++(globalNameCount);
333                Name_Data name_data;
334                name_data.name_string = predefined[i];
335                name_data.lgth = strlen(predefined[i]);
336                UTF8NameTable.push_back(name_data);
337                printf("predefined name: %s, global name count: %d\n",predefined[i],globalNameCount);
338//              UTF8NameTable.push_back(predefined[i]);
339        }*/
340        pool = new StringPool;
341}
342
343
344StringPool::StringPool() {
345       buffer_capacity = INIT_STRINGPOOL_SIZE;
346       buffer_space_used = 0;
347       pool_buffers.push_back(new char [buffer_capacity]);
348}
349
350StringPool::~StringPool() {
351       vector<char * >::iterator i;
352       for (i = pool_buffers.begin(); i != pool_buffers.end(); i++) {
353               delete [] *i;
354       }
355}
356
357char * StringPool::Insert(char * s, int lgth) {
358       while (lgth + buffer_space_used >= buffer_capacity) {
359               buffer_capacity *= 2;
360               pool_buffers.push_back(new char [buffer_capacity]);
361               buffer_space_used = 0;
362       }
363       char * insertion_ptr = &pool_buffers.back()[buffer_space_used];
364       memcpy(insertion_ptr, s, lgth);
365       insertion_ptr[lgth] = '\0';
366       buffer_space_used += lgth + 1;
367       return insertion_ptr;
368}
369
370
371
Note: See TracBrowser for help on using the repository browser.