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_sprintfa_int (GString
*string
,
574 buffer
= g_strdup_vprintf (fmt
, args
);
575 g_string_append (string
, buffer
);
580 g_string_sprintf (GString
*string
,
586 g_string_truncate (string
, 0);
588 va_start (args
, fmt
);
589 g_string_sprintfa_int (string
, fmt
, args
);
594 g_string_sprintfa (GString
*string
,
600 va_start (args
, fmt
);
601 g_string_sprintfa_int (string
, fmt
, args
);