Optimise single-character insertions

This commit is contained in:
Ross Burton 2005-08-18 09:30:24 +00:00
parent a1ab92582c
commit efa05f88ef
7 changed files with 155 additions and 12 deletions

View File

@ -1,3 +1,14 @@
2005-08-18 Ross Burton <ross@burtonini.com>
* 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 <mclasen@redhat.com>
* configure.in: Check for crt_externs.h and _NSGetEnviron.

View File

@ -1,3 +1,14 @@
2005-08-18 Ross Burton <ross@burtonini.com>
* 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 <mclasen@redhat.com>
* configure.in: Check for crt_externs.h and _NSGetEnviron.

View File

@ -1,3 +1,14 @@
2005-08-18 Ross Burton <ross@burtonini.com>
* 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 <mclasen@redhat.com>
* configure.in: Check for crt_externs.h and _NSGetEnviron.

View File

@ -1,3 +1,14 @@
2005-08-18 Ross Burton <ross@burtonini.com>
* 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 <mclasen@redhat.com>
* configure.in: Check for crt_externs.h and _NSGetEnviron.

View File

@ -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*

View File

@ -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;

View File

@ -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;
}