@@ -218,31 +218,33 @@ def read_f8le(self):
218
218
# ========================================================================
219
219
220
220
def align_to_byte (self ):
221
- self .bits = 0
222
221
self .bits_left = 0
222
+ self .bits = 0
223
223
224
224
def read_bits_int_be (self , n ):
225
+ res = 0
226
+
225
227
bits_needed = n - self .bits_left
228
+ self .bits_left = - bits_needed % 8
229
+
226
230
if bits_needed > 0 :
227
231
# 1 bit => 1 byte
228
232
# 8 bits => 1 byte
229
233
# 9 bits => 2 bytes
230
- bytes_needed = ((bits_needed - 1 ) // 8 ) + 1
234
+ bytes_needed = ((bits_needed - 1 ) // 8 ) + 1 # `ceil(bits_needed / 8)`
231
235
buf = self .read_bytes (bytes_needed )
236
+ if PY2 :
237
+ buf = bytearray (buf )
232
238
for byte in buf :
233
- byte = KaitaiStream .int_from_byte (byte )
234
- self .bits <<= 8
235
- self .bits |= byte
236
- self .bits_left += 8
237
-
238
- # raw mask with required number of 1s, starting from lowest bit
239
- mask = (1 << n ) - 1
240
- # shift self.bits to align the highest bits with the mask & derive reading result
241
- shift_bits = self .bits_left - n
242
- res = (self .bits >> shift_bits ) & mask
243
- # clear top bits that we've just read => AND with 1s
244
- self .bits_left -= n
245
- mask = (1 << self .bits_left ) - 1
239
+ res = res << 8 | byte
240
+
241
+ new_bits = res
242
+ res = res >> self .bits_left | self .bits << bits_needed
243
+ self .bits = new_bits # will be masked at the end of the function
244
+ else :
245
+ res = self .bits >> - bits_needed # shift unneeded bits out
246
+
247
+ mask = (1 << self .bits_left ) - 1 # `bits_left` is in range 0..7
246
248
self .bits &= mask
247
249
248
250
return res
@@ -253,26 +255,31 @@ def read_bits_int(self, n):
253
255
return self .read_bits_int_be (n )
254
256
255
257
def read_bits_int_le (self , n ):
258
+ res = 0
256
259
bits_needed = n - self .bits_left
260
+
257
261
if bits_needed > 0 :
258
262
# 1 bit => 1 byte
259
263
# 8 bits => 1 byte
260
264
# 9 bits => 2 bytes
261
- bytes_needed = ((bits_needed - 1 ) // 8 ) + 1
265
+ bytes_needed = ((bits_needed - 1 ) // 8 ) + 1 # `ceil(bits_needed / 8)`
262
266
buf = self .read_bytes (bytes_needed )
263
- for byte in buf :
264
- byte = KaitaiStream .int_from_byte (byte )
265
- self .bits |= (byte << self .bits_left )
266
- self .bits_left += 8
267
-
268
- # raw mask with required number of 1s, starting from lowest bit
269
- mask = (1 << n ) - 1
270
- # derive reading result
271
- res = self .bits & mask
272
- # remove bottom bits that we've just read by shifting
273
- self .bits >>= n
274
- self .bits_left -= n
267
+ if PY2 :
268
+ buf = bytearray (buf )
269
+ for i , byte in enumerate (buf ):
270
+ res |= byte << (i * 8 )
271
+
272
+ new_bits = res >> bits_needed
273
+ res = res << self .bits_left | self .bits
274
+ self .bits = new_bits
275
+ else :
276
+ res = self .bits
277
+ self .bits >>= n
278
+
279
+ self .bits_left = - bits_needed % 8
275
280
281
+ mask = (1 << n ) - 1 # no problem with this in Python (arbitrary precision integers)
282
+ res &= mask
276
283
return res
277
284
278
285
# ========================================================================
0 commit comments