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

source_changes at macosforge.org source_changes at macosforge.org
Sun Mar 29 16:33:18 PDT 2009


Revision: 1257
          http://trac.macosforge.org/projects/ruby/changeset/1257
Author:   lsansonetti at apple.com
Date:     2009-03-29 16:33:18 -0700 (Sun, 29 Mar 2009)
Log Message:
-----------
reverted patrick's gets implementation because it's buggy (breaks #require of one liners) + fixed the indentation

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

Modified: MacRuby/branches/experimental/io.c
===================================================================
--- MacRuby/branches/experimental/io.c	2009-03-29 10:46:50 UTC (rev 1256)
+++ MacRuby/branches/experimental/io.c	2009-03-29 23:33:18 UTC (rev 1257)
@@ -1204,66 +1204,83 @@
 static VALUE
 rb_io_gets_m(VALUE io, SEL sel, int argc, VALUE *argv)
 {
-	VALUE sep, limit;
-	rb_scan_args(argc, argv, "02", &sep, &limit);
-	rb_io_t *io_struct = ExtractIOStruct(io);
-	
-	if (rb_io_eof(io, 0) == Qtrue) {
-		return Qnil;
+    VALUE sep, limit;
+    rb_scan_args(argc, argv, "02", &sep, &limit);
+    rb_io_t *io_struct = ExtractIOStruct(io);
+
+    if (rb_io_eof(io, 0) == Qtrue) {
+	return Qnil;
+    }
+
+    if (NIL_P(rb_rs)) {
+	// TODO: Get rid of this when the fix comes in for the $\ variable.
+	rb_rs = (VALUE)CFSTR("\n");
+    }
+
+    if (NIL_P(sep)) {
+	// no arguments were passed at all.
+	// FIXME: if you pass nil, it's suppose to read everything. that sucks.
+	sep = rb_rs;
+	limit = Qnil;
+    } 
+    else {
+	if (TYPE(sep) != T_STRING) {
+	    // sep wasn't given, limit was.
+	    limit = sep;
+	    sep = rb_rs;
+	} 
+	else if (RSTRING_LEN(sep) == 0) {
+	    sep = (VALUE)CFSTR("\n\n");
 	}
-	
-	if (NIL_P(rb_rs)) {
-		// TODO: Get rid of this when the fix comes in for the $\ variable.
-		rb_rs = (VALUE)CFSTR("\n");
+    }
+    long line_limit = (NIL_P(limit) ? -1 : FIX2LONG(limit));
+    // now that we've got our parameters, let's get down to business.
+
+    VALUE bstr = rb_bytestring_new();
+    CFMutableDataRef data = rb_bytestring_wrapped_data(bstr);
+    if (line_limit != -1) {
+	CFDataIncreaseLength(data, line_limit);
+	UInt8 *b = CFDataGetMutableBytePtr(data);
+	rb_io_read_internal(io_struct, b, line_limit);
+	CFRange r = CFStringFind((CFStringRef)bstr, (CFStringRef)sep, 0);
+	if (r.location != kCFNotFound) {
+	    CFDataSetLength(data, r.location);
 	}
-	
-	if (NIL_P(sep)) {
-		// no arguments were passed at all.
-		// FIXME: if you pass nil, it's suppose to read everything. that sucks.
-		sep = rb_rs;
-		limit = Qnil;
-	} else {
-		if (TYPE(sep) != T_STRING) {
-			// sep wasn't given, limit was.
-			limit = sep;
-			sep = rb_rs;
-		} else if (RSTRING_LEN(sep) == 0) {
-			sep = (VALUE)CFSTR("\n\n");
-		}
+    }
+    else {
+	long s = 512;
+	CFDataSetLength(data, s);
+
+	const char *sepstr = RSTRING_PTR(sep);
+	const int seplen = RSTRING_LEN(sep);
+	assert(seplen > 0);
+	UInt8 *buf = CFDataGetMutableBytePtr(data);
+	UInt8 *tmp_buf = alloca(seplen);
+	long data_read = 0;
+
+	while (true) {
+	    if (rb_io_read_internal(io_struct, tmp_buf, seplen) != seplen) {
+		break;
+	    }
+	    if (data_read >= s) {
+		s += s;
+		CFDataSetLength(data, s);
+		buf = CFDataGetMutableBytePtr(data);
+	    }
+	    memcpy(&buf[data_read], tmp_buf, seplen);
+	    data_read += seplen;
+
+	    if (memcmp(tmp_buf, sepstr, seplen) == 0) {
+		break;
+	    }
 	}
-	long line_limit = (NIL_P(limit) ? -1 : FIX2LONG(limit));
-	// now that we've got our parameters, let's get down to business.
-	
-	VALUE bstr = rb_bytestring_new();
-	CFMutableDataRef data = rb_bytestring_wrapped_data(bstr);
-	// this is not the best code i've ever written, but it'll do.
-	if(line_limit != -1) {
-		CFDataIncreaseLength(data, line_limit);
-		UInt8 *b = CFDataGetMutableBytePtr(data);
-		rb_io_read_internal(io_struct, b, line_limit);
-		CFRange r = CFStringFind((CFStringRef)bstr, (CFStringRef)sep, 0);
-		if (r.location != kCFNotFound) {
-			CFDataSetLength(data, r.location);
-		}
-	} else {
-		// Though this isn't the worst possible implementation, it could
-		// certainly use a little work. If it causes problems we'll take a look at it.
-		long string_offset = 0;
-		int seplen = RSTRING_LEN(sep);
-		for(;;) {
-			CFDataIncreaseLength(data, seplen);
-			UInt8 *b = CFDataGetMutableBytePtr(data) + string_offset;
-			long read = rb_io_read_internal(io_struct, b, seplen);
-			CFRange r = CFStringFind((CFStringRef)bstr, (CFStringRef)sep, 0);
-			if ((r.location != kCFNotFound) || (rb_io_eof(io, 0) == Qtrue)) {
-				CFDataSetLength(data, r.location + (seplen));
-				break;
-			} else {
-				string_offset += read;
-			}
-		}
+
+	if (data_read == 0) {
+	    return Qnil;
 	}
-	
+	CFDataSetLength(data, data_read);
+    }
+
     return bstr; 
 }
 
@@ -1331,9 +1348,11 @@
 static VALUE
 rb_io_readline(VALUE io, SEL sel, int argc, VALUE *argv)
 {
-	VALUE ret = rb_io_gets_m(io, sel, argc, argv);
-	if(NIL_P(ret)) rb_eof_error();
-	return ret;
+    VALUE ret = rb_io_gets_m(io, sel, argc, argv);
+    if (NIL_P(ret)) {
+	rb_eof_error();
+    }
+    return ret;
 }
 
 /*
@@ -1845,7 +1864,7 @@
 VALUE
 rb_io_gets(VALUE io, SEL sel)
 {
-	return rb_io_gets_m(io, sel, 0, NULL);
+    return rb_io_gets_m(io, 0, 0, NULL);
 }
 
 /*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090329/fbc2bed7/attachment.html>


More information about the macruby-changes mailing list