class Net::InternetMessageIO
:nodoc: internal use only
def buffer_filling(buf, src)
def buffer_filling(buf, src) case src when String # for speeding up. 0.step(src.size - 1, 1024) do |i| buf << src[i, 1024] yield end when File # for speeding up. while s = src.read(1024) buf << s yield end else # generic reader src.each do |str| buf << str yield if buf.size > 1024 end yield unless buf.empty? end end
def dot_stuff(s)
def dot_stuff(s) s.sub(/\A\./, '..') end
def each_crlf_line(src)
def each_crlf_line(src) buffer_filling(@wbuf, src) do while line = @wbuf.slice!(/\A[^\r\n]*(?:\n|\r(?:\n|(?!\z)))/) yield line.chomp("\n") + "\r\n" end end end
def each_list_item
def each_list_item while (str = readuntil("\r\n")) != ".\r\n" yield str.chop end end
def each_message_chunk
def each_message_chunk LOG 'reading message...' LOG_off() read_bytes = 0 while (line = readuntil("\r\n")) != ".\r\n" read_bytes += line.size yield line.delete_prefix('.') end LOG_on() LOG "read message (#{read_bytes} bytes)" end
def initialize(*, **)
def initialize(*, **) super @wbuf = nil end
def using_each_crlf_line
def using_each_crlf_line @wbuf = ''.b yield if not @wbuf.empty? # unterminated last line write0 dot_stuff(@wbuf.chomp) + "\r\n" elsif @written_bytes == 0 # empty src write0 "\r\n" end write0 ".\r\n" @wbuf = nil end
def write_message(src)
def write_message(src) LOG "writing message from #{src.class}" LOG_off() len = writing { using_each_crlf_line { write_message_0 src } } LOG_on() LOG "wrote #{len} bytes" len end
def write_message_0(src)
def write_message_0(src) prev = @written_bytes each_crlf_line(src) do |line| write0 dot_stuff(line) end @written_bytes - prev end
def write_message_by_block(&block)
def write_message_by_block(&block) LOG 'writing message from block' LOG_off() len = writing { using_each_crlf_line { begin block.call(WriteAdapter.new(self.method(:write_message_0))) rescue LocalJumpError # allow `break' from writer block end } } LOG_on() LOG "wrote #{len} bytes" len end