[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