source: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-io/mrblib/io.rb@ 439

Last change on this file since 439 was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 6.3 KB
Line 
1##
2# IO
3
4class IOError < StandardError; end
5class EOFError < IOError; end
6
7class IO
8 SEEK_SET = 0
9 SEEK_CUR = 1
10 SEEK_END = 2
11
12 BUF_SIZE = 4096
13
14 def self.open(*args, &block)
15 io = self.new(*args)
16
17 return io unless block
18
19 begin
20 yield io
21 ensure
22 begin
23 io.close unless io.closed?
24 rescue StandardError
25 end
26 end
27 end
28
29 def self.popen(command, mode = 'r', opts={}, &block)
30 if !self.respond_to?(:_popen)
31 raise NotImplementedError, "popen is not supported on this platform"
32 end
33 io = self._popen(command, mode, opts)
34 return io unless block
35
36 begin
37 yield io
38 ensure
39 begin
40 io.close unless io.closed?
41 rescue IOError
42 # nothing
43 end
44 end
45 end
46
47 def self.pipe(&block)
48 if !self.respond_to?(:_pipe)
49 raise NotImplementedError, "pipe is not supported on this platform"
50 end
51 if block
52 begin
53 r, w = IO._pipe
54 yield r, w
55 ensure
56 r.close unless r.closed?
57 w.close unless w.closed?
58 end
59 else
60 IO._pipe
61 end
62 end
63
64 def self.read(path, length=nil, offset=nil, opt=nil)
65 if not opt.nil? # 4 arguments
66 offset ||= 0
67 elsif not offset.nil? # 3 arguments
68 if offset.is_a? Hash
69 opt = offset
70 offset = 0
71 else
72 opt = {}
73 end
74 elsif not length.nil? # 2 arguments
75 if length.is_a? Hash
76 opt = length
77 offset = 0
78 length = nil
79 else
80 offset = 0
81 opt = {}
82 end
83 else # only 1 argument
84 opt = {}
85 offset = 0
86 length = nil
87 end
88
89 str = ""
90 fd = -1
91 io = nil
92 begin
93 if path[0] == "|"
94 io = IO.popen(path[1..-1], (opt[:mode] || "r"))
95 else
96 mode = opt[:mode] || "r"
97 fd = IO.sysopen(path, mode)
98 io = IO.open(fd, mode)
99 end
100 io.seek(offset) if offset > 0
101 str = io.read(length)
102 ensure
103 if io
104 io.close
105 elsif fd != -1
106 IO._sysclose(fd)
107 end
108 end
109 str
110 end
111
112 def flush
113 # mruby-io always writes immediately (no output buffer).
114 raise IOError, "closed stream" if self.closed?
115 self
116 end
117
118 def hash
119 # We must define IO#hash here because IO includes Enumerable and
120 # Enumerable#hash will call IO#read...
121 self.__id__
122 end
123
124 def write(string)
125 str = string.is_a?(String) ? string : string.to_s
126 return 0 if str.empty?
127 unless @buf.empty?
128 # reset real pos ignore buf
129 seek(pos, SEEK_SET)
130 end
131 len = syswrite(str)
132 len
133 end
134
135 def <<(str)
136 write(str)
137 self
138 end
139
140 def eof?
141 _check_readable
142 begin
143 _read_buf
144 return @buf.empty?
145 rescue EOFError
146 return true
147 end
148 end
149 alias_method :eof, :eof?
150
151 def pos
152 raise IOError if closed?
153 sysseek(0, SEEK_CUR) - @buf.bytesize
154 end
155 alias_method :tell, :pos
156
157 def pos=(i)
158 seek(i, SEEK_SET)
159 end
160
161 def rewind
162 seek(0, SEEK_SET)
163 end
164
165 def seek(i, whence = SEEK_SET)
166 raise IOError if closed?
167 sysseek(i, whence)
168 @buf = ''
169 0
170 end
171
172 def _read_buf
173 return @buf if @buf && @buf.bytesize > 0
174 sysread(BUF_SIZE, @buf)
175 end
176
177 def ungetc(substr)
178 raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
179 if @buf.empty?
180 @buf.replace(substr)
181 else
182 @buf[0,0] = substr
183 end
184 nil
185 end
186
187 def read(length = nil, outbuf = "")
188 unless length.nil?
189 unless length.is_a? Fixnum
190 raise TypeError.new "can't convert #{length.class} into Integer"
191 end
192 if length < 0
193 raise ArgumentError.new "negative length: #{length} given"
194 end
195 if length == 0
196 return "" # easy case
197 end
198 end
199
200 array = []
201 while 1
202 begin
203 _read_buf
204 rescue EOFError
205 array = nil if array.empty? and (not length.nil?) and length != 0
206 break
207 end
208
209 if length
210 consume = (length <= @buf.bytesize) ? length : @buf.bytesize
211 array.push IO._bufread(@buf, consume)
212 length -= consume
213 break if length == 0
214 else
215 array.push @buf
216 @buf = ''
217 end
218 end
219
220 if array.nil?
221 outbuf.replace("")
222 nil
223 else
224 outbuf.replace(array.join)
225 end
226 end
227
228 def readline(arg = "\n", limit = nil)
229 case arg
230 when String
231 rs = arg
232 when Fixnum
233 rs = "\n"
234 limit = arg
235 else
236 raise ArgumentError
237 end
238
239 if rs.nil?
240 return read
241 end
242
243 if rs == ""
244 rs = "\n\n"
245 end
246
247 array = []
248 while 1
249 begin
250 _read_buf
251 rescue EOFError
252 array = nil if array.empty?
253 break
254 end
255
256 if limit && limit <= @buf.size
257 array.push @buf[0, limit]
258 @buf[0, limit] = ""
259 break
260 elsif idx = @buf.index(rs)
261 len = idx + rs.size
262 array.push @buf[0, len]
263 @buf[0, len] = ""
264 break
265 else
266 array.push @buf
267 @buf = ''
268 end
269 end
270
271 raise EOFError.new "end of file reached" if array.nil?
272
273 array.join
274 end
275
276 def gets(*args)
277 begin
278 readline(*args)
279 rescue EOFError
280 nil
281 end
282 end
283
284 def readchar
285 _read_buf
286 _readchar(@buf)
287 end
288
289 def getc
290 begin
291 readchar
292 rescue EOFError
293 c = @buf[0]
294 @buf[0,1]="" if c
295 nil
296 end
297 end
298
299 # 15.2.20.5.3
300 def each(&block)
301 return to_enum unless block
302
303 while line = self.gets
304 block.call(line)
305 end
306 self
307 end
308
309 # 15.2.20.5.4
310 def each_byte(&block)
311 return to_enum(:each_byte) unless block
312
313 while char = self.getc
314 block.call(char)
315 end
316 self
317 end
318
319 # 15.2.20.5.5
320 alias each_line each
321
322 alias each_char each_byte
323
324 def readlines
325 ary = []
326 while (line = gets)
327 ary << line
328 end
329 ary
330 end
331
332 def puts(*args)
333 i = 0
334 len = args.size
335 while i < len
336 s = args[i].to_s
337 write s
338 write "\n" if (s[-1] != "\n")
339 i += 1
340 end
341 write "\n" if len == 0
342 nil
343 end
344
345 def print(*args)
346 i = 0
347 len = args.size
348 while i < len
349 write args[i].to_s
350 i += 1
351 end
352 end
353
354 def printf(*args)
355 write sprintf(*args)
356 nil
357 end
358
359 alias_method :to_i, :fileno
360 alias_method :tty?, :isatty
361end
362
363STDIN = IO.open(0, "r")
364STDOUT = IO.open(1, "w")
365STDERR = IO.open(2, "w")
366
367$stdin = STDIN
368$stdout = STDOUT
369$stderr = STDERR
Note: See TracBrowser for help on using the repository browser.