This module is used to extend sockets and other IO objects, to allow them to be buffered for both read and write. This abstraction makes it quite easy to write a select-based event loop (see Net::SSH::Connection::Session#listen_to).
The general idea is that instead of calling # directly on an IO that has been extended with this module, you call # (to add pending input to the internal read buffer), and then # (to read from that buffer). Likewise, you don’t call # directly, you call # to add data to the write buffer, and then # or # to actually send the data across the wire.
In this way you can easily use the object as an argument to IO.select, calling # when it is available for read, or # when it is available for write, and then call # and # during the idle times.
socket = TCPSocket.new(address, port) socket.extend(Net::SSH::BufferedIo) ssh.listen_to(socket) ssh.loop do if socket.available > 0 puts socket.read_available socket.enqueue("response\n") end end
Note that this module must be used to extend an instance, and should not be included in a class. If you do want to use it via an include, then you must make sure to invoke the private # method in your class’ # method:
class Foo < IO include Net::SSH::BufferedIo def initialize initialize_buffered_io # ... end end
Returns the number of bytes available to be read from the input buffer. (See #.)
# File lib/net/ssh/buffered_io.rb, line 79 79: def available 80: input.available 81: end
Enqueues data in the output buffer, to be written when # is called. Note that the data is not sent immediately by this method!
# File lib/net/ssh/buffered_io.rb, line 85 85: def enqueue(data) 86: output.append(data) 87: end
Tries to read up to n bytes of data from the remote end, and appends the data to the input buffer. It returns the number of bytes read, or 0 if no data was available to be read.
# File lib/net/ssh/buffered_io.rb, line 63 63: def fill(n=8192) 64: input.consume! 65: data = recv(n) 66: debug { "read #{data.length} bytes" } 67: input.append(data) 68: return data.length 69: end
Returns true if there is data waiting in the output buffer, and false otherwise.
# File lib/net/ssh/buffered_io.rb, line 91 91: def pending_write? 92: output.length > 0 93: end
Read up to length bytes from the input buffer. If length is nil, all available data is read from the buffer. (See #.)
# File lib/net/ssh/buffered_io.rb, line 73 73: def read_available(length=nil) 74: input.read(length || available) 75: end
Sends as much of the pending output as possible. Returns true if any data was sent, and false otherwise.
# File lib/net/ssh/buffered_io.rb, line 97 97: def send_pending 98: if output.length > 0 99: sent = send(output.to_s, 0) 100: debug { "sent #{sent} bytes" } 101: output.consume!(sent) 102: return sent > 0 103: else 104: return false 105: end 106: end
Calls # repeatedly, if necessary, blocking until the output buffer is empty.
# File lib/net/ssh/buffered_io.rb, line 110 110: def wait_for_pending_sends 111: send_pending 112: while output.length > 0 113: result = Net::SSH::Compat.io_select(nil, [self]) or next 114: next unless result[1].any? 115: send_pending 116: end 117: end
Initializes the intput and output buffers for this object. This method is called automatically when the module is mixed into an object via Object#extend (see Net::SSH::BufferedIo.extended), but must be called explicitly in the initialize method of any class that uses Module#include to add this module.
# File lib/net/ssh/buffered_io.rb, line 144 144: def initialize_buffered_io 145: @input = Net::SSH::Buffer.new 146: @output = Net::SSH::Buffer.new 147: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.