From: Ross Burton Date: Thu, 18 Aug 2005 09:30:24 +0000 (+0000) Subject: Optimise single-character insertions X-Git-Tag: GLIB_2_8_1~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=efa05f88efe52b32aff01d3694b6ebe3cd9cfe6a;p=platform%2Fupstream%2Fglib.git Optimise single-character insertions --- diff --git a/ChangeLog b/ChangeLog index 2b065ae..41c53b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-08-18 Ross Burton + + * glib/gstring.c: + Optimise single-character insertions. + + * glib/gutf8.c: + Note copied code. + + * tests/string-test.c: + Add tests for new optimisation, and fix a leak. + 2005-08-17 Matthias Clasen * configure.in: Check for crt_externs.h and _NSGetEnviron. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 2b065ae..41c53b7 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,14 @@ +2005-08-18 Ross Burton + + * glib/gstring.c: + Optimise single-character insertions. + + * glib/gutf8.c: + Note copied code. + + * tests/string-test.c: + Add tests for new optimisation, and fix a leak. + 2005-08-17 Matthias Clasen * configure.in: Check for crt_externs.h and _NSGetEnviron. diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 2b065ae..41c53b7 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,14 @@ +2005-08-18 Ross Burton + + * glib/gstring.c: + Optimise single-character insertions. + + * glib/gutf8.c: + Note copied code. + + * tests/string-test.c: + Add tests for new optimisation, and fix a leak. + 2005-08-17 Matthias Clasen * configure.in: Check for crt_externs.h and _NSGetEnviron. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 2b065ae..41c53b7 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,14 @@ +2005-08-18 Ross Burton + + * glib/gstring.c: + Optimise single-character insertions. + + * glib/gutf8.c: + Note copied code. + + * tests/string-test.c: + Add tests for new optimisation, and fix a leak. + 2005-08-17 Matthias Clasen * configure.in: Check for crt_externs.h and _NSGetEnviron. diff --git a/glib/gstring.c b/glib/gstring.c index 43125eb..c0c0b6f 100644 --- a/glib/gstring.c +++ b/glib/gstring.c @@ -510,7 +510,10 @@ g_string_insert_len (GString *string, g_memmove (string->str + pos + len, string->str + pos, string->len - pos); /* insert the new string */ - memcpy (string->str + pos, val, len); + if (len == 1) + string->str[pos] = *val; + else + memcpy (string->str + pos, val, len); } string->len += len; @@ -675,18 +678,71 @@ GString* g_string_insert_unichar (GString *string, gssize pos, gunichar wc) -{ - gchar buf[6]; - gint charlen; +{ + gint charlen, first, i; + gchar *dest; - /* We could be somewhat more efficient here by computing - * the length, adding the space, then converting into that - * space, by cut-and-pasting the internals of g_unichar_to_utf8. - */ g_return_val_if_fail (string != NULL, NULL); - charlen = g_unichar_to_utf8 (wc, buf); - return g_string_insert_len (string, pos, buf, charlen); + /* Code copied from g_unichar_to_utf() */ + if (wc < 0x80) + { + first = 0; + charlen = 1; + } + else if (wc < 0x800) + { + first = 0xc0; + charlen = 2; + } + else if (wc < 0x10000) + { + first = 0xe0; + charlen = 3; + } + else if (wc < 0x200000) + { + first = 0xf0; + charlen = 4; + } + else if (wc < 0x4000000) + { + first = 0xf8; + charlen = 5; + } + else + { + first = 0xfc; + charlen = 6; + } + /* End of copied code */ + + g_string_maybe_expand (string, charlen); + + if (pos < 0) + pos = string->len; + else + g_return_val_if_fail (pos <= string->len, string); + + /* If not just an append, move the old stuff */ + if (pos < string->len) + g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos); + + dest = string->str + pos; + /* Code copied from g_unichar_to_utf() */ + for (i = charlen - 1; i > 0; --i) + { + dest[i] = (wc & 0x3f) | 0x80; + wc >>= 6; + } + dest[0] = wc | first; + /* End of copied code */ + + string->len += charlen; + + string->str[string->len] = 0; + + return string; } GString* diff --git a/glib/gutf8.c b/glib/gutf8.c index d3aa85d..dc87523 100644 --- a/glib/gutf8.c +++ b/glib/gutf8.c @@ -536,6 +536,7 @@ int g_unichar_to_utf8 (gunichar c, gchar *outbuf) { + /* If this gets modified, also update the copy in g_string_insert_unichar() */ guint len = 0; int first; int i; diff --git a/tests/string-test.c b/tests/string-test.c index d129b53..4ba7fc2 100644 --- a/tests/string-test.c +++ b/tests/string-test.c @@ -133,7 +133,6 @@ main (int argc, g_string_free (string1, TRUE); /* append_len */ - string1 = g_string_new ("firsthalf"); g_string_append_len (string1, "lasthalfjunkjunk", strlen ("lasthalf")); g_assert (strcmp (string1->str, "firsthalflasthalf") == 0); @@ -164,7 +163,6 @@ main (int argc, g_string_free (string1, TRUE); /* insert_len */ - string1 = g_string_new ("firstlast"); g_string_insert_len (string1, 5, "middlejunkjunk", strlen ("middle")); g_assert (strcmp (string1->str, "firstmiddlelast") == 0); @@ -209,6 +207,48 @@ main (int argc, g_assert (strcmp (string1->str, "boring text") == 0); g_string_free (string1, TRUE); + /* insert_unichar with insertion in middle */ + string1 = g_string_new ("firsthalf"); + g_string_insert_unichar (string1, 5, 0x0041); + g_assert (strcmp (string1->str, "first\x41half") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("firsthalf"); + g_string_insert_unichar (string1, 5, 0x0298); + g_assert (strcmp (string1->str, "first\xCA\x98half") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("firsthalf"); + g_string_insert_unichar (string1, 5, 0xFFFD); + g_assert (strcmp (string1->str, "first\xEF\xBF\xBDhalf") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("firsthalf"); + g_string_insert_unichar (string1, 5, 0x1D100); + g_assert (strcmp (string1->str, "first\xF0\x9D\x84\x80half") == 0); + g_string_free (string1, TRUE); + + /* insert_unichar with insertion at end */ + string1 = g_string_new ("start"); + g_string_insert_unichar (string1, -1, 0x0041); + g_assert (strcmp (string1->str, "start\x41") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("start"); + g_string_insert_unichar (string1, -1, 0x0298); + g_assert (strcmp (string1->str, "start\xCA\x98") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("start"); + g_string_insert_unichar (string1, -1, 0xFFFD); + g_assert (strcmp (string1->str, "start\xEF\xBF\xBD") == 0); + g_string_free (string1, TRUE); + + string1 = g_string_new ("start"); + g_string_insert_unichar (string1, -1, 0x1D100); + g_assert (strcmp (string1->str, "start\xF0\x9D\x84\x80") == 0); + g_string_free (string1, TRUE); + /* g_string_equal */ string1 = g_string_new ("test"); string2 = g_string_new ("te"); @@ -261,6 +301,8 @@ main (int argc, tmp_string = (gchar *) g_malloc (10); g_snprintf (tmp_string, 10, "%2$s %1$s", "a", "b"); g_assert (strcmp (tmp_string, "b a") == 0); + g_free (tmp_string); + return 0; }