mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'master' of https://github.com/iij/mruby-io into test
Conflicts: src/io.c
This commit is contained in:
@@ -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
|
||||
|
||||
+54
-1
@@ -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)
|
||||
{
|
||||
@@ -370,21 +380,6 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_io_bless(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
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);
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
@@ -393,6 +388,17 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
|
||||
return mrb_io_initialize(mrb, io);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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));
|
||||
|
||||
+24
-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
|
||||
|
||||
Reference in New Issue
Block a user