Class: Cabriolet::Binary::Bitstream
- Inherits:
-
Object
- Object
- Cabriolet::Binary::Bitstream
- Defined in:
- lib/cabriolet/binary/bitstream.rb
Overview
Bitstream provides bit-level I/O operations for reading compressed data
Instance Attribute Summary collapse
-
#buffer_size ⇒ Object
readonly
Returns the value of attribute buffer_size.
-
#handle ⇒ Object
readonly
Returns the value of attribute handle.
-
#io_system ⇒ Object
readonly
Returns the value of attribute io_system.
Instance Method Summary collapse
-
#byte_align ⇒ void
Align to the next byte boundary.
-
#initialize(io_system, handle, buffer_size = Cabriolet.default_buffer_size) ⇒ Bitstream
constructor
Initialize a new bitstream.
-
#peek_bits(num_bits) ⇒ Integer
Peek at bits without consuming them.
-
#read_bits(num_bits) ⇒ Integer
Read specified number of bits from the stream.
-
#read_bits_be(num_bits) ⇒ Integer
Read bits in big-endian (MSB first) order.
-
#read_byte ⇒ Integer?
Read a single byte from the input.
-
#read_uint16_le ⇒ Integer
Read a 16-bit little-endian value.
-
#read_uint32_le ⇒ Integer
Read a 32-bit little-endian value.
-
#reset ⇒ void
Reset the bitstream state.
-
#skip_bits(num_bits) ⇒ void
Skip specified number of bits.
Constructor Details
#initialize(io_system, handle, buffer_size = Cabriolet.default_buffer_size) ⇒ Bitstream
Initialize a new bitstream
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/cabriolet/binary/bitstream.rb', line 14 def initialize(io_system, handle, buffer_size = Cabriolet.default_buffer_size) @io_system = io_system @handle = handle @buffer_size = buffer_size @buffer = "" @buffer_pos = 0 @bit_buffer = 0 @bits_left = 0 end |
Instance Attribute Details
#buffer_size ⇒ Object (readonly)
Returns the value of attribute buffer_size.
7 8 9 |
# File 'lib/cabriolet/binary/bitstream.rb', line 7 def buffer_size @buffer_size end |
#handle ⇒ Object (readonly)
Returns the value of attribute handle.
7 8 9 |
# File 'lib/cabriolet/binary/bitstream.rb', line 7 def handle @handle end |
#io_system ⇒ Object (readonly)
Returns the value of attribute io_system.
7 8 9 |
# File 'lib/cabriolet/binary/bitstream.rb', line 7 def io_system @io_system end |
Instance Method Details
#byte_align ⇒ void
This method returns an undefined value.
Align to the next byte boundary
71 72 73 74 75 |
# File 'lib/cabriolet/binary/bitstream.rb', line 71 def byte_align discard_bits = @bits_left % 8 @bit_buffer >>= discard_bits @bits_left -= discard_bits end |
#peek_bits(num_bits) ⇒ Integer
Peek at bits without consuming them
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/cabriolet/binary/bitstream.rb', line 81 def peek_bits(num_bits) if num_bits < 1 || num_bits > 32 raise ArgumentError, "Can only peek 1-32 bits at a time" end # Ensure we have enough bits while @bits_left < num_bits byte = read_byte return 0 if byte.nil? @bit_buffer |= (byte << @bits_left) @bits_left += 8 end @bit_buffer & ((1 << num_bits) - 1) end |
#read_bits(num_bits) ⇒ Integer
Read specified number of bits from the stream
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/cabriolet/binary/bitstream.rb', line 30 def read_bits(num_bits) if num_bits < 1 || num_bits > 32 raise ArgumentError, "Can only read 1-32 bits at a time" end # Ensure we have enough bits in the buffer while @bits_left < num_bits byte = read_byte return 0 if byte.nil? # EOF @bit_buffer |= (byte << @bits_left) @bits_left += 8 end # Extract the requested bits result = @bit_buffer & ((1 << num_bits) - 1) @bit_buffer >>= num_bits @bits_left -= num_bits result end |
#read_bits_be(num_bits) ⇒ Integer
Read bits in big-endian (MSB first) order
112 113 114 115 116 117 118 |
# File 'lib/cabriolet/binary/bitstream.rb', line 112 def read_bits_be(num_bits) result = 0 num_bits.times do result = (result << 1) | read_bits(1) end result end |
#read_byte ⇒ Integer?
Read a single byte from the input
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/cabriolet/binary/bitstream.rb', line 56 def read_byte if @buffer_pos >= @buffer.bytesize @buffer = @io_system.read(@handle, @buffer_size) @buffer_pos = 0 return nil if @buffer.empty? end byte = @buffer.getbyte(@buffer_pos) @buffer_pos += 1 byte end |
#read_uint16_le ⇒ Integer
Read a 16-bit little-endian value
123 124 125 |
# File 'lib/cabriolet/binary/bitstream.rb', line 123 def read_uint16_le read_bits(16) end |
#read_uint32_le ⇒ Integer
Read a 32-bit little-endian value
130 131 132 133 134 |
# File 'lib/cabriolet/binary/bitstream.rb', line 130 def read_uint32_le low = read_bits(16) high = read_bits(16) (high << 16) | low end |
#reset ⇒ void
This method returns an undefined value.
Reset the bitstream state
139 140 141 142 143 144 145 |
# File 'lib/cabriolet/binary/bitstream.rb', line 139 def reset @buffer = "" @buffer_pos = 0 @bit_buffer = 0 @bits_left = 0 @io_system.seek(@handle, 0, Constants::SEEK_START) end |
#skip_bits(num_bits) ⇒ void
This method returns an undefined value.
Skip specified number of bits
103 104 105 106 |
# File 'lib/cabriolet/binary/bitstream.rb', line 103 def skip_bits(num_bits) read_bits(num_bits) nil end |