changed g_str_hash() to a 31 bit version based on a submission by Karl
authorHavoc Pennington <hp@pobox.com>
Thu, 17 Feb 2000 11:57:35 +0000 (11:57 +0000)
committerTim Janik <timj@src.gnome.org>
Thu, 17 Feb 2000 11:57:35 +0000 (11:57 +0000)
Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>

        * gstring.c: changed g_str_hash() to a 31 bit version based on
        a submission by Karl Nelson and hand optimized ad absurdum by
        various people ;)

        * gstring.c: applied patch from havoc for new gstring functions,
        added some more sanity checks, coding style fixups.

2000-02-13  Havoc Pennington  <hp@pobox.com>

        * tests/string-test.c (main): Add tests for the new GString
        features

        * testglib.c (main): Add tests for the new GString features

        * gstring.c (g_string_insert_len): New function; insert
        a given length of string at a given position.
        (g_string_append): reimplement in terms of g_string_insert_len
        (g_string_append_len): new function
        (g_string_insert_c): accept -1 for "pos" arg to mean "append"
        (g_string_append_c): reimplement in terms of g_string_insert_c
        (g_string_prepend): reimplement in terms of g_string_insert_len
        (g_string_prepend_len): new function
        (g_string_prepend_c): reimplement in terms of g_string_insert_c
        (g_string_insert): reimplement in terms of g_string_insert_len

        * glib.h: Declare g_string_insert_len, g_string_append_len,
        g_string_prepend_len

15 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib.h
glib/glib.h
glib/gstring.c
gstring.c
testglib.c
tests/string-test.c
tests/testglib.c

index 555d8c3..378c364 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
index 555d8c3..378c364 100644 (file)
@@ -1,3 +1,33 @@
+Thu Feb 17 12:53:44 2000  Tim Janik  <timj@gtk.org>
+
+        * gstring.c: changed g_str_hash() to a 31 bit version based on
+       a submission by Karl Nelson and hand optimized ad absurdum by
+       various people ;)
+
+       * gstring.c: applied patch from havoc for new gstring functions,
+       added some more sanity checks, coding style fixups.
+
+2000-02-13  Havoc Pennington  <hp@pobox.com>
+
+       * tests/string-test.c (main): Add tests for the new GString 
+       features
+
+       * testglib.c (main): Add tests for the new GString features
+
+       * gstring.c (g_string_insert_len): New function; insert 
+       a given length of string at a given position. 
+       (g_string_append): reimplement in terms of g_string_insert_len
+       (g_string_append_len): new function
+       (g_string_insert_c): accept -1 for "pos" arg to mean "append"
+       (g_string_append_c): reimplement in terms of g_string_insert_c
+       (g_string_prepend): reimplement in terms of g_string_insert_len
+       (g_string_prepend_len): new function
+       (g_string_prepend_c): reimplement in terms of g_string_insert_c
+       (g_string_insert): reimplement in terms of g_string_insert_len
+
+       * glib.h: Declare g_string_insert_len, g_string_append_len,
+       g_string_prepend_len
+       
 Sun Feb 13 08:16:47 2000  Tim Janik  <timj@gtk.org>
 
        * configure.in: wtf??? someone destroyed the configure.in, reverting to
diff --git a/glib.h b/glib.h
index 84c4170..bcbb53d 100644 (file)
--- a/glib.h
+++ b/glib.h
@@ -1825,19 +1825,29 @@ gchar*        g_string_chunk_insert_const  (GStringChunk *chunk,
 GString*     g_string_new              (const gchar     *init);
 GString*     g_string_sized_new         (guint           dfl_size);
 void        g_string_free              (GString         *string,
-                                        gint             free_segment);
-GString*     g_string_assign            (GString        *lval,
+                                        gboolean         free_segment);
+GString*     g_string_assign            (GString        *string,
                                         const gchar     *rval);
 GString*     g_string_truncate          (GString        *string,
                                         gint             len);
+GString*     g_string_insert_len        (GString         *string,
+                                         gint             pos,
+                                         const gchar     *val,
+                                         gint             len);
 GString*     g_string_append            (GString        *string,
                                         const gchar     *val);
+GString*     g_string_append_len        (GString        *string,
+                                        const gchar     *val,
+                                         gint             len);
 GString*     g_string_append_c          (GString        *string,
                                         gchar            c);
 GString*     g_string_prepend           (GString        *string,
                                         const gchar     *val);
 GString*     g_string_prepend_c         (GString        *string,
                                         gchar            c);
+GString*     g_string_prepend_len       (GString        *string,
+                                        const gchar     *val,
+                                         gint             len);
 GString*     g_string_insert            (GString        *string,
                                         gint             pos,
                                         const gchar     *val);
index 84c4170..bcbb53d 100644 (file)
@@ -1825,19 +1825,29 @@ gchar*        g_string_chunk_insert_const  (GStringChunk *chunk,
 GString*     g_string_new              (const gchar     *init);
 GString*     g_string_sized_new         (guint           dfl_size);
 void        g_string_free              (GString         *string,
-                                        gint             free_segment);
-GString*     g_string_assign            (GString        *lval,
+                                        gboolean         free_segment);
+GString*     g_string_assign            (GString        *string,
                                         const gchar     *rval);
 GString*     g_string_truncate          (GString        *string,
                                         gint             len);
+GString*     g_string_insert_len        (GString         *string,
+                                         gint             pos,
+                                         const gchar     *val,
+                                         gint             len);
 GString*     g_string_append            (GString        *string,
                                         const gchar     *val);
+GString*     g_string_append_len        (GString        *string,
+                                        const gchar     *val,
+                                         gint             len);
 GString*     g_string_append_c          (GString        *string,
                                         gchar            c);
 GString*     g_string_prepend           (GString        *string,
                                         const gchar     *val);
 GString*     g_string_prepend_c         (GString        *string,
                                         gchar            c);
+GString*     g_string_prepend_len       (GString        *string,
+                                        const gchar     *val,
+                                         gint             len);
 GString*     g_string_insert            (GString        *string,
                                         gint             pos,
                                         const gchar     *val);
index f5bab71..aba8b12 100644 (file)
@@ -68,28 +68,27 @@ static GMemChunk *string_mem_chunk = NULL;
  */
 
 gint
-g_str_equal (gconstpointer v, gconstpointer v2)
+g_str_equal (gconstpointer v1,
+            gconstpointer v2)
 {
-  return strcmp ((const gchar*) v, (const gchar*)v2) == 0;
+  const gchar *string1 = v1;
+  const gchar *string2 = v2;
+  
+  return strcmp (string1, string2) == 0;
 }
 
-/* a char* hash function from ASU */
+/* 31 bit hash function */
 guint
-g_str_hash (gconstpointer v)
+g_str_hash (gconstpointer key)
 {
-  const char *s = (char*)v;
-  const char *p;
-  guint h=0, g;
-
-  for(p = s; *p != '\0'; p += 1) {
-    h = ( h << 4 ) + *p;
-    if ( ( g = h & 0xf0000000 ) ) {
-      h = h ^ (g >> 24);
-      h = h ^ g;
-    }
-  }
+  const char *p = key;
+  guint h = *p;
+
+  if (h)
+    for (p += 1; *p != '\0'; p++)
+      h = (h << 5) - h + *p;
 
-  return h /* % M */;
+  return h;
 }
 
 
@@ -160,7 +159,7 @@ g_string_chunk_insert (GStringChunk *fchunk,
       chunk->storage_next = 0;
     }
 
-  pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
+  pos = ((char *) chunk->storage_list->data) + chunk->storage_next;
 
   strcpy (pos, string);
 
@@ -254,7 +253,7 @@ g_string_new (const gchar *init)
 
 void
 g_string_free (GString *string,
-              gint free_segment)
+              gboolean free_segment)
 {
   g_return_if_fail (string != NULL);
 
@@ -267,107 +266,127 @@ g_string_free (GString *string,
 }
 
 GString*
-g_string_assign (GString *lval,
+g_string_assign (GString     *string,
                 const gchar *rval)
 {
-  g_string_truncate (lval, 0);
-  g_string_append (lval, rval);
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (rval != NULL, string);
+  
+  g_string_truncate (string, 0);
+  g_string_append (string, rval);
 
-  return lval;
+  return string;
 }
 
 GString*
-g_string_truncate (GStringfstring,
-                  gint len)
+g_string_truncate (GString *fstring,
+                  gint     len)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
 
-  string->len = len;
+  string->len = MIN (len, string->len);
 
-  string->str[len] = 0;
+  string->str[string->len] = 0;
 
   return fstring;
 }
 
 GString*
-g_string_append (GString *fstring,
-                const gchar *val)
+g_string_insert_len (GString     *fstring,
+                    gint         pos,
+                    const gchar *val,
+                    gint         len)
 {
-  GRealString *string = (GRealString*)fstring;
-  int len;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
   g_return_val_if_fail (val != NULL, fstring);
+  g_return_val_if_fail (pos <= string->len, fstring);
+
+  if (len < 0)
+    len = strlen (val);
+
+  if (pos < 0)
+    pos = string->len;
   
-  len = strlen (val);
   g_string_maybe_expand (string, len);
 
-  strcpy (string->str + string->len, val);
+  /* If we aren't appending at the end, move a hunk
+   * of the old string to the end, opening up space
+   */
+  if (pos < string->len)
+    g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
+  
+  /* insert the new string */
+  strncpy (string->str + pos, val, len);
 
   string->len += len;
 
+  string->str[string->len] = 0;
+
   return fstring;
 }
 
 GString*
-g_string_append_c (GString *fstring,
-                  gchar c)
-{
-  GRealString *string = (GRealString*)fstring;
-
-  g_return_val_if_fail (string != NULL, NULL);
-  g_string_maybe_expand (string, 1);
-
-  string->str[string->len++] = c;
-  string->str[string->len] = 0;
+g_string_append (GString     *fstring,
+                const gchar *val)
+{  
+  g_return_val_if_fail (fstring != NULL, NULL);
+  g_return_val_if_fail (val != NULL, fstring);
 
-  return fstring;
+  return g_string_insert_len (fstring, -1, val, -1);
 }
 
 GString*
-g_string_prepend (GString *fstring,
-                 const gchar *val)
+g_string_append_len (GString    *string,
+                     const gchar *val,
+                     gint         len)
 {
-  GRealString *string = (GRealString*)fstring;
-  gint len;
-
   g_return_val_if_fail (string != NULL, NULL);
-  g_return_val_if_fail (val != NULL, fstring);
+  g_return_val_if_fail (val != NULL, string);
 
-  len = strlen (val);
-  g_string_maybe_expand (string, len);
-
-  g_memmove (string->str + len, string->str, string->len);
-
-  strncpy (string->str, val, len);
-
-  string->len += len;
+  return g_string_insert_len (string, -1, val, len);
+}
 
-  string->str[string->len] = 0;
+GString*
+g_string_append_c (GString *fstring,
+                  gchar    c)
+{
+  g_return_val_if_fail (fstring != NULL, NULL);
 
-  return fstring;
+  return g_string_insert_c (fstring, -1, c);
 }
 
 GString*
-g_string_prepend_c (GString *fstring,
-                   gchar    c)
+g_string_prepend (GString     *fstring,
+                 const gchar *val)
 {
-  GRealString *string = (GRealString*)fstring;
+  g_return_val_if_fail (fstring != NULL, NULL);
+  g_return_val_if_fail (val != NULL, fstring);
+  
+  return g_string_insert_len (fstring, 0, val, -1);
+}
 
+GString*
+g_string_prepend_len (GString    *string,
+                      const gchar *val,
+                      gint         len)
+{
   g_return_val_if_fail (string != NULL, NULL);
-  g_string_maybe_expand (string, 1);
+  g_return_val_if_fail (val != NULL, string);
 
-  g_memmove (string->str + 1, string->str, string->len);
-
-  string->str[0] = c;
-
-  string->len += 1;
-
-  string->str[string->len] = 0;
+  return g_string_insert_len (string, 0, val, len);
+}
 
-  return fstring;
+GString*
+g_string_prepend_c (GString *fstring,
+                   gchar    c)
+{  
+  g_return_val_if_fail (fstring != NULL, NULL);
+  
+  return g_string_insert_c (fstring, 0, c);
 }
 
 GString*
@@ -375,41 +394,31 @@ g_string_insert (GString     *fstring,
                 gint         pos,
                 const gchar *val)
 {
-  GRealString *string = (GRealString*)fstring;
-  gint len;
-
-  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (fstring != NULL, NULL);
   g_return_val_if_fail (val != NULL, fstring);
-  g_return_val_if_fail (pos >= 0, fstring);
-  g_return_val_if_fail (pos <= string->len, fstring);
-
-  len = strlen (val);
-  g_string_maybe_expand (string, len);
-
-  g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
-
-  strncpy (string->str + pos, val, len);
-
-  string->len += len;
-
-  string->str[string->len] = 0;
-
-  return fstring;
+  g_return_val_if_fail (pos <= fstring->len, fstring);
+  
+  return g_string_insert_len (fstring, pos, val, -1);
 }
 
-GString *
+GString*
 g_string_insert_c (GString *fstring,
                   gint     pos,
                   gchar    c)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
   g_return_val_if_fail (pos <= string->len, fstring);
 
   g_string_maybe_expand (string, 1);
 
-  g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
+  if (pos < 0)
+    pos = string->len;
+  
+  /* If not just an append, move the old stuff */
+  if (pos < string->len)
+    g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
 
   string->str[pos] = c;
 
@@ -422,8 +431,8 @@ g_string_insert_c (GString *fstring,
 
 GString*
 g_string_erase (GString *fstring,
-               gint pos,
-               gint len)
+               gint     pos,
+               gint     len)
 {
   GRealString *string = (GRealString*)fstring;
 
@@ -446,7 +455,7 @@ g_string_erase (GString *fstring,
 GString*
 g_string_down (GString *fstring)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
   guchar *s;
 
   g_return_val_if_fail (string != NULL, NULL);
@@ -465,7 +474,7 @@ g_string_down (GString *fstring)
 GString*
 g_string_up (GString *fstring)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
   guchar *s;
 
   g_return_val_if_fail (string != NULL, NULL);
index f5bab71..aba8b12 100644 (file)
--- a/gstring.c
+++ b/gstring.c
@@ -68,28 +68,27 @@ static GMemChunk *string_mem_chunk = NULL;
  */
 
 gint
-g_str_equal (gconstpointer v, gconstpointer v2)
+g_str_equal (gconstpointer v1,
+            gconstpointer v2)
 {
-  return strcmp ((const gchar*) v, (const gchar*)v2) == 0;
+  const gchar *string1 = v1;
+  const gchar *string2 = v2;
+  
+  return strcmp (string1, string2) == 0;
 }
 
-/* a char* hash function from ASU */
+/* 31 bit hash function */
 guint
-g_str_hash (gconstpointer v)
+g_str_hash (gconstpointer key)
 {
-  const char *s = (char*)v;
-  const char *p;
-  guint h=0, g;
-
-  for(p = s; *p != '\0'; p += 1) {
-    h = ( h << 4 ) + *p;
-    if ( ( g = h & 0xf0000000 ) ) {
-      h = h ^ (g >> 24);
-      h = h ^ g;
-    }
-  }
+  const char *p = key;
+  guint h = *p;
+
+  if (h)
+    for (p += 1; *p != '\0'; p++)
+      h = (h << 5) - h + *p;
 
-  return h /* % M */;
+  return h;
 }
 
 
@@ -160,7 +159,7 @@ g_string_chunk_insert (GStringChunk *fchunk,
       chunk->storage_next = 0;
     }
 
-  pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
+  pos = ((char *) chunk->storage_list->data) + chunk->storage_next;
 
   strcpy (pos, string);
 
@@ -254,7 +253,7 @@ g_string_new (const gchar *init)
 
 void
 g_string_free (GString *string,
-              gint free_segment)
+              gboolean free_segment)
 {
   g_return_if_fail (string != NULL);
 
@@ -267,107 +266,127 @@ g_string_free (GString *string,
 }
 
 GString*
-g_string_assign (GString *lval,
+g_string_assign (GString     *string,
                 const gchar *rval)
 {
-  g_string_truncate (lval, 0);
-  g_string_append (lval, rval);
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (rval != NULL, string);
+  
+  g_string_truncate (string, 0);
+  g_string_append (string, rval);
 
-  return lval;
+  return string;
 }
 
 GString*
-g_string_truncate (GStringfstring,
-                  gint len)
+g_string_truncate (GString *fstring,
+                  gint     len)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
 
-  string->len = len;
+  string->len = MIN (len, string->len);
 
-  string->str[len] = 0;
+  string->str[string->len] = 0;
 
   return fstring;
 }
 
 GString*
-g_string_append (GString *fstring,
-                const gchar *val)
+g_string_insert_len (GString     *fstring,
+                    gint         pos,
+                    const gchar *val,
+                    gint         len)
 {
-  GRealString *string = (GRealString*)fstring;
-  int len;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
   g_return_val_if_fail (val != NULL, fstring);
+  g_return_val_if_fail (pos <= string->len, fstring);
+
+  if (len < 0)
+    len = strlen (val);
+
+  if (pos < 0)
+    pos = string->len;
   
-  len = strlen (val);
   g_string_maybe_expand (string, len);
 
-  strcpy (string->str + string->len, val);
+  /* If we aren't appending at the end, move a hunk
+   * of the old string to the end, opening up space
+   */
+  if (pos < string->len)
+    g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
+  
+  /* insert the new string */
+  strncpy (string->str + pos, val, len);
 
   string->len += len;
 
+  string->str[string->len] = 0;
+
   return fstring;
 }
 
 GString*
-g_string_append_c (GString *fstring,
-                  gchar c)
-{
-  GRealString *string = (GRealString*)fstring;
-
-  g_return_val_if_fail (string != NULL, NULL);
-  g_string_maybe_expand (string, 1);
-
-  string->str[string->len++] = c;
-  string->str[string->len] = 0;
+g_string_append (GString     *fstring,
+                const gchar *val)
+{  
+  g_return_val_if_fail (fstring != NULL, NULL);
+  g_return_val_if_fail (val != NULL, fstring);
 
-  return fstring;
+  return g_string_insert_len (fstring, -1, val, -1);
 }
 
 GString*
-g_string_prepend (GString *fstring,
-                 const gchar *val)
+g_string_append_len (GString    *string,
+                     const gchar *val,
+                     gint         len)
 {
-  GRealString *string = (GRealString*)fstring;
-  gint len;
-
   g_return_val_if_fail (string != NULL, NULL);
-  g_return_val_if_fail (val != NULL, fstring);
+  g_return_val_if_fail (val != NULL, string);
 
-  len = strlen (val);
-  g_string_maybe_expand (string, len);
-
-  g_memmove (string->str + len, string->str, string->len);
-
-  strncpy (string->str, val, len);
-
-  string->len += len;
+  return g_string_insert_len (string, -1, val, len);
+}
 
-  string->str[string->len] = 0;
+GString*
+g_string_append_c (GString *fstring,
+                  gchar    c)
+{
+  g_return_val_if_fail (fstring != NULL, NULL);
 
-  return fstring;
+  return g_string_insert_c (fstring, -1, c);
 }
 
 GString*
-g_string_prepend_c (GString *fstring,
-                   gchar    c)
+g_string_prepend (GString     *fstring,
+                 const gchar *val)
 {
-  GRealString *string = (GRealString*)fstring;
+  g_return_val_if_fail (fstring != NULL, NULL);
+  g_return_val_if_fail (val != NULL, fstring);
+  
+  return g_string_insert_len (fstring, 0, val, -1);
+}
 
+GString*
+g_string_prepend_len (GString    *string,
+                      const gchar *val,
+                      gint         len)
+{
   g_return_val_if_fail (string != NULL, NULL);
-  g_string_maybe_expand (string, 1);
+  g_return_val_if_fail (val != NULL, string);
 
-  g_memmove (string->str + 1, string->str, string->len);
-
-  string->str[0] = c;
-
-  string->len += 1;
-
-  string->str[string->len] = 0;
+  return g_string_insert_len (string, 0, val, len);
+}
 
-  return fstring;
+GString*
+g_string_prepend_c (GString *fstring,
+                   gchar    c)
+{  
+  g_return_val_if_fail (fstring != NULL, NULL);
+  
+  return g_string_insert_c (fstring, 0, c);
 }
 
 GString*
@@ -375,41 +394,31 @@ g_string_insert (GString     *fstring,
                 gint         pos,
                 const gchar *val)
 {
-  GRealString *string = (GRealString*)fstring;
-  gint len;
-
-  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (fstring != NULL, NULL);
   g_return_val_if_fail (val != NULL, fstring);
-  g_return_val_if_fail (pos >= 0, fstring);
-  g_return_val_if_fail (pos <= string->len, fstring);
-
-  len = strlen (val);
-  g_string_maybe_expand (string, len);
-
-  g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
-
-  strncpy (string->str + pos, val, len);
-
-  string->len += len;
-
-  string->str[string->len] = 0;
-
-  return fstring;
+  g_return_val_if_fail (pos <= fstring->len, fstring);
+  
+  return g_string_insert_len (fstring, pos, val, -1);
 }
 
-GString *
+GString*
 g_string_insert_c (GString *fstring,
                   gint     pos,
                   gchar    c)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
 
   g_return_val_if_fail (string != NULL, NULL);
   g_return_val_if_fail (pos <= string->len, fstring);
 
   g_string_maybe_expand (string, 1);
 
-  g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
+  if (pos < 0)
+    pos = string->len;
+  
+  /* If not just an append, move the old stuff */
+  if (pos < string->len)
+    g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
 
   string->str[pos] = c;
 
@@ -422,8 +431,8 @@ g_string_insert_c (GString *fstring,
 
 GString*
 g_string_erase (GString *fstring,
-               gint pos,
-               gint len)
+               gint     pos,
+               gint     len)
 {
   GRealString *string = (GRealString*)fstring;
 
@@ -446,7 +455,7 @@ g_string_erase (GString *fstring,
 GString*
 g_string_down (GString *fstring)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
   guchar *s;
 
   g_return_val_if_fail (string != NULL, NULL);
@@ -465,7 +474,7 @@ g_string_down (GString *fstring)
 GString*
 g_string_up (GString *fstring)
 {
-  GRealString *string = (GRealString*)fstring;
+  GRealString *string = (GRealString *) fstring;
   guchar *s;
 
   g_return_val_if_fail (string != NULL, NULL);
index 868fe4f..1d14971 100644 (file)
@@ -726,6 +726,65 @@ main (int   argc,
   g_print ("and next 70:\n%s\n", string2->str+142);
   g_print ("last 70 chars:\n%s\n", string2->str+string2->len - 70);
 
+  g_string_free (string1, TRUE);
+  g_string_free (string2, TRUE);
+
+  /* append */
+  string1 = g_string_new ("firsthalf");
+  g_string_append (string1, "lasthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  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);
+  g_string_free (string1, TRUE);  
+  
+  /* prepend */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend (string1, "firsthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+
+  /* prepend_len */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend_len (string1, "firsthalfjunkjunk", strlen ("firsthalf"));
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert */
+  string1 = g_string_new ("firstlast");
+  g_string_insert (string1, 5, "middle");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  g_string_free (string1, TRUE);
+
+  /* insert with pos == end of the string */
+  string1 = g_string_new ("firstmiddle");
+  g_string_insert (string1, strlen ("firstmiddle"), "last");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  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);
+  g_string_free (string1, TRUE);
+
+  /* insert_len with magic -1 pos for append */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, -1, "lastjunkjunk", strlen ("last"));
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert_len with magic -1 len for strlen-the-string */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, 5, "last", -1);
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
+  
   g_print ("ok\n");
 
   g_print ("checking timers...\n");
index 4502f97..539b904 100644 (file)
@@ -120,6 +120,65 @@ main (int   argc,
                    string1->str,
                    10, 666, 15, 15, 666.666666666, 666.666666666);
 #endif
+  
+  g_string_free (string1, TRUE);
+  g_string_free (string2, TRUE);
+
+  /* append */
+  string1 = g_string_new ("firsthalf");
+  g_string_append (string1, "lasthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  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);
+  g_string_free (string1, TRUE);  
+  
+  /* prepend */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend (string1, "firsthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+
+  /* prepend_len */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend_len (string1, "firsthalfjunkjunk", strlen ("firsthalf"));
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert */
+  string1 = g_string_new ("firstlast");
+  g_string_insert (string1, 5, "middle");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  g_string_free (string1, TRUE);
+
+  /* insert with pos == end of the string */
+  string1 = g_string_new ("firstmiddle");
+  g_string_insert (string1, strlen ("firstmiddle"), "last");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  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);
+  g_string_free (string1, TRUE);
+
+  /* insert_len with magic -1 pos for append */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, -1, "lastjunkjunk", strlen ("last"));
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert_len with magic -1 len for strlen-the-string */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, 5, "last", -1);
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
 
   return 0;
 }
index 868fe4f..1d14971 100644 (file)
@@ -726,6 +726,65 @@ main (int   argc,
   g_print ("and next 70:\n%s\n", string2->str+142);
   g_print ("last 70 chars:\n%s\n", string2->str+string2->len - 70);
 
+  g_string_free (string1, TRUE);
+  g_string_free (string2, TRUE);
+
+  /* append */
+  string1 = g_string_new ("firsthalf");
+  g_string_append (string1, "lasthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  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);
+  g_string_free (string1, TRUE);  
+  
+  /* prepend */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend (string1, "firsthalf");
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+
+  /* prepend_len */
+  string1 = g_string_new ("lasthalf");
+  g_string_prepend_len (string1, "firsthalfjunkjunk", strlen ("firsthalf"));
+  g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert */
+  string1 = g_string_new ("firstlast");
+  g_string_insert (string1, 5, "middle");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  g_string_free (string1, TRUE);
+
+  /* insert with pos == end of the string */
+  string1 = g_string_new ("firstmiddle");
+  g_string_insert (string1, strlen ("firstmiddle"), "last");
+  g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
+  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);
+  g_string_free (string1, TRUE);
+
+  /* insert_len with magic -1 pos for append */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, -1, "lastjunkjunk", strlen ("last"));
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
+  
+  /* insert_len with magic -1 len for strlen-the-string */
+  string1 = g_string_new ("first");
+  g_string_insert_len (string1, 5, "last", -1);
+  g_assert (strcmp (string1->str, "firstlast") == 0);
+  g_string_free (string1, TRUE);
+  
   g_print ("ok\n");
 
   g_print ("checking timers...\n");