1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
45 typedef struct _GRealStringChunk GRealStringChunk;
46 typedef struct _GRealString GRealString;
48 struct _GRealStringChunk
50 GHashTable *const_table;
64 G_LOCK_DEFINE_STATIC (string_mem_chunk);
65 static GMemChunk *string_mem_chunk = NULL;
71 g_str_equal (gconstpointer v1,
74 const gchar *string1 = v1;
75 const gchar *string2 = v2;
77 return strcmp (string1, string2) == 0;
80 /* 31 bit hash function */
82 g_str_hash (gconstpointer key)
88 for (p += 1; *p != '\0'; p++)
89 h = (h << 5) - h + *p;
99 g_string_chunk_new (gint default_size)
101 GRealStringChunk *new_chunk = g_new (GRealStringChunk, 1);
104 while (size < default_size)
107 new_chunk->const_table = NULL;
108 new_chunk->storage_list = NULL;
109 new_chunk->storage_next = size;
110 new_chunk->default_size = size;
111 new_chunk->this_size = size;
113 return (GStringChunk*) new_chunk;
117 g_string_chunk_free (GStringChunk *fchunk)
119 GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
122 g_return_if_fail (chunk != NULL);
124 if (chunk->storage_list)
126 for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
127 g_free (tmp_list->data);
129 g_slist_free (chunk->storage_list);
132 if (chunk->const_table)
133 g_hash_table_destroy (chunk->const_table);
139 g_string_chunk_insert (GStringChunk *fchunk,
142 GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
143 gint len = strlen (string);
146 g_return_val_if_fail (chunk != NULL, NULL);
148 if ((chunk->storage_next + len + 1) > chunk->this_size)
150 gint new_size = chunk->default_size;
152 while (new_size < len+1)
155 chunk->storage_list = g_slist_prepend (chunk->storage_list,
156 g_new (char, new_size));
158 chunk->this_size = new_size;
159 chunk->storage_next = 0;
162 pos = ((char *) chunk->storage_list->data) + chunk->storage_next;
164 strcpy (pos, string);
166 chunk->storage_next += len + 1;
172 g_string_chunk_insert_const (GStringChunk *fchunk,
175 GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
178 g_return_val_if_fail (chunk != NULL, NULL);
180 if (!chunk->const_table)
181 chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
183 lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
187 lookup = g_string_chunk_insert (fchunk, string);
188 g_hash_table_insert (chunk->const_table, lookup, lookup);
197 nearest_power (gint num)
208 g_string_maybe_expand (GRealString* string, gint len)
210 if (string->len + len >= string->alloc)
212 string->alloc = nearest_power (string->len + len + 1);
213 string->str = g_realloc (string->str, string->alloc);
218 g_string_sized_new (guint dfl_size)
222 G_LOCK (string_mem_chunk);
223 if (!string_mem_chunk)
224 string_mem_chunk = g_mem_chunk_new ("string mem chunk",
225 sizeof (GRealString),
226 1024, G_ALLOC_AND_FREE);
228 string = g_chunk_new (GRealString, string_mem_chunk);
229 G_UNLOCK (string_mem_chunk);
235 g_string_maybe_expand (string, MAX (dfl_size, 2));
238 return (GString*) string;
242 g_string_new (const gchar *init)
246 string = g_string_sized_new (init ? strlen (init) + 2 : 2);
249 g_string_append (string, init);
255 g_string_new_len (const gchar *init,
261 return g_string_new (init);
264 string = g_string_sized_new (len);
267 g_string_append_len (string, init, len);
274 g_string_free (GString *string,
275 gboolean free_segment)
279 g_return_val_if_fail (string != NULL, NULL);
283 g_free (string->str);
287 segment = string->str;
289 G_LOCK (string_mem_chunk);
290 g_mem_chunk_free (string_mem_chunk, string);
291 G_UNLOCK (string_mem_chunk);
297 g_string_equal (const GString *v,
301 GRealString *string1 = (GRealString *) v;
302 GRealString *string2 = (GRealString *) v2;
303 gint i = string1->len;
305 if (i != string2->len)
321 /* 31 bit hash function */
323 g_string_hash (const GString *str)
325 const gchar *p = str->str;
331 h = (h << 5) - h + *p;
339 g_string_assign (GString *string,
342 g_return_val_if_fail (string != NULL, NULL);
343 g_return_val_if_fail (rval != NULL, string);
345 g_string_truncate (string, 0);
346 g_string_append (string, rval);
352 g_string_truncate (GString *fstring,
355 GRealString *string = (GRealString *) fstring;
357 g_return_val_if_fail (string != NULL, NULL);
359 string->len = MIN (len, string->len);
361 string->str[string->len] = 0;
367 g_string_insert_len (GString *fstring,
372 GRealString *string = (GRealString *) fstring;
374 g_return_val_if_fail (string != NULL, NULL);
375 g_return_val_if_fail (val != NULL, fstring);
376 g_return_val_if_fail (pos <= string->len, fstring);
384 g_string_maybe_expand (string, len);
386 /* If we aren't appending at the end, move a hunk
387 * of the old string to the end, opening up space
389 if (pos < string->len)
390 g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
392 /* insert the new string */
393 g_memmove (string->str + pos, val, len);
397 string->str[string->len] = 0;
403 g_string_append (GString *fstring,
406 g_return_val_if_fail (fstring != NULL, NULL);
407 g_return_val_if_fail (val != NULL, fstring);
409 return g_string_insert_len (fstring, -1, val, -1);
413 g_string_append_len (GString *string,
417 g_return_val_if_fail (string != NULL, NULL);
418 g_return_val_if_fail (val != NULL, string);
420 return g_string_insert_len (string, -1, val, len);
424 g_string_append_c (GString *fstring,
427 g_return_val_if_fail (fstring != NULL, NULL);
429 return g_string_insert_c (fstring, -1, c);
433 g_string_prepend (GString *fstring,
436 g_return_val_if_fail (fstring != NULL, NULL);
437 g_return_val_if_fail (val != NULL, fstring);
439 return g_string_insert_len (fstring, 0, val, -1);
443 g_string_prepend_len (GString *string,
447 g_return_val_if_fail (string != NULL, NULL);
448 g_return_val_if_fail (val != NULL, string);
450 return g_string_insert_len (string, 0, val, len);
454 g_string_prepend_c (GString *fstring,
457 g_return_val_if_fail (fstring != NULL, NULL);
459 return g_string_insert_c (fstring, 0, c);
463 g_string_insert (GString *fstring,
467 g_return_val_if_fail (fstring != NULL, NULL);
468 g_return_val_if_fail (val != NULL, fstring);
469 g_return_val_if_fail (pos <= fstring->len, fstring);
471 return g_string_insert_len (fstring, pos, val, -1);
475 g_string_insert_c (GString *fstring,
479 GRealString *string = (GRealString *) fstring;
481 g_return_val_if_fail (string != NULL, NULL);
482 g_return_val_if_fail (pos <= string->len, fstring);
484 g_string_maybe_expand (string, 1);
489 /* If not just an append, move the old stuff */
490 if (pos < string->len)
491 g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
493 string->str[pos] = c;
497 string->str[string->len] = 0;
503 g_string_erase (GString *fstring,
507 GRealString *string = (GRealString*)fstring;
509 g_return_val_if_fail (string != NULL, NULL);
510 g_return_val_if_fail (len >= 0, fstring);
511 g_return_val_if_fail (pos >= 0, fstring);
512 g_return_val_if_fail (pos <= string->len, fstring);
513 g_return_val_if_fail (pos + len <= string->len, fstring);
515 if (pos + len < string->len)
516 g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
520 string->str[string->len] = 0;
526 g_string_down (GString *fstring)
528 GRealString *string = (GRealString *) fstring;
530 gint n = string->len;
532 g_return_val_if_fail (string != NULL, NULL);
534 s = (guchar *) string->str;
547 g_string_up (GString *fstring)
549 GRealString *string = (GRealString *) fstring;
551 gint n = string->len;
553 g_return_val_if_fail (string != NULL, NULL);
555 s = (guchar *) string->str;
568 g_string_printfa_internal (GString *string,
574 buffer = g_strdup_vprintf (fmt, args);
575 g_string_append (string, buffer);
580 g_string_printf (GString *string,
586 g_string_truncate (string, 0);
588 va_start (args, fmt);
589 g_string_printfa_internal (string, fmt, args);
594 g_string_printfa (GString *string,
600 va_start (args, fmt);
601 g_string_printfa_internal (string, fmt, args);