Proposed patch: Modify glib to permit embedded NULs in GString.
- From: "David Wheeler" <dwheeler ida org>
- To: gtk-devel-list gnome org
- Subject: Proposed patch: Modify glib to permit embedded NULs in GString.
- Date: Tue, 27 Jun 2000 16:35:27 -0400
Here's a proposed glib patch & ChangeLog entry. It does 3 things:
* It modifies glib so GString can support embedded ASCII NULs (\0).
Many other languages' string type can do this (Perl, Python, Ada, etc.).
It's often convenient to be able to handle NULs in strings, and there's
no reason that GString shouldn't be able to do this too.
* It adds a "gboolean g_string_equal()". This is primarily because,
if there are embedded NULs, the strcmp() functions no longer do the trick.
Besides, any string data type should have an equality test available.
* Finally, it changes the return type of g_str_equal from "gint" to "gboolean".
Somehow this was missed in the big move to gboolean, and it makes
no sense for this function to be "different" than the rest.
This caused several lines in glib.h to change due to reformatting.
Seem okay?
Tue Jun 27 12:40:23 EDT 2000 David A. Wheeler <dwheeler@dwheeler.com>
* glib.h: Added g_string_equal for comparing GStrings;
changed g_str_equal so it returns gboolean (instead of gint).
* gstring.c: Modified GString implementation to support embedded
ASCII NUL ('\0') characters, and implemented g_string_equal.
* testglib.c: Added tests for g_string_equal and tests for
proper handling of embedded ASCII NUL characters.
--- glib.orig/glib.h Sat Jun 24 18:30:10 2000
+++ glib/glib.h Tue Jun 27 12:20:35 2000
@@ -1865,6 +1865,8 @@
GString* g_string_sized_new (guint dfl_size);
void g_string_free (GString *string,
gboolean free_segment);
+gboolean g_string_equal (const GString *v,
+ const GString *v2);
GString* g_string_assign (GString *string,
const gchar *rval);
GString* g_string_truncate (GString *string,
@@ -1989,13 +1991,13 @@
/* Hash Functions
*/
-gint g_str_equal (gconstpointer v,
- gconstpointer v2);
-guint g_str_hash (gconstpointer v);
-
-gint g_int_equal (gconstpointer v,
- gconstpointer v2);
-guint g_int_hash (gconstpointer v);
+gboolean g_str_equal (gconstpointer v,
+ gconstpointer v2);
+guint g_str_hash (gconstpointer v);
+
+gint g_int_equal (gconstpointer v,
+ gconstpointer v2);
+guint g_int_hash (gconstpointer v);
/* This "hash" function will just return the key's adress as an
* unsigned integer. Useful for hashing on plain adresses or
--- glib.orig/gstring.c Fri May 19 06:01:08 2000
+++ glib/gstring.c Tue Jun 27 12:22:06 2000
@@ -67,7 +67,7 @@
/* Hash Functions.
*/
-gint
+gboolean
g_str_equal (gconstpointer v1,
gconstpointer v2)
{
@@ -265,6 +265,30 @@
G_UNLOCK (string_mem_chunk);
}
+gboolean
+g_string_equal (const GString *v,
+ const GString *v2)
+{
+ gchar *p, *q;
+ GRealString *string1 = (GRealString *) v;
+ GRealString *string2 = (GRealString *) v2;
+ gint i = string1->len;
+
+ if (i != string2->len)
+ return FALSE;
+
+ p = string1->str;
+ q = string2->str;
+ while (i) {
+ if (*p != *q)
+ return FALSE;
+ p++;
+ q++;
+ i--;
+ }
+ return TRUE;
+}
+
GString*
g_string_assign (GString *string,
const gchar *rval)
@@ -320,7 +344,7 @@
g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* insert the new string */
- strncpy (string->str + pos, val, len);
+ g_memmove (string->str + pos, val, len);
string->len += len;
@@ -457,15 +481,17 @@
{
GRealString *string = (GRealString *) fstring;
guchar *s;
+ gint n = string->len;
g_return_val_if_fail (string != NULL, NULL);
s = string->str;
- while (*s)
+ while (n)
{
*s = tolower (*s);
s++;
+ n--;
}
return fstring;
@@ -476,15 +502,17 @@
{
GRealString *string = (GRealString *) fstring;
guchar *s;
+ gint n = string->len;
g_return_val_if_fail (string != NULL, NULL);
s = string->str;
- while (*s)
+ while (n)
{
*s = toupper (*s);
s++;
+ n--;
}
return fstring;
--- glib.orig/testglib.c Wed Mar 1 04:44:09 2000
+++ glib/testglib.c Tue Jun 27 12:30:31 2000
@@ -795,7 +795,37 @@
g_string_insert_len (string1, 5, "last", -1);
g_assert (strcmp (string1->str, "firstlast") == 0);
g_string_free (string1, TRUE);
+
+ /* g_string_equal */
+ string1 = g_string_new ("test");
+ string2 = g_string_new ("te");
+ g_assert (! g_string_equal(string1, string2));
+ g_string_append (string2, "st");
+ g_assert (g_string_equal(string1, string2));
+ g_string_free (string1, TRUE);
+ g_string_free (string2, TRUE);
+ /* Special case test: Handle embedded ASCII 0 (NUL) characters. */
+ string1 = g_string_new ("fiddle");
+ string2 = g_string_new ("fiddle");
+ g_assert (g_string_equal(string1, string2));
+ g_string_append_c(string1, '\0');
+ g_assert (! g_string_equal(string1, string2));
+ g_string_append_c(string2, '\0');
+ g_assert (g_string_equal(string1, string2));
+ g_string_append_c(string1, 'x');
+ g_string_append_c(string2, 'y');
+ g_assert (! g_string_equal(string1, string2));
+ g_assert (string1->len == 8);
+ g_string_append(string1, "yzzy");
+ g_assert (string1->len == 12);
+ g_assert ( memcmp(string1->str, "fiddle\0xyzzy", 13) == 0);
+ g_string_insert(string1, 1, "QED");
+ g_assert ( memcmp(string1->str, "fQEDiddle\0xyzzy", 16) == 0);
+ g_string_free (string1, TRUE);
+ g_string_free (string2, TRUE);
+
+
g_print ("ok\n");
g_print ("checking timers...\n");
--
--- David A. Wheeler
dwheeler@ida.org
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]