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/.
39 typedef struct _GRealStringChunk GRealStringChunk
;
40 typedef struct _GRealString GRealString
;
42 struct _GRealStringChunk
44 GHashTable
*const_table
;
58 G_LOCK_DEFINE_STATIC (string_mem_chunk
);
59 static GMemChunk
*string_mem_chunk
= NULL
;
65 g_str_equal (gconstpointer v
, gconstpointer v2
)
67 return strcmp ((const gchar
*) v
, (const gchar
*)v2
) == 0;
70 /* 31 bit hash function */
72 g_str_hash (gconstpointer key
)
78 for (p
+= 1; *p
!= '\0'; p
++)
79 h
= (h
<< 5) - h
+ *p
;
88 g_string_chunk_new (gint default_size
)
90 GRealStringChunk
*new_chunk
= g_new (GRealStringChunk
, 1);
93 while (size
< default_size
)
96 new_chunk
->const_table
= NULL
;
97 new_chunk
->storage_list
= NULL
;
98 new_chunk
->storage_next
= size
;
99 new_chunk
->default_size
= size
;
100 new_chunk
->this_size
= size
;
102 return (GStringChunk
*) new_chunk
;
106 g_string_chunk_free (GStringChunk
*fchunk
)
108 GRealStringChunk
*chunk
= (GRealStringChunk
*) fchunk
;
111 g_return_if_fail (chunk
!= NULL
);
113 if (chunk
->storage_list
)
115 for (tmp_list
= chunk
->storage_list
; tmp_list
; tmp_list
= tmp_list
->next
)
116 g_free (tmp_list
->data
);
118 g_slist_free (chunk
->storage_list
);
121 if (chunk
->const_table
)
122 g_hash_table_destroy (chunk
->const_table
);
128 g_string_chunk_insert (GStringChunk
*fchunk
,
131 GRealStringChunk
*chunk
= (GRealStringChunk
*) fchunk
;
132 gint len
= strlen (string
);
135 g_return_val_if_fail (chunk
!= NULL
, NULL
);
137 if ((chunk
->storage_next
+ len
+ 1) > chunk
->this_size
)
139 gint new_size
= chunk
->default_size
;
141 while (new_size
< len
+1)
144 chunk
->storage_list
= g_slist_prepend (chunk
->storage_list
,
145 g_new (char, new_size
));
147 chunk
->this_size
= new_size
;
148 chunk
->storage_next
= 0;
151 pos
= ((char*)chunk
->storage_list
->data
) + chunk
->storage_next
;
153 strcpy (pos
, string
);
155 chunk
->storage_next
+= len
+ 1;
161 g_string_chunk_insert_const (GStringChunk
*fchunk
,
164 GRealStringChunk
*chunk
= (GRealStringChunk
*) fchunk
;
167 g_return_val_if_fail (chunk
!= NULL
, NULL
);
169 if (!chunk
->const_table
)
170 chunk
->const_table
= g_hash_table_new (g_str_hash
, g_str_equal
);
172 lookup
= (char*) g_hash_table_lookup (chunk
->const_table
, (gchar
*)string
);
176 lookup
= g_string_chunk_insert (fchunk
, string
);
177 g_hash_table_insert (chunk
->const_table
, lookup
, lookup
);
186 nearest_pow (gint num
)
197 g_string_maybe_expand (GRealString
* string
, gint len
)
199 if (string
->len
+ len
>= string
->alloc
)
201 string
->alloc
= nearest_pow (string
->len
+ len
+ 1);
202 string
->str
= g_realloc (string
->str
, string
->alloc
);
207 g_string_sized_new (guint dfl_size
)
211 G_LOCK (string_mem_chunk
);
212 if (!string_mem_chunk
)
213 string_mem_chunk
= g_mem_chunk_new ("string mem chunk",
214 sizeof (GRealString
),
215 1024, G_ALLOC_AND_FREE
);
217 string
= g_chunk_new (GRealString
, string_mem_chunk
);
218 G_UNLOCK (string_mem_chunk
);
224 g_string_maybe_expand (string
, MAX (dfl_size
, 2));
227 return (GString
*) string
;
231 g_string_new (const gchar
*init
)
235 string
= g_string_sized_new (2);
238 g_string_append (string
, init
);
244 g_string_free (GString
*string
,
247 g_return_if_fail (string
!= NULL
);
250 g_free (string
->str
);
252 G_LOCK (string_mem_chunk
);
253 g_mem_chunk_free (string_mem_chunk
, string
);
254 G_UNLOCK (string_mem_chunk
);
258 g_string_assign (GString
*lval
,
261 g_return_val_if_fail (lval
!= NULL
, NULL
);
262 g_return_val_if_fail (rval
!= NULL
, NULL
);
264 g_string_truncate (lval
, 0);
265 g_string_append (lval
, rval
);
271 g_string_truncate (GString
* fstring
,
274 GRealString
*string
= (GRealString
*)fstring
;
276 g_return_val_if_fail (string
!= NULL
, NULL
);
277 g_return_val_if_fail (len
>= 0, NULL
);
281 string
->str
[len
] = 0;
287 g_string_append (GString
*fstring
,
290 GRealString
*string
= (GRealString
*)fstring
;
293 g_return_val_if_fail (string
!= NULL
, NULL
);
294 g_return_val_if_fail (val
!= NULL
, fstring
);
297 g_string_maybe_expand (string
, len
);
299 strcpy (string
->str
+ string
->len
, val
);
307 g_string_append_c (GString
*fstring
,
310 GRealString
*string
= (GRealString
*)fstring
;
312 g_return_val_if_fail (string
!= NULL
, NULL
);
313 g_string_maybe_expand (string
, 1);
315 string
->str
[string
->len
++] = c
;
316 string
->str
[string
->len
] = 0;
322 g_string_prepend (GString
*fstring
,
325 GRealString
*string
= (GRealString
*)fstring
;
328 g_return_val_if_fail (string
!= NULL
, NULL
);
329 g_return_val_if_fail (val
!= NULL
, fstring
);
332 g_string_maybe_expand (string
, len
);
334 g_memmove (string
->str
+ len
, string
->str
, string
->len
);
336 strncpy (string
->str
, val
, len
);
340 string
->str
[string
->len
] = 0;
346 g_string_prepend_c (GString
*fstring
,
349 GRealString
*string
= (GRealString
*)fstring
;
351 g_return_val_if_fail (string
!= NULL
, NULL
);
352 g_string_maybe_expand (string
, 1);
354 g_memmove (string
->str
+ 1, string
->str
, string
->len
);
360 string
->str
[string
->len
] = 0;
366 g_string_insert (GString
*fstring
,
370 GRealString
*string
= (GRealString
*)fstring
;
373 g_return_val_if_fail (string
!= NULL
, NULL
);
374 g_return_val_if_fail (val
!= NULL
, fstring
);
375 g_return_val_if_fail (pos
>= 0, fstring
);
376 g_return_val_if_fail (pos
<= string
->len
, fstring
);
379 g_string_maybe_expand (string
, len
);
381 g_memmove (string
->str
+ pos
+ len
, string
->str
+ pos
, string
->len
- pos
);
383 strncpy (string
->str
+ pos
, val
, len
);
387 string
->str
[string
->len
] = 0;
393 g_string_insert_c (GString
*fstring
,
397 GRealString
*string
= (GRealString
*)fstring
;
399 g_return_val_if_fail (string
!= NULL
, NULL
);
400 g_return_val_if_fail (pos
<= string
->len
, fstring
);
402 g_string_maybe_expand (string
, 1);
404 g_memmove (string
->str
+ pos
+ 1, string
->str
+ pos
, string
->len
- pos
);
406 string
->str
[pos
] = c
;
410 string
->str
[string
->len
] = 0;
416 g_string_erase (GString
*fstring
,
420 GRealString
*string
= (GRealString
*)fstring
;
422 g_return_val_if_fail (string
!= NULL
, NULL
);
423 g_return_val_if_fail (len
>= 0, fstring
);
424 g_return_val_if_fail (pos
>= 0, fstring
);
425 g_return_val_if_fail (pos
<= string
->len
, fstring
);
426 g_return_val_if_fail (pos
+ len
<= string
->len
, fstring
);
428 if (pos
+ len
< string
->len
)
429 g_memmove (string
->str
+ pos
, string
->str
+ pos
+ len
, string
->len
- (pos
+ len
));
433 string
->str
[string
->len
] = 0;
439 g_string_down (GString
*fstring
)
441 GRealString
*string
= (GRealString
*)fstring
;
444 g_return_val_if_fail (string
!= NULL
, NULL
);
458 g_string_up (GString
*fstring
)
460 GRealString
*string
= (GRealString
*)fstring
;
463 g_return_val_if_fail (string
!= NULL
, NULL
);
477 g_string_sprintfa_int (GString
*string
,
483 buffer
= g_strdup_vprintf (fmt
, args
);
484 g_string_append (string
, buffer
);
489 g_string_sprintf (GString
*string
,
495 g_string_truncate (string
, 0);
497 va_start (args
, fmt
);
498 g_string_sprintfa_int (string
, fmt
, args
);
503 g_string_sprintfa (GString
*string
,
509 va_start (args
, fmt
);
510 g_string_sprintfa_int (string
, fmt
, args
);