Class: Cabriolet::Binary::BitstreamWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/cabriolet/binary/bitstream_writer.rb

Overview

BitstreamWriter provides bit-level I/O operations for writing compressed data

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_system, handle, buffer_size = Cabriolet.default_buffer_size, msb_first: false) ⇒ BitstreamWriter

Initialize a new bitstream writer

Parameters:

  • io_system (System::IOSystem)

    I/O system for writing data

  • handle (System::FileHandle, System::MemoryHandle)

    Handle to write to

  • buffer_size (Integer) (defaults to: Cabriolet.default_buffer_size)

    Size of the output buffer

  • msb_first (Boolean) (defaults to: false)

    Whether to write bits MSB-first (for Quantum)



15
16
17
18
19
20
21
22
23
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 15

def initialize(io_system, handle,
buffer_size = Cabriolet.default_buffer_size, msb_first: false)
  @io_system = io_system
  @handle = handle
  @buffer_size = buffer_size
  @msb_first = msb_first
  @bit_buffer = 0
  @bits_in_buffer = 0
end

Instance Attribute Details

#buffer_sizeObject (readonly)

Returns the value of attribute buffer_size.



7
8
9
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 7

def buffer_size
  @buffer_size
end

#handleObject (readonly)

Returns the value of attribute handle.



7
8
9
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 7

def handle
  @handle
end

#io_systemObject (readonly)

Returns the value of attribute io_system.



7
8
9
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 7

def io_system
  @io_system
end

Instance Method Details

#byte_alignvoid

This method returns an undefined value.

Align to the next byte boundary by padding with zeros



53
54
55
56
57
58
59
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 53

def byte_align
  return if @bits_in_buffer.zero?

  # Pad with zeros to complete the current byte
  padding_bits = 8 - (@bits_in_buffer % 8)
  write_bits(0, padding_bits) if padding_bits < 8
end

#flushvoid

This method returns an undefined value.

Flush any remaining bits in the buffer



64
65
66
67
68
69
70
71
72
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 64

def flush
  return if @bits_in_buffer.zero?

  # Write any remaining bits (padded with zeros)
  byte = @bit_buffer & 0xFF
  write_byte(byte)
  @bit_buffer = 0
  @bits_in_buffer = 0
end

#flush_msbvoid

This method returns an undefined value.

Flush MSB buffer (write remaining bits padded to 16-bit boundary)



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 160

def flush_msb
  return if @bits_in_buffer.zero?

  # Pad to 16-bit boundary
  padding = (16 - @bits_in_buffer) % 16
  @bit_buffer <<= padding if padding.positive?
  @bits_in_buffer += padding

  # Write final 16-bit word
  if @bits_in_buffer == 16
    word = @bit_buffer & 0xFFFF
    write_byte((word >> 8) & 0xFF)
    write_byte(word & 0xFF)
  end

  @bit_buffer = 0
  @bits_in_buffer = 0
end

#write_bits(value, num_bits) ⇒ void

This method returns an undefined value.

Write specified number of bits to the stream

Parameters:

  • value (Integer)

    Value to write

  • num_bits (Integer)

    Number of bits to write (1-32)

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 31

def write_bits(value, num_bits)
  if num_bits < 1 || num_bits > 32
    raise ArgumentError,
          "Can only write 1-32 bits at a time"
  end

  # Add bits to buffer (LSB first, like DEFLATE)
  @bit_buffer |= ((value & ((1 << num_bits) - 1)) << @bits_in_buffer)
  @bits_in_buffer += num_bits

  # Flush complete bytes
  while @bits_in_buffer >= 8
    byte = @bit_buffer & 0xFF
    write_byte(byte)
    @bit_buffer >>= 8
    @bits_in_buffer -= 8
  end
end

#write_bits_be(value, num_bits) ⇒ void

This method returns an undefined value.

Write bits in big-endian (MSB first) order

Parameters:

  • value (Integer)

    Value to write

  • num_bits (Integer)

    Number of bits to write



107
108
109
110
111
112
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 107

def write_bits_be(value, num_bits)
  num_bits.times do |i|
    bit = (value >> (num_bits - 1 - i)) & 1
    write_bits(bit, 1)
  end
end

#write_bits_msb(value, num_bits) ⇒ void

This method returns an undefined value.

Write bits MSB-first (for Quantum compression) Accumulates bits and writes 16-bit words MSB-first

Parameters:

  • value (Integer)

    Value to write

  • num_bits (Integer)

    Number of bits to write



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 137

def write_bits_msb(value, num_bits)
  if num_bits < 1 || num_bits > 32
    raise ArgumentError,
          "Can only write 1-32 bits at a time"
  end

  # Add bits to buffer (MSB first)
  @bit_buffer = (@bit_buffer << num_bits) | (value & ((1 << num_bits) - 1))
  @bits_in_buffer += num_bits

  # Flush complete 16-bit words MSB-first
  while @bits_in_buffer >= 16
    @bits_in_buffer -= 16
    word = (@bit_buffer >> @bits_in_buffer) & 0xFFFF
    # Write MSB first
    write_byte((word >> 8) & 0xFF)
    write_byte(word & 0xFF)
  end
end

#write_byte(byte) ⇒ void

This method returns an undefined value.

Write a single byte to the output

Parameters:

  • byte (Integer)

    Byte value to write



78
79
80
81
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 78

def write_byte(byte)
  data = [byte].pack("C")
  @io_system.write(@handle, data)
end

#write_bytes(bytes) ⇒ void

This method returns an undefined value.

Write multiple bytes to the output

Parameters:

  • bytes (String, Array<Integer>)

    Bytes to write



97
98
99
100
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 97

def write_bytes(bytes)
  data = bytes.is_a?(String) ? bytes : bytes.pack("C*")
  @io_system.write(@handle, data)
end

#write_raw_byte(byte) ⇒ void

This method returns an undefined value.

Write a raw byte directly (for signatures, etc.) This ensures the bit buffer is flushed first

Parameters:

  • byte (Integer)

    Byte value to write



88
89
90
91
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 88

def write_raw_byte(byte)
  flush if @bits_in_buffer.positive?
  write_byte(byte)
end

#write_uint16_le(value) ⇒ void

This method returns an undefined value.

Write a 16-bit little-endian value

Parameters:

  • value (Integer)

    16-bit value



118
119
120
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 118

def write_uint16_le(value)
  write_bits(value & 0xFFFF, 16)
end

#write_uint32_le(value) ⇒ void

This method returns an undefined value.

Write a 32-bit little-endian value

Parameters:

  • value (Integer)

    32-bit value



126
127
128
129
# File 'lib/cabriolet/binary/bitstream_writer.rb', line 126

def write_uint32_le(value)
  write_bits(value & 0xFFFF, 16)
  write_bits((value >> 16) & 0xFFFF, 16)
end