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 Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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-1999. 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)
258 g_return_if_fail (string != NULL);
261 g_free (string->str);
263 G_LOCK (string_mem_chunk);
264 g_mem_chunk_free (string_mem_chunk, string);
265 G_UNLOCK (string_mem_chunk);
269 g_string_assign (GString *string,
272 g_return_val_if_fail (string != NULL, NULL);
273 g_return_val_if_fail (rval != NULL, string);
275 g_string_truncate (string, 0);
276 g_string_append (string, rval);
282 g_string_truncate (GString *fstring,
285 GRealString *string = (GRealString *) fstring;
287 g_return_val_if_fail (string != NULL, NULL);
289 string->len = MIN (len, string->len);
291 string->str[string->len] = 0;
297 g_string_insert_len (GString *fstring,
302 GRealString *string = (GRealString *) fstring;
304 g_return_val_if_fail (string != NULL, NULL);
305 g_return_val_if_fail (val != NULL, fstring);
306 g_return_val_if_fail (pos <= string->len, fstring);
314 g_string_maybe_expand (string, len);
316 /* If we aren't appending at the end, move a hunk
317 * of the old string to the end, opening up space
319 if (pos < string->len)
320 g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
322 /* insert the new string */
323 strncpy (string->str + pos, val, len);
327 string->str[string->len] = 0;
333 g_string_append (GString *fstring,
336 g_return_val_if_fail (fstring != NULL, NULL);
337 g_return_val_if_fail (val != NULL, fstring);
339 return g_string_insert_len (fstring, -1, val, -1);
343 g_string_append_len (GString *string,
347 g_return_val_if_fail (string != NULL, NULL);
348 g_return_val_if_fail (val != NULL, string);
350 return g_string_insert_len (string, -1, val, len);
354 g_string_append_c (GString *fstring,
357 g_return_val_if_fail (fstring != NULL, NULL);
359 return g_string_insert_c (fstring, -1, c);
363 g_string_prepend (GString *fstring,
366 g_return_val_if_fail (fstring != NULL, NULL);
367 g_return_val_if_fail (val != NULL, fstring);
369 return g_string_insert_len (fstring, 0, val, -1);
373 g_string_prepend_len (GString *string,
377 g_return_val_if_fail (string != NULL, NULL);
378 g_return_val_if_fail (val != NULL, string);
380 return g_string_insert_len (string, 0, val, len);
384 g_string_prepend_c (GString *fstring,
387 g_return_val_if_fail (fstring != NULL, NULL);
389 return g_string_insert_c (fstring, 0, c);
393 g_string_insert (GString *fstring,
397 g_return_val_if_fail (fstring != NULL, NULL);
398 g_return_val_if_fail (val != NULL, fstring);
399 g_return_val_if_fail (pos <= fstring->len, fstring);
401 return g_string_insert_len (fstring, pos, val, -1);
405 g_string_insert_c (GString *fstring,
409 GRealString *string = (GRealString *) fstring;
411 g_return_val_if_fail (string != NULL, NULL);
412 g_return_val_if_fail (pos <= string->len, fstring);
414 g_string_maybe_expand (string, 1);
419 /* If not just an append, move the old stuff */
420 if (pos < string->len)
421 g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
423 string->str[pos] = c;
427 string->str[string->len] = 0;
433 g_string_erase (GString *fstring,
437 GRealString *string = (GRealString*)fstring;
439 g_return_val_if_fail (string != NULL, NULL);
440 g_return_val_if_fail (len >= 0, fstring);
441 g_return_val_if_fail (pos >= 0, fstring);
442 g_return_val_if_fail (pos <= string->len, fstring);
443 g_return_val_if_fail (pos + len <= string->len, fstring);
445 if (pos + len < string->len)
446 g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
450 string->str[string->len] = 0;
456 g_string_down (GString *fstring)
458 GRealString *string = (GRealString *) fstring;
461 g_return_val_if_fail (string != NULL, NULL);
475 g_string_up (GString *fstring)
477 GRealString *string = (GRealString *) fstring;
480 g_return_val_if_fail (string != NULL, NULL);
494 g_string_sprintfa_int (GString *string,
500 buffer = g_strdup_vprintf (fmt, args);
501 g_string_append (string, buffer);
506 g_string_sprintf (GString *string,
512 g_string_truncate (string, 0);
514 va_start (args, fmt);
515 g_string_sprintfa_int (string, fmt, args);
520 g_string_sprintfa (GString *string,
526 va_start (args, fmt);
527 g_string_sprintfa_int (string, fmt, args);