Commit d9f3fd86 authored by Paolo Bosetti's avatar Paolo Bosetti

Merge branch 'master' of https://github.com/iij/mruby-io into test

Conflicts:
	src/io.c
parents ee2859de f7c054bd
......@@ -4,28 +4,6 @@ mruby-io
IO, File module for mruby
## License
Copyright (c) 2013 Internet Initiative Japan Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
## Implemented methods
### IO
......@@ -40,7 +18,7 @@ DEALINGS IN THE SOFTWARE.
| IO.foreach | | |
| IO.pipe | | |
| IO.popen | o | |
| IO.read | | |
| IO.read | o | |
| IO.readlines | | |
| IO.select | | |
| IO.sysopen | o | |
......@@ -183,3 +161,25 @@ DEALINGS IN THE SOFTWARE.
| File#size | | |
| File#truncate | | |
## License
Copyright (c) 2013 Internet Initiative Japan Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
......@@ -9,7 +9,6 @@ class File < IO
attr_accessor :path
def initialize(fd_or_path, mode = "r", perm = 0666)
self._bless
if fd_or_path.kind_of? Fixnum
super(fd_or_path, mode)
else
......
......@@ -41,6 +41,59 @@ 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
end
def write(string)
str = string.is_a?(String) ? string : string.to_s
return str.size unless str.size > 0
......@@ -125,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
......
......@@ -8,7 +8,12 @@
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#include <fcntl.h>
#include <limits.h>
......
......@@ -8,7 +8,12 @@
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#if defined(_WIN32) || defined(_WIN64)
#define LSTAT stat
......
......@@ -3,16 +3,19 @@
*/
#include "mruby.h"
#include "mruby/hash.h"
#include "mruby/data.h"
#include "mruby/khash.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/variable.h"
#include "mruby/ext/io.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#if defined(_WIN32) || defined(_WIN64)
#include <io.h>
......@@ -25,9 +28,16 @@
#endif
static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr);
static int mrb_io_modenum_to_flags(mrb_state *mrb, int modenum);
static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags);
#if MRUBY_RELEASE_NO < 10000
static struct RClass *
mrb_module_get(mrb_state *mrb, const char *name)
{
return mrb_class_get(mrb, name);
}
#endif
static int
mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
{
......@@ -371,26 +381,22 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
}
mrb_value
mrb_io_bless(mrb_state *mrb, mrb_value io)
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
{
if (mrb_type(io) != MRB_TT_DATA) {
mrb_raise(mrb, E_TYPE_ERROR, "expected IO object");
return mrb_nil_value();
}
DATA_TYPE(io) = &mrb_io_type;
DATA_PTR(io) = NULL;
DATA_PTR(io) = mrb_io_alloc(mrb);
mrb_value io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
return io;
return mrb_io_initialize(mrb, io);
}
mrb_value
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
{
mrb_value io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
return mrb_io_initialize(mrb, io);
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
......@@ -549,7 +555,7 @@ mrb_io_pid(mrb_state *mrb, mrb_value io)
static struct timeval
time2timeval(mrb_state *mrb, mrb_value time)
{
struct timeval t;
struct timeval t = { 0, 0 };
switch (mrb_type(time)) {
case MRB_TT_FIXNUM:
......@@ -762,12 +768,12 @@ mrb_init_io(mrb_state *mrb)
mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */
#ifndef _WIN32
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));
#endif
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, "_bless", mrb_io_bless, MRB_ARGS_NONE());
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());
mrb_define_method(mrb, io, "sysseek", mrb_io_sysseek, MRB_ARGS_REQ(1));
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment