source: proto/CSV/csv.py @ 1942

Last change on this file since 1942 was 1215, checked in by lindanl, 8 years ago

CSV parsing: quote using parity method

File size: 2.5 KB
Line 
1#
2# csv.py
3#
4#
5# Dan Lin
6# March 4, 2010
7#
8#----------------------------------------------------------------------------
9#
10# We use python's unlimited precision integers for unbounded bit streams.
11# This permits simple logical operations on the entire stream.
12# Assumption: bitstreams are little-endian (e.g., as on x86).
13#
14#----------------------------------------------------------------------------
15#
16
17
18import bitutil
19
20import csvclass
21       
22import sys
23
24def simd_const_4(hexdigit,EOF_mask):
25        lgth = bitutil.count_leading_zeroes(~EOF_mask)/4
26        return int(hexdigit*(lgth+1),16)&EOF_mask
27
28def parse_escape(lex, EOF_mask):
29        odd = simd_const_4('a',EOF_mask)
30        even = simd_const_4('5',EOF_mask)
31       
32        start = lex.BackSlash &~ bitutil.Advance(lex.BackSlash)
33        even_start = start & even
34
35        even_final = (even_start + lex.BackSlash) & ~lex.BackSlash
36        escape = even_final & odd
37       
38        odd_start = start & odd
39        odd_final = (odd_start + lex.BackSlash) & ~lex.BackSlash
40        escape = escape | (odd_final & even)
41       
42        return escape
43       
44def parse_quote_seq(quote,EOF_mask):   
45        cursor = 1
46        quote_start = 0
47        quote_end = 0
48        while(cursor):
49                cursor =  bitutil.ScanThru(cursor, (~quote)&EOF_mask)
50                quote_start |= cursor
51                cursor = bitutil.Advance(cursor)
52                cursor =  bitutil.ScanThru(cursor, (~quote)&EOF_mask)
53                quote_end |= cursor
54                cursor = bitutil.Advance(cursor)&EOF_mask
55        quote_mask = quote_end-quote_start
56        return  quote_mask
57       
58def parse_quote_parity(quote,EOF_mask): 
59        p2 = quote ^ (quote << 1)
60        p4 = p2 ^ (p2 << 2)
61        p8 = p4 ^ (p4 << 4)
62        p16 = p8 ^ (p8 << 8)
63        p32 = p16 ^ (p16 << 16)
64        p64 = p32 ^ (p32 << 32)
65        quote_mask = p64 ^ (p64 << 64)
66        return  quote_mask     
67       
68def csv_parse(u8data):
69        (bit, EOF_mask) = bitutil.transpose_streams(u8data)
70        lex = csvclass.classify_bytes(bit)
71        escape = parse_escape(lex, EOF_mask)   
72        quote = lex.DQuote &~ escape
73        quote_mask = parse_quote_parity(quote, EOF_mask)
74        eol = (lex.CR&~quote_mask) | (lex.LF&~lex.CR&~quote_mask)
75        delim = lex.Comma&~quote_mask
76        return (escape, quote, eol, delim)
77
78
79def demo_csv(u8data):
80
81        lgth = len(u8data)
82       
83        (escape, quote, eol, delim) = csv_parse(u8data)
84        bitutil.print_aligned_u8_byte_streams([('input data', u8data), 
85                              ('escape', bitutil.bitstream2string(escape, lgth)),
86                              ('quote', bitutil.bitstream2string(quote, lgth)),
87                              ('eol', bitutil.bitstream2string(eol, lgth)),
88                              ('delim', bitutil.bitstream2string(delim, lgth))])
89
90
91if __name__ == "__main__":
92        import doctest
93        doctest.testmod()
94       
95        if len(sys.argv) > 1:
96                u8data = bitutil.readfile(sys.argv[1]) 
97                demo_csv(u8data)
98        else:
99                print("Usage: python csv.py <file>")   
100               
101 
102       
103       
Note: See TracBrowser for help on using the repository browser.