-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathbinary.py
108 lines (85 loc) · 2.51 KB
/
binary.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
96
97
98
99
100
101
102
103
104
105
106
import sys
import struct
import array
import pytz
WORD_SIZE = struct.calcsize('L')
if sys.maxsize == 2**63-1:
ADDR_SIZE = 8
ADDR_CHAR = 'q'
else:
ADDR_SIZE = 4
ADDR_CHAR = 'l'
PY3 = sys.version_info[0] >= 3
def read_word(fileobj):
"""Read a single long from `fileobj`."""
b = fileobj.read(WORD_SIZE)
#do not use UNPACK_CHAR here
r = int(struct.unpack('l', b)[0])
return r
def read_addr(fileobj):
return struct.unpack(ADDR_CHAR, fileobj.read(ADDR_SIZE))[0]
def read_addresses(fileobj, count):
"""Read `addresses` longs from `fileobj`."""
if PY3:
r = array.array(ADDR_CHAR)
b = fileobj.read(ADDR_SIZE * count)
r.frombytes(b)
else:
r = [struct.unpack(ADDR_CHAR, fileobj.read(ADDR_SIZE))[0] \
for i in range(count)]
return r
def read_byte(fileobj):
value = fileobj.read(1)
if PY3:
return value[0]
return ord(value[0])
def read_char(fileobj):
value = fileobj.read(1)
if PY3:
return chr(value[0])
return value[0]
def read_bytes(fileobj):
lgt = int(struct.unpack('<i', fileobj.read(4))[0])
return fileobj.read(lgt)
def read_string(fileobj, little_endian=False):
if little_endian:
lgt = int(struct.unpack('<i', fileobj.read(4))[0])
data = fileobj.read(lgt)
if PY3:
data = data.decode('utf-8')
return data
else:
lgt = int(struct.unpack('l', fileobj.read(WORD_SIZE))[0])
return fileobj.read(lgt)
def read_le_u16(fileobj):
return int(struct.unpack('<H', fileobj.read(2))[0])
def read_le_u64(fileobj):
return int(struct.unpack('<Q', fileobj.read(8))[0])
def read_s64(fileobj):
return int(struct.unpack('q', fileobj.read(8))[0])
def read_le_s64(fileobj):
return int(struct.unpack('<q', fileobj.read(8))[0])
def read_timeval(fileobj):
tv_sec = read_s64(fileobj)
tv_usec = read_s64(fileobj)
return tv_sec * 10**6 + tv_usec
def read_timezone(fileobj):
timezone = fileobj.read(8).strip(b'\x00')
timezone = timezone.decode('ascii')
if timezone:
return pytz.timezone(timezone)
return None
def encode_le_u16(value):
return struct.pack('<H', value)
def encode_le_s32(value):
return struct.pack('<i', value)
def encode_le_u32(value):
return struct.pack('<I', value)
def encode_le_s64(value):
return struct.pack('<q', value)
def encode_le_u64(value):
return struct.pack('<Q', value)
def encode_str(val):
if PY3:
val = val.encode()
return struct.pack("<i", len(val)) + val