[Commits] textview.c 1.96.2.251 1.96.2.252

colin at claws-mail.org colin at claws-mail.org
Thu Oct 25 09:45:02 CEST 2012


Update of /home/claws-mail/claws/src
In directory srv:/tmp/cvs-serv8174/src

Modified Files:
      Tag: gtk2
	textview.c 
Log Message:
2012-10-25 [colin]	3.8.1cvs106

	* src/common/utils.c
	* src/common/utils.h
	* src/textview.c
		Avoid strlen() on inner loop in textview_make_clickable_parts*()
		reduces cost of strcasestr() in textview_make_clickable_parts*()
		from 30% to 15%. Patch by Igor Mammedov

Index: textview.c
===================================================================
RCS file: /home/claws-mail/claws/src/textview.c,v
retrieving revision 1.96.2.251
retrieving revision 1.96.2.252
diff -u -d -r1.96.2.251 -r1.96.2.252
--- textview.c	25 Oct 2012 07:43:34 -0000	1.96.2.251
+++ textview.c	25 Oct 2012 07:44:59 -0000	1.96.2.252
@@ -1311,7 +1311,8 @@
 	GtkTextView *text = GTK_TEXT_VIEW(textview->text);
 	GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
 	GtkTextIter iter;
-	gchar *mybuf = g_strdup(linebuf);
+	gint mybuf_len = strlen(linebuf);
+	gchar *mybuf = g_strndup(linebuf, mybuf_len);
 	
 	/* parse table - in order of priority */
 	struct table {
@@ -1319,6 +1320,7 @@
 
 		/* token search function */
 		gchar    *(*search)	(const gchar *haystack,
+					 gint  haystack_len,
 					 const gchar *needle);
 		/* part parsing function */
 		gboolean  (*parse)	(const gchar *start,
@@ -1332,14 +1334,14 @@
 	};
 
 	static struct table parser[] = {
-		{"http://",  strcasestr, get_uri_part,   make_uri_string},
-		{"https://", strcasestr, get_uri_part,   make_uri_string},
-		{"ftp://",   strcasestr, get_uri_part,   make_uri_string},
-		{"sftp://",  strcasestr, get_uri_part,   make_uri_string},
-		{"gopher://",strcasestr, get_uri_part,   make_uri_string},
-		{"www.",     strcasestr, get_uri_part,   make_http_string},
-		{"mailto:",  strcasestr, get_uri_part,   make_uri_string},
-		{"@",        strcasestr, get_email_part, make_email_string}
+		{"http://",  strncasestr, get_uri_part,   make_uri_string},
+		{"https://", strncasestr, get_uri_part,   make_uri_string},
+		{"ftp://",   strncasestr, get_uri_part,   make_uri_string},
+		{"sftp://",  strncasestr, get_uri_part,   make_uri_string},
+		{"gopher://",strncasestr, get_uri_part,   make_uri_string},
+		{"www.",     strncasestr, get_uri_part,   make_http_string},
+		{"mailto:",  strncasestr, get_uri_part,   make_uri_string},
+		{"@",        strncasestr, get_email_part, make_email_string}
 	};
 	const gint PARSE_ELEMS = sizeof parser / sizeof parser[0];
 
@@ -1354,25 +1356,30 @@
 
 	if (!g_utf8_validate(linebuf, -1, NULL)) {
 		g_free(mybuf);
-		mybuf = g_malloc(strlen(linebuf)*2 +1);
-		conv_localetodisp(mybuf, strlen(linebuf)*2 +1, linebuf);
+		mybuf = g_malloc(mybuf_len*2 +1);
+		conv_localetodisp(mybuf, mybuf_len*2 +1, linebuf);
+		mybuf_len = strlen(mybuf);
 	}
 
 	gtk_text_buffer_get_end_iter(buffer, &iter);
 
 	/* parse for clickable parts, and build a list of begin and end positions  */
 	for (n = 0; n < PARSE_ELEMS; n++) {
+		gint len = mybuf_len;
+		gint needle_len = strlen(parser[n].needle);
 		for (walk = mybuf;;) {
-			gchar *scanpos = parser[n].search(walk, parser[n].needle);
+			gchar *scanpos = parser[n].search(walk, len, parser[n].needle);
 			if (scanpos) {
 				/* check if URI can be parsed */
 				if (parser[n].parse(walk, scanpos, &bp, &ep, hdr)
-						&& (size_t) (ep - bp - 1) > strlen(parser[n].needle)) {
+						&& (size_t) (ep - bp - 1) > needle_len) {
 					ADD_TXT_POS(bp, ep, n);
+					len -= ep - walk;
 					walk = ep;
-				} else
-					walk = scanpos +
-						strlen(parser[n].needle);
+				} else {
+					len -= (scanpos + needle_len) - walk;
+					walk = scanpos + needle_len;
+				}
 			} else
 				break;
 		}
@@ -1423,6 +1430,7 @@
 	GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
 	GtkTextIter start_iter, end_iter;
 	gchar *mybuf;
+	gint mybuf_len;
 	gint offset = 0;
 	/* parse table - in order of priority */
 	struct table {
@@ -1430,6 +1438,7 @@
 
 		/* token search function */
 		gchar    *(*search)	(const gchar *haystack,
+					 gint  haystack_len,
 					 const gchar *needle);
 		/* part parsing function */
 		gboolean  (*parse)	(const gchar *start,
@@ -1443,13 +1452,13 @@
 	};
 
 	static struct table parser[] = {
-		{"http://",  strcasestr, get_uri_part,   make_uri_string},
-		{"https://", strcasestr, get_uri_part,   make_uri_string},
-		{"ftp://",   strcasestr, get_uri_part,   make_uri_string},
-		{"sftp://",  strcasestr, get_uri_part,   make_uri_string},
-		{"www.",     strcasestr, get_uri_part,   make_http_string},
-		{"mailto:",  strcasestr, get_uri_part,   make_uri_string},
-		{"@",        strcasestr, get_email_part, make_email_string}
+		{"http://",  strncasestr, get_uri_part,   make_uri_string},
+		{"https://", strncasestr, get_uri_part,   make_uri_string},
+		{"ftp://",   strncasestr, get_uri_part,   make_uri_string},
+		{"sftp://",  strncasestr, get_uri_part,   make_uri_string},
+		{"www.",     strncasestr, get_uri_part,   make_http_string},
+		{"mailto:",  strncasestr, get_uri_part,   make_uri_string},
+		{"@",        strncasestr, get_email_part, make_email_string}
 	};
 	const gint PARSE_ELEMS = sizeof parser / sizeof parser[0];
 
@@ -1468,18 +1477,23 @@
 	offset = gtk_text_iter_get_offset(&start_iter);
 
 	/* parse for clickable parts, and build a list of begin and end positions  */
+	mybuf_len = strlen(mybuf);
 	for (n = 0; n < PARSE_ELEMS; n++) {
+		gint len = mybuf_len;
+		gint needle_len = strlen(parser[n].needle);
 		for (walk = mybuf;;) {
-			gchar *scanpos = parser[n].search(walk, parser[n].needle);
+			gchar *scanpos = parser[n].search(walk, len, parser[n].needle);
 			if (scanpos) {
 				/* check if URI can be parsed */
 				if (parser[n].parse(walk, scanpos, &bp, &ep, FALSE)
-						&& (size_t) (ep - bp - 1) > strlen(parser[n].needle)) {
+						&& (size_t) (ep - bp - 1) > needle_len) {
 					ADD_TXT_POS_LATER(bp, ep, n);
+					len -= ep - walk;
 					walk = ep;
-				} else
-					walk = scanpos +
-						strlen(parser[n].needle);
+				} else {
+					len -= (scanpos + needle_len) - walk;
+					walk = scanpos + needle_len;
+				}
 			} else
 				break;
 		}



More information about the Commits mailing list