Skip to content

Commit fced0f4

Browse files
committed
Apply some unfortunate optimizations to buffer.read_ functions.
1 parent 67a82fb commit fced0f4

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

sc2reader/utils.py

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,25 +150,71 @@ def read_byte(self):
150150
if self.bit_shift==0:
151151
return ord(self.read_basic(1))
152152
else:
153-
return self.read(1)[0]
153+
extra_bits = self.bit_shift
154+
hi_bits = self.last_byte >> extra_bits
155+
last_byte = ord(self.read_basic(1))
156+
lo_bits = last_byte & self.lo_masks[extra_bits]
157+
self.last_byte = last_byte
158+
return hi_bits << extra_bits | lo_bits
159+
154160

155161
def read_int(self, endian=LITTLE_ENDIAN):
156-
""" int32 read """
157-
chars = self.read_basic(4) if self.bit_shift==0 else self.read_chars(4)
158-
return struct.unpack(endian+'I', chars)[0]
162+
if self.bit_shift == 0:
163+
return struct.unpack(endian+'I', self.read_basic(4))[0]
164+
165+
else:
166+
old_bit_shift = self.bit_shift
167+
168+
# Get all the bytes at once
169+
hi_bits = self.shift(8 - old_bit_shift)
170+
block = struct.unpack('>I', self.read_basic(4))[0]
171+
172+
# Reformat them according to the rules
173+
number = (block >> 8) << old_bit_shift | (block & self.lo_masks[old_bit_shift])
174+
number += hi_bits << (24 + old_bit_shift)
175+
176+
# If the number is little endian, repack it
177+
if endian == LITTLE_ENDIAN:
178+
number = (number & 0xFF000000) >> 24 | (number & 0xFF0000) >> 8 | (number & 0xFF00) << 8 | (number & 0xFF) << 24
179+
180+
# Reset the shift
181+
self.last_byte = block & 0xFF
182+
self.bit_shift = old_bit_shift
183+
184+
return number
159185

160186
def read_short(self, endian=LITTLE_ENDIAN):
161187
""" short16 read """
162-
chars = self.read_basic(2) if self.bit_shift==0 else self.read_chars(2)
163-
return struct.unpack(endian+'H', chars)[0]
188+
if self.bit_shift == 0:
189+
return struct.unpack(endian+'H', self.read_basic(2))[0]
190+
191+
else:
192+
old_bit_shift = self.bit_shift
193+
194+
# Get all the bytes at once
195+
hi_bits = self.shift(8 - old_bit_shift)
196+
block = struct.unpack('>H', self.read_basic(2))[0]
197+
198+
# Reformat them according to the rules
199+
number = (block >> 8) << old_bit_shift | (block & self.lo_masks[old_bit_shift])
200+
number += hi_bits << (8 + old_bit_shift)
201+
202+
# If the number is little endian, repack it
203+
if endian == LITTLE_ENDIAN:
204+
number = (number & 0xFF00) >> 8 | (number & 0xFF) << 8
205+
206+
# Reset the shift
207+
self.last_byte = block & 0xFF
208+
self.bit_shift = old_bit_shift
209+
210+
return number
164211

165212
def read_chars(self, length=0):
166213
if self.bit_shift==0:
167214
return self.read_basic(length)
168215
else:
169216
self.char_buffer.truncate(0)
170-
for byte in self.read(length):
171-
self.char_buffer.write(chr(byte))
217+
self.char_buffer.writelines(map(chr,self.read(length)))
172218
return self.char_buffer.getvalue()
173219

174220
def read_hex(self, length=0):

0 commit comments

Comments
 (0)