-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathbinarystdin.py
89 lines (79 loc) · 2.03 KB
/
binarystdin.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
import sys
class BinaryStdin:
buffer = 0
n = 0
initialized = False
@classmethod
def read_str(cls):
if cls.is_empty():
raise Exception("reading from empty input stream")
s = []
while not cls.is_empty():
b = cls.read_byte()
s.append(chr(b))
return "".join(s)
@classmethod
def read_int(cls):
if cls.is_empty():
raise Exception("reading from empty input stream")
x = 0
for i in range(4):
b = cls.read_byte()
x <<= 8
x |= b
return x
@classmethod
def read_int_r(cls, r):
if r < 1 or r > 32:
raise Exception("invalid r")
if r == 32:
return cls.read_int()
x = 0
for i in range(r):
x <<= 1
bit = cls.read_bool()
if bit:
x |= 1
return x
@classmethod
def read_byte(cls):
if cls.is_empty():
raise Exception("reading from empty input stream")
if cls.n == 8:
b = cls.buffer
cls.fill_buffer()
return b
x = cls.buffer
x <<= (8-cls.n)
old_n = cls.n
cls.fill_buffer()
cls.n = old_n
x |= (cls.buffer >> cls.n)
return x & 0xff
@classmethod
def read_bool(cls):
if cls.is_empty():
raise Exception("reading from empty input stream")
cls.n -= 1
bit = (cls.buffer >> cls.n & 1) == 1
if cls.n == 0:
cls.fill_buffer()
return bit
@classmethod
def fill_buffer(cls):
byte = sys.stdin.buffer.read(1)
if byte == b'':
cls.buffer = EOFError
cls.n = -1
return
cls.n = 8
cls.buffer = ord(byte)
@classmethod
def initialize(cls):
cls.fill_buffer()
cls.initialized = True
@classmethod
def is_empty(cls):
if not cls.initialized:
cls.initialize()
return cls.buffer == EOFError