source: proto/parabix2/template_tag_match.c @ 567

Last change on this file since 567 was 567, checked in by lindanl, 9 years ago

matching tag names up to 16 bytes

File size: 12.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include "../lib/lib_simd.h"
7#include "../lib/block_carry.h"
8
9       
10#define BUFFER_SIZE 12800   
11#define BLOCK_SIZE 128
12
13typedef long ScanBlock;
14typedef SIMD_type BytePack;
15typedef SIMD_type BitBlock;
16
17#include "xmldecl.h"
18#include "xml_error.c"
19#include "xmldecl.c"
20#include "namechars.h"
21
22#include "../lib/perflib/perfsec.h"
23
24#include "tag_matcher.cpp"
25
26#ifdef BUFFER_PROFILING
27        BOM_Table * parser_timer;
28
29#elif CODE_CLOCKER
30        #define NUM_EVENTS 1
31        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
32        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
33        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
34        int cal_size = 20;
35        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
36#else
37        void * parser_timer;
38#endif
39
40int block_base=0;
41int buffer_base=0;
42int buffer_last;
43char * source;
44
45
46static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int)) {
47        int blk;
48        int block_pos = 0;
49
50        for (blk = 0; blk < blk_count; blk++) {
51                ScanBlock s = stream[blk];
52                while(s) {
53                        int code = (ProcessPos(cfzl(s) + block_pos));
54                        if (code) return code;
55                        s = s & (s-1);  // clear rightmost bit.
56                }
57                block_pos += 8 * sizeof(ScanBlock);
58        }
59        return 0;
60} 
61
62
63
64inline bool bit_test(unsigned char * bit_Map, int codepoint) {
65        return (bit_Map[codepoint/8] >> (7 - codepoint % 8)) & 1;
66}
67
68bool is_XML10_NameStrt_codepoint(int codepoint) {
69        switch (codepoint >> 12) {
70                case 0: return bit_test(NameStrt_XML10_0000_11FF, codepoint);
71                case 1: if (codepoint <= 0x11FF)
72                                return bit_test(NameStrt_XML10_0000_11FF, codepoint);
73                        else if (codepoint < 0x1E00) return false;
74                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
75                case 2: if (codepoint > 0x2182) return false;
76                        else return bit_test(NameStrt_XML10_2000_21FF, codepoint & 0x1FF);
77                case 3: if (codepoint > 0x312C) return false;
78                        else return bit_test(NameStrt_XML10_3000_31FF, codepoint & 0x1FF);
79                case 4: return codepoint >= 0x4E00;
80                case 5: case 6: case 7: case 8: return true;
81                case 9: return codepoint <= 0x9FA5;
82                case 0xA: return codepoint >= 0xAC00;
83                case 0xB: case 0xC: return true;
84                case 0xD: return codepoint <= 0xD7A3;
85                default: return false;
86        }
87}
88
89bool is_XML10_NameChar_codepoint(int codepoint) {
90        switch (codepoint >> 12) {
91                case 0: return bit_test(NameChar_XML10_0000_11FF, codepoint);
92                case 1: if (codepoint <= 0x11FF)
93                                return bit_test(NameChar_XML10_0000_11FF, codepoint);
94                        else if (codepoint < 0x1E00) return false;
95                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
96                case 2: if (codepoint > 0x2182) return false;
97                        else return bit_test(NameChar_XML10_2000_21FF, codepoint & 0x1FF);
98                case 3: if (codepoint > 0x312C) return false;
99                        else return bit_test(NameChar_XML10_3000_31FF, codepoint & 0x1FF);
100                case 4: return codepoint >= 0x4E00;
101                case 5: case 6: case 7: case 8: return true;
102                case 9: return codepoint <= 0x9FA5;
103                case 0xA:       return codepoint >= 0xAC00;
104                case 0xB: case 0xC: return true;
105                case 0xD: return codepoint <= 0xD7A3;
106                default: return false;
107        }
108}
109
110inline int XML_10_UTF8_NameStrt_bytes (unsigned char bytes[]) {
111        if (bytes[0] <= 0x7F) {
112                if (bit_test(NameStrt_XML10_0000_11FF, (int) bytes[0])) return 1;
113                else return 0;
114        }
115        else if (bytes[0] <= 0xDF) {
116                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
117                if (bit_test(NameStrt_XML10_0000_11FF, codepoint)) return 2;
118                else return 0;
119        }
120        else if (bytes[0] <= 0xEF) {
121                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
122                return is_XML10_NameStrt_codepoint(codepoint) ? 3 : 0;
123        }
124        else return 0;
125}
126
127inline int XML_10_UTF8_NameChar_bytes (unsigned char bytes[]) {
128        if (bytes[0] <= 0x7F) {
129                if (bit_test(NameChar_XML10_0000_11FF, (int) bytes[0])) return 1;
130                else return 0;
131        }
132        else if (bytes[0] <= 0xDF) {
133                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
134                if (bit_test(NameChar_XML10_0000_11FF, codepoint)) return 2;
135                else return 0;
136        }
137        else if (bytes[0] <= 0xEF) {
138                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
139                return is_XML10_NameChar_codepoint(codepoint) ? 3 : 0;
140        }
141        else return 0;
142}
143
144
145static inline int NameStrt_check(int pos) {
146        int block_pos = block_base + pos;
147        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
148              fprintf(stderr, "name start error found at position %i\n",block_pos+buffer_base);
149              exit(-1);
150        }
151        return 0;
152}
153
154static inline int Name_check(int pos) {
155        int block_pos = block_base + pos;
156        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
157              fprintf(stderr, "name error found at position %i\n",block_pos+buffer_base);
158              exit(-1);
159        }
160        return 0;
161}
162/*
163static inline int Tag_match(int pos) {
164        int block_pos = block_base + pos;
165        if(source[block_pos]=='/' ){
166          tag_depth--;
167          if (tag_depth<0){
168            fprintf(stderr, "tag matching error at position %i\n",block_pos+buffer_base);
169            exit(-1);
170          }       
171        }
172        else if(source[block_pos]=='>')
173          tag_depth--;
174        else
175          tag_depth++;
176        return 0;
177}*/
178
179
180#define s2p_step(s0,s1,hi_mask,shift,p0,p1)  \
181{ \
182BitBlock t0,t1; \
183t0= simd_pack_16_hh(s0,s1) ; \
184t1= simd_pack_16_ll(s0,s1) ; \
185p0= simd_if(hi_mask,t0,simd_srli_16(t1,shift) ) ; \
186p1= simd_if(hi_mask,simd_slli_16(t0,shift) ,t1) ; \
187} \
188
189#define s2p_bytepack(s0,s1,s2,s3,s4,s5,s6,s7,p0,p1,p2,p3,p4,p5,p6,p7)  \
190{BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
191BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
192BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
193BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
194s2p_step(s0,s1,simd_himask_2,1,bit00224466_0,bit11335577_0)  \
195s2p_step(s2,s3,simd_himask_2,1,bit00224466_1,bit11335577_1)  \
196s2p_step(s4,s5,simd_himask_2,1,bit00224466_2,bit11335577_2)  \
197s2p_step(s6,s7,simd_himask_2,1,bit00224466_3,bit11335577_3)  \
198s2p_step(bit00224466_0,bit00224466_1,simd_himask_4,2,bit00004444_0,bit22226666_0)  \
199s2p_step(bit00224466_2,bit00224466_3,simd_himask_4,2,bit00004444_1,bit22226666_1)  \
200s2p_step(bit11335577_0,bit11335577_1,simd_himask_4,2,bit11115555_0,bit33337777_0)  \
201s2p_step(bit11335577_2,bit11335577_3,simd_himask_4,2,bit11115555_1,bit33337777_1)  \
202s2p_step(bit00004444_0,bit00004444_1,simd_himask_8,4,p0,p4)  \
203s2p_step(bit11115555_0,bit11115555_1,simd_himask_8,4,p1,p5)  \
204s2p_step(bit22226666_0,bit22226666_1,simd_himask_8,4,p2,p6)  \
205s2p_step(bit33337777_0,bit33337777_1,simd_himask_8,4,p3,p7)  \
206} \
207
208#define p2s_step(p0,p1,hi_mask,shift,s0,s1)  \
209{ \
210BitBlock t0,t1; \
211t0= simd_if(hi_mask,p0,simd_srli_16(p1,shift) ) ; \
212t1= simd_if(hi_mask,simd_slli_16(p0,shift) ,p1) ; \
213s0= simd_mergeh_8(t0,t1) ; \
214s1= simd_mergel_8(t0,t1) ; \
215} \
216
217#define p2s_bytemerge(p0,p1,p2,p3,p4,p5,p6,p7,s0,s1,s2,s3,s4,s5,s6,s7)  \
218{ \
219BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
220BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
221BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
222BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
223p2s_step(p0,p4,simd_himask_8,4,bit00004444_0,bit00004444_1)  \
224p2s_step(p1,p5,simd_himask_8,4,bit11115555_0,bit11115555_1)  \
225p2s_step(p2,p6,simd_himask_8,4,bit22226666_0,bit22226666_1)  \
226p2s_step(p3,p7,simd_himask_8,4,bit33337777_0,bit33337777_1)  \
227p2s_step(bit00004444_0,bit22226666_0,simd_himask_4,2,bit00224466_0,bit00224466_1)  \
228p2s_step(bit11115555_0,bit33337777_0,simd_himask_4,2,bit11335577_0,bit11335577_1)  \
229p2s_step(bit00004444_1,bit22226666_1,simd_himask_4,2,bit00224466_2,bit00224466_3)  \
230p2s_step(bit11115555_1,bit33337777_1,simd_himask_4,2,bit11335577_2,bit11335577_3)  \
231p2s_step(bit00224466_0,bit11335577_0,simd_himask_2,1,s0,s1)  \
232p2s_step(bit00224466_1,bit11335577_1,simd_himask_2,1,s2,s3)  \
233p2s_step(bit00224466_2,bit11335577_2,simd_himask_2,1,s4,s5)  \
234p2s_step(bit00224466_3,bit11335577_3,simd_himask_2,1,s6,s7)  \
235} \
236
237
238void do_process(FILE *infile, FILE *outfile) {
239
240  @decl
241
242  BytePack U8[8];
243  int buf_pos = 0;
244  int block_pos = 0;
245  int errpos = 0;
246  int chars_avail = 0;
247  int check_pos = 0;
248  char srcbuf[BUFFER_SIZE+BLOCK_SIZE];
249 
250  buffer_base = buf_pos;
251  source = srcbuf;
252 
253  EOF_mask = simd_const_1(1);
254  chars_avail = fread((void *)srcbuf, 1, BUFFER_SIZE, infile);
255 
256  tag_matcher t(srcbuf);
257
258  Entity_Info * e = new Entity_Info;
259  e->AnalyzeSignature((unsigned char *)srcbuf);
260  XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
261
262  decl_parser.ReadXMLInfo(*e);
263
264  if (e->content_start != 0) {
265        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_avail - e->content_start);
266        if (chars_avail == BUFFER_SIZE) {
267                chars_avail = BUFFER_SIZE - e->content_start + 
268                             fread(&srcbuf[BUFFER_SIZE-e->content_start], 1, e->content_start, infile);
269        }
270        else chars_avail -=e->content_start;
271  }
272 
273  @stream_stmts
274
275  while(chars_avail>0){
276
277    PERF_SEC_START(parser_timer);
278
279    block_pos = 0;
280
281    if(chars_avail < BUFFER_SIZE){
282   
283      while (block_pos < chars_avail){
284
285        int bytes = chars_avail - block_pos;   
286        block_base = block_pos;
287         
288        if(bytes < BLOCK_SIZE){
289          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-bytes));
290        }
291        BytePack * U8pack = (BytePack *) &srcbuf[block_pos];
292        U8[0] = sisd_load_unaligned(&U8pack[0]);
293        U8[1] = sisd_load_unaligned(&U8pack[1]);
294        U8[2] = sisd_load_unaligned(&U8pack[2]);
295        U8[3] = sisd_load_unaligned(&U8pack[3]);
296        U8[4] = sisd_load_unaligned(&U8pack[4]);
297        U8[5] = sisd_load_unaligned(&U8pack[5]);
298        U8[6] = sisd_load_unaligned(&U8pack[6]);
299        U8[7] = sisd_load_unaligned(&U8pack[7]); 
300       
301        s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
302        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
303
304        array_bit__0_ = simd_and(array_bit__0_, EOF_mask);
305        array_bit__1_ = simd_and(array_bit__1_, EOF_mask);
306        array_bit__2_ = simd_and(array_bit__2_, EOF_mask);
307        array_bit__3_ = simd_and(array_bit__3_, EOF_mask);
308        array_bit__4_ = simd_and(array_bit__4_, EOF_mask);
309        array_bit__5_ = simd_and(array_bit__5_, EOF_mask);
310        array_bit__6_ = simd_and(array_bit__6_, EOF_mask);
311        array_bit__7_ = simd_and(array_bit__7_, EOF_mask);
312
313        @block_stmts
314
315
316        if (bitblock_has_bit(error_mask)) {
317          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
318          fprintf(stderr, "error found at position %i\n",errpos);
319          exit(-1);
320        }
321       
322        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
323          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
324          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
325        }
326           
327        t.store_streams(tag_marks, ElemNameFollows);
328       
329        block_pos += BLOCK_SIZE;
330      }
331    }
332    else{
333      while (block_pos < chars_avail){
334       
335        block_base = block_pos;
336         
337        BytePack * U8pack = (BytePack *) &srcbuf[block_pos];
338        U8[0] = sisd_load_unaligned(&U8pack[0]);
339        U8[1] = sisd_load_unaligned(&U8pack[1]);
340        U8[2] = sisd_load_unaligned(&U8pack[2]);
341        U8[3] = sisd_load_unaligned(&U8pack[3]);
342        U8[4] = sisd_load_unaligned(&U8pack[4]);
343        U8[5] = sisd_load_unaligned(&U8pack[5]);
344        U8[6] = sisd_load_unaligned(&U8pack[6]);
345        U8[7] = sisd_load_unaligned(&U8pack[7]); 
346       
347        s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
348        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
349
350        @block_stmts
351       
352        if (bitblock_has_bit(error_mask)) {
353          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
354          fprintf(stderr, "error found at position %i\n",errpos);
355          exit(-1);
356        }
357       
358        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
359          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
360          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
361        }
362           
363        t.store_streams(tag_marks, ElemNameFollows);
364
365        block_pos += BLOCK_SIZE;
366      }
367    }
368
369    t.StreamScan(chars_avail);
370    t.Advance_buffer();
371
372    PERF_SEC_END(parser_timer, chars_avail);
373
374    buf_pos += chars_avail;
375    buffer_base = buf_pos;
376    chars_avail = fread((void *)srcbuf, 1, BUFFER_SIZE, infile);
377    buffer_last = buffer_base + chars_avail;
378
379   
380   
381  }
382  if(t.depth!=0){
383    fprintf(stderr, "tag matching error (depth %i) at position %i\n", t.depth, buffer_last);
384    exit(-1);
385  }       
386   
387}
388
389
390
391int
392main(int argc, char * argv[]) {
393        char * infilename, * outfilename;       
394        FILE *infile, *outfile;
395        struct stat fileinfo;
396
397        if (argc < 2) {
398                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
399                exit(-1);
400        }
401
402        infilename = argv[1];
403        stat(infilename, &fileinfo);
404        infile = fopen(infilename, "rb");
405        if (!infile) {
406                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
407                exit(-1);
408        }
409       
410        if (argc < 3) outfile = stdout;
411        else {
412                outfilename = argv[2];
413                outfile = fopen(outfilename, "wb");
414                if (!outfile) {
415                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
416                        exit(-1);
417                }
418        }
419
420//      PERF_SEC_BIND(1);
421
422        PERF_SEC_INIT(parser_timer);
423
424        do_process(infile, outfile);
425       
426        PERF_SEC_DUMP(parser_timer);
427       
428        PERF_SEC_DESTROY(parser_timer);
429
430        fclose(infile);
431        fclose(outfile);
432        return(0);
433}
Note: See TracBrowser for help on using the repository browser.