[macruby-changes] [147] MacRuby/trunk/string.c

source_changes at macosforge.org source_changes at macosforge.org
Thu Apr 17 17:46:07 PDT 2008


Revision: 147
          http://trac.macosforge.org/projects/ruby/changeset/147
Author:   lsansonetti at apple.com
Date:     2008-04-17 17:46:06 -0700 (Thu, 17 Apr 2008)

Log Message:
-----------
fixing #delete, implementing #count, fixing more leaks

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

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-04-17 08:08:28 UTC (rev 146)
+++ MacRuby/trunk/string.c	2008-04-18 00:46:06 UTC (rev 147)
@@ -138,9 +138,11 @@
 	    return NULL;
 #if 1 
 	GC_WB(&s->cfdata, (void *)CFDataCreateCopy(NULL, data));
+	CFRelease((CFTypeRef)data);
 #else
 	GC_WB(&s->cfdata, (void *)data);
 #endif
+	CFMakeCollectable((CFTypeRef)s->cfdata);
     }
     return s->cfdata;    
 }
@@ -1447,12 +1449,23 @@
 {
 #if WITH_OBJC
     long n = CFStringGetLength((CFStringRef)str);
+    CFStringRef substr;
     if (beg < 0)
 	beg += n;
-    if (beg + len > n || beg < 0)
+    if (beg > n || beg < 0)
 	return Qnil;
-    return (VALUE)CFStringCreateWithSubstring(NULL, (CFStringRef)str, 
-	CFRangeMake(beg, len));
+    if (beg + len > n)
+	return (VALUE)CFSTR("");
+    if (len == 1) {
+	UniChar c = CFStringGetCharacterAtIndex((CFStringRef)str, beg);
+	substr = CFStringCreateWithCharacters(NULL, &c, 1);
+    }
+    else {
+	substr = CFStringCreateWithSubstring(NULL, (CFStringRef)str, 
+	    CFRangeMake(beg, len));
+    }
+    CFMakeCollectable((CFTypeRef)substr);
+    return (VALUE)substr;
 #else
     VALUE str2 = rb_str_new5(str, RSTRING_PTR(str)+beg, len);
 
@@ -5121,23 +5134,77 @@
     if (n == 0)
     	return;
 
-    /* TODO this doesn't actually support tokens such as '^e' or 'a-z'. */ 
     for (i = 0, charset = NULL; i < charset_count; i++) {
 	VALUE s = charsets[i];
+	bool exclude;
+	const char *sptr, *p;
 
 	StringValue(s);
 
-	if (charset == NULL) {
-	    charset = CFCharacterSetCreateMutable(NULL);
-	    CFCharacterSetAddCharactersInString(
-		(CFMutableCharacterSetRef)charset,
-		(CFStringRef)s);
+	sptr = RSTRING_CPTR(s);
+	exclude = sptr[0] == '^';
+
+	p = NULL;
+	if (exclude || (p = strchr(sptr, '-')) != NULL) {
+	    CFMutableCharacterSetRef subset;
+	    const char *b, *e;
+
+	    b = exclude ? sptr + 1 : sptr;
+	    e = sptr + strlen(sptr) - 1;
+	    subset = CFCharacterSetCreateMutable(NULL);
+	    while (p != NULL) {
+		if (p > b && *(p - 1) != '\\' && *(p + 1) != '\0') {
+		    CFCharacterSetAddCharactersInRange(subset,
+			    CFRangeMake(*(p - 1), *(p + 1) - *(p - 1) + 1));
+		}
+		if (p > b) {
+		    CFStringRef substr;
+		    substr = CFStringCreateWithBytes(NULL,
+			    (const UInt8 *)b,
+			    (CFIndex)p - (CFIndex)b,
+			    kCFStringEncodingUTF8,
+			    false);
+		    CFCharacterSetAddCharactersInString(subset, substr);
+		    CFRelease(substr);
+		}
+
+		b = p + 2;
+		p = strchr(b, '-');
+	    }
+	    if (b <= e) {
+		CFStringRef substr;
+		substr = CFStringCreateWithBytes(NULL,
+			(const UInt8 *)b,
+			(CFIndex)e - (CFIndex)b + 1,
+			kCFStringEncodingUTF8,
+			false);
+		CFCharacterSetAddCharactersInString(subset, substr);
+		CFRelease(substr);
+	    }
+
+	    if (exclude)
+		CFCharacterSetInvert(subset);
+
+	    if (charset == NULL) {
+		charset = subset;
+	    }
+	    else {
+		CFCharacterSetIntersect(charset, subset);
+		CFRelease(subset);
+	    }
 	}
 	else {
-	    CFCharacterSetRef subset;
-	    subset = CFCharacterSetCreateWithCharactersInString(NULL, 
-		(CFStringRef)s);
-	    CFCharacterSetIntersect((CFMutableCharacterSetRef)charset, subset);
+	    if (charset == NULL) {
+		charset = CFCharacterSetCreateMutable(NULL);
+		CFCharacterSetAddCharactersInString(charset, (CFStringRef)s);
+	    }
+	    else {
+		CFCharacterSetRef subset;
+		subset = CFCharacterSetCreateWithCharactersInString(NULL,
+		    (CFStringRef)s);
+		CFCharacterSetIntersect(charset, subset);
+		CFRelease(subset);	
+	    }
 	}
     }
 
@@ -5151,6 +5218,8 @@
 		&result_range)) {
 	(*cb)(&search_range, (const CFRange *)&result_range, str, ctx);
     }
+
+    CFRelease(charset);	
 }
 
 #endif
@@ -5402,12 +5471,28 @@
  *     a.count "ej-m"          #=> 4
  */
 
+#if WITH_OBJC
+static void
+rb_str_count_cb(CFRange *search_range, const CFRange *result_range, 
+    CFStringRef str, void *ctx)
+{
+    search_range->length -= result_range->length 
+	+ (result_range->location - search_range->location);
+    search_range->location = result_range->location + result_range->length;
+    (*(int *)ctx) += result_range->length;
+}
+#endif
+
 static VALUE
 rb_str_count(int argc, VALUE *argv, VALUE str)
 {
 #if WITH_OBJC
-    /* TODO could share the same logic than #delete */
-    rb_notimplement();
+    int count;
+    if (argc < 1)
+	rb_raise(rb_eArgError, "wrong number of arguments");
+    count = 0;
+    str_charset_find((CFStringRef)str, argv, argc, rb_str_count_cb, &count); 
+    return INT2NUM(count);
 #else
     char table[256];
     rb_encoding *enc = 0;

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


More information about the macruby-changes mailing list