* 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.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "config.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.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.
- */
-
-/**
- * g_str_equal:
- * @v1: a key
- * @v2: a key to compare with @v1
- *
- * Compares two strings for byte-by-byte equality and returns %TRUE
- * if they are equal. It can be passed to g_hash_table_new() as the
- * @key_equal_func parameter, when using strings as keys in a #GHashTable.
- *
- * Note that this function is primarily meant as a hash table comparison
- * function. For a general-purpose, %NULL-safe string comparison function,
- * see g_strcmp0().
+ * SECTION:strings
+ * @title: Strings
+ * @short_description: text buffers which grow automatically
+ * as text is added
*
- * Returns: %TRUE if the two keys match
+ * A #GString is an object that handles the memory management of a C
+ * string for you. The emphasis of #GString is on text, typically
+ * UTF-8. Crucially, the "str" member of a #GString is guaranteed to
+ * have a trailing nul character, and it is therefore always safe to
+ * call functions such as strchr() or g_strdup() on it.
+ *
+ * However, a #GString can also hold arbitrary binary data, because it
+ * has a "len" member, which includes any possible embedded nul
+ * characters in the data. Conceptually then, #GString is like a
+ * #GByteArray with the addition of many convenience methods for text,
+ * and a guaranteed nul terminator.
*/
-gboolean
-g_str_equal (gconstpointer v1,
- gconstpointer v2)
-{
- const gchar *string1 = v1;
- const gchar *string2 = v2;
-
- return strcmp (string1, string2) == 0;
-}
/**
- * g_str_hash:
- * @v: a string key
- *
- * Converts a string to a hash value.
- *
- * This function implements the widely used "djb" hash apparently posted
- * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
- * unsigned hash value starts at 5381 and for each byte 'c' in the
- * string, is updated: <literal>hash = hash * 33 + c</literal>. This
- * function uses the signed value of each byte.
- *
- * It can be passed to g_hash_table_new() as the @hash_func parameter,
- * when using strings as keys in a #GHashTable.
+ * GString:
+ * @str: points to the character data. It may move as text is added.
+ * The @str field is null-terminated and so
+ * can be used as an ordinary C string.
+ * @len: contains the length of the string, not including the
+ * terminating nul byte.
+ * @allocated_len: the number of bytes that can be stored in the
+ * string before it needs to be reallocated. May be larger than @len.
*
- * Returns: a hash value corresponding to the key
+ * The GString struct contains the public fields of a GString.
*/
-guint
-g_str_hash (gconstpointer v)
-{
- const signed char *p;
- guint32 h = 5381;
- for (p = v; *p != '\0'; p++)
- h = (h << 5) + h + *p;
-
- return h;
-}
#define MY_MAXSIZE ((gsize)-1)
}
}
-/* 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
- * @short_description: text buffers which grow automatically
- * as text is added
- *
- * A #GString is an object that handles the memory management
- * of a C string for you. You can think of it as similar to a
- * Java StringBuffer. In addition to the string itself, GString
- * stores the length of the string, so can be used for binary
- * data with embedded nul bytes. To access the C string managed
- * by the GString @string, simply use @string->str.
- */
-
-/**
- * GString:
- * @str: points to the character data. It may move as text is added.
- * The @str field is null-terminated and so
- * can be used as an ordinary C string.
- * @len: contains the length of the string, not including the
- * terminating nul byte.
- * @allocated_len: the number of bytes that can be stored in the
- * string before it needs to be reallocated. May be larger than @len.
- *
- * The GString struct contains the public fields of a GString.
- */
-
-
static void
g_string_maybe_expand (GString *string,
gsize len)
/**
* g_string_new:
- * @init: the initial text to copy into the string
+ * @init: (allow-none): the initial text to copy into the string, or %NULL to
+ * start with an empty string.
*
* Creates a new #GString, initialized with the given string.
*
}
/**
+ * g_string_free_to_bytes:
+ * @string: (transfer full): a #GString
+ *
+ * Transfers ownership of the contents of @string to a newly allocated
+ * #GBytes. The #GString structure itself is deallocated, and it is
+ * therefore invalid to use @string after invoking this function.
+ *
+ * Note that while #GString ensures that its buffer always has a
+ * trailing nul character (not reflected in its "len"), the returned
+ * #GBytes does not include this extra nul; i.e. it has length exactly
+ * equal to the "len" member.
+ *
+ * Returns: A newly allocated #GBytes containing contents of @string; @string itself is freed
+ * Since: 2.34
+ */
+GBytes*
+g_string_free_to_bytes (GString *string)
+{
+ gsize len;
+ gchar *buf;
+
+ g_return_val_if_fail (string != NULL, NULL);
+
+ len = string->len;
+
+ buf = g_string_free (string, FALSE);
+
+ return g_bytes_new_take (buf, len);
+}
+
+/**
* g_string_equal:
* @v: a #GString
* @v2: another #GString
* Compares two strings for equality, returning %TRUE if they are equal.
* For use with #GHashTable.
*
- * Returns: %TRUE if they strings are the same length and contain the
+ * Returns: %TRUE if the strings are the same length and contain the
* same bytes
*/
gboolean
* of the newly added area are undefined. (However, as
* always, string->str[string->len] will be a nul byte.)
*
- * Return value: @string
+ * Returns: @string
*/
GString *
g_string_set_size (GString *string,
/* Open up space where we are going to insert. */
if (pos < string->len)
- g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
+ memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* Move the source part before the gap, if any. */
if (offset < pos)
* 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);
+ memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* insert the new string */
if (len == 1)
* Converts a Unicode character into UTF-8, and appends it
* to the string.
*
- * Return value: @string
+ * Returns: @string
*/
GString *
g_string_append_unichar (GString *string,
* Converts a Unicode character into UTF-8, and prepends it
* to the string.
*
- * Return value: @string
+ * Returns: @string
*/
GString *
g_string_prepend_unichar (GString *string,
/* 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);
+ memmove (string->str + pos + 1, string->str + pos, string->len - pos);
string->str[pos] = c;
* Converts a Unicode character into UTF-8, and insert it
* into the string at the given position.
*
- * Return value: @string
+ * Returns: @string
*/
GString *
g_string_insert_unichar (GString *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);
+ memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
dest = string->str + pos;
/* Code copied from g_unichar_to_utf() */
*
* Overwrites part of a string, lengthening it if necessary.
*
- * Return value: @string
+ * Returns: @string
*
* Since: 2.14
*/
* Overwrites part of a string, lengthening it if necessary.
* This function will work with embedded nuls.
*
- * Return value: @string
+ * Returns: @string
*
* Since: 2.14
*/
g_return_val_if_fail (pos + len <= string->len, string);
if (pos + len < string->len)
- g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
+ memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
}
string->len -= len;
*
* Converts all uppercase ASCII letters to lowercase ASCII letters.
*
- * Return value: passed-in @string pointer, with all the
+ * Returns: passed-in @string pointer, with all the
* uppercase characters converted to lowercase in place,
* with semantics that exactly match g_ascii_tolower().
*/
*
* Converts all lowercase ASCII letters to uppercase ASCII letters.
*
- * Return value: passed-in @string pointer, with all the
+ * Returns: passed-in @string pointer, with all the
* lowercase characters converted to uppercase in place,
* with semantics that exactly match g_ascii_toupper().
*/
*
* Converts a #GString to uppercase.
*
- * Return value: @string
+ * Returns: @string
*
* Deprecated:2.2: This function uses the locale-specific
* toupper() function, which is almost never the right thing.