[glib] Move GStringChunk into its own files



commit 10d86cda0266d7467cab449892e5fbb9258c607f
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Oct 1 23:38:23 2011 -0400

    Move GStringChunk into its own files

 glib/Makefile.am    |    2 +
 glib/glib.h         |    1 +
 glib/gstring.c      |  271 ------------------------------------------
 glib/gstring.h      |   17 ---
 glib/gstringchunk.c |  325 +++++++++++++++++++++++++++++++++++++++++++++++++++
 glib/gstringchunk.h |   53 +++++++++
 6 files changed, 381 insertions(+), 288 deletions(-)
---
diff --git a/glib/Makefile.am b/glib/Makefile.am
index c96e2a2..ebed44e 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -178,6 +178,7 @@ libglib_2_0_la_SOURCES = 	\
 	gstdio.c		\
 	gstrfuncs.c		\
 	gstring.c		\
+	gstringchunk.c		\
 	gtestutils.c		\
 	gthread.c		\
 	gthreadprivate.h	\
@@ -297,6 +298,7 @@ glibsubinclude_HEADERS =   \
 	gstrfuncs.h	\
 	gtestutils.h	\
 	gstring.h	\
+	gstringchunk.h	\
 	gthread.h	\
 	gthreadpool.h	\
 	gtimer.h	\
diff --git a/glib/glib.h b/glib/glib.h
index 2ca19d2..b8607b0 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -77,6 +77,7 @@
 #include <glib/gspawn.h>
 #include <glib/gstrfuncs.h>
 #include <glib/gstring.h>
+#include <glib/gstringchunk.h>
 #include <glib/gtestutils.h>
 #include <glib/gthread.h>
 #include <glib/gthreadpool.h>
diff --git a/glib/gstring.c b/glib/gstring.c
index da5b3d6..8d6ef2c 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -44,50 +44,6 @@
 #include "gprintf.h"
 
 
-/**
- * SECTION:string_chunks
- * @title: String Chunks
- * @short_description: efficient storage of groups of strings
- *
- * String chunks are used to store groups of strings. Memory is
- * allocated in blocks, and as strings are added to the #GStringChunk
- * they are copied into the next free position in a block. When a block
- * is full a new block is allocated.
- *
- * When storing a large number of strings, string chunks are more
- * efficient than using g_strdup() since fewer calls to malloc() are
- * needed, and less memory is wasted in memory allocation overheads.
- *
- * By adding strings with g_string_chunk_insert_const() it is also
- * possible to remove duplicates.
- *
- * To create a new #GStringChunk use g_string_chunk_new().
- *
- * To add strings to a #GStringChunk use g_string_chunk_insert().
- *
- * To add strings to a #GStringChunk, but without duplicating strings
- * which are already in the #GStringChunk, use
- * g_string_chunk_insert_const().
- *
- * To free the entire #GStringChunk use g_string_chunk_free(). It is
- * not possible to free individual strings.
- */
-
-/**
- * GStringChunk:
- *
- * An opaque data structure representing String Chunks. It should only
- * be accessed by using the following functions.
- */
-struct _GStringChunk
-{
-  GHashTable *const_table;
-  GSList     *storage_list;
-  gsize       storage_next;
-  gsize       this_size;
-  gsize       default_size;
-};
-
 /* Hash Functions.
  */
 
@@ -165,233 +121,6 @@ nearest_power (gsize base, gsize num)
     }
 }
 
-/* String Chunks.
- */
-
-/**
- * g_string_chunk_new:
- * @size: the default size of the blocks of memory which are
- *     allocated to store the strings. If a particular string
- *     is larger than this default size, a larger block of
- *     memory will be allocated for it.
- *
- * Creates a new #GStringChunk.
- *
- * Returns: a new #GStringChunk
- */
-GStringChunk*
-g_string_chunk_new (gsize size)
-{
-  GStringChunk *new_chunk = g_new (GStringChunk, 1);
-  gsize actual_size = 1;
-
-  actual_size = nearest_power (1, size);
-
-  new_chunk->const_table       = NULL;
-  new_chunk->storage_list      = NULL;
-  new_chunk->storage_next      = actual_size;
-  new_chunk->default_size      = actual_size;
-  new_chunk->this_size         = actual_size;
-
-  return new_chunk;
-}
-
-/**
- * g_string_chunk_free:
- * @chunk: a #GStringChunk
- *
- * Frees all memory allocated by the #GStringChunk.
- * After calling g_string_chunk_free() it is not safe to
- * access any of the strings which were contained within it.
- */
-void
-g_string_chunk_free (GStringChunk *chunk)
-{
-  GSList *tmp_list;
-
-  g_return_if_fail (chunk != NULL);
-
-  if (chunk->storage_list)
-    {
-      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
-        g_free (tmp_list->data);
-
-      g_slist_free (chunk->storage_list);
-    }
-
-  if (chunk->const_table)
-    g_hash_table_destroy (chunk->const_table);
-
-  g_free (chunk);
-}
-
-/**
- * g_string_chunk_clear:
- * @chunk: a #GStringChunk
- *
- * Frees all strings contained within the #GStringChunk.
- * After calling g_string_chunk_clear() it is not safe to
- * access any of the strings which were contained within it.
- *
- * Since: 2.14
- */
-void
-g_string_chunk_clear (GStringChunk *chunk)
-{
-  GSList *tmp_list;
-
-  g_return_if_fail (chunk != NULL);
-
-  if (chunk->storage_list)
-    {
-      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
-        g_free (tmp_list->data);
-
-      g_slist_free (chunk->storage_list);
-
-      chunk->storage_list = NULL;
-      chunk->storage_next = chunk->default_size;
-      chunk->this_size    = chunk->default_size;
-    }
-
-  if (chunk->const_table)
-      g_hash_table_remove_all (chunk->const_table);
-}
-
-/**
- * g_string_chunk_insert:
- * @chunk: a #GStringChunk
- * @string: the string to add
- *
- * Adds a copy of @string to the #GStringChunk.
- * It returns a pointer to the new copy of the string
- * in the #GStringChunk. The characters in the string
- * can be changed, if necessary, though you should not
- * change anything after the end of the string.
- *
- * Unlike g_string_chunk_insert_const(), this function
- * does not check for duplicates. Also strings added
- * with g_string_chunk_insert() will not be searched
- * by g_string_chunk_insert_const() when looking for
- * duplicates.
- *
- * Returns: a pointer to the copy of @string within
- *     the #GStringChunk
- */
-gchar*
-g_string_chunk_insert (GStringChunk *chunk,
-                       const gchar  *string)
-{
-  g_return_val_if_fail (chunk != NULL, NULL);
-
-  return g_string_chunk_insert_len (chunk, string, -1);
-}
-
-/**
- * g_string_chunk_insert_const:
- * @chunk: a #GStringChunk
- * @string: the string to add
- *
- * Adds a copy of @string to the #GStringChunk, unless the same
- * string has already been added to the #GStringChunk with
- * g_string_chunk_insert_const().
- *
- * This function is useful if you need to copy a large number
- * of strings but do not want to waste space storing duplicates.
- * But you must remember that there may be several pointers to
- * the same string, and so any changes made to the strings
- * should be done very carefully.
- *
- * Note that g_string_chunk_insert_const() will not return a
- * pointer to a string added with g_string_chunk_insert(), even
- * if they do match.
- *
- * Returns: a pointer to the new or existing copy of @string
- *          within the #GStringChunk
- */
-gchar*
-g_string_chunk_insert_const (GStringChunk *chunk,
-                             const gchar  *string)
-{
-  char* lookup;
-
-  g_return_val_if_fail (chunk != NULL, NULL);
-
-  if (!chunk->const_table)
-    chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
-
-  lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
-
-  if (!lookup)
-    {
-      lookup = g_string_chunk_insert (chunk, string);
-      g_hash_table_insert (chunk->const_table, lookup, lookup);
-    }
-
-  return lookup;
-}
-
-/**
- * g_string_chunk_insert_len:
- * @chunk: a #GStringChunk
- * @string: bytes to insert
- * @len: number of bytes of @string to insert, or -1 to insert a
- *     nul-terminated string
- *
- * Adds a copy of the first @len bytes of @string to the #GStringChunk.
- * The copy is nul-terminated.
- *
- * Since this function does not stop at nul bytes, it is the caller's
- * responsibility to ensure that @string has at least @len addressable
- * bytes.
- *
- * The characters in the returned string can be changed, if necessary,
- * though you should not change anything after the end of the string.
- *
- * Return value: a pointer to the copy of @string within the #GStringChunk
- *
- * Since: 2.4
- */
-gchar*
-g_string_chunk_insert_len (GStringChunk *chunk,
-                           const gchar  *string,
-                           gssize        len)
-{
-  gssize size;
-  gchar* pos;
-
-  g_return_val_if_fail (chunk != NULL, NULL);
-
-  if (len < 0)
-    size = strlen (string);
-  else
-    size = len;
-
-  if ((chunk->storage_next + size + 1) > chunk->this_size)
-    {
-      gsize new_size = nearest_power (chunk->default_size, size + 1);
-
-      chunk->storage_list = g_slist_prepend (chunk->storage_list,
-                                             g_new (gchar, new_size));
-
-      chunk->this_size = new_size;
-      chunk->storage_next = 0;
-    }
-
-  pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next;
-
-  *(pos + size) = '\0';
-
-  memcpy (pos, string, size);
-
-  chunk->storage_next += size + 1;
-
-  return pos;
-}
-
-/* Strings.
- */
-
 /**
  * SECTION:strings
  * @title: Strings
diff --git a/glib/gstring.h b/glib/gstring.h
index 68c494f..242c481 100644
--- a/glib/gstring.h
+++ b/glib/gstring.h
@@ -38,7 +38,6 @@
 G_BEGIN_DECLS
 
 typedef struct _GString         GString;
-typedef struct _GStringChunk    GStringChunk;
 
 struct _GString
 {
@@ -47,22 +46,6 @@ struct _GString
   gsize allocated_len;
 };
 
-/* String Chunks
- */
-GStringChunk* g_string_chunk_new           (gsize size);
-void          g_string_chunk_free          (GStringChunk *chunk);
-void          g_string_chunk_clear         (GStringChunk *chunk);
-gchar*        g_string_chunk_insert        (GStringChunk *chunk,
-                                            const gchar  *string);
-gchar*        g_string_chunk_insert_len    (GStringChunk *chunk,
-                                            const gchar  *string,
-                                            gssize        len);
-gchar*        g_string_chunk_insert_const  (GStringChunk *chunk,
-                                            const gchar  *string);
-
-
-/* Strings
- */
 GString*     g_string_new               (const gchar     *init);
 GString*     g_string_new_len           (const gchar     *init,
                                          gssize           len);
diff --git a/glib/gstringchunk.c b/glib/gstringchunk.c
new file mode 100644
index 0000000..20362d6
--- /dev/null
+++ b/glib/gstringchunk.c
@@ -0,0 +1,325 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gstringchunk.h"
+
+#include "ghash.h"
+#include "gslist.h"
+#include "gmessages.h"
+
+/**
+ * SECTION:string_chunks
+ * @title: String Chunks
+ * @short_description: efficient storage of groups of strings
+ *
+ * String chunks are used to store groups of strings. Memory is
+ * allocated in blocks, and as strings are added to the #GStringChunk
+ * they are copied into the next free position in a block. When a block
+ * is full a new block is allocated.
+ *
+ * When storing a large number of strings, string chunks are more
+ * efficient than using g_strdup() since fewer calls to malloc() are
+ * needed, and less memory is wasted in memory allocation overheads.
+ *
+ * By adding strings with g_string_chunk_insert_const() it is also
+ * possible to remove duplicates.
+ *
+ * To create a new #GStringChunk use g_string_chunk_new().
+ *
+ * To add strings to a #GStringChunk use g_string_chunk_insert().
+ *
+ * To add strings to a #GStringChunk, but without duplicating strings
+ * which are already in the #GStringChunk, use
+ * g_string_chunk_insert_const().
+ *
+ * To free the entire #GStringChunk use g_string_chunk_free(). It is
+ * not possible to free individual strings.
+ */
+
+/**
+ * GStringChunk:
+ *
+ * An opaque data structure representing String Chunks.
+ * It should only be accessed by using the following functions.
+ */
+struct _GStringChunk
+{
+  GHashTable *const_table;
+  GSList     *storage_list;
+  gsize       storage_next;
+  gsize       this_size;
+  gsize       default_size;
+};
+
+#define MY_MAXSIZE ((gsize)-1)
+
+static inline gsize
+nearest_power (gsize base,
+               gsize num)
+{
+  if (num > MY_MAXSIZE / 2)
+    {
+      return MY_MAXSIZE;
+    }
+  else
+    {
+      gsize n = base;
+
+      while (n < num)
+        n <<= 1;
+
+      return n;
+    }
+}
+
+/**
+ * g_string_chunk_new:
+ * @size: the default size of the blocks of memory which are
+ *     allocated to store the strings. If a particular string
+ *     is larger than this default size, a larger block of
+ *     memory will be allocated for it.
+ *
+ * Creates a new #GStringChunk.
+ *
+ * Returns: a new #GStringChunk
+ */
+GStringChunk *
+g_string_chunk_new (gsize size)
+{
+  GStringChunk *new_chunk = g_new (GStringChunk, 1);
+  gsize actual_size = 1;
+
+  actual_size = nearest_power (1, size);
+
+  new_chunk->const_table  = NULL;
+  new_chunk->storage_list = NULL;
+  new_chunk->storage_next = actual_size;
+  new_chunk->default_size = actual_size;
+  new_chunk->this_size    = actual_size;
+
+  return new_chunk;
+}
+
+/**
+ * g_string_chunk_free:
+ * @chunk: a #GStringChunk
+ *
+ * Frees all memory allocated by the #GStringChunk.
+ * After calling g_string_chunk_free() it is not safe to
+ * access any of the strings which were contained within it.
+ */
+void
+g_string_chunk_free (GStringChunk *chunk)
+{
+  GSList *tmp_list;
+
+  g_return_if_fail (chunk != NULL);
+
+  if (chunk->storage_list)
+    {
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+        g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+    }
+
+  if (chunk->const_table)
+    g_hash_table_destroy (chunk->const_table);
+
+  g_free (chunk);
+}
+
+/**
+ * g_string_chunk_clear:
+ * @chunk: a #GStringChunk
+ *
+ * Frees all strings contained within the #GStringChunk.
+ * After calling g_string_chunk_clear() it is not safe to
+ * access any of the strings which were contained within it.
+ *
+ * Since: 2.14
+ */
+void
+g_string_chunk_clear (GStringChunk *chunk)
+{
+  GSList *tmp_list;
+
+  g_return_if_fail (chunk != NULL);
+
+  if (chunk->storage_list)
+    {
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+        g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+
+      chunk->storage_list = NULL;
+      chunk->storage_next = chunk->default_size;
+      chunk->this_size    = chunk->default_size;
+    }
+
+  if (chunk->const_table)
+      g_hash_table_remove_all (chunk->const_table);
+}
+
+/**
+ * g_string_chunk_insert:
+ * @chunk: a #GStringChunk
+ * @string: the string to add
+ *
+ * Adds a copy of @string to the #GStringChunk.
+ * It returns a pointer to the new copy of the string
+ * in the #GStringChunk. The characters in the string
+ * can be changed, if necessary, though you should not
+ * change anything after the end of the string.
+ *
+ * Unlike g_string_chunk_insert_const(), this function
+ * does not check for duplicates. Also strings added
+ * with g_string_chunk_insert() will not be searched
+ * by g_string_chunk_insert_const() when looking for
+ * duplicates.
+ *
+ * Returns: a pointer to the copy of @string within
+ *     the #GStringChunk
+ */
+gchar*
+g_string_chunk_insert (GStringChunk *chunk,
+                       const gchar  *string)
+{
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  return g_string_chunk_insert_len (chunk, string, -1);
+}
+
+/**
+ * g_string_chunk_insert_const:
+ * @chunk: a #GStringChunk
+ * @string: the string to add
+ *
+ * Adds a copy of @string to the #GStringChunk, unless the same
+ * string has already been added to the #GStringChunk with
+ * g_string_chunk_insert_const().
+ *
+ * This function is useful if you need to copy a large number
+ * of strings but do not want to waste space storing duplicates.
+ * But you must remember that there may be several pointers to
+ * the same string, and so any changes made to the strings
+ * should be done very carefully.
+ *
+ * Note that g_string_chunk_insert_const() will not return a
+ * pointer to a string added with g_string_chunk_insert(), even
+ * if they do match.
+ *
+ * Returns: a pointer to the new or existing copy of @string
+ *     within the #GStringChunk
+ */
+gchar*
+g_string_chunk_insert_const (GStringChunk *chunk,
+                             const gchar  *string)
+{
+  char* lookup;
+
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  if (!chunk->const_table)
+    chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+  lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
+
+  if (!lookup)
+    {
+      lookup = g_string_chunk_insert (chunk, string);
+      g_hash_table_insert (chunk->const_table, lookup, lookup);
+    }
+
+  return lookup;
+}
+
+/**
+ * g_string_chunk_insert_len:
+ * @chunk: a #GStringChunk
+ * @string: bytes to insert
+ * @len: number of bytes of @string to insert, or -1 to insert a
+ *     nul-terminated string
+ *
+ * Adds a copy of the first @len bytes of @string to the #GStringChunk.
+ * The copy is nul-terminated.
+ *
+ * Since this function does not stop at nul bytes, it is the caller's
+ * responsibility to ensure that @string has at least @len addressable
+ * bytes.
+ *
+ * The characters in the returned string can be changed, if necessary,
+ * though you should not change anything after the end of the string.
+ *
+ * Return value: a pointer to the copy of @string within the #GStringChunk
+ *
+ * Since: 2.4
+ */
+gchar*
+g_string_chunk_insert_len (GStringChunk *chunk,
+                           const gchar  *string,
+                           gssize        len)
+{
+  gssize size;
+  gchar* pos;
+
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  if (len < 0)
+    size = strlen (string);
+  else
+    size = len;
+
+  if ((chunk->storage_next + size + 1) > chunk->this_size)
+    {
+      gsize new_size = nearest_power (chunk->default_size, size + 1);
+
+      chunk->storage_list = g_slist_prepend (chunk->storage_list,
+                                             g_new (gchar, new_size));
+
+      chunk->this_size = new_size;
+      chunk->storage_next = 0;
+    }
+
+  pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next;
+
+  *(pos + size) = '\0';
+
+  memcpy (pos, string, size);
+
+  chunk->storage_next += size + 1;
+
+  return pos;
+}
diff --git a/glib/gstringchunk.h b/glib/gstringchunk.h
new file mode 100644
index 0000000..9654885
--- /dev/null
+++ b/glib/gstringchunk.h
@@ -0,0 +1,53 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_STRINGCHUNK_H__
+#define __G_STRINGCHUNK_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GStringChunk GStringChunk;
+
+GStringChunk* g_string_chunk_new          (gsize size);
+void          g_string_chunk_free         (GStringChunk *chunk);
+void          g_string_chunk_clear        (GStringChunk *chunk);
+gchar*        g_string_chunk_insert       (GStringChunk *chunk,
+                                           const gchar  *string);
+gchar*        g_string_chunk_insert_len   (GStringChunk *chunk,
+                                           const gchar  *string,
+                                           gssize        len);
+gchar*        g_string_chunk_insert_const (GStringChunk *chunk,
+                                           const gchar  *string);
+
+G_END_DECLS
+
+#endif /* __G_STRING_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]