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