[macruby-changes] [166] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 23 15:54:02 PDT 2008


Revision: 166
          http://trac.macosforge.org/projects/ruby/changeset/166
Author:   lsansonetti at apple.com
Date:     2008-04-23 15:54:02 -0700 (Wed, 23 Apr 2008)

Log Message:
-----------
fixing String subclassing/metaclassing

Modified Paths:
--------------
    MacRuby/trunk/class.c
    MacRuby/trunk/io.c
    MacRuby/trunk/string.c

Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c	2008-04-23 22:53:34 UTC (rev 165)
+++ MacRuby/trunk/class.c	2008-04-23 22:54:02 UTC (rev 166)
@@ -103,6 +103,7 @@
 
 void rb_objc_install_array_primitives(Class);
 void rb_objc_install_hash_primitives(Class);
+void rb_objc_install_string_primitives(Class);
 
 static VALUE
 rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass)
@@ -148,7 +149,8 @@
     if (name == NULL)
 	FL_SET(obj, RCLASS_ANONYMOUS);
 
-    if (rb_cArray != 0 && rb_cHash != 0 && ocsuper != NULL) {
+    if (rb_cArray != 0 && rb_cHash != 0 && rb_cString != 0 
+	&& ocsuper != NULL) {
 	do {
 	    if (ocsuper == RCLASS_OCID(rb_cArray)) {
 		rb_objc_install_array_primitives(ocklass);
@@ -158,6 +160,10 @@
 		rb_objc_install_hash_primitives(ocklass);
 		break;
 	    }
+	    if (ocsuper == RCLASS_OCID(rb_cString)) {
+		rb_objc_install_string_primitives(ocklass);
+		break;
+	    }
 	    ocsuper = class_getSuperclass(ocsuper);
 	}
 	while (ocsuper != NULL);	

Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c	2008-04-23 22:53:34 UTC (rev 165)
+++ MacRuby/trunk/io.c	2008-04-23 22:54:02 UTC (rev 166)
@@ -798,7 +798,7 @@
 	return rb_funcall(io, id_write, 1, str);
     }
     io = tmp;
-    if (RSTRING_LEN(str) == 0) return INT2FIX(0);
+    if (RSTRING_CLEN(str) == 0) return INT2FIX(0);
 
     GetOpenFile(io, fptr);
     rb_io_check_writable(fptr);

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-04-23 22:53:34 UTC (rev 165)
+++ MacRuby/trunk/string.c	2008-04-23 22:54:02 UTC (rev 166)
@@ -2364,6 +2364,9 @@
 #endif
 }
 
+#if WITH_OBJC
+static bool rb_objc_str_is_pure(VALUE);
+#endif
 
 /*
  *  call-seq:
@@ -2387,6 +2390,14 @@
 	return rb_equal(str2, str1);
     }
 #if WITH_OBJC
+    if (!rb_objc_str_is_pure(str2)) {
+	/* This is to work around a strange bug in CFEqual's objc 
+	 * dispatching.
+	 */
+	VALUE tmp = str1;
+	str1 = str2;
+	str2 = tmp;
+    }
     if (CFEqual((CFTypeRef)str1, (CFTypeRef)str2))
 	return Qtrue;
 #else
@@ -4272,10 +4283,6 @@
  *  Returns the receiver.
  */
 
-#if WITH_OBJC
-static bool rb_objc_str_is_pure(VALUE);
-#endif
-
 static VALUE
 rb_str_to_s(VALUE str)
 {
@@ -7977,11 +7984,124 @@
 	? __nscfstring = (Class)objc_getClass("NSCFString") \
 	: __nscfstring)
 
+#define PREPARE_RCV(x) \
+    Class old = *(Class *)x; \
+    *(Class *)x = NSCFSTRING();
+
+#define RESTORE_RCV(x) \
+    *(Class *)x = old;
+
 static bool
 rb_objc_str_is_pure(VALUE str)
 {
     return *(Class *)str == NSCFSTRING();
 }
+
+static CFIndex
+imp_rb_str_length(void *rcv, SEL sel)
+{
+    CFIndex length;
+    PREPARE_RCV(rcv);
+    length = CFStringGetLength((CFStringRef)rcv);
+    RESTORE_RCV(rcv);
+    return length;
+}
+
+static UniChar
+imp_rb_str_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
+{
+    UniChar character;
+    PREPARE_RCV(rcv);
+    character = CFStringGetCharacterAtIndex((CFStringRef)rcv, idx);
+    RESTORE_RCV(rcv);
+    return character;
+}
+
+static void
+imp_rb_str_getCharactersRange(void *rcv, SEL sel, UniChar *buffer, 
+			      CFRange range)
+{
+    PREPARE_RCV(rcv);
+    CFStringGetCharacters((CFStringRef)rcv, range, buffer);
+    RESTORE_RCV(rcv);
+}
+
+static void
+imp_rb_str_replaceCharactersInRangeWithString(void *rcv, SEL sel, 
+					      CFRange range, void *str)
+{
+    PREPARE_RCV(rcv);
+    CFStringReplace((CFMutableStringRef)rcv, range, (CFStringRef)str);
+    RESTORE_RCV(rcv);
+}
+
+static const UniChar *
+imp_rb_str_fastCharacterContents(void *rcv, SEL sel)
+{
+    const UniChar *ptr;
+    PREPARE_RCV(rcv);
+    ptr = CFStringGetCharactersPtr((CFStringRef)rcv);
+    RESTORE_RCV(rcv);
+    return ptr;
+}
+
+static const char *
+imp_rb_str_fastCStringContents(void *rcv, SEL sel, bool nullTerminaisonRequired)
+{
+    const char *cstr;
+    PREPARE_RCV(rcv);
+    cstr = CFStringGetCStringPtr((CFStringRef)rcv, 0);
+    /* XXX nullTerminaisonRequired should perhaps be honored */
+    RESTORE_RCV(rcv);
+    return cstr;
+}
+
+static CFStringEncoding
+imp_rb_str_fastestEncodingInCFStringEncoding(void *rcv, SEL sel)
+{
+    CFStringEncoding encoding;
+    PREPARE_RCV(rcv);
+    encoding =  CFStringGetFastestEncoding((CFStringRef)rcv);
+    RESTORE_RCV(rcv);
+    return encoding;
+}
+
+static bool
+imp_rb_str_isEqual(void *rcv, SEL sel, void *other)
+{
+    bool flag;
+    PREPARE_RCV(rcv);
+    flag = CFEqual((CFTypeRef)rcv, (CFTypeRef)other);    
+    RESTORE_RCV(rcv);
+    return flag;
+}
+
+void
+rb_objc_install_string_primitives(Class klass)
+{
+#define INSTALL_METHOD(selname, imp)                            \
+    do {                                                        \
+        SEL sel = sel_registerName(selname);                    \
+        Method method = class_getInstanceMethod(klass, sel);    \
+        assert(method != NULL);                                 \
+        assert(class_addMethod(klass, sel, (IMP)imp,            \
+                    method_getTypeEncoding(method)));           \
+    }                                                           \
+    while(0)
+
+    INSTALL_METHOD("length", imp_rb_str_length);
+    INSTALL_METHOD("characterAtIndex:", imp_rb_str_characterAtIndex);
+    INSTALL_METHOD("getCharacters:range:", imp_rb_str_getCharactersRange);
+    INSTALL_METHOD("replaceCharactersInRange:withString:", 
+	imp_rb_str_replaceCharactersInRangeWithString);
+    INSTALL_METHOD("_fastCharacterContents", imp_rb_str_fastCharacterContents);
+    INSTALL_METHOD("_fastCStringContents:", imp_rb_str_fastCStringContents);
+    INSTALL_METHOD("_fastestEncodingInCFStringEncoding",
+	imp_rb_str_fastestEncodingInCFStringEncoding);
+    INSTALL_METHOD("isEqual:", imp_rb_str_isEqual);
+
+#undef INSTALL_METHOD
+}
 #endif
 
 /*

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080423/d3bedc1f/attachment-0001.html


More information about the macruby-changes mailing list