123456789_123456789_123456789_123456789_123456789_

Class: Net::BufferedIO

Do not use. This class is for internal use only.
Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Inherits: Object
Defined in: lib/net/protocol.rb

Overview

internal use only

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(io, read_timeout: 60, write_timeout: 60, continue_timeout: nil, debug_output: nil) ⇒ BufferedIO

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 116

def initialize(io, read_timeout: 60, write_timeout: 60, continue_timeout: nil, debug_output: nil)
  @io = io
  @read_timeout = read_timeout
  @write_timeout = write_timeout
  @continue_timeout = continue_timeout
  @debug_output = debug_output
  @rbuf = ''.b
end

Instance Attribute Details

#closed?Boolean (readonly)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 139

def closed?
  @io.closed?
end

#continue_timeout (rw)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 128

attr_accessor :continue_timeout

#debug_output (rw)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 129

attr_accessor :debug_output

#eof?Boolean (readonly)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 135

def eof?
  @io.eof?
end

#io (readonly)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 125

attr_reader :io

#read_timeout (rw)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 126

attr_accessor :read_timeout

#write_timeout (rw)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 127

attr_accessor :write_timeout

Instance Method Details

#<<(*strs)

Alias for #write.

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 254

alias << write

#close

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 143

def close
  @io.close
end

#inspect

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 131

def inspect
  "#<#{self.class} io=#{@io}>"
end

LOG(msg) (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 319

def LOG(msg)
  return unless @debug_output
  @debug_output << msg + "\n"
end

LOG_off (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 310

def LOG_off
  @save_debug_out = @debug_output
  @debug_output = nil
end

LOG_on (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 315

def LOG_on
  @debug_output = @save_debug_out
end

#rbuf_consume(len) (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 231

def rbuf_consume(len)
  if len == @rbuf.size
    s = @rbuf
    @rbuf = ''.b
  else
    s = @rbuf.slice!(0, len)
  end
  @debug_output << %Q[-> #{s.dump}\n] if @debug_output
  s
end

#rbuf_fill (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 210

def rbuf_fill
  tmp = @rbuf.empty? ? @rbuf : nil
  case rv = @io.read_nonblock(BUFSIZE, tmp, exception: false)
  when String
    return if rv.equal?(tmp)
    @rbuf << rv
    rv.clear
    return
  when :wait_readable
    (io = @io.to_io).wait_readable(@read_timeout) or raise Net::ReadTimeout.new(io)
    # continue looping
  when :wait_writable
    # OpenSSL::Buffering#read_nonblock may fail with IO::WaitWritable.
    # http://www.openssl.org/support/faq.html#PROG10
    (io = @io.to_io).wait_writable(@read_timeout) or raise Net::ReadTimeout.new(io)
    # continue looping
  when nil
    raise EOFError, 'end of file reached'
  end while true
end

#read(len, dest = ''.b, ignore_eof = false)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 153

def read(len, dest = ''.b, ignore_eof = false)
  LOG "reading #{len} bytes..."
  read_bytes = 0
  begin
    while read_bytes + @rbuf.size < len
      s = rbuf_consume(@rbuf.size)
      read_bytes += s.size
      dest << s
      rbuf_fill
    end
    s = rbuf_consume(len - read_bytes)
    read_bytes += s.size
    dest << s
  rescue EOFError
    raise unless ignore_eof
  end
  LOG "read #{read_bytes} bytes"
  dest
end

#read_all(dest = ''.b)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 173

def read_all(dest = ''.b)
  LOG 'reading all...'
  read_bytes = 0
  begin
    while true
      s = rbuf_consume(@rbuf.size)
      read_bytes += s.size
      dest << s
      rbuf_fill
    end
  rescue EOFError
    ;
  end
  LOG "read #{read_bytes} bytes"
  dest
end

#readline

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 202

def readline
  readuntil("\n").chop
end

#readuntil(terminator, ignore_eof = false)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 190

def readuntil(terminator, ignore_eof = false)
  begin
    until idx = @rbuf.index(terminator)
      rbuf_fill
    end
    return rbuf_consume(idx + terminator.size)
  rescue EOFError
    raise unless ignore_eof
    return rbuf_consume(@rbuf.size)
  end
end

#write(*strs) Also known as: #<<

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 248

def write(*strs)
  writing {
    write0(*strs)
  }
end

#write0(*strs) (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 274

def write0(*strs)
  @debug_output << strs.map(&:dump).join if @debug_output
  orig_written_bytes = @written_bytes
  strs.each_with_index do |str, i|
    need_retry = true
    case len = @io.write_nonblock(str, exception: false)
    when Integer
      @written_bytes += len
      len -= str.bytesize
      if len == 0
        if strs.size == i+1
          return @written_bytes - orig_written_bytes
        else
          need_retry = false
          # next string
        end
      elsif len < 0
        str = str.byteslice(len, -len)
      else # len > 0
        need_retry = false
        # next string
      end
      # continue looping
    when :wait_writable
      (io = @io.to_io).wait_writable(@write_timeout) or raise Net::WriteTimeout.new(io)
      # continue looping
    end while need_retry
  end
end

#writeline(str)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 256

def writeline(str)
  writing {
    write0 str + "\r\n"
  }
end

#writing (private)

[ GitHub ]

  
# File 'lib/net/protocol.rb', line 264

def writing
  @written_bytes = 0
  @debug_output << '<- ' if @debug_output
  yield
  @debug_output << "\n" if @debug_output
  bytes = @written_bytes
  @written_bytes = nil
  bytes
end