@@ -292,28 +292,29 @@ def align_to_byte
292
292
end
293
293
294
294
def read_bits_int_be ( n )
295
+ res = 0
296
+
295
297
bits_needed = n - @bits_left
298
+ @bits_left = -bits_needed % 8
299
+
296
300
if bits_needed > 0
297
301
# 1 bit => 1 byte
298
302
# 8 bits => 1 byte
299
303
# 9 bits => 2 bytes
300
- bytes_needed = ( ( bits_needed - 1 ) / 8 ) + 1
304
+ bytes_needed = ( ( bits_needed - 1 ) / 8 ) + 1 # `ceil(bits_needed / 8)`
301
305
buf = read_bytes ( bytes_needed )
302
306
buf . each_byte { |byte |
303
- @bits <<= 8
304
- @bits |= byte
305
- @bits_left += 8
307
+ res = res << 8 | byte
306
308
}
309
+
310
+ new_bits = res
311
+ res = res >> @bits_left | @bits << bits_needed
312
+ @bits = new_bits # will be masked at the end of the function
313
+ else
314
+ res = @bits >> -bits_needed # shift unneeded bits out
307
315
end
308
316
309
- # raw mask with required number of 1s, starting from lowest bit
310
- mask = ( 1 << n ) - 1
311
- # shift @bits to align the highest bits with the mask & derive reading result
312
- shift_bits = @bits_left - n
313
- res = ( @bits >> shift_bits ) & mask
314
- # clear top bits that we've just read => AND with 1s
315
- @bits_left -= n
316
- mask = ( 1 << @bits_left ) - 1
317
+ mask = ( 1 << @bits_left ) - 1 # `@bits_left` is in range 0..7
317
318
@bits &= mask
318
319
319
320
res
@@ -326,28 +327,34 @@ def read_bits_int(n)
326
327
end
327
328
328
329
def read_bits_int_le ( n )
330
+ res = 0
329
331
bits_needed = n - @bits_left
330
- if bits_needed > 0
332
+
333
+ if bits_needed > 0 then
331
334
# 1 bit => 1 byte
332
335
# 8 bits => 1 byte
333
336
# 9 bits => 2 bytes
334
- bytes_needed = ( ( bits_needed - 1 ) / 8 ) + 1
337
+ bytes_needed = ( ( bits_needed - 1 ) / 8 ) + 1 # `ceil(bits_needed / 8)`
335
338
buf = read_bytes ( bytes_needed )
339
+ i = 0
336
340
buf . each_byte { |byte |
337
- @bits |= ( byte << @bits_left )
338
- @bits_left += 8
341
+ res |= byte << ( i * 8 )
342
+ i += 1
339
343
}
344
+
345
+ new_bits = res >> bits_needed
346
+ res = res << @bits_left | @bits
347
+ @bits = new_bits
348
+ else
349
+ res = @bits
350
+ @bits >>= n
340
351
end
341
352
342
- # raw mask with required number of 1s, starting from lowest bit
343
- mask = ( 1 << n ) - 1
344
- # derive reading result
345
- res = @bits & mask
346
- # remove bottom bits that we've just read by shifting
347
- @bits >>= n
348
- @bits_left -= n
353
+ @bits_left = -bits_needed % 8
349
354
350
- res
355
+ mask = ( 1 << n ) - 1 # no problem with this in Ruby (arbitrary precision integers)
356
+ res &= mask
357
+ return res
351
358
end
352
359
353
360
# @!endgroup
0 commit comments