class BinData::IO::Write
See IO::Read for more information.
The IO can handle bitstreams in either big or little endian format.
object.
If io
is a string it will be automatically wrapped in an StringIO
Create a new IO Write wrapper around io
. io
must provide #write.
def flushbits
def flushbits raise "Internal state error nbits = #{@wnbits}" if @wnbits >= 8 if @wnbits > 0 writebits(0, 8 - @wnbits, @wendian) end end
def initialize(io)
def initialize(io) if BinData::IO::Write === io raise ArgumentError, "io must not be a BinData::IO::Write" end # wrap strings in a StringIO if io.respond_to?(:to_str) io = BinData::IO.create_string_io(io.to_str) end @raw_io = io @wnbits = 0 @wval = 0 @wendian = nil @bytes_remaining = nil end
def mask(nbits)
def mask(nbits) (1 << nbits) - 1 end
def with_buffer(n, &block)
are written inside the block, the remainder will be padded with '\0'
+block+ will be contained within this buffer. If less than +n+ bytes
Sets a buffer of +n+ bytes on the io stream. Any writes inside the
def with_buffer(n, &block) prev = @bytes_remaining if prev n = prev if n > prev prev -= n end @bytes_remaining = n begin block.call write_raw("\0" * @bytes_remaining) ensure @bytes_remaining = prev end end
def write_big_endian_bits(val, nbits)
def write_big_endian_bits(val, nbits) while nbits > 0 bits_req = 8 - @wnbits if nbits >= bits_req msb_bits = (val >> (nbits - bits_req)) & mask(bits_req) nbits -= bits_req val &= mask(nbits) @wval = (@wval << bits_req) | msb_bits write_raw(@wval.chr) @wval = 0 @wnbits = 0 else @wval = (@wval << nbits) | val @wnbits += nbits nbits = 0 end end end
def write_little_endian_bits(val, nbits)
def write_little_endian_bits(val, nbits) while nbits > 0 bits_req = 8 - @wnbits if nbits >= bits_req lsb_bits = val & mask(bits_req) nbits -= bits_req val >>= bits_req @wval = @wval | (lsb_bits << @wnbits) write_raw(@wval.chr) @wval = 0 @wnbits = 0 else @wval = @wval | (val << @wnbits) @wnbits += nbits nbits = 0 end end end
def write_raw(data)
def write_raw(data) if @bytes_remaining if data.size > @bytes_remaining data = data[0, @bytes_remaining] end @bytes_remaining -= data.size end @raw_io.write(data) end
def writebits(val, nbits, endian)
Writes +nbits+ bits from +val+ to the stream. +endian+ specifies whether
def writebits(val, nbits, endian) if @wendian != endian # don't mix bits of differing endian flushbits @wendian = endian end clamped_val = val & mask(nbits) if endian == :big write_big_endian_bits(clamped_val, nbits) else write_little_endian_bits(clamped_val, nbits) end end
def writebytes(str)
def writebytes(str) flushbits write_raw(str) end