summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTomoyuki Sahara <[email protected]>2014-02-25 12:19:52 +0900
committerTomoyuki Sahara <[email protected]>2014-02-25 12:19:52 +0900
commit56a8c592dd02cc603a57669b37035f4b8054c587 (patch)
tree0b990167d2f95ba8285debb7df1e17a71d78a61e
parent7fd585bae174751e69b3a5e3a65e18eabaf7b1bd (diff)
downloadmruby-56a8c592dd02cc603a57669b37035f4b8054c587.tar.gz
mruby-56a8c592dd02cc603a57669b37035f4b8054c587.zip
add IO.read
-rw-r--r--README.md2
-rw-r--r--mrblib/io.rb50
-rw-r--r--src/io.c15
-rw-r--r--test/io.rb25
4 files changed, 87 insertions, 5 deletions
diff --git a/README.md b/README.md
index 9cfdabbe8..ee7d640eb 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/io.c b/src/io.c
index 78a04f8af..8c9de3667 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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