Skip to content

Commit d93322f

Browse files
committed
Adds new read methods for ByteDecoders.
read_cstring: reads NULL terminated c-style strings read_uint: read arbitrary length unsigned integers
1 parent 465dc71 commit d93322f

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

sc2reader/decoders.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,19 @@ def __init__(self, contents, endian):
4747
self.tell = self._buffer.tell
4848

4949
# decode the endian value if necessary
50-
endian = endian.lower()
51-
if endian.lower() == 'little':
52-
endian = "<"
53-
elif endian.lower() == 'big':
54-
endian = ">"
55-
elif endian not in ('<','>'):
56-
raise ValueError("Endian must be one of 'little', '<', 'big', or '>' but was: "+endian)
50+
self.endian = endian.lower()
51+
if self.endian.lower() == 'little':
52+
self.endian = "<"
53+
elif self.endian.lower() == 'big':
54+
self.endian = ">"
55+
elif self.endian not in ('<', '>'):
56+
raise ValueError("Endian must be one of 'little', '<', 'big', or '>' but was: "+self.endian)
5757

5858
# Pre-compiling
59-
self._unpack_int = struct.Struct(endian+'I').unpack
60-
self._unpack_short = struct.Struct(endian+'H').unpack
61-
self._unpack_longlong = struct.Struct(endian+'Q').unpack
62-
self._unpack_bytes = lambda bytes: bytes if endian == '>' else bytes[::-1]
59+
self._unpack_int = struct.Struct(self.endian+'I').unpack
60+
self._unpack_short = struct.Struct(self.endian+'H').unpack
61+
self._unpack_longlong = struct.Struct(self.endian+'Q').unpack
62+
self._unpack_bytes = lambda bytes: bytes if self.endian == '>' else bytes[::-1]
6363

6464
def done(self):
6565
""" Returns true when all bytes have been decoded """
@@ -94,6 +94,25 @@ def read_bytes(self, count):
9494
""" Returns the next ``count`` bytes as a byte string """
9595
return self._unpack_bytes(self.read(count))
9696

97+
def read_uint(self, count):
98+
""" Returns the next ``count`` bytes as an unsigned integer """
99+
unpack = struct.Struct(self.endian+'B'*count).unpack
100+
uint = 0
101+
for byte in unpack(self.read(count)):
102+
uint = uint << 8 | byte
103+
return uint
104+
105+
def read_cstring(self):
106+
""" Read a NULL byte terminated character string. Ignores endian. """
107+
cstring = StringIO()
108+
while True:
109+
c = self.read(1)
110+
if ord(c) == 0:
111+
return cstring.getvalue()
112+
else:
113+
cstring.write(c)
114+
115+
97116
class BitPackedDecoder(object):
98117
"""
99118
:param contents: The string of file-like object to decode

0 commit comments

Comments
 (0)