Class: IO

Inherits:
Object
  • Object
show all
Defined in:
lib/neverblock/io/io.rb

Direct Known Subclasses

BasicSocket, File

Constant Summary collapse

NB_BUFFER_LENGTH =
128*1024

Instance Method Summary collapse

Instance Method Details

#getcObject



172
173
174
175
176
177
178
179
# File 'lib/neverblock/io/io.rb', line 172

def getc
   return rb_getc if self.file?
	begin
		res = readchar
	rescue EOFError
		res = nil
	end
end

#gets(sep = $/) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/neverblock/io/io.rb', line 142

def gets(sep=$/)
   return rb_gets(sep) if self.file?
	res = ""
	sep = "\n\n" if sep == ""
	sep = $/ if sep.nil?
	while res.index(sep).nil?
	  break if (c = read(1)).nil?
	  res << c
	end
	$_ = res
	res
end


188
189
190
191
# File 'lib/neverblock/io/io.rb', line 188

def print(*args)
   return rb_print if self.file?
	args.each{|element|syswrite(element)}
end

#rb_getcObject



22
# File 'lib/neverblock/io/io.rb', line 22

alias_method :rb_getc,      :getc

#rb_getsObject



21
# File 'lib/neverblock/io/io.rb', line 21

alias_method :rb_gets,      :gets

#rb_printObject



26
# File 'lib/neverblock/io/io.rb', line 26

alias_method :rb_print,     :print

#rb_readObject



19
# File 'lib/neverblock/io/io.rb', line 19

alias_method :rb_read,      :read

#rb_readcharObject



23
# File 'lib/neverblock/io/io.rb', line 23

alias_method :rb_readchar,  :readchar

#rb_readlineObject



24
# File 'lib/neverblock/io/io.rb', line 24

alias_method :rb_readline,  :readline

#rb_readlinesObject



25
# File 'lib/neverblock/io/io.rb', line 25

alias_method :rb_readlines, :readlines

#rb_sysreadObject



17
# File 'lib/neverblock/io/io.rb', line 17

alias_method :rb_sysread,   :sysread

#rb_syswriteObject



18
# File 'lib/neverblock/io/io.rb', line 18

alias_method :rb_syswrite,  :syswrite

#rb_writeObject



20
# File 'lib/neverblock/io/io.rb', line 20

alias_method :rb_write,     :write

#read(length = nil, sbuffer = nil) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/neverblock/io/io.rb', line 54

def read(length=nil, sbuffer=nil)
  return rb_read(length, sbuffer) if self.file?
  return '' if length == 0
  if sbuffer.nil?
    sbuffer = '' 
  else
   sbuffer = sbuffer.to_str
   sbuffer.delete!(sbuffer)
  end    
  if length.nil?
    # we need to read till end of stream
    loop do
      begin 
        sbuffer << sysread(NB_BUFFER_LENGTH)
      rescue EOFError
    	  break
      end
    end
    return sbuffer 
  else # length != nil
    if self.buffer.length >= length
      sbuffer << self.buffer.slice!(0, length)
      return sbuffer
    elsif self.buffer.length > 0
      sbuffer << self.buffer
    end
    self.buffer = ''
    remaining_length = length - sbuffer.length
   while sbuffer.length < length && remaining_length > 0 
    begin 
	    sbuffer << sysread(NB_BUFFER_LENGTH < remaining_length ? remaining_length : NB_BUFFER_LENGTH)
        remaining_length = remaining_length - sbuffer.length   
    rescue EOFError
        break
    end #begin
   end	#while	  
  end #if length 
  return nil if sbuffer.length.zero? && length > 0
  return sbuffer if sbuffer.length <= length
self.buffer << sbuffer.slice!(length, sbuffer.length-1)
  return sbuffer
end

#read_neverblock(*args) ⇒ Object

This method is the delegation method which reads using read_nonblock() and registers the IO call with event loop if the call blocks. The value



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/neverblock/io/io.rb', line 32

def read_neverblock(*args)
res = ""
begin
    old_flags = get_flags			
	res << read_nonblock(*args)
    set_flags(old_flags)
rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR
    set_flags(old_flags)
		NB.wait(:read, self)
		retry
end
res
end

#readcharObject

Raises:

  • (EOFError)


165
166
167
168
169
170
# File 'lib/neverblock/io/io.rb', line 165

def readchar
   return rb_readchar if self.file?
	ch = read(1)
	raise EOFError if ch.nil?
	ch
end

#readline(sep = $/) ⇒ Object

Raises:

  • (EOFError)


181
182
183
184
185
186
# File 'lib/neverblock/io/io.rb', line 181

def readline(sep = $/)
   return rb_readline(sep) if self.file?
	res = gets(sep)
	raise EOFError if res == nil
	res
end

#readlines(sep = $/) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'lib/neverblock/io/io.rb', line 155

def readlines(sep=$/)
   return rb_readlines(sep) if self.file?
	res = []
	begin
		loop{res << readline(sep)}
	rescue EOFError
	end
	res
end

#readpartial(length = nil, sbuffer = nil) ⇒ Object

Raises:

  • (ArgumentError)


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/neverblock/io/io.rb', line 97

def readpartial(length=nil,sbuffer=nil)
 raise ArgumentError if !length.nil? && length < 0
  if sbuffer.nil?
    sbuffer = '' 
  else
   sbuffer = sbuffer.to_str
   sbuffer.delete!(sbuffer)
  end
 
  if self.buffer.length >= length
     sbuffer << self.buffer.slice!(0, length)
  elsif self.buffer.length > 0 
    sbuffer << self.buffer.slice!(0, self.buffer.length-1)
  else
    sbuffer << rb_sysread(length)
  end  
   return sbuffer  
end

#sysread(length) ⇒ Object

The is the main reading method that all other methods use. If the mode is set to neverblock it uses the delegation method. Otherwise it uses the original ruby read method.



50
51
52
# File 'lib/neverblock/io/io.rb', line 50

def sysread(length)
  self.neverblock? ? read_neverblock(length) : rb_sysread(length)
end

#syswrite(*args) ⇒ Object



131
132
133
134
# File 'lib/neverblock/io/io.rb', line 131

def syswrite(*args)	
	return rb_syswrite(*args) unless self.neverblock?
		write_neverblock(*args)
end

#write(data) ⇒ Object



136
137
138
139
140
# File 'lib/neverblock/io/io.rb', line 136

def write(data)
   return 0 if data.to_s.empty?
   return rb_write(data) if self.file?
	syswrite(data)
end

#write_neverblock(data) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/neverblock/io/io.rb', line 116

def write_neverblock(data)
written = 0
begin
    old_flags = get_flags			
	written = written + write_nonblock(data[written,data.length])
    set_flags(old_flags)
	raise Errno::EAGAIN if written < data.length
rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR
    set_flags(old_flags)
		NB.wait(:write, self)
	retry
 end
written
end