[macruby-changes] [954] MacRuby/branches/experimental/io.c

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 17 13:22:13 PDT 2009


Revision: 954
          http://trac.macosforge.org/projects/ruby/changeset/954
Author:   pthomson at apple.com
Date:     2009-03-17 13:22:12 -0700 (Tue, 17 Mar 2009)
Log Message:
-----------
Reimplemented a whole bunch of the IO methods.

Modified Paths:
--------------
    MacRuby/branches/experimental/io.c

Modified: MacRuby/branches/experimental/io.c
===================================================================
--- MacRuby/branches/experimental/io.c	2009-03-17 12:08:00 UTC (rev 953)
+++ MacRuby/branches/experimental/io.c	2009-03-17 20:22:12 UTC (rev 954)
@@ -102,6 +102,20 @@
 //     return S_ISSOCK(sbuf.st_mode);
 // }
 
+
+static int extract_mode_flags(VALUE mode_string) {
+    int result = 0;
+    const char *path = RSTRING_PTR(mode_string);
+    if (strchr(path, 'r')) {
+        result |= FMODE_READABLE;
+    }
+    if (strchr(path, 'w')) {
+        result |= FMODE_WRITABLE;
+    }
+    return result;
+}
+
+
 void
 rb_eof_error(void)
 {
@@ -165,36 +179,6 @@
 	    || CFWriteStreamGetStatus(io_struct->writeStream) == kCFStreamStatusOpen);
 }
 
-#if 0
-// These methods are not used yet.
-static int
-rb_io_get_fd_from_data(CFDataRef data)
-{
-    assert(data != NULL);
-    int fd;
-    assert(CFDataGetLength(data) == sizeof(fd));
-    CFDataGetBytes(data, CFRangeMake(0, sizeof(fd)), (UInt8 *)&fd);
-    CFRelease(data);
-    return fd;
-}
-
-static int
-rb_io_get_read_stream_fd(rb_io_t *io_struct)
-{
-    CFDataRef data = CFReadStreamCopyProperty(io_struct->readStream, 
-	    kCFStreamPropertySocketNativeHandle);
-    return rb_io_get_fd_from_data(data);
-}
-
-static int
-rb_io_get_write_stream_fd(rb_io_t *io_struct)
-{
-    CFDataRef data = CFWriteStreamCopyProperty(io_struct->writeStream, 
-	    kCFStreamPropertySocketNativeHandle);
-    return rb_io_get_fd_from_data(data);
-}
-#endif
-
 #define FMODE_PREP (1<<16)
 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
 #define PREP_STDIO_NAME(f) ((f)->path)
@@ -266,90 +250,43 @@
     return (VALUE)io;
 }
 
-static inline CFReadStreamRef
-rb_io_open_read_stream(int fd, CFURLRef url)
-{
-    CFReadStreamRef r;
 
-    if (url != NULL) {
-	r = CFReadStreamCreateWithFile(NULL, url);
-	assert(r != NULL);
-    }
-    else {
-	// TODO
-	abort();
-    }
+CFReadStreamRef _CFReadStreamCreateFromFileDescriptor(CFAllocatorRef alloc, int fd);
+CFWriteStreamRef _CFWriteStreamCreateFromFileDescriptor(CFAllocatorRef alloc, int fd);
 
-    if (!CFReadStreamOpen(r)) {
-	rb_raise(rb_eRuntimeError, "cannot open read stream");
-    }
-
-    return r;
-}
-
-static inline CFWriteStreamRef
-rb_io_open_write_stream(int fd, CFURLRef url)
+static inline void 
+prepare_io_from_fd(rb_io_t *io_struct, int fd, int mode)
 {
-    CFWriteStreamRef w;
-
-    if (url != NULL) {
-	w = CFWriteStreamCreateWithFile(NULL, url);
-	assert(w != NULL);
-    }
-    else {
-	// TODO
-	abort();
-    }
-
-    if (!CFWriteStreamOpen(w)) {
-	rb_raise(rb_eRuntimeError, "cannot open read stream");
-    }
-
-    return w;
-}
-
-static inline void
-prep_io_struct(rb_io_t *io_struct, int fd, int mode, const char *path)
-{
     CFReadStreamRef r = NULL;
     CFWriteStreamRef w = NULL;
     
-    if (path != NULL) {
-	CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL,
-		(const UInt8 *)path, strlen(path), false);
-	assert(url != NULL);
-	if (mode & FMODE_READABLE) {
-	    r = rb_io_open_read_stream(fd, url);
-	}
-	if (mode & FMODE_WRITABLE) {
-	    w = rb_io_open_write_stream(fd, url);
-	}
-	CFRelease(url);	
+    if (mode & FMODE_READABLE) {
+    	r = _CFReadStreamCreateFromFileDescriptor(NULL, fd);
     }
-    else {
-	// TODO
-	//CFStreamCreatePairWithSocket(NULL, fd, &r, &w);
-	abort();
+    
+    if (mode & FMODE_WRITABLE) {
+    	w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd);
     }
-
+    
     assert(r != NULL || w != NULL);
-
+    
     if (r != NULL) {
-	GC_WB(&io_struct->readStream, r);
-	CFMakeCollectable(r);
+    	CFReadStreamOpen(r);
+    	GC_WB(&io_struct->readStream, r);
+    	CFMakeCollectable(r);
+    } 
+	else {
+    	io_struct->readStream = NULL;
     }
-    else {
-	io_struct->readStream = NULL;
-    }
-
+    
     if (w != NULL) {
-	GC_WB(&io_struct->writeStream, w);
-	CFMakeCollectable(w);
+    	CFWriteStreamOpen(w);
+    	GC_WB(&io_struct->writeStream, w);
+    	CFMakeCollectable(w);
+    } else {
+    	io_struct->writeStream = NULL;
     }
-    else {
-	io_struct->writeStream = NULL;
-    }
-    
+    // TODO: Eventually make the ungetc_buf a ByteString
     io_struct->fd = fd;
     io_struct->ungetc_buf = NULL;
     io_struct->ungetc_buf_len = 0;
@@ -357,26 +294,15 @@
 }
 
 static VALUE
-prep_io(int fd, int mode, VALUE klass, const char *path)
+prep_io(int fd, int mode, VALUE klass)
 {
     VALUE io = io_alloc(rb_cIO, 0);
-
-    rb_io_t *io_struct = RFILE(io)->fptr;
-
-    prep_io_struct(io_struct, fd, mode, path);
-
+	rb_io_t *io_struct = ExtractIOStruct(io);
+    prepare_io_from_fd(io_struct, fd, mode);
     rb_objc_keep_for_exit_finalize((VALUE)io);
-
     return io;
 }
 
-static VALUE
-prep_stdio(FILE *f, int mode, VALUE klass, const char *path)
-{
-    VALUE io = prep_io(fileno(f), mode|FMODE_PREP, klass, path);
-    return io;
-}
-
 /*
  *  call-seq:
  *     ios.write(string)    => integer
@@ -1083,7 +1009,8 @@
 static VALUE
 rb_io_lineno(VALUE io, SEL sel)
 {
-rb_notimplement();
+    rb_io_t *io_s = ExtractIOStruct(io);
+    return INT2FIX(io_s->lineno);
 }
 
 /*
@@ -1104,9 +1031,11 @@
  */
 
 static VALUE
-rb_io_set_lineno(VALUE io, SEL sel, VALUE lineno)
+rb_io_set_lineno(VALUE io, SEL sel, VALUE line_no)
 {
-rb_notimplement();
+    rb_io_t *io_s = ExtractIOStruct(io);
+    io_s->lineno = FIX2INT(line_no);
+    return line_no;
 }
 
 /*
@@ -1468,7 +1397,8 @@
 static VALUE
 rb_io_isatty(VALUE io, SEL sel)
 {
-    rb_notimplement();
+    rb_io_t *io_s = ExtractIOStruct(io);
+    return CONDITION_TO_BOOLEAN(isatty(io_s->fd));
 }
 
 /*
@@ -1620,7 +1550,7 @@
     if (path != NULL && strcmp(path, "-") != 0) {
 	klass = rb_cFile;
     }
-    return prep_io(fd, rb_io_modenum_flags(mode), klass, path);
+    return prep_io(fd, rb_io_modenum_flags(mode), klass);
 }
 
 static VALUE
@@ -1843,10 +1773,18 @@
  *
  */
 
+static VALUE rb_io_s_new(VALUE klass, SEL sel, int argc, VALUE *argv);
+
 static VALUE
 rb_io_s_open(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-rb_notimplement();
+    VALUE io = rb_io_s_new(klass, sel, argc, argv);
+    if (rb_block_given_p()) {
+        VALUE ret = rb_vm_yield(1, &io);
+        rb_io_close_m(io, 0);
+        return ret;
+    }
+    return io;
 }
 
 /*
@@ -1972,11 +1910,27 @@
  *
  *     Got: in Child
  */
+ 
+int extract_oflags(VALUE str) {
+    // TODO maybe use a switch statement here, I dunno.
+    return O_RDONLY;
+}
 
 static VALUE
 rb_f_open(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-rb_notimplement();
+    // FIX THE HELL OUT OF ME!!!!
+    // TODO: Handle the pipes, subprocess, etc.
+    // TODO: Take into account the provided file permissions.
+    // TODO: Handle files that don't exist.
+    VALUE path, modes, permissions;
+    rb_scan_args(argc, argv, "12", &path, &modes, &permissions);
+    
+    StringValue(path);
+    int mode = (NIL_P(modes) ? O_RDONLY : rb_io_modenum_flags(modes));
+    const char *filepath = RSTRING_PTR(path);
+    int fd = open(filepath, mode);
+    return prep_io(fd, FMODE_READWRITE, klass);
 }
 
 /*
@@ -2020,7 +1974,7 @@
 VALUE
 rb_io_printf(VALUE out, SEL sel, int argc, VALUE *argv)
 {
-    rb_notimplement();
+    return rb_io_write(out, sel, rb_f_sprintf(argc, argv));
 }
 
 /*
@@ -2037,7 +1991,21 @@
 static VALUE
 rb_f_printf(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-rb_notimplement();
+    VALUE io;
+    if (argc == 0) {
+        return Qnil;
+    }
+    
+    if (TYPE(argv[0]) == T_STRING) {
+        io = rb_stdout;
+    } 
+    else {
+        io = argv[0];
+        argv++;
+        argc--;
+    }
+    
+    return rb_io_printf(io, sel, argc, argv);
 }
 
 /*
@@ -2060,11 +2028,13 @@
  *     This is 100 percent.
  */
 
+
+
 VALUE
 rb_io_print(VALUE io, SEL sel, int argc, VALUE *argv)
 {
     VALUE line;
-    if(argc == 0) {
+    if (argc == 0) {
         // No arguments? Bloody Perlisms...
         argc = 1;
         line = rb_lastline_get();
@@ -2072,11 +2042,11 @@
     }
     while(argc--) {
         rb_io_write(rb_stdout, 0, *argv++);
-        if(!NIL_P(rb_output_fs)) {
+        if (!NIL_P(rb_output_fs)) {
             rb_io_write(rb_stdout, 0, rb_output_fs);
         }
     }
-    if(!NIL_P(rb_output_rs)) {
+    if (!NIL_P(rb_output_rs)) {
         rb_io_write(rb_stdout, 0, rb_output_rs);
     }
     return Qnil;
@@ -2133,7 +2103,9 @@
 static VALUE
 rb_io_putc(VALUE io, SEL sel, VALUE ch)
 {
-rb_notimplement();
+    char c = NUM2CHR(ch);
+    rb_io_write(io, sel, rb_str_new(&c, 1));
+    return ch;
 }
 
 /*
@@ -2148,7 +2120,7 @@
 static VALUE
 rb_f_putc(VALUE recv, SEL sel, VALUE ch)
 {
-rb_notimplement();
+    return rb_io_putc(rb_stdout, sel, ch);
 }
 
 /*
@@ -2286,6 +2258,7 @@
 //     }
 // }
 
+// TODO: Fix this; the documentation is wrong.
 
 /*
  *  call-seq:
@@ -2319,7 +2292,13 @@
 static VALUE
 rb_io_initialize(VALUE io, SEL sel, int argc, VALUE *argv)
 {
-    rb_notimplement();
+    VALUE file_descriptor, mode;
+    int mode_flags;
+    rb_io_t *io_struct = ExtractIOStruct(io);
+    rb_scan_args(argc, argv, "11", &file_descriptor, &mode);
+    mode_flags = (NIL_P(mode) ? FMODE_READABLE : extract_mode_flags(mode));
+    prepare_io_from_fd(io_struct, FIX2INT(file_descriptor), mode_flags);
+    return io;
 }
 
 /*
@@ -2346,6 +2325,14 @@
 static VALUE
 rb_file_initialize(VALUE io, SEL sel, int argc, VALUE *argv)
 {
+	// VALUE path, mode, permissions, io;
+	// rb_io_t *io_s;
+	// rb_scan_args(argc, argv, "12", &path, &mode, &permissions);
+	// // TODO: I completely ignore the mode and permissions here. Fix that.
+	// io = io_alloc(klass, sel);
+	// io_s = ExtractIOStruct(io);
+	// prepare_io_from_path(io_s, path, O_RDONLY | O_WRONLY);
+	// return io;
     rb_notimplement();
 }
 
@@ -2368,9 +2355,10 @@
  */
 
 static VALUE
-rb_io_s_new(VALUE klass, SEL sel, VALUE fd, VALUE mode)
+rb_io_s_new(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-    rb_notimplement();
+    VALUE io = io_alloc(klass, sel);
+    return rb_io_initialize(io, sel, argc, argv);
 }
 
 
@@ -2982,21 +2970,17 @@
 rb_io_s_read(VALUE recv, SEL sel, int argc, VALUE *argv)
 {
     VALUE fname, length, offset, opt;
-
     rb_scan_args(argc, argv, "13", &fname, &length, &offset, &opt);
 
     // TODO honor opt
 
     StringValue(fname);
 
-    CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL,
-	    (const UInt8 *)RSTRING_PTR(fname), RSTRING_LEN(fname), false);
-    assert(url != NULL);
+	const char *path = RSTRING_PTR(fname);
+	int fd = open(path, O_RDONLY);
+    CFReadStreamRef readStream = _CFReadStreamCreateFromFileDescriptor(NULL, fd);
+	CFReadStreamOpen(readStream);
 
-    CFReadStreamRef readStream = rb_io_open_read_stream(-1, url);
-
-    CFRelease(url);
-
     if (!NIL_P(offset)) {
 	long o = FIX2LONG(offset);
 	rb_io_read_stream_set_offset(readStream, o);
@@ -3034,6 +3018,7 @@
 
     CFReadStreamClose(readStream);
     CFRelease(readStream);
+    close(fd);
 
     return outbuf;
 }
@@ -3718,17 +3703,16 @@
     rb_objc_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0);
     rb_objc_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1);
 
-    // TODO: Replace these with their real equivalents - they're nil now.
-    rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "/dev/stdin");
+    rb_stdin = prep_io(fileno(stdin), FMODE_READABLE, rb_cIO);
     rb_define_variable("$stdin", &rb_stdin);
     rb_define_global_const("STDIN", rb_stdin);
     
-    rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "/dev/stdout");
+    rb_stdout = prep_io(fileno(stdout), FMODE_WRITABLE, rb_cIO);
     rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
     rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter);
     rb_define_global_const("STDOUT", rb_stdout);
     
-    rb_stderr = prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "/dev/stderr");
+    rb_stderr = prep_io(fileno(stderr), FMODE_WRITABLE|FMODE_SYNC, rb_cIO);
     rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
     rb_define_global_const("STDERR", rb_stderr);
  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090317/f4b411ce/attachment-0001.html>


More information about the macruby-changes mailing list