source: proto/parabix2/template.c @ 560

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

stream scan for name checking

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