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

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

ファイルを追加、更新。

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 6.6 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 fd = IO.sysopen(path)
97 io = IO.open(fd, opt[:mode] || "r")
98 end
99 io.seek(offset) if offset > 0
100 str = io.read(length)
101 ensure
102 if io
103 io.close
104 elsif fd != -1
105 IO._sysclose(fd)
106 end
107 end
108 str
109 end
110
111 def flush
112 # mruby-io always writes immediately (no output buffer).
113 raise IOError, "closed stream" if self.closed?
114 self
115 end
116
117 def hash
118 # We must define IO#hash here because IO includes Enumerable and
119 # Enumerable#hash will call IO#read...
120 self.__id__
121 end
122
123 def write(string)
124 str = string.is_a?(String) ? string : string.to_s
125 return str.size unless str.size > 0
126
127 len = syswrite(str)
128 if len != -1
129 @pos += len
130 return len
131 end
132
133 raise IOError
134 end
135
136 def <<(str)
137 write(str)
138 self
139 end
140
141 def eof?
142 _check_readable
143 begin
144 buf = _read_buf
145 return buf.size == 0
146 rescue EOFError
147 return true
148 end
149 end
150 alias_method :eof, :eof?
151
152 def pos
153 raise IOError if closed?
154 @pos
155 end
156 alias_method :tell, :pos
157
158 def pos=(i)
159 seek(i, SEEK_SET)
160 end
161
162 def rewind
163 seek(0, SEEK_SET)
164 end
165
166 def seek(i, whence = SEEK_SET)
167 raise IOError if closed?
168 @pos = sysseek(i, whence)
169 @buf = ''
170 0
171 end
172
173 def _read_buf
174 return @buf if @buf && @buf.size > 0
175 @buf = sysread(BUF_SIZE)
176 end
177
178 def ungetc(substr)
179 raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
180 @pos -= substr.size
181 if @buf.empty?
182 @buf = substr.dup
183 else
184 @buf = substr + @buf
185 end
186 nil
187 end
188
189 def read(length = nil)
190 unless length.nil?
191 unless length.is_a? Fixnum
192 raise TypeError.new "can't convert #{length.class} into Integer"
193 end
194 if length < 0
195 raise ArgumentError.new "negative length: #{length} given"
196 end
197 if length == 0
198 return "" # easy case
199 end
200 end
201
202 array = []
203 start_pos = @pos
204 while 1
205 begin
206 _read_buf
207 rescue EOFError => e
208 array = nil if array.empty? and (not length.nil?) and length != 0
209 break
210 end
211
212 if length && (@pos - start_pos + @buf.size) >= length
213 len = length - (@pos - start_pos)
214 array.push @buf[0, len]
215 @pos += len
216 @buf = @buf[len, @buf.size - len]
217 break
218 else
219 array.push @buf
220 @pos += @buf.size
221 @buf = ''
222 end
223 end
224
225 array && array.join
226 end
227
228 def readline(arg = $/, limit = nil)
229 case arg
230 when String
231 rs = arg
232 when Fixnum
233 rs = $/
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 = $/ + $/
245 end
246
247 array = []
248 start_pos = @pos
249 while 1
250 begin
251 _read_buf
252 rescue EOFError => e
253 array = nil if array.empty?
254 break
255 end
256
257 if limit && (@pos - start_pos + @buf.size) >= limit
258 len = limit - (@pos - start_pos)
259 array.push @buf[0, len]
260 @pos += len
261 @buf = @buf[len, @buf.size - len]
262 break
263 elsif idx = @buf.index(rs)
264 len = idx + rs.size
265 array.push @buf[0, len]
266 @pos += len
267 @buf = @buf[len, @buf.size - len]
268 break
269 else
270 array.push @buf
271 @pos += @buf.size
272 @buf = ''
273 end
274 end
275
276 raise EOFError.new "end of file reached" if array.nil?
277
278 array.join
279 end
280
281 def gets(*args)
282 begin
283 readline(*args)
284 rescue EOFError => e
285 nil
286 end
287 end
288
289 def readchar
290 _read_buf
291 c = @buf[0]
292 @buf = @buf[1, @buf.size]
293 @pos += 1
294 c
295 end
296
297 def getc
298 begin
299 readchar
300 rescue EOFError => e
301 nil
302 end
303 end
304
305 # 15.2.20.5.3
306 def each(&block)
307 while line = self.gets
308 block.call(line)
309 end
310 self
311 end
312
313 # 15.2.20.5.4
314 def each_byte(&block)
315 while char = self.getc
316 block.call(char)
317 end
318 self
319 end
320
321 # 15.2.20.5.5
322 alias each_line each
323
324 alias each_char each_byte
325
326 def readlines
327 ary = []
328 while (line = gets)
329 ary << line
330 end
331 ary
332 end
333
334 def puts(*args)
335 i = 0
336 len = args.size
337 while i < len
338 s = args[i].to_s
339 write s
340 write "\n" if (s[-1] != "\n")
341 i += 1
342 end
343 write "\n" if len == 0
344 nil
345 end
346
347 def print(*args)
348 i = 0
349 len = args.size
350 while i < len
351 write args[i].to_s
352 i += 1
353 end
354 end
355
356 def printf(*args)
357 write sprintf(*args)
358 nil
359 end
360
361 alias_method :to_i, :fileno
362 alias_method :tty?, :isatty
363end
364
365STDIN = IO.open(0, "r")
366STDOUT = IO.open(1, "w")
367STDERR = IO.open(2, "w")
368
369$stdin = STDIN
370$stdout = STDOUT
371$stderr = STDERR
372
373module Kernel
374 def print(*args)
375 $stdout.print(*args)
376 end
377
378 def puts(*args)
379 $stdout.puts(*args)
380 end
381
382 def printf(*args)
383 $stdout.printf(*args)
384 end
385
386 def gets(*args)
387 $stdin.gets(*args)
388 end
389
390 def getc(*args)
391 $stdin.getc(*args)
392 end
393end
Note: See TracBrowser for help on using the repository browser.