class NIO::ByteBuffer

Efficient byte buffers for performant I/O operations

def [](index)

Returns:
  • (Integer) - byte at the given index

Raises:
  • (ArgumentError) - index is invalid (either negative or larger than limit)
def [](index)
  raise ArgumentError, "negative index given" if index < 0
  raise ArgumentError, "specified index exceeds limit" if index >= @limit
  @buffer.bytes[index]
end

def clear

Clear the buffer, resetting it to the default state
def clear
  @buffer   = ("\0" * @capacity).force_encoding(Encoding::BINARY)
  @position = 0
  @limit    = @capacity
  @mark     = nil
  self
end

def compact

Sets the position to the end of the moved data, and the limit to the capacity
Move data between the position and limit to the beginning of the buffer
def compact
  @buffer[0...(@limit - @position)] = @buffer[@position...@limit]
  @position = @limit - @position
  @limit = capacity
  self
end

def each(&block)

Returns:
  • (self) -
def each(&block)
  @buffer[0...@limit].each_byte(&block)
end

def flip

Set the buffer's current position as the limit and set the position to 0
def flip
  @limit = @position
  @position = 0
  @mark = nil
  self
end

def full?

Returns:
  • (true, false) -
def full?
  remaining.zero?
end

def get(length = remaining)

Returns:
  • (String) - bytes read from buffer

Raises:
  • (NIO::ByteBuffer::UnderflowError) - not enough data remaining in buffer
def get(length = remaining)
  raise ArgumentError, "negative length given" if length < 0
  raise UnderflowError, "not enough data in buffer" if length > @limit - @position
  result = @buffer[@position...length]
  @position += length
  result
end

def initialize(capacity)

Returns:
  • (NIO::ByteBuffer) -

Parameters:
  • capacity (Integer) -- size of buffer in bytes
def initialize(capacity)
  raise TypeError, "no implicit conversion of #{capacity.class} to Integer" unless capacity.is_a?(Integer)
  @capacity = capacity
  clear
end

def inspect

Returns:
  • (String) - string describing the state of the buffer
def inspect
  format(
    "#<%s:0x%x @position=%d @limit=%d @capacity=%d>",
    self.class,
    object_id << 1,
    @position,
    @limit,
    @capacity
  )
end

def limit=(new_limit)

Raises:
  • (ArgumentError) - new limit was invalid

Parameters:
  • new_limit (Integer) -- position in the buffer
def limit=(new_limit)
  raise ArgumentError, "negative limit given" if new_limit < 0
  raise ArgumentError, "specified limit exceeds capacity" if new_limit > @capacity
  @position = new_limit if @position > new_limit
  @mark = nil if @mark && @mark > new_limit
  @limit = new_limit
end

def mark

Mark a position to return to using the `#reset` method
def mark
  @mark = @position
  self
end

def position=(new_position)

Raises:
  • (ArgumentError) - new position was invalid

Parameters:
  • new_position (Integer) -- position in the buffer
def position=(new_position)
  raise ArgumentError, "negative position given" if new_position < 0
  raise ArgumentError, "specified position exceeds capacity" if new_position > @capacity
  @mark = nil if @mark && @mark > new_position
  @position = new_position
end

def put(str)

Returns:
  • (self) -

Raises:
  • (NIO::ByteBuffer::OverflowError) - buffer is full
  • (TypeError) - given a non-string type

Parameters:
  • str (#to_str) -- data to add to the buffer
def put(str)
  raise TypeError, "expected String, got #{str.class}" unless str.respond_to?(:to_str)
  str = str.to_str
  raise OverflowError, "buffer is full" if str.length > @limit - @position
  @buffer[@position...str.length] = str
  @position += str.length
  self
end

def read_from(io)

Returns:
  • (Integer) - number of bytes read (0 if none were available)

Parameters:
  • Ruby (IO) -- IO object to read from
def read_from(io)
  nbytes = @limit - @position
  raise OverflowError, "buffer is full" if nbytes.zero?
  bytes_read = IO.try_convert(io).read_nonblock(nbytes, exception: false)
  return 0 if bytes_read == :wait_readable
  self << bytes_read
  bytes_read.length
end

def remaining

Returns:
  • (Integer) - number of bytes remaining
def remaining
  @limit - @position
end

def reset

Raises:
  • (NIO::ByteBuffer::MarkUnsetError) - mark has not been set (call `#mark` first)
def reset
  raise MarkUnsetError, "mark has not been set" unless @mark
  @position = @mark
  self
end

def rewind

Set the buffer's current position to 0, leaving the limit unchanged
def rewind
  @position = 0
  @mark = nil
  self
end

def write_to(io)

Returns:
  • (Integer) - number of bytes written (0 if the write would block)

Parameters:
  • Ruby (IO) -- IO object to write to
def write_to(io)
  nbytes = @limit - @position
  raise UnderflowError, "no data remaining in buffer" if nbytes.zero?
  bytes_written = IO.try_convert(io).write_nonblock(@buffer[@position...@limit], exception: false)
  return 0 if bytes_written == :wait_writable
  @position += bytes_written
  bytes_written
end