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 (2);
249 g_string_append (string, init);
255 g_string_free (GString *string,
256 gboolean free_segment)
260 g_return_val_if_fail (string != NULL, NULL);
264 g_free (string->str);
268 segment = string->str;
270 G_LOCK (string_mem_chunk);
271 g_mem_chunk_free (string_mem_chunk, string);
272 G_UNLOCK (string_mem_chunk);
278 g_string_equal (const GString *v,
282 GRealString *string1 = (GRealString *) v;
283 GRealString *string2 = (GRealString *) v2;
284 gint i = string1->len;
286 if (i != string2->len)
302 /* 31 bit hash function */
304 g_string_hash (const GString *str)
306 const gchar *p = str->str;
312 h = (h << 5) - h + *p;
320 g_string_assign (GString *string,
323 g_return_val_if_fail (string != NULL, NULL);
324 g_return_val_if_fail (rval != NULL, string);
326 g_string_truncate (string, 0);
327 g_string_append (string, rval);
333 g_string_truncate (GString *fstring,
336 GRealString *string = (GRealString *) fstring;
338 g_return_val_if_fail (string != NULL, NULL);
340 string->len = MIN (len, string->len);
342 string->str[string->len] = 0;
348 g_string_insert_len (GString *fstring,
353 GRealString *string = (GRealString *) fstring;
355 g_return_val_if_fail (string != NULL, NULL);
356 g_return_val_if_fail (val != NULL, fstring);
357 g_return_val_if_fail (pos <= string->len, fstring);
365 g_string_maybe_expand (string, len);
367 /* If we aren't appending at the end, move a hunk
368 * of the old string to the end, opening up space
370 if (pos < string->len)
371 g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
373 /* insert the new string */
374 g_memmove (string->str + pos, val, len);
378 string->str[string->len] = 0;
384 g_string_append (GString *fstring,
387 g_return_val_if_fail (fstring != NULL, NULL);
388 g_return_val_if_fail (val != NULL, fstring);
390 return g_string_insert_len (fstring, -1, val, -1);
394 g_string_append_len (GString *string,
398 g_return_val_if_fail (string != NULL, NULL);
399 g_return_val_if_fail (val != NULL, string);
401 return g_string_insert_len (string, -1, val, len);
405 g_string_append_c (GString *fstring,
408 g_return_val_if_fail (fstring != NULL, NULL);
410 return g_string_insert_c (fstring, -1, c);
414 g_string_prepend (GString *fstring,
417 g_return_val_if_fail (fstring != NULL, NULL);
418 g_return_val_if_fail (val != NULL, fstring);
420 return g_string_insert_len (fstring, 0, val, -1);
424 g_string_prepend_len (GString *string,
428 g_return_val_if_fail (string != NULL, NULL);
429 g_return_val_if_fail (val != NULL, string);
431 return g_string_insert_len (string, 0, val, len);
435 g_string_prepend_c (GString *fstring,
438 g_return_val_if_fail (fstring != NULL, NULL);
440 return g_string_insert_c (fstring, 0, c);
444 g_string_insert (GString *fstring,
448 g_return_val_if_fail (fstring != NULL, NULL);
449 g_return_val_if_fail (val != NULL, fstring);
450 g_return_val_if_fail (pos <= fstring->len, fstring);
452 return g_string_insert_len (fstring, pos, val, -1);
456 g_string_insert_c (GString *fstring,
460 GRealString *string = (GRealString *) fstring;
462 g_return_val_if_fail (string != NULL, NULL);
463 g_return_val_if_fail (pos <= string->len, fstring);
465 g_string_maybe_expand (string, 1);
470 /* If not just an append, move the old stuff */
471 if (pos < string->len)
472 g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
474 string->str[pos] = c;
478 string->str[string->len] = 0;
484 g_string_erase (GString *fstring,
488 GRealString *string = (GRealString*)fstring;
490 g_return_val_if_fail (string != NULL, NULL);
491 g_return_val_if_fail (len >= 0, fstring);
492 g_return_val_if_fail (pos >= 0, fstring);
493 g_return_val_if_fail (pos <= string->len, fstring);
494 g_return_val_if_fail (pos + len <= string->len, fstring);
496 if (pos + len < string->len)
497 g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
501 string->str[string->len] = 0;
507 g_string_down (GString *fstring)
509 GRealString *string = (GRealString *) fstring;
511 gint n = string->len;
513 g_return_val_if_fail (string != NULL, NULL);
515 s = (guchar *) string->str;
528 g_string_up (GString *fstring)
530 GRealString *string = (GRealString *) fstring;
532 gint n = string->len;
534 g_return_val_if_fail (string != NULL, NULL);
536 s = (guchar *) string->str;
549 g_string_sprintfa_int (GString *string,
555 buffer = g_strdup_vprintf (fmt, args);
556 g_string_append (string, buffer);
561 g_string_sprintf (GString *string,
567 g_string_truncate (string, 0);
569 va_start (args, fmt);
570 g_string_sprintfa_int (string, fmt, args);
575 g_string_sprintfa (GString *string,
581 va_start (args, fmt);
582 g_string_sprintfa_int (string, fmt, args);