lib/lightio/library/io.rb in lightio-0.3.2 vs lib/lightio/library/io.rb in lightio-0.4.0.pre
- old
+ new
@@ -1,11 +1,13 @@
-require 'forwardable'
module LightIO::Library
class IO
+ include Base
include LightIO::Wrap::IOWrapper
- wrap ::IO
+ mock ::IO
+ extend LightIO::Module::IO::ClassMethods
+
wrap_blocking_methods :read, :write
alias_method :<<, :write
def read(length=nil, outbuf=nil)
@@ -17,11 +19,11 @@
outbuf << data
if length == outbuf.size
return outbuf
end
else
- return length.nil? ? '' : nil
+ return length.nil? ? outbuf : nil
end
end
end
def readpartial(maxlen, outbuf=nil)
@@ -38,11 +40,11 @@
read(1)
end
def getc
wait_readable
- @io.getc
+ @obj.getc
end
def readline(*args)
line = gets(*args)
raise EOFError, 'end of file reached' if line.nil?
@@ -69,11 +71,11 @@
b
end
def eof
wait_readable
- @io.eof?
+ @obj.eof
end
alias eof? eof
def gets(*args)
@@ -93,102 +95,29 @@
break if c == sep
end
$_ = s
end
- def close(*args)
- # close watcher before io closed
- @io_watcher.close
- @io.close(*args)
- end
-
def to_io
self
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
end
- @io_watcher.wait_readable
- end
-
- class << self
- def open(*args)
- io = self.new(*args)
- return io unless block_given?
- begin
- yield io
- ensure
- io.close if io.respond_to? :close
- end
- end
-
- def pipe(*args)
- r, w = raw_class.pipe
- if block_given?
- begin
- return yield r, w
- ensure
- w.close
- r.close
- end
- end
- [IO._wrap(r), IO._wrap(w)]
- end
-
- def select(read_fds, write_fds=nil, _except_fds=nil, timeout=nil)
- timer = timeout && Time.now
- read_fds ||= []
- write_fds ||= []
- loop do
- # make sure io registered, then clear io watcher status
- read_fds.each {|fd| get_io_watcher(fd).tap {|io| io.readable?; io.clear_status}}
- write_fds.each {|fd| get_io_watcher(fd).tap {|io| io.writable?; io.clear_status}}
- # run ioloop once
- LightIO.sleep 0
- r_fds = read_fds.select {|fd|
- io = convert_to_io(fd)
- io.closed? ? raise(IOError, 'closed stream') : get_io_watcher(io).readable?
- }
- w_fds = write_fds.select {|fd|
- io = convert_to_io(fd)
- io.closed? ? raise(IOError, 'closed stream') : get_io_watcher(io).writable?
- }
- e_fds = []
- if r_fds.empty? && w_fds.empty?
- if timeout && Time.now - timer > timeout
- return nil
- end
- else
- return [r_fds, w_fds, e_fds]
- end
- end
- end
-
- private
- def convert_to_io(io)
- unless io.respond_to?(:to_io)
- raise TypeError, "no implicit conversion of #{io.class} into IO"
- end
- to_io = io.to_io
- unless to_io.is_a?(IO)
- raise TypeError, "can't convert #{io.class} to IO (#{io.class}#to_io gives #{to_io.class})"
- end
- to_io
- end
-
- def get_io_watcher(io)
- unless io.is_a?(IO)
- io = convert_to_io(io)
- end
- io.instance_variable_get(:@io_watcher)
- end
+ io_watcher.wait_readable
end
end
end