Class: BinData::IO::Write

Inherits:
Object
  • Object
show all
Defined in:
lib/bindata/io.rb

Overview

Create a new IO Write wrapper around io. io must provide #write. If io is a string it will be automatically wrapped in an StringIO object.

The IO can handle bitstreams in either big or little endian format.

See IO::Read for more information.

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ Write

Returns a new instance of Write.



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/bindata/io.rb', line 184

def initialize(io)
  if self.class === io
    raise ArgumentError, "io must not be a #{self.class}"
  end

  # wrap strings in a StringIO
  if io.respond_to?(:to_str)
    io = BinData::IO.create_string_io(io.to_str)
  end

  @io = RawIO.new(io)

  @wnbits  = 0
  @wval    = 0
  @wendian = nil
end

Instance Method Details

#flushbitsObject Also known as: flush

To be called after all writebits have been applied.



251
252
253
254
255
256
257
# File 'lib/bindata/io.rb', line 251

def flushbits
  raise "Internal state error nbits = #{@wnbits}" if @wnbits >= 8

  if @wnbits > 0
    writebits(0, 8 - @wnbits, @wendian)
  end
end

#seek_to_abs_offset(n) ⇒ Object

Seek to an absolute offset within the io stream.

Raises:

  • (IOError)


219
220
221
222
223
224
# File 'lib/bindata/io.rb', line 219

def seek_to_abs_offset(n)
  raise IOError, "stream is unseekable" unless @io.seekable?

  flushbits
  @io.seek_abs(n)
end

#transform(io) ⇒ Object

Allow transforming data in the output stream. See BinData::Buffer as an example.

io must be an instance of Transform.

yields self and io to the given block



207
208
209
210
211
212
213
214
215
216
# File 'lib/bindata/io.rb', line 207

def transform(io)
  flushbits

  saved = @io
  @io = io.prepend_to_chain(@io)
  yield(self, io)
  io.after_write_transform
ensure
  @io = saved
end

#writebits(val, nbits, endian) ⇒ Object

Writes nbits bits from val to the stream. endian specifies whether the bits are to be stored in :big or :little endian format.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/bindata/io.rb', line 234

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

#writebytes(str) ⇒ Object

Writes the given string of bytes to the io stream.



227
228
229
230
# File 'lib/bindata/io.rb', line 227

def writebytes(str)
  flushbits
  write(str)
end