source: proto/parabix2/pablo.py @ 1959

Last change on this file since 1959 was 1959, checked in by lindanl, 7 years ago

Add prototype that can run under python and is compilable as well

File size: 5.6 KB
Line 
1#
2# pablo.py
3#
4# Bitstream Utilities
5#
6# These are quick-and-dirty Python implementations of utilities
7# for demo purposes only.
8#
9# Dan Lin, Robert D. Cameron
10# March 24, 2012
11#
12#----------------------------------------------------------------------------
13#
14# We use python's unlimited precision integers for unbounded bit streams.
15# This permits simple logical operations on the entire stream.
16# Assumption: bitstreams are little-endian (e.g., as on x86).
17#
18#----------------------------------------------------------------------------
19#
20import sys
21import codecs
22# Utility functions for demo purposes.
23
24EOF_mask = 0
25data = ''
26
27def writefile(filename, s, charcode='utf-8',):
28        f = codecs.open(filename, 'w', encoding=charcode)
29        f.write(s) # writes encoded bytes to file
30        f.close()
31
32def readfile(filename):
33        f = open(filename, 'r')
34        contents = f.read() 
35        f.close()
36        return contents
37
38def transpose_streams(s, b):
39        mask = 128
40        index = 0
41        while index < 8:
42                current = 0
43                cursor = 1
44                for byte in s:
45                        if  (ord(byte) & mask != 0):
46                                current += cursor
47                        cursor <<= 1
48                       
49                index+=1
50                mask>>=1
51                if index == 1:
52                        b.bit_0 = current
53                elif index == 2:
54                        b.bit_1 = current
55                elif index == 3:
56                        b.bit_2 = current
57                elif index == 4:
58                        b.bit_3 = current
59                elif index == 5:
60                        b.bit_4 = current
61                elif index == 6:
62                        b.bit_5 = current
63                elif index == 7:
64                        b.bit_6 = current
65                elif index == 8:
66                        b.bit_7 = current
67        data = s
68        return cursor-1  # basis streams and EOF mask
69
70def inFile(lex_error):
71        return EOF_mask & lex_error
72
73def atEOF(strm):
74        if strm > EOF_mask or strm < 0:
75                return EOF_mask + 1
76        else:
77                return 0
78
79def count_leading_zeroes(strm):
80        zeroes = 0
81        while (strm & 0xFFFFFFFF) == 0: 
82                zeroes += 32
83                strm >>= 32
84        while (strm & 1) == 0:
85                zeroes += 1
86                strm >>= 1
87        return zeroes
88       
89def NoteError(s, lex_error):
90        pos = count_leading_zeroes(lex_error)
91        print s + " at position " + str(pos)
92#
93#  ScanThru is the core operation for parallel scanning.
94#  Given a bitstream Cursors marking current cursor positions,
95#  advance each cursor through occurrences of a character
96#  class identified by ScanStream.
97
98def ScanThru(Cursors, ScanStream):
99        return (Cursors + ScanStream) & ~ScanStream
100       
101def ScanTo(Cursors, ScanStream): 
102        return (Cursors + (~ScanStream & EOF_mask) ) & ScanStream
103
104def ScanToFirst(ScanStream):
105        return ScanTo(1, ScanStream)
106#
107# Advance all cursors by one position.
108def Advance(stream):
109        return stream + stream
110
111
112#Functions copied from bitutil.py
113def writefile(filename, s, charcode='utf-8',):
114        f = codecs.open(filename, 'w', encoding=charcode)
115        f.write(s) # writes encoded bytes to file
116        f.close()
117
118def EOF_mask(strm_lgth):
119        mask = 1
120        mask <<= (strm_lgth)
121        mask -= 1
122        return mask
123
124def extract_bit(strm, pos):
125        bit = (strm >> pos) & 1
126        return bit
127
128def inverse_transpose(bitset, len):
129        bytestream=""
130        cursor = 1
131        for i in range(0, len):
132                byteval = 0
133                for j in range(0,8):
134                        if bitset[j] & cursor != 0:
135                                byteval += 128 >> j
136                bytestream += chr(byteval)
137                cursor += cursor
138        return bytestream
139                       
140def filter_bits(bitstream, delmask):
141        newstream = 0
142        cursor = 1
143        while delmask > 0:
144                if delmask & 1 == 0:
145                        if bitstream & 1 == 1:
146                                newstream += cursor
147                        cursor += cursor
148                delmask >>= 1
149                bitstream >>= 1
150        while bitstream > 0:
151                if bitstream & 1 == 1:
152                        newstream += cursor
153                cursor += cursor
154                bitstream >>= 1         
155        return newstream
156                       
157def filter_bytes(bytestream, delmask):
158        newstream=""
159        cursor = 1
160        for c in bytestream:
161                if delmask & cursor == 0:
162                        newstream += c
163                cursor += cursor
164        return newstream
165                       
166def merge_bytes(stream1, stream2):
167        s = ""
168        for i in range(len(stream1)):
169                s += stream1[i]
170                s += stream2[i]
171        return s
172
173def bitstream2string(stream, lgth):
174        str = ""
175        for i in range(lgth):
176                if stream & 1 == 1: str += '1'
177                else: str += '_'
178                stream >>= 1
179        return str
180
181def bitstream2stringLE(stream, lgth):
182        str = ""
183        for i in range(lgth):
184                if stream & 1 == 1: str = '1' + str
185                else: str = '_' + str
186                stream >>= 1
187        return str
188
189def print_aligned_streams(stream_list):
190        """Print out a set of aligned streams."""
191        label_max = max([len(p[0]) for p in stream_list])
192        for p in stream_list:
193                print (p[0] + " "*(label_max - len(p[0]))) + ": " + p[1] 
194
195def latex_streams(stream_list):
196        """Return a latex table for streams."""
197        table = "\\begin{tabular}{cr}"
198        for p in stream_list:
199                table += "\\\\\n" + p[0] +" & \\verb`" + p[1] +"`"
200        return table + "\n\\end{tabular}\n"
201
202def print_aligned_u8_byte_streams(u8_byte_stream):
203        """Print out a set of 'encoding' aligned streams."""
204
205        # Set the system info to print utf-8
206        info = codecs.lookup('utf-8')
207        sys.stdout = info.streamwriter(sys.stdout) 
208
209        label_max = max([len(p[0]) for p in u8_byte_stream])
210        for p in u8_byte_stream:
211                sys.stdout.write(p[0] + " "*(label_max - len(p[0])) + ": ")
212               
213                for c in (p[1].decode('utf-8')):                        # for each unicode character
214                        u8_seq_len = len(c.encode('utf-8'))     # encode the unicode character as utf-8 and get the utf-8 sequence length
215                        if u8_seq_len == 1:
216                                sys.stdout.write(c)
217                        elif u8_seq_len == 2:
218                                sys.stdout.write('2_')                          # align 2 byte sequences with a trailing _
219                        elif u8_seq_len == 3:
220                                sys.stdout.write('3__')                         # align 3 byte sequences with 2 trailing _
221                        elif u8_seq_len == 4:
222                                sys.stdout.write('4___')                        # align 2 byte sequences with 3 trailing _               
223                        else:
224                                sys.stdout.write('Error: Invalid UTF-8 character sequence of length: ' + str(u8_seq_len) + '.')                 
225                sys.stdout.write('\n')   
226
227def high_nybble_stream(bytes):
228        str=""
229        for b in bytes:
230                h = hex(ord(b))[-2]
231                if h == 'x': str += '0'
232                else: str += h
233        return str
234
235def low_nybble_stream(bytes):
236        str=""
237        for b in bytes:
238                str += hex(ord(b))[-1]
239        return str
240
Note: See TracBrowser for help on using the repository browser.