lib/lightio/library/io.rb in lightio-0.4.0.pre vs lib/lightio/library/io.rb in lightio-0.4.0

- old
+ new

@@ -4,120 +4,144 @@ include LightIO::Wrap::IOWrapper mock ::IO extend LightIO::Module::IO::ClassMethods - wrap_blocking_methods :read, :write + def to_io + self + end - alias_method :<<, :write + # abstract for io-like operations + module IOMethods + class << self + def included(base) + base.send(:wrap_blocking_methods, :read, :write) + base.send(:alias_method, :<<, :write) + end + end - def read(length=nil, outbuf=nil) - raise ArgumentError, "negative length #{length} given" if length && length < 0 - (outbuf ||= "").clear - loop do - readlen = length.nil? ? 4096 : length - outbuf.size - if (data = wait_nonblock(:read_nonblock, readlen)) - outbuf << data - if length == outbuf.size - return outbuf + def wait(timeout = nil, mode = :read) + io_watcher.wait(timeout, mode) && self + end + + def wait_readable(timeout = nil) + wait(timeout, :read) && self + end + + def wait_writable(timeout = nil) + wait(timeout, :write) && self + end + + def read(length=nil, outbuf=nil) + raise ArgumentError, "negative length #{length} given" if length && length < 0 + (outbuf ||= "").clear + loop do + readlen = length.nil? ? 4096 : length - outbuf.size + if (data = wait_nonblock(:read_nonblock, readlen)) + outbuf << data + if length == outbuf.size + return outbuf + end + else + return length.nil? ? outbuf : nil end + end + end + + def readpartial(maxlen, outbuf=nil) + (outbuf ||= "").clear + if (data = wait_nonblock(:read_nonblock, maxlen)) + outbuf << data else - return length.nil? ? outbuf : nil + raise EOFError, 'end of file reached' end + outbuf end - end - def readpartial(maxlen, outbuf=nil) - (outbuf ||= "").clear - if (data = wait_nonblock(:read_nonblock, maxlen)) - outbuf << data - else - raise EOFError, 'end of file reached' + def getbyte + read(1) end - outbuf - end - def getbyte - read(1) - end + def getc + wait_readable + @obj.getc + end - def getc - wait_readable - @obj.getc - end + def readline(*args) + line = gets(*args) + raise EOFError, 'end of file reached' if line.nil? + line + end - def readline(*args) - line = gets(*args) - raise EOFError, 'end of file reached' if line.nil? - line - end + def readlines(*args) + result = [] + until eof? + result << readline(*args) + end + result + end - def readlines(*args) - result = [] - until eof? - result << readline(*args) + def readchar + c = getc + raise EOFError, 'end of file reached' if c.nil? + c end - result - end - def readchar - c = getc - raise EOFError, 'end of file reached' if c.nil? - c - end + def readbyte + b = getbyte + raise EOFError, 'end of file reached' if b.nil? + b + end - def readbyte - b = getbyte - raise EOFError, 'end of file reached' if b.nil? - b - end + def eof + wait_readable + @obj.eof + end - def eof - wait_readable - @obj.eof - end + alias eof? eof - alias eof? eof + def gets(*args) + raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..2)" if args.size > 2 + sep = $/ + if args[0].is_a?(Numeric) + limit = args.shift + else + sep = args.shift if args.size > 0 + limit = args.shift if args.first.is_a?(Numeric) + end + s = '' + while (c = getbyte) + s << c + break if limit && s.size == limit + break if c == sep + end + s = nil if s.empty? + $_ = s + end - def gets(*args) - raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..2)" if args.size > 2 - return nil if eof? - sep = $/ - if args[0].is_a?(Numeric) - limit = args.shift - else - sep = args.shift if args.size > 0 - limit = args.shift if args.first.is_a?(Numeric) + def print(*obj) + obj.each do |s| + write(s) + end end - s = '' - while (c = getc) - s << c - break if limit && s.size == limit - break if c == sep + + def printf(*args) + write(sprintf(*args)) end - $_ = s - end - def to_io - self - end + def puts(*obj) + obj.each do |s| + write(s) + write($/) + end + end - def close(*args) - # close watcher before io closed - io_watcher.close - @obj.close - end - - private - def wait_readable - # if IO is already readable, continue wait_readable may block it forever - # so use getbyte detect this situation - # Maybe move getc and gets to thread pool is a good idea - b = getbyte - if b - ungetbyte(b) - return + def close(*args) + # close watcher before io closed + io_watcher.close + @obj.close end - io_watcher.wait_readable end + + prepend IOMethods end end