Feature #1081 » sorah_implementation.diff
| io.c | ||
|---|---|---|
|
long length;
|
||
|
};
|
||
|
struct write_arg {
|
||
|
VALUE io;
|
||
|
VALUE str;
|
||
|
int nosync;
|
||
|
};
|
||
|
static VALUE
|
||
|
io_binwrite_string(VALUE arg)
|
||
|
{
|
||
| ... | ... | |
|
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
|
||
|
}
|
||
|
static VALUE
|
||
|
io_s_write(struct write_arg *arg)
|
||
|
{
|
||
|
return io_write(arg->io,arg->str,arg->nosync);
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* IO.write(name, string, [offset] ) => fixnum
|
||
|
* IO.write(name, string, [offset], open_args ) => fixnum
|
||
|
*
|
||
|
* Opens the file, optionally seeks to the given <i>offset</i>, writes
|
||
|
* <i>string</i>, then returns the length written.
|
||
|
* <code>write</code> ensures the file is closed before returning.
|
||
|
* If <i>offset</i> is not given, the file is truncated. Otherwise,
|
||
|
* it is not truncated.
|
||
|
*
|
||
|
* If the last argument is a hash, it specifies option for internal
|
||
|
* open(). The key would be the following. open_args: is exclusive
|
||
|
* to others.
|
||
|
*
|
||
|
* encoding: string or encoding
|
||
|
*
|
||
|
* specifies encoding of the read string. encoding will be ignored
|
||
|
* if length is specified.
|
||
|
*
|
||
|
* mode: string
|
||
|
*
|
||
|
* specifies mode argument for open(). it should start with "w" or "a" or "r+"
|
||
|
* otherwise it would cause error.
|
||
|
*
|
||
|
* perm: fixnum
|
||
|
*
|
||
|
* specifies perm argument for open().
|
||
|
*
|
||
|
* open_args: array of strings
|
||
|
*
|
||
|
* specifies arguments for open() as an array.
|
||
|
*
|
||
|
* IO.write("testfile", "0123456789") #=> "0123456789"
|
||
|
* IO.write("testfile", "0123456789", 20) #=> "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
|
||
|
*/
|
||
|
static VALUE
|
||
|
rb_io_s_write(int argc, VALUE *argv, VALUE io)
|
||
|
{
|
||
|
VALUE opt, offset, string;
|
||
|
struct foreach_arg arg;
|
||
|
struct write_arg warg;
|
||
|
rb_scan_args(argc, argv, "21:", NULL, &string, &offset, &opt);
|
||
|
if(NIL_P(opt)) opt = rb_hash_new();
|
||
|
else opt = rb_hash_dup(opt);
|
||
|
if(NIL_P(rb_hash_aref(opt,sym_mode))) {
|
||
|
if(NIL_P(offset)) {
|
||
|
rb_hash_aset(opt,sym_mode,INT2NUM(O_WRONLY|O_TRUNC|O_CREAT));
|
||
|
}else{
|
||
|
rb_hash_aset(opt,sym_mode,INT2NUM(O_WRONLY|O_CREAT));
|
||
|
}
|
||
|
}
|
||
|
open_key_args(argc,argv,opt,&arg);
|
||
|
if(NIL_P(arg.io)) return Qnil;
|
||
|
if(!NIL_P(offset)) {
|
||
|
struct seek_arg sarg;
|
||
|
int state = 0;
|
||
|
sarg.io = arg.io;
|
||
|
sarg.offset = offset;
|
||
|
sarg.mode = SEEK_SET;
|
||
|
rb_protect(seek_before_access, (VALUE)&sarg, &state);
|
||
|
if (state) {
|
||
|
rb_io_close(arg.io);
|
||
|
rb_jump_tag(state);
|
||
|
}
|
||
|
}
|
||
|
warg.io = arg.io;
|
||
|
warg.str = string;
|
||
|
warg.nosync = 0;
|
||
|
return rb_ensure(io_s_write, (VALUE)&warg, rb_io_close, arg.io);
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* IO.binwrite(name, string, [offset] ) => fixnum
|
||
|
*
|
||
|
* Opens the file, optionally seeks to the given <i>offset</i>, write
|
||
|
* <i>string</i> then returns the length written.
|
||
|
* <code>binwrite</code> ensures the file is closed before returning.
|
||
|
* The open mode would be "wb:ASCII-8BIT".
|
||
|
* If <i>offset</i> is not given, the file is truncated. Otherwise,
|
||
|
* it is not truncated.
|
||
|
*
|
||
|
* IO.binwrite("testfile", "0123456789") #=> "0123456789"
|
||
|
* IO.binwrite("testfile", "0123456789", 20) #=> "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
|
||
|
*/
|
||
|
static VALUE
|
||
|
rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
|
||
|
{
|
||
|
VALUE path, string, offset, mode;
|
||
|
struct write_arg arg;
|
||
|
rb_scan_args(argc, argv, "21", &path, &string, &offset);
|
||
|
#ifdef O_BINARY
|
||
|
if(NIL_P(offset)){
|
||
|
mode = INT2NUM(O_WRONLY|O_TRUNC|O_CREAT|O_BINARY);
|
||
|
}else{
|
||
|
mode = INT2NUM(O_RDWR|O_CREAT|O_BINARY);
|
||
|
}
|
||
|
#else
|
||
|
if(NIL_P(offset)) {
|
||
|
mode = INT2NUM(O_WRONLY|O_TRUNC|O_CREAT);
|
||
|
}else{
|
||
|
mode = INT2NUM(O_RDWR|O_CREAT);
|
||
|
}
|
||
|
#endif
|
||
|
arg.io = rb_io_open(path,mode,INT2FIX(0666),Qnil);
|
||
|
arg.str = string;
|
||
|
arg.nosync = 0;
|
||
|
if(NIL_P(arg.io)) return Qnil;
|
||
|
#ifndef O_BINARY
|
||
|
rb_io_binmode_m(arg.io);
|
||
|
#endif
|
||
|
if(!NIL_P(offset)) {
|
||
|
struct seek_arg sarg;
|
||
|
int state = 0;
|
||
|
sarg.io = arg.io;
|
||
|
sarg.offset = offset;
|
||
|
sarg.mode = SEEK_SET;
|
||
|
rb_protect(seek_before_access, (VALUE)&sarg, &state);
|
||
|
if (state) {
|
||
|
rb_io_close(arg.io);
|
||
|
rb_jump_tag(state);
|
||
|
}
|
||
|
}
|
||
|
return rb_ensure(io_s_write, (VALUE)&arg, rb_io_close, arg.io);
|
||
|
}
|
||
|
struct copy_stream_struct {
|
||
|
VALUE src;
|
||
|
VALUE dst;
|
||
| ... | ... | |
|
rb_define_singleton_method(rb_cIO, "readlines", rb_io_s_readlines, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "read", rb_io_s_read, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "binread", rb_io_s_binread, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "write", rb_io_s_write, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "binwrite", rb_io_s_binwrite, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "select", rb_f_select, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "pipe", rb_io_s_pipe, -1);
|
||
|
rb_define_singleton_method(rb_cIO, "try_convert", rb_io_s_try_convert, 1);
|
||
| test/ruby/test_io.rb | ||
|---|---|---|
|
end
|
||
|
end
|
||
|
def test_s_write
|
||
|
t = Tempfile.new("foo")
|
||
|
path = t.path
|
||
|
t.close(false)
|
||
|
File.write(path, "foo\nbar\nbaz")
|
||
|
assert_equal("foo\nbar\nbaz", File.read(path))
|
||
|
File.write(path, "FOO", 0)
|
||
|
assert_equal("FOO\nbar\nbaz", File.read(path))
|
||
|
File.write(path, "BAR")
|
||
|
assert_equal("BAR", File.read(path))
|
||
|
File.write(path, "\u{3042}", mode: "w", encoding: "EUC-JP")
|
||
|
assert_equal("\u{3042}".encode("EUC-JP"), File.read(path, encoding: "EUC-JP"))
|
||
|
File.delete t
|
||
|
assert_equal(6, File.write(path,'string',2))
|
||
|
File.delete t
|
||
|
assert_raise(Errno::EINVAL) { File.write('/tmp/nonexisting','string',-2) }
|
||
|
assert_equal(6, File.write(path, 'string'))
|
||
|
assert_equal(3, File.write(path, 'sub', 1))
|
||
|
assert_equal("ssubng", File.read(path))
|
||
|
File.delete t
|
||
|
assert_equal(3, File.write(path, "foo", encoding: "UTF-8"))
|
||
|
File.delete t
|
||
|
assert_equal(3, File.write(path, "foo", 0, encoding: "UTF-8"))
|
||
|
assert_equal("foo", File.read(path))
|
||
|
assert_equal(1, File.write(path, "f", 1, encoding: "UTF-8"))
|
||
|
assert_equal("ffo", File.read(path))
|
||
|
File.delete t
|
||
|
assert_equal(1, File.write(path, "f", 1, encoding: "UTF-8"))
|
||
|
assert_equal("\00f", File.read(path))
|
||
|
assert_equal(1, File.write(path, "f", 0, encoding: "UTF-8"))
|
||
|
assert_equal("ff", File.read(path))
|
||
|
t.unlink
|
||
|
end
|
||
|
def test_s_binwrite
|
||
|
t = Tempfile.new("foo")
|
||
|
path = t.path
|
||
|
t.close(false)
|
||
|
File.binwrite(path, "foo\nbar\nbaz")
|
||
|
assert_equal("foo\nbar\nbaz", File.read(path))
|
||
|
File.binwrite(path, "FOO", 0)
|
||
|
assert_equal("FOO\nbar\nbaz", File.read(path))
|
||
|
File.binwrite(path, "BAR")
|
||
|
assert_equal("BAR", File.read(path))
|
||
|
File.binwrite(path, "\u{3042}")
|
||
|
assert_equal("\u{3042}".force_encoding("ASCII-8BIT"), File.binread(path))
|
||
|
File.delete t
|
||
|
assert_equal(6, File.binwrite(path,'string',2))
|
||
|
File.delete t
|
||
|
assert_equal(6, File.binwrite(path, 'string'))
|
||
|
assert_equal(3, File.binwrite(path, 'sub', 1))
|
||
|
assert_equal("ssubng", File.binread(path))
|
||
|
assert_equal(6, File.size(path))
|
||
|
assert_raise(Errno::EINVAL) { File.binwrite('/tmp/nonexisting','string',-2) }
|
||
|
assert_raise(TypeError) { File.binwrite(path, "string", mode: "w", encoding: "EUC-JP") }
|
||
|
t.unlink
|
||
|
end
|
||
|
end
|
||
- « Previous
- 1
- …
- 4
- 5
- 6
- Next »