Class: Proxy::Dynflow::IOBuffer

Inherits:
Object
  • Object
show all
Defined in:
lib/smart_proxy_dynflow/io_buffer.rb

Overview

Note:

Using a single IOBuffer with a single IO for both reads and writes might not be a good idea. If you need to use a single IO for both reads and writes, wrap it in two separate IOBuffers.

A buffer around an IO object providing buffering and convenience methods for non-blocking reads and writes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ IOBuffer

Returns a new instance of IOBuffer.

Parameters:

  • io (IO)

    The IO object to be buffered



17
18
19
20
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 17

def initialize(io)
  @buffer = ''
  @io = io
end

Instance Attribute Details

#bufferString (readonly)

The buffer where the data read from the underlying IO is buffered

Returns:

  • (String)

    the current value of buffer



12
13
14
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 12

def buffer
  @buffer
end

#ioObject

Returns the value of attribute io.



13
14
15
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 13

def io
  @io
end

Instance Method Details

#add_data(data) ⇒ void

This method returns an undefined value.

Adds data to the buffer. If the buffer is used for writing, then this should be the preferred method of queueing the data to be written.



102
103
104
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 102

def add_data(data)
  @buffer += data
end

#closevoid

This method returns an undefined value.

Closes the underlying IO. Does nothing if the IO is already closed.



65
66
67
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 65

def close
  @io.close unless @io.closed?
end

#closed?true, false

Checks whether the underlying IO is empty

Returns:

  • (true, false)

    whether the underlying IO is empty



58
59
60
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 58

def closed?
  @io.closed?
end

#empty?true, false

Checks whether the buffer is empty

Returns:

  • (true, false)

    whether the buffer is empty



51
52
53
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 51

def empty?
  @buffer.empty?
end

#on_data {|data| ... } ⇒ void

Note:

Note that if the callback is provided, the buffer will store the return value of the callback instead of the raw data.

This method returns an undefined value.

Sets a callback to be executed each time data is read from the underlying IO.

Yield Parameters:

  • data (String)

    read from the underlying IO

Yield Returns:

  • (String)

    data to be buffered



30
31
32
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 30

def on_data(&block)
  @callback = block
end

#read_available!void

This method returns an undefined value.

Reads all the data that is currently waiting in the IO and stores it. If EOFError is encountered during the read, the underlying IO is closed.



73
74
75
76
77
78
79
80
81
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 73

def read_available!
  data = ''
  loop { data += @io.read_nonblock(4096) }
rescue IO::WaitReadable # rubocop:disable Lint/SuppressedException
rescue EOFError
  close
ensure
  @buffer += with_callback(data) unless data.empty?
end

#to_ioIO

Exposes the underlying IO so that the buffer itself can be used in IO.select calls.

Returns:

  • (IO)

    the underlying IO



37
38
39
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 37

def to_io
  @io
end

#to_sString

Exposes the contents of the buffer as a String

Returns:

  • (String)

    the buffered data



44
45
46
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 44

def to_s
  @buffer
end

#write_available!void

This method returns an undefined value.

Writes all the data into the IO that can be written without blocking. It is a no-op if there are no data to be written. If an EOFError is encountered during the write, the underlying IO is closed.



88
89
90
91
92
93
94
95
96
# File 'lib/smart_proxy_dynflow/io_buffer.rb', line 88

def write_available!
  until @buffer.empty?
    n = @io.write_nonblock(@buffer)
    @buffer = @buffer.bytes.drop(n).pack('c*')
  end
rescue IO::WaitWritable # rubocop:disable Lint/SuppressedException
rescue EOFError
  close
end