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

To be called after all +writebits+ have been applied.
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
  @write_count = 0
  @bytes_remaining = nil
end

def mask(nbits)

def mask(nbits)
  (1 << nbits) - 1
end

def offset

up when writing bitfields.
Returns the current offset of the io stream. Offset will be rounded
def offset
  @write_count + (@wnbits > 0 ? 1 : 0)
end

def with_buffer(n, &block)

bytes.
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
  @write_count += data.size
  @raw_io.write(data)
end

def writebits(val, nbits, endian)

the bits are to be stored in +:big+ or +:little+ endian format.
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)

Writes the given string of bytes to the io stream.
def writebytes(str)
  flushbits
  write_raw(str)
end