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

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 6.5 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 if 0 < @buf.length
127 # reset real pos ignore buf
128 seek(pos, SEEK_SET)
129 end
130 len = syswrite(str)
131 len
132 end
133
134 def <<(str)
135 write(str)
136 self
137 end
138
139 def eof?
140 _check_readable
141 begin
142 buf = _read_buf
143 return buf.size == 0
144 rescue EOFError
145 return true
146 end
147 end
148 alias_method :eof, :eof?
149
150 def pos
151 raise IOError if closed?
152 sysseek(0, SEEK_CUR) - @buf.length
153 end
154 alias_method :tell, :pos
155
156 def pos=(i)
157 seek(i, SEEK_SET)
158 end
159
160 def rewind
161 seek(0, SEEK_SET)
162 end
163
164 def seek(i, whence = SEEK_SET)
165 raise IOError if closed?
166 sysseek(i, whence)
167 @buf = ''
168 0
169 end
170
171 def _read_buf
172 return @buf if @buf && @buf.size > 0
173 @buf = sysread(BUF_SIZE)
174 end
175
176 def ungetc(substr)
177 raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
178 if @buf.empty?
179 @buf = substr.dup
180 else
181 @buf = substr + @buf
182 end
183 nil
184 end
185
186 def read(length = nil, outbuf = "")
187 unless length.nil?
188 unless length.is_a? Fixnum
189 raise TypeError.new "can't convert #{length.class} into Integer"
190 end
191 if length < 0
192 raise ArgumentError.new "negative length: #{length} given"
193 end
194 if length == 0
195 return "" # easy case
196 end
197 end
198
199 array = []
200 while 1
201 begin
202 _read_buf
203 rescue EOFError
204 array = nil if array.empty? and (not length.nil?) and length != 0
205 break
206 end
207
208 if length
209 consume = (length <= @buf.size) ? length : @buf.size
210 array.push @buf[0, consume]
211 @buf = @buf[consume, @buf.size - 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 = $/, 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 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 = @buf[limit, @buf.size - limit]
259 break
260 elsif idx = @buf.index(rs)
261 len = idx + rs.size
262 array.push @buf[0, len]
263 @buf = @buf[len, @buf.size - 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 c = @buf[0]
287 @buf = @buf[1, @buf.size]
288 c
289 end
290
291 def getc
292 begin
293 readchar
294 rescue EOFError
295 nil
296 end
297 end
298
299 # 15.2.20.5.3
300 def each(&block)
301 while line = self.gets
302 block.call(line)
303 end
304 self
305 end
306
307 # 15.2.20.5.4
308 def each_byte(&block)
309 while char = self.getc
310 block.call(char)
311 end
312 self
313 end
314
315 # 15.2.20.5.5
316 alias each_line each
317
318 alias each_char each_byte
319
320 def readlines
321 ary = []
322 while (line = gets)
323 ary << line
324 end
325 ary
326 end
327
328 def puts(*args)
329 i = 0
330 len = args.size
331 while i < len
332 s = args[i].to_s
333 write s
334 write "\n" if (s[-1] != "\n")
335 i += 1
336 end
337 write "\n" if len == 0
338 nil
339 end
340
341 def print(*args)
342 i = 0
343 len = args.size
344 while i < len
345 write args[i].to_s
346 i += 1
347 end
348 end
349
350 def printf(*args)
351 write sprintf(*args)
352 nil
353 end
354
355 alias_method :to_i, :fileno
356 alias_method :tty?, :isatty
357end
358
359STDIN = IO.open(0, "r")
360STDOUT = IO.open(1, "w")
361STDERR = IO.open(2, "w")
362
363$stdin = STDIN
364$stdout = STDOUT
365$stderr = STDERR
366
367module Kernel
368 def print(*args)
369 $stdout.print(*args)
370 end
371
372 def puts(*args)
373 $stdout.puts(*args)
374 end
375
376 def printf(*args)
377 $stdout.printf(*args)
378 end
379
380 def gets(*args)
381 $stdin.gets(*args)
382 end
383
384 def getc(*args)
385 $stdin.getc(*args)
386 end
387end
Note: See TracBrowser for help on using the repository browser.