diff options
| author | Tomoyuki Sahara <[email protected]> | 2014-02-25 12:19:52 +0900 |
|---|---|---|
| committer | Tomoyuki Sahara <[email protected]> | 2014-02-25 12:19:52 +0900 |
| commit | 56a8c592dd02cc603a57669b37035f4b8054c587 (patch) | |
| tree | 0b990167d2f95ba8285debb7df1e17a71d78a61e | |
| parent | 7fd585bae174751e69b3a5e3a65e18eabaf7b1bd (diff) | |
| download | mruby-56a8c592dd02cc603a57669b37035f4b8054c587.tar.gz mruby-56a8c592dd02cc603a57669b37035f4b8054c587.zip | |
add IO.read
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | mrblib/io.rb | 50 | ||||
| -rw-r--r-- | src/io.c | 15 | ||||
| -rw-r--r-- | test/io.rb | 25 |
4 files changed, 87 insertions, 5 deletions
@@ -18,7 +18,7 @@ IO, File module for mruby | IO.foreach | | | | IO.pipe | | | | IO.popen | o | | -| IO.read | | | +| IO.read | o | | | IO.readlines | | | | IO.select | | | | IO.sysopen | o | | diff --git a/mrblib/io.rb b/mrblib/io.rb index 63a1bb714..4c69a4b99 100644 --- a/mrblib/io.rb +++ b/mrblib/io.rb @@ -41,6 +41,54 @@ class IO end end + + def self.read(path, length=nil, offset=nil, opt=nil) + if not opt.nil? # 4 arguments + offset ||= 0 + elsif not offset.nil? # 3 arguments + if offset.is_a? Hash + opt = offset + offset = 0 + else + opt = {} + end + elsif not length.nil? # 2 arguments + if length.is_a? Hash + opt = length + offset = 0 + length = nil + else + offset = 0 + opt = {} + end + else # only 1 argument + opt = {} + offset = 0 + length = nil + end + + str = "" + fd = -1 + io = nil + begin + if path[0] == "|" + io = IO.popen(path[1..-1], (opt[:mode] || "r")) + else + fd = IO.sysopen(path) + io = IO.open(fd, opt[:mode] || "r") + end + io.seek(offset) if offset > 0 + str = io.read(length) + ensure + if io + io.close + elsif fd != -1 + IO._sysclose(fd) + end + end + str + end + def flush # mruby-io always writes immediately (no output buffer). self @@ -130,7 +178,7 @@ class IO begin _read_buf rescue EOFError => e - str = nil if str.empty? + str = nil if str.empty? and (not length.nil?) and length != 0 break end @@ -3,7 +3,6 @@ */ #include "mruby.h" - #include "mruby/hash.h" #include "mruby/data.h" #include "mruby/khash.h" @@ -373,6 +372,17 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass) } mrb_value +mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass) +{ + mrb_int fd; + mrb_get_args(mrb, "i", &fd); + if (close(fd) == -1) { + mrb_sys_fail(mrb, "close"); + } + return mrb_fixnum_value(0); +} + +mrb_value mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) { mrb_value path = mrb_nil_value(); @@ -741,9 +751,10 @@ mrb_init_io(mrb_state *mrb) mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */ mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, io, "_sysclose", mrb_io_s_sysclose, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(2)); - mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY()); mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY()); + mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY()); mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ANY()); /* 15.2.20.5.21 (x)*/ mrb_define_method(mrb, io, "sysread", mrb_io_sysread, MRB_ARGS_ANY()); diff --git a/test/io.rb b/test/io.rb index 49a2a3f97..02507a9d4 100644 --- a/test/io.rb +++ b/test/io.rb @@ -130,7 +130,7 @@ assert('IO#read') do io = IO.new fd assert_equal 'mruby', io.read(5) assert_equal $mrbtest_io_msg[5,100] + "\n", io.read - assert_equal nil, io.read + assert_equal "", io.read io.close io.closed? end @@ -251,6 +251,29 @@ assert('IO.popen') do io.closed? end +assert('IO.read') do + # empty file + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.close + assert_equal "", IO.read($mrbtest_io_wfname) + assert_equal nil, IO.read($mrbtest_io_wfname, 1) + + # one byte file + fd = IO.sysopen $mrbtest_io_wfname, "w" + io = IO.new fd, "w" + io.write "123" + io.close + assert_equal "123", IO.read($mrbtest_io_wfname) + assert_equal "", IO.read($mrbtest_io_wfname, 0) + assert_equal "1", IO.read($mrbtest_io_wfname, 1) + assert_equal "", IO.read($mrbtest_io_wfname, 0, 10) + assert_equal "23", IO.read($mrbtest_io_wfname, 2, 1) + assert_equal "23", IO.read($mrbtest_io_wfname, 10, 1) + assert_equal "", IO.read($mrbtest_io_wfname, nil, 10) + assert_equal nil, IO.read($mrbtest_io_wfname, 1, 10) +end + assert('IO#fileno') do fd = IO.sysopen $mrbtest_io_rfname io = IO.new fd |
