lib/rev/buffered_io.rb in rev-0.1.1 vs lib/rev/buffered_io.rb in rev-0.1.2

- old
+ new

@@ -5,27 +5,35 @@ #++ require File.dirname(__FILE__) + '/../rev' module Rev + # A buffered I/O class witch fits into the Rev Watcher framework. + # It provides both an observer which reads data as it's received + # from the wire and a buffered writer which stores data and writes + # it out each time the socket becomes writable. + # + # This class is primarily meant as a base class for other streams + # which need non-blocking writing, and is used to implement Rev's + # Socket class and its associated subclasses. class BufferedIO < IOWatcher # Maximum number of bytes to consume at once INPUT_SIZE = 16384 def initialize(io) # Output buffer - @write_buffer = '' + @write_buffer = Rev::Buffer.new # Coerce the argument into an IO object if possible @io = IO.try_convert(io) super(@io) end # # Callbacks for asynchronous events # - + # Called whenever the IO object receives data def on_read(data); end event_callback :on_read # Called whenever a write completes and the output buffer is empty @@ -40,27 +48,11 @@ # Write interface # # Write data in a buffered, non-blocking manner def write(data) - # Attempt a zero copy write - if @write_buffer.empty? - written = write_nonblock data - - # If we lucked out and wrote out the whole buffer, return - if written == data.size - on_write_complete - return data.size - end - - # Otherwise slice what we wrote out and begin buffered writing - data.slice!(0, written) if written - end - - @write_buffer << data - schedule_write - data.size + buffered_write data end # Number of bytes are currently in the output buffer def output_buffer_size @write_buffer.size @@ -71,22 +63,33 @@ detach if attached? @writer.detach if @writer and @writer.attached? @io.close unless @io.closed? on_close + nil end + # Is the IO object closed? + def closed? + @io.closed? + end + ######### protected ######### + # Buffered writer + def buffered_write(data) + @write_buffer << data + schedule_write + data.size + end + # Attempt to write the contents of the output buffer def write_output_buffer return if @write_buffer.empty? - written = write_nonblock @write_buffer - @write_buffer.slice!(0, written) if written - + @write_buffer.write_to(@io) return unless @write_buffer.empty? @writer.disable if @writer and @writer.enabled? on_write_complete end