[Mono-list] little patch for string-icalls.c

Gonzalo Paniagua Javier gonzalo@gnome-db.org
Fri, 19 Apr 2002 19:37:14 +0200


--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline

	Here it is. 

	There are a couple of fixes and changes to
	mono_string_cmp_char() that makes it be faster by saving some
	function calls.


--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="stricall.diff"

Index: ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/metadata/ChangeLog,v
retrieving revision 1.301
diff -u -r1.301 ChangeLog
--- ChangeLog	19 Apr 2002 12:33:57 -0000	1.301
+++ ChangeLog	19 Apr 2002 13:42:39 -0000
@@ -1,3 +1,9 @@
+2002-04-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+	* string-icalls.c: fix IndexOf and LastIndexOf. Now
+	InternalCompareStr don't call twice mono_string_cmp_char for the last
+	character. Improved performance in mono_string_cmp_char.
+
 2002-04-19  Dan Lewis  <dihlewis@yahoo.co.uk>
 
 	* object.h, object.c: changed array format so that szarrays do not
Index: string-icalls.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/string-icalls.c,v
retrieving revision 1.2
diff -u -r1.2 string-icalls.c
--- string-icalls.c	18 Apr 2002 09:43:58 -0000	1.2
+++ string-icalls.c	19 Apr 2002 13:42:39 -0000
@@ -283,6 +283,9 @@
 	cmpstr = mono_string_chars(value);
 
 	for (pos = sindex; pos != count + sindex; pos++) {
+		if (pos + lencmpstr > count + sindex)
+			return -1;
+
 		if (0 == memcmp(src + pos, cmpstr, lencmpstr * sizeof(gunichar2)))
 			return pos;
 	}
@@ -338,7 +341,7 @@
 	src = mono_string_chars(me);
 	cmpstr = mono_string_chars(value);
 
-	for (pos = sindex; pos > sindex - count; pos -= lencmpstr) {
+	for (pos = sindex; pos > sindex - count; pos--) {
 		if (0 == memcmp(src + pos, cmpstr, lencmpstr * sizeof(gunichar2)))
 			return pos;
 	}
@@ -486,6 +489,7 @@
 	*/
 	gint32 lenstr1;
 	gint32 lenstr2;
+	gint32 charcmp;
 	gunichar2 *str1;
 	gunichar2 *str2;
 
@@ -509,8 +513,9 @@
 		if (i1 + pos >= lenstr1 || i2 + pos >= lenstr2)
 			break;
 
-		if (0 != mono_string_cmp_char(str1[i1 + pos], str2[i2 + pos], mode))
-			break;
+		charcmp = mono_string_cmp_char(str1[i1 + pos], str2[i2 + pos], mode);
+		if (charcmp != 0)
+			return charcmp;
 	}
 
 	/* the lesser wins, so if we have looped until length we just need to check the last char */
@@ -557,20 +562,24 @@
 mono_string_cmp_char (gunichar2 c1, gunichar2 c2, gint16 mode)
 {
 	gint32 result;
+	GUnicodeType c1type, c2type;
 
+	c1type = g_unichar_type (c1);
+	c2type = g_unichar_type (c2);
 	switch (mode) {
 	case 0:	
 		/* TODO: compare with culture info */
-		if (g_unichar_isupper(c1) && g_unichar_islower(c2))
+		if (c1type == G_UNICODE_UPPERCASE_LETTER && c2type == G_UNICODE_LOWERCASE_LETTER)
 			return 1;
 					
-		if (g_unichar_islower(c1) && g_unichar_isupper(c2))
+		if (c1type == G_UNICODE_LOWERCASE_LETTER && c2type == G_UNICODE_UPPERCASE_LETTER)
 			return -1;
 	
 		result = (gint32) c1 - c2;
 		break;
 	case 1:	
-		result = (gint32) g_unichar_tolower(c1) - g_unichar_tolower(c2);
+		result = (gint32) (c1type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c1) : c1) - 
+				  (c2type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c2) : c2);
 		break;
 		/* fix: compare ordinal */
 	case 2:	
@@ -578,11 +587,5 @@
 		break;
 	}
 
-	if (result < 0)
-		return -1;
-
-	if (result > 0)
-		return 1;
-
-	return 0;
+	return ((result < 0) ? -1 : (result > 0) ? 1 : 0);
 }

--cWoXeonUoKmBZSoM--