-
Notifications
You must be signed in to change notification settings - Fork 43
/
binary_out.py
95 lines (80 loc) · 2.15 KB
/
binary_out.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Created for BADS 2018
# See README.md for details
# This is python3
import struct
import sys
"""
Binary output. This class provides methods for converting
some primitive type variables (boolean, byte, char, and int)
to sequences of bits and writing them
to an output stream.
The output stream can be standard output or another outputstream.
Uses big-endian (most-significant byte first).
The client must flush() the output stream when finished writing bits.
The client should not intermix calls to BinaryOut with calls to stdout;
otherwise unexpected behavior will result.
"""
class BinaryOut:
def __init__(self, os=sys.stdout):
"""
Initializes a binary output stream from a
specified output stream. Defaults to stdin.
:param os: the output streamt to write to.
"""
self.out = os.buffer
self.buffer = 0 #8-bit buffer of bits to write out
self.n = 0 #number of bits used in buffer
def _writeBit(self, x):
self.buffer <<= 1
if(x):
self.buffer |=1
self.n += 1
if(self.n == 8):
self._clearBuffer()
def _writeByte(self, x):
assert x >= 0 and x < 256
#optimized if byte-alligned
if(self.n == 0):
self.out.write(struct.pack('B',x))
return
#otherwise write one bit at a time
for i in range(0,8):
bit = ((x >> (8 - i - 1)) & 1) == 1
self._writeBit(bit)
def _clearBuffer(self):
if(self.n == 0):
return
if(self.n > 0):
self.buffer <<= (8-self.n)
self.out.write(self.buffer.to_bytes(1,'big'))
self.n = 0
self.buffer = 0
def flush(self):
self._clearBuffer()
self.out.flush()
def close(self):
self.flush()
self.out.close()
def write_bool(self,x):
self._writeBit(x)
def write_byte(self,x):
self._writeByte(x & 0xff)
def write_int(self,x):
self._writeByte(((x >> 24)& 0xff))
self._writeByte(((x >> 16)& 0xff))
self._writeByte(((x >> 8)& 0xff))
self._writeByte(((x >> 0)& 0xff))
def write_char(self, x):
if(ord(x)<0 or ord(x)>=256):
raise ValueError("Illegal 8-bit char = {}".format(x))
self._writeByte(ord(x))
def write_string(self, s):
for i in s:
self.write_char(s[i])
def main():
out = BinaryOut()
for i in sys.argv[1]:
out.write_char(i)
out.close()
if __name__ == '__main__':
main()