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) super(io) @wnbits = 0 @wval = 0 @wendian = nil end
def mask(nbits)
def mask(nbits) (1 << nbits) - 1 end
def offset
Returns the current offset of the io stream. Offset will be rounded
def offset offset_raw + (@wnbits > 0 ? 1 : 0) end
def seekbytes(n)
def seekbytes(n) flushbits seek(n) end
def with_buffer(n)
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) with_buffer_common(n) do |_buf_start, buf_end| yield write("\0" * (buf_end - offset)) end end
def write(data)
def write(data) n = buffer_limited_n(data.size) if n < data.size data = data[0, n] end write_raw(data) 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(@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(@wval.chr) @wval = 0 @wnbits = 0 else @wval = @wval | (val << @wnbits) @wnbits += nbits nbits = 0 end end 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(str) end