RosettaCodeData/Task/Bitwise-IO/Python/bitwise-io-1.py

90 lines
2.3 KiB
Python
Raw Permalink Normal View History

2016-12-05 22:15:40 +01:00
class BitWriter(object):
2013-04-10 16:19:29 -07:00
def __init__(self, f):
self.accumulator = 0
self.bcount = 0
self.out = f
2018-06-22 20:57:24 +00:00
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.flush()
2013-04-10 16:19:29 -07:00
def __del__(self):
2015-11-18 06:14:39 +00:00
try:
self.flush()
2018-06-22 20:57:24 +00:00
except ValueError: # I/O operation on closed file.
2015-11-18 06:14:39 +00:00
pass
2013-04-10 16:19:29 -07:00
2016-12-05 22:15:40 +01:00
def _writebit(self, bit):
if self.bcount == 8:
2013-04-10 16:19:29 -07:00
self.flush()
if bit > 0:
2016-12-05 22:15:40 +01:00
self.accumulator |= 1 << 7-self.bcount
2013-04-10 16:19:29 -07:00
self.bcount += 1
def writebits(self, bits, n):
while n > 0:
2016-12-05 22:15:40 +01:00
self._writebit(bits & 1 << n-1)
2013-04-10 16:19:29 -07:00
n -= 1
def flush(self):
2016-12-05 22:15:40 +01:00
self.out.write(bytearray([self.accumulator]))
2013-04-10 16:19:29 -07:00
self.accumulator = 0
self.bcount = 0
2016-12-05 22:15:40 +01:00
class BitReader(object):
2013-04-10 16:19:29 -07:00
def __init__(self, f):
self.input = f
self.accumulator = 0
self.bcount = 0
self.read = 0
2018-06-22 20:57:24 +00:00
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
2016-12-05 22:15:40 +01:00
def _readbit(self):
if not self.bcount:
2013-04-10 16:19:29 -07:00
a = self.input.read(1)
2016-12-05 22:15:40 +01:00
if a:
2013-04-10 16:19:29 -07:00
self.accumulator = ord(a)
self.bcount = 8
self.read = len(a)
2016-12-05 22:15:40 +01:00
rv = (self.accumulator & (1 << self.bcount-1)) >> self.bcount-1
2013-04-10 16:19:29 -07:00
self.bcount -= 1
return rv
def readbits(self, n):
v = 0
while n > 0:
2016-12-05 22:15:40 +01:00
v = (v << 1) | self._readbit()
2013-04-10 16:19:29 -07:00
n -= 1
return v
2016-12-05 22:15:40 +01:00
if __name__ == '__main__':
import os
import sys
2018-06-22 20:57:24 +00:00
# Determine this module's name from it's file name and import it.
2016-12-05 22:15:40 +01:00
module_name = os.path.splitext(os.path.basename(__file__))[0]
bitio = __import__(module_name)
with open('bitio_test.dat', 'wb') as outfile:
2018-06-22 20:57:24 +00:00
with bitio.BitWriter(outfile) as writer:
chars = '12345abcde'
for ch in chars:
writer.writebits(ord(ch), 7)
2016-12-05 22:15:40 +01:00
with open('bitio_test.dat', 'rb') as infile:
2018-06-22 20:57:24 +00:00
with bitio.BitReader(infile) as reader:
chars = []
while True:
x = reader.readbits(7)
if not reader.read: # End-of-file?
break
chars.append(chr(x))
print(''.join(chars))