source: proto/parabix2/bitutil.py @ 313

Last change on this file since 313 was 313, checked in by ksherdy, 10 years ago

Open file for read. Revert transpose_stream method name.

File size: 4.2 KB
Line 
1#
2# bitutil.py
3#
4# Bitstream Utilities
5#
6# These are quick-and-dirty Python implementations of utilities
7# for demo purposes only.
8#
9# Robert D. Cameron
10# August 19, 2009
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#
24
25def writefile(filename, s, charcode='utf-8',):
26        f = codecs.open(filename, 'w', encoding=charcode)
27        f.write(s) # writes encoded bytes to file
28        f.close()
29
30def readfile(filename):
31        f = open(filename, 'r')
32        contents = f.read() 
33        f.close()
34        return contents
35
36def count_leading_zeroes(strm):
37        zeroes = 0
38        while (strm & 0xFFFFFFFF) == 0: 
39                zeroes += 32
40                strm >>= 32
41        while (strm & 1) == 0:
42                zeroes += 1
43                strm >>= 1
44        return zeroes
45
46def extract_bit(strm, pos):
47        bit = (strm >> pos) & 1
48        return bit
49
50def transpose_streams(s):
51        b = []
52        mask = 128
53        index = 0
54        while index < 8:
55                current = 0
56                cursor = 1
57                for byte in s:
58                        if  (ord(byte) & mask != 0):
59                                current += cursor
60                        cursor <<= 1
61                       
62                index+=1
63                mask>>=1
64                b.append(current)
65        return (b, cursor-1)  # basis streams and EOF mask
66
67def inverse_transpose(bitset, len):
68        bytestream=""
69        cursor = 1
70        for i in range(0, len):
71                byteval = 0
72                for j in range(0,8):
73                        if bitset[j] & cursor != 0:
74                                byteval += 128 >> j
75                bytestream += chr(byteval)
76                cursor += cursor
77        return bytestream
78                       
79def filter_bits(bitstream, delmask):
80        newstream = 0
81        cursor = 1
82        while delmask > 0:
83                if delmask & 1 == 0:
84                        if bitstream & 1 == 1:
85                                newstream += cursor
86                        cursor += cursor
87                delmask >>= 1
88                bitstream >>= 1
89        while bitstream > 0:
90                if bitstream & 1 == 1:
91                        newstream += cursor
92                cursor += cursor
93                bitstream >>= 1         
94        return newstream
95                       
96def filter_bytes(bytestream, delmask):
97        newstream=""
98        cursor = 1
99        for c in bytestream:
100                if delmask & cursor == 0:
101                        newstream += c
102                cursor += cursor
103        return newstream
104                       
105def merge_bytes(stream1, stream2):
106        s = ""
107        for i in range(len(stream1)):
108                s += stream1[i]
109                s += stream2[i]
110        return s
111
112def bitstream2string(stream, lgth):
113        str = ""
114        for i in range(lgth):
115                if stream & 1 == 1: str += '1'
116                else: str += '_'
117                stream >>= 1
118        return str
119
120def print_aligned_streams(stream_list):
121        """Print out a set of aligned streams."""
122        label_max = max([len(p[0]) for p in stream_list])
123        for p in stream_list:
124                print (p[0] + " "*(label_max - len(p[0]))) + ": " + p[1] 
125
126def print_aligned_u8_byte_streams(u8_byte_stream):
127        """Print out a set of 'encoding' aligned streams."""
128
129        # Set the system info to print utf-8
130        info = codecs.lookup('utf-8')
131        sys.stdout = info.streamwriter(sys.stdout) 
132
133        label_max = max([len(p[0]) for p in u8_byte_stream])
134        for p in u8_byte_stream:
135                sys.stdout.write(p[0] + " "*(label_max - len(p[0])) + ": ")
136               
137                for c in (p[1].decode('utf-8')):                        # for each unicode character
138                        u8_seq_len = len(c.encode('utf-8'))     # encode the unicode character as utf-8 and get the utf-8 sequence length
139                        if u8_seq_len == 1:
140                                sys.stdout.write(c)
141                        elif u8_seq_len == 2:
142                                sys.stdout.write('2_')                          # align 2 byte sequences with a trailing 2
143                        elif u8_seq_len == 3:
144                                sys.stdout.write('3__')                         # align 3 byte sequences with 2 trailing 3's
145                        elif u8_seq_len == 4:
146                                sys.stdout.write('4___')                        # align 2 byte sequences with 3 trailing 4's             
147                        else:
148                                sys.stdout.write('Error: Invalid UTF-8 character sequence of length: ' + str(u8_seq_len) + '.')                 
149                sys.stdout.write('\n')   
150
151def high_nybble_stream(bytes):
152        str=""
153        for b in bytes:
154                h = hex(ord(b))[-2]
155                if h == 'x': str += '0'
156                else: str += h
157        return str
158
159def low_nybble_stream(bytes):
160        str=""
161        for b in bytes:
162                str += hex(ord(b))[-1]
163        return str
164
165
166       
167#
168#  ScanThru is the core operation for parallel scanning.
169#  Given a bitstream Cursors marking current cursor positions,
170#  advance each cursor through occurrences of a character
171#  class identified by ScanStream.
172
173def ScanThru(Cursors, ScanStream):
174        return (Cursors + ScanStream) & ~ScanStream
175
176#
177# Advance all cursors by one position.
178def Advance(stream):
179        return stream + stream
180
Note: See TracBrowser for help on using the repository browser.