ruby-changes:38037
From: nobu <ko1@a...>
Date: Mon, 30 Mar 2015 11:28:31 +0900 (JST)
Subject: [ruby-changes:38037] nobu:r50118 (trunk): io.c: use read/write methods if possible
nobu 2015-03-30 11:28:02 +0900 (Mon, 30 Mar 2015) New Revision: 50118 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50118 Log: io.c: use read/write methods if possible * io.c (copy_stream_body): use the arguments without conversion if having read, readpartial, and write methods, than conversion by to_path method. [ruby-core:68676] [Bug #11015] Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 50117) +++ ChangeLog (revision 50118) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon Mar 30 11:27:54 2015 Nobuyoshi Nakada <nobu@r...> + + * io.c (copy_stream_body): use the arguments without conversion if + having read, readpartial, and write methods, than conversion by + to_path method. [ruby-core:68676] [Bug #11015] + Sun Mar 29 21:08:37 2015 SHIBATA Hiroshi <shibata.hiroshi@g...> * gc.c (objspace_allrefs_destruct_i): fix a typo. Index: io.c =================================================================== --- io.c (revision 50117) +++ io.c (revision 50118) @@ -10515,52 +10515,57 @@ copy_stream_body(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L10515 stp->total = 0; - if (src_io == argf || - !(RB_TYPE_P(src_io, T_FILE) || - RB_TYPE_P(src_io, T_STRING) || - rb_respond_to(src_io, rb_intern("to_path")))) { - src_fd = -1; + if (src_io == argf) { + src_fd = -1; + } + else if (RB_TYPE_P(src_io, T_FILE)) { + goto io_src; + } + else if (!RB_TYPE_P(src_io, T_STRING) && + (rb_respond_to(src_io, id_read) || + rb_respond_to(src_io, id_readpartial))) { + src_fd = -1; } else { - if (!RB_TYPE_P(src_io, T_FILE)) { - VALUE args[2]; - FilePathValue(src_io); - args[0] = src_io; - args[1] = INT2NUM(O_RDONLY|common_oflags); - src_io = rb_class_new_instance(2, args, rb_cFile); - stp->src = src_io; - stp->close_src = 1; - } - GetOpenFile(src_io, src_fptr); - rb_io_check_byte_readable(src_fptr); - src_fd = src_fptr->fd; + VALUE args[2]; + FilePathValue(src_io); + args[0] = src_io; + args[1] = INT2NUM(O_RDONLY|common_oflags); + src_io = rb_class_new_instance(2, args, rb_cFile); + stp->src = src_io; + stp->close_src = 1; + io_src: + GetOpenFile(src_io, src_fptr); + rb_io_check_byte_readable(src_fptr); + src_fd = src_fptr->fd; } stp->src_fd = src_fd; - if (dst_io == argf || - !(RB_TYPE_P(dst_io, T_FILE) || - RB_TYPE_P(dst_io, T_STRING) || - rb_respond_to(dst_io, rb_intern("to_path")))) { - dst_fd = -1; + if (dst_io == argf) { + dst_fd = -1; + } + else if (RB_TYPE_P(dst_io, T_FILE)) { + dst_io = GetWriteIO(dst_io); + stp->dst = dst_io; + goto io_dst; + } + else if (!RB_TYPE_P(dst_io, T_STRING) && + rb_respond_to(dst_io, id_write)) { + dst_fd = -1; } else { - if (!RB_TYPE_P(dst_io, T_FILE)) { - VALUE args[3]; - FilePathValue(dst_io); - args[0] = dst_io; - args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags); - args[2] = INT2FIX(0666); - dst_io = rb_class_new_instance(3, args, rb_cFile); - stp->dst = dst_io; - stp->close_dst = 1; - } - else { - dst_io = GetWriteIO(dst_io); - stp->dst = dst_io; - } - GetOpenFile(dst_io, dst_fptr); - rb_io_check_writable(dst_fptr); - dst_fd = dst_fptr->fd; + VALUE args[3]; + FilePathValue(dst_io); + args[0] = dst_io; + args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags); + args[2] = INT2FIX(0666); + dst_io = rb_class_new_instance(3, args, rb_cFile); + stp->dst = dst_io; + stp->close_dst = 1; + io_dst: + GetOpenFile(dst_io, dst_fptr); + rb_io_check_writable(dst_fptr); + dst_fd = dst_fptr->fd; } stp->dst_fd = dst_fd; Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 50117) +++ test/ruby/test_io.rb (revision 50118) @@ -873,6 +873,21 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L873 } end + def test_copy_stream_strio_to_tempfile + bug11015 = '[ruby-core:68676] [Bug #11015]' + # StringIO to Tempfile + src = StringIO.new("abcd") + dst = Tempfile.new("baz") + ret = IO.copy_stream(src, dst) + assert_equal(4, ret) + pos = dst.pos + dst.rewind + assert_equal("abcd", dst.read) + assert_equal(4, pos, bug11015) + ensure + dst.close! + end + def test_copy_stream_write_in_binmode bug8767 = '[ruby-core:56518] [Bug #8767]' mkcdtmpdir { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/