class NonblockingIOWrapper

Provides a platform-independent, non-blocking wrapper for reading an {ruby-doc.org/core-2.2.2/IO.html IO}-like object. This wrapper object must be enumerated using the {#each} method.

Public Class Methods

new(io, read_length = (128 * 1024)) click to toggle source

Initialize this wrapper around the io object and read at most read_length bytes in a non-blocking manner.

@param [IO] io an IO-like object @param [Fixnum] read_length the buffer length to read

# File lib/bel_parser/parsers/nonblocking_io_wrapper.rb, line 10
def initialize(io, read_length = (128 * 1024))
  @io          = io
  @read_length = read_length
  @read_method = nonblocking_read(@io)
end

Public Instance Methods

each() { |buffer| ... } click to toggle source

Yields each buffer read from the wrapped IO-like object to the provided block (e.g. +{ |block| … }+). The read length is set on {#initialize}.

@yield the buffers read from the IO-like object @yieldparam [String] buffer the read buffer as uninterpreted bytes

# File lib/bel_parser/parsers/nonblocking_io_wrapper.rb, line 21
def each
  while (buffer = @read_method.call(@read_length))
    yield buffer
  end
rescue IO::WaitReadable
  IO.select([@io])
  retry
# rubocop:disable HandleExceptions
rescue EOFError
  # end of stream; parsing complete
end

Private Instance Methods

nonblocking_read(io) click to toggle source

Returns the method, appropriate for your platform, to read IO in a non-blocking manner.

@example Call directly.

nonblocking_read(StringIO.new('hello')).call(4)

@param [IO] io an IO-like object @return [Method] a non-blocking read method

# File lib/bel_parser/parsers/nonblocking_io_wrapper.rb, line 43
def nonblocking_read(io)
  if Gem.win_platform?
    io.method(:sysread)
  else
    io.method(:read_nonblock)
  end
end