[macruby-changes] [1892] MacRuby/branches/experimental/io.c
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jun 19 16:50:20 PDT 2009
Revision: 1892
http://trac.macosforge.org/projects/ruby/changeset/1892
Author: lsansonetti at apple.com
Date: 2009-06-19 16:50:18 -0700 (Fri, 19 Jun 2009)
Log Message:
-----------
fixed IO.copy_streams to actually work (it was severily broken), added a fast path that uses copyfile(2) if both arguments are strings
Modified Paths:
--------------
MacRuby/branches/experimental/io.c
Modified: MacRuby/branches/experimental/io.c
===================================================================
--- MacRuby/branches/experimental/io.c 2009-06-19 23:04:40 UTC (rev 1891)
+++ MacRuby/branches/experimental/io.c 2009-06-19 23:50:18 UTC (rev 1892)
@@ -20,6 +20,7 @@
#include <paths.h>
#include <fcntl.h>
#include <unistd.h>
+#include <copyfile.h>
#include <sys/select.h>
#include <sys/ioctl.h>
@@ -3625,21 +3626,69 @@
*
*/
static VALUE
-rb_io_s_copy_stream(VALUE id, SEL sel, int argc, VALUE *argv)
+rb_io_s_copy_stream(VALUE rcv, SEL sel, int argc, VALUE *argv)
{
- VALUE src, dst, len, offset;
- rb_scan_args(argc, argv, "22", &src, &dst, &len, &offset);
- VALUE old_offset = rb_io_tell(src, 0); // save the old offset
- if(!NIL_P(offset)) {
- // seek if necessary
- rb_io_seek(src, 0, offset);
+ VALUE src, dst, len, offset;
+ rb_scan_args(argc, argv, "22", &src, &dst, &len, &offset);
+
+ bool src_is_path = false, dst_is_path = false;
+
+ VALUE old_src_offset = Qnil;
+ if (TYPE(src) != T_FILE) {
+ FilePathValue(src);
+ src_is_path = true;
+ }
+ else {
+ old_src_offset = rb_io_tell(src, 0); // save the old offset
+ if (!NIL_P(offset)) {
+ // seek if necessary
+ rb_io_seek(src, 0, offset);
}
- VALUE data_read = (NIL_P(len) ? io_read(src, 0, 0, NULL) : io_read(src, 0, 1, &len));
- VALUE copied = io_write(dst, 0, data_read);
- if(!NIL_P(offset)) {
- rb_io_seek(src, 0, old_offset); // restore the old offset
+ }
+
+ if (TYPE(dst) != T_FILE) {
+ FilePathValue(dst);
+ dst_is_path = true;
+ }
+
+ if (src_is_path && dst_is_path) {
+ // Fast path!
+ copyfile_state_t s = copyfile_state_alloc();
+ if (copyfile(RSTRING_PTR(src), RSTRING_PTR(dst), s, COPYFILE_ALL)
+ != 0) {
+ copyfile_state_free(s);
+ rb_sys_fail("copyfile() failed");
}
- return copied;
+ int src_fd = -2;
+ assert(copyfile_state_get(s, COPYFILE_STATE_SRC_FD, &src_fd) == 0);
+ struct stat st;
+ if (fstat(src_fd, &st) != 0) {
+ rb_sys_fail("fstat() failed");
+ }
+ copyfile_state_free(s);
+ return LONG2NUM(st.st_size);
+ }
+ else {
+ if (src_is_path) {
+ src = rb_f_open(rcv, 0, 1, &src);
+ }
+ if (dst_is_path) {
+ VALUE args[2];
+ args[0] = dst;
+ args[1] = rb_str_new2("w");
+ dst = rb_f_open(rcv, 0, 2, args);
+ }
+ }
+
+ VALUE data_read = NIL_P(len)
+ ? io_read(src, 0, 0, NULL) : io_read(src, 0, 1, &len);
+
+ VALUE copied = io_write(dst, 0, data_read);
+
+ if (!NIL_P(old_src_offset)) {
+ rb_io_seek(src, 0, old_src_offset); // restore the old offset
+ }
+ return copied;
}
/*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090619/c032c03b/attachment.html>
More information about the macruby-changes
mailing list