Avoid an unnecessary strlen if len is -1. (#169692, Benoit Dejean)
[platform/upstream/glib.git] / glib / gstring.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 /* 
28  * MT safe
29  */
30
31 #include "config.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <ctype.h>
41
42 #include "glib.h"
43 #include "gprintf.h"
44
45 #include "galias.h"
46
47 struct _GStringChunk
48 {
49   GHashTable *const_table;
50   GSList     *storage_list;
51   gsize       storage_next;    
52   gsize       this_size;       
53   gsize       default_size;    
54 };
55
56 G_LOCK_DEFINE_STATIC (string_mem_chunk);
57 static GMemChunk *string_mem_chunk = NULL;
58
59 /* Hash Functions.
60  */
61
62 /**
63  * g_str_equal:
64  * @v1: a key. 
65  * @v2: a key to compare with @v1.
66  * 
67  * Compares two strings and returns %TRUE if they are equal.
68  * It can be passed to g_hash_table_new() as the @key_equal_func
69  * parameter, when using strings as keys in a #GHashTable.
70  *
71  * Returns: %TRUE if the two keys match.
72  */
73 gboolean
74 g_str_equal (gconstpointer v1,
75              gconstpointer v2)
76 {
77   const gchar *string1 = v1;
78   const gchar *string2 = v2;
79   
80   return strcmp (string1, string2) == 0;
81 }
82
83 /**
84  * g_str_hash:
85  * @v: a string key.
86  *
87  * Converts a string to a hash value.
88  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
89  * when using strings as keys in a #GHashTable.
90  *
91  * Returns: a hash value corresponding to the key.
92  */
93 guint
94 g_str_hash (gconstpointer v)
95 {
96   /* 31 bit hash function */
97   const signed char *p = v;
98   guint32 h = *p;
99
100   if (h)
101     for (p += 1; *p != '\0'; p++)
102       h = (h << 5) - h + *p;
103
104   return h;
105 }
106
107 #define MY_MAXSIZE ((gsize)-1)
108
109 static inline gsize
110 nearest_power (gsize base, gsize num)    
111 {
112   if (num > MY_MAXSIZE / 2)
113     {
114       return MY_MAXSIZE;
115     }
116   else
117     {
118       gsize n = base;
119
120       while (n < num)
121         n <<= 1;
122       
123       return n;
124     }
125 }
126
127 /* String Chunks.
128  */
129
130 GStringChunk*
131 g_string_chunk_new (gsize default_size)    
132 {
133   GStringChunk *new_chunk = g_new (GStringChunk, 1);
134   gsize size = 1;    
135
136   size = nearest_power (1, default_size);
137
138   new_chunk->const_table       = NULL;
139   new_chunk->storage_list      = NULL;
140   new_chunk->storage_next      = size;
141   new_chunk->default_size      = size;
142   new_chunk->this_size         = size;
143
144   return new_chunk;
145 }
146
147 void
148 g_string_chunk_free (GStringChunk *chunk)
149 {
150   GSList *tmp_list;
151
152   g_return_if_fail (chunk != NULL);
153
154   if (chunk->storage_list)
155     {
156       for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
157         g_free (tmp_list->data);
158
159       g_slist_free (chunk->storage_list);
160     }
161
162   if (chunk->const_table)
163     g_hash_table_destroy (chunk->const_table);
164
165   g_free (chunk);
166 }
167
168 gchar*
169 g_string_chunk_insert (GStringChunk *chunk,
170                        const gchar  *string)
171 {
172   g_return_val_if_fail (chunk != NULL, NULL);
173
174   return g_string_chunk_insert_len (chunk, string, -1);
175 }
176
177 gchar*
178 g_string_chunk_insert_const (GStringChunk *chunk,
179                              const gchar  *string)
180 {
181   char* lookup;
182
183   g_return_val_if_fail (chunk != NULL, NULL);
184
185   if (!chunk->const_table)
186     chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
187
188   lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
189
190   if (!lookup)
191     {
192       lookup = g_string_chunk_insert (chunk, string);
193       g_hash_table_insert (chunk->const_table, lookup, lookup);
194     }
195
196   return lookup;
197 }
198
199 /**
200  * g_string_chunk_insert_len:
201  * @chunk: a #GStringChunk
202  * @string: bytes to insert
203  * @len: number of bytes of @string to insert, or -1 to insert a 
204  *     nul-terminated string. 
205  * 
206  * Adds a copy of the first @len bytes of @string to the #GStringChunk. The
207  * copy is nul-terminated.
208  * 
209  * The characters in the string can be changed, if necessary, though you
210  * should not change anything after the end of the string.
211  * 
212  * Return value: a pointer to the copy of @string within the #GStringChunk
213  * 
214  * Since: 2.4
215  **/
216 gchar*
217 g_string_chunk_insert_len (GStringChunk *chunk,
218                            const gchar  *string, 
219                            gssize        len)
220 {
221   gssize size;
222   gchar* pos;
223
224   g_return_val_if_fail (chunk != NULL, NULL);
225
226   if (len < 0)
227     size = strlen (string);
228   else
229     size = len;
230   
231   if ((chunk->storage_next + size + 1) > chunk->this_size)
232     {
233       gsize new_size = nearest_power (chunk->default_size, size + 1);
234
235       chunk->storage_list = g_slist_prepend (chunk->storage_list,
236                                              g_new (gchar, new_size));
237
238       chunk->this_size = new_size;
239       chunk->storage_next = 0;
240     }
241
242   pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next;
243
244   *(pos + size) = '\0';
245
246   strncpy (pos, string, size);
247   if (len > 0)
248     size = strlen (pos);
249
250   chunk->storage_next += size + 1;
251
252   return pos;
253 }
254
255 /* Strings.
256  */
257 static void
258 g_string_maybe_expand (GString* string,
259                        gsize    len) 
260 {
261   if (string->len + len >= string->allocated_len)
262     {
263       string->allocated_len = nearest_power (1, string->len + len + 1);
264       string->str = g_realloc (string->str, string->allocated_len);
265     }
266 }
267
268 GString*
269 g_string_sized_new (gsize dfl_size)    
270 {
271   GString *string;
272
273   G_LOCK (string_mem_chunk);
274   if (!string_mem_chunk)
275     string_mem_chunk = g_mem_chunk_new ("string mem chunk",
276                                         sizeof (GString),
277                                         1024, G_ALLOC_AND_FREE);
278
279   string = g_chunk_new (GString, string_mem_chunk);
280   G_UNLOCK (string_mem_chunk);
281
282   string->allocated_len = 0;
283   string->len   = 0;
284   string->str   = NULL;
285
286   g_string_maybe_expand (string, MAX (dfl_size, 2));
287   string->str[0] = 0;
288
289   return string;
290 }
291
292 GString*
293 g_string_new (const gchar *init)
294 {
295   GString *string;
296
297   if (init == NULL || *init == '\0')
298     string = g_string_sized_new (2);
299   else 
300     {
301       gint len;
302
303       len = strlen (init);
304       string = g_string_sized_new (len + 2);
305
306       g_string_append_len (string, init, len);
307     }
308
309   return string;
310 }
311
312 GString*
313 g_string_new_len (const gchar *init,
314                   gssize       len)    
315 {
316   GString *string;
317
318   if (len < 0)
319     return g_string_new (init);
320   else
321     {
322       string = g_string_sized_new (len);
323       
324       if (init)
325         g_string_append_len (string, init, len);
326       
327       return string;
328     }
329 }
330
331 gchar*
332 g_string_free (GString *string,
333                gboolean free_segment)
334 {
335   gchar *segment;
336
337   g_return_val_if_fail (string != NULL, NULL);
338
339   if (free_segment)
340     {
341       g_free (string->str);
342       segment = NULL;
343     }
344   else
345     segment = string->str;
346
347   G_LOCK (string_mem_chunk);
348   g_mem_chunk_free (string_mem_chunk, string);
349   G_UNLOCK (string_mem_chunk);
350
351   return segment;
352 }
353
354 gboolean
355 g_string_equal (const GString *v,
356                 const GString *v2)
357 {
358   gchar *p, *q;
359   GString *string1 = (GString *) v;
360   GString *string2 = (GString *) v2;
361   gsize i = string1->len;    
362
363   if (i != string2->len)
364     return FALSE;
365
366   p = string1->str;
367   q = string2->str;
368   while (i)
369     {
370       if (*p != *q)
371         return FALSE;
372       p++;
373       q++;
374       i--;
375     }
376   return TRUE;
377 }
378
379 /* 31 bit hash function */
380 guint
381 g_string_hash (const GString *str)
382 {
383   const gchar *p = str->str;
384   gsize n = str->len;    
385   guint h = 0;
386
387   while (n--)
388     {
389       h = (h << 5) - h + *p;
390       p++;
391     }
392
393   return h;
394 }
395
396 GString*
397 g_string_assign (GString     *string,
398                  const gchar *rval)
399 {
400   g_return_val_if_fail (string != NULL, NULL);
401   g_return_val_if_fail (rval != NULL, string);
402
403   /* Make sure assigning to itself doesn't corrupt the string.  */
404   if (string->str != rval)
405     {
406       /* Assigning from substring should be ok since g_string_truncate
407          does not realloc.  */
408       g_string_truncate (string, 0);
409       g_string_append (string, rval);
410     }
411
412   return string;
413 }
414
415 GString*
416 g_string_truncate (GString *string,
417                    gsize    len)    
418 {
419   g_return_val_if_fail (string != NULL, NULL);
420
421   string->len = MIN (len, string->len);
422   string->str[string->len] = 0;
423
424   return string;
425 }
426
427 /**
428  * g_string_set_size:
429  * @string: a #GString
430  * @len: the new length
431  * 
432  * Sets the length of a #GString. If the length is less than
433  * the current length, the string will be truncated. If the
434  * length is greater than the current length, the contents
435  * of the newly added area are undefined. (However, as
436  * always, string->str[string->len] will be a nul byte.) 
437  * 
438  * Return value: @string
439  **/
440 GString*
441 g_string_set_size (GString *string,
442                    gsize    len)    
443 {
444   g_return_val_if_fail (string != NULL, NULL);
445
446   if (len >= string->allocated_len)
447     g_string_maybe_expand (string, len - string->len);
448   
449   string->len = len;
450   string->str[len] = 0;
451
452   return string;
453 }
454
455 GString*
456 g_string_insert_len (GString     *string,
457                      gssize       pos,    
458                      const gchar *val,
459                      gssize       len)    
460 {
461   g_return_val_if_fail (string != NULL, NULL);
462   g_return_val_if_fail (val != NULL, string);
463
464   if (len < 0)
465     len = strlen (val);
466
467   if (pos < 0)
468     pos = string->len;
469   else
470     g_return_val_if_fail (pos <= string->len, string);
471
472   /* Check whether val represents a substring of string.  This test
473      probably violates chapter and verse of the C standards, since
474      ">=" and "<=" are only valid when val really is a substring.
475      In practice, it will work on modern archs.  */
476   if (val >= string->str && val <= string->str + string->len)
477     {
478       gsize offset = val - string->str;
479       gsize precount = 0;
480
481       g_string_maybe_expand (string, len);
482       val = string->str + offset;
483       /* At this point, val is valid again.  */
484
485       /* Open up space where we are going to insert.  */
486       if (pos < string->len)
487         g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
488
489       /* Move the source part before the gap, if any.  */
490       if (offset < pos)
491         {
492           precount = MIN (len, pos - offset);
493           memcpy (string->str + pos, val, precount);
494         }
495
496       /* Move the source part after the gap, if any.  */
497       if (len > precount)
498         memcpy (string->str + pos + precount,
499                 val + /* Already moved: */ precount + /* Space opened up: */ len,
500                 len - precount);
501     }
502   else
503     {
504       g_string_maybe_expand (string, len);
505
506       /* If we aren't appending at the end, move a hunk
507        * of the old string to the end, opening up space
508        */
509       if (pos < string->len)
510         g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
511
512       /* insert the new string */
513       memcpy (string->str + pos, val, len);
514     }
515
516   string->len += len;
517
518   string->str[string->len] = 0;
519
520   return string;
521 }
522
523 GString*
524 g_string_append (GString     *string,
525                  const gchar *val)
526 {  
527   g_return_val_if_fail (string != NULL, NULL);
528   g_return_val_if_fail (val != NULL, string);
529
530   return g_string_insert_len (string, -1, val, -1);
531 }
532
533 GString*
534 g_string_append_len (GString     *string,
535                      const gchar *val,
536                      gssize       len)    
537 {
538   g_return_val_if_fail (string != NULL, NULL);
539   g_return_val_if_fail (val != NULL, string);
540
541   return g_string_insert_len (string, -1, val, len);
542 }
543
544 #undef g_string_append_c
545 GString*
546 g_string_append_c (GString *string,
547                    gchar    c)
548 {
549   g_return_val_if_fail (string != NULL, NULL);
550
551   return g_string_insert_c (string, -1, c);
552 }
553
554 /**
555  * g_string_append_unichar:
556  * @string: a #GString
557  * @wc: a Unicode character
558  * 
559  * Converts a Unicode character into UTF-8, and appends it
560  * to the string.
561  * 
562  * Return value: @string
563  **/
564 GString*
565 g_string_append_unichar (GString  *string,
566                          gunichar  wc)
567 {  
568   g_return_val_if_fail (string != NULL, NULL);
569   
570   return g_string_insert_unichar (string, -1, wc);
571 }
572
573 GString*
574 g_string_prepend (GString     *string,
575                   const gchar *val)
576 {
577   g_return_val_if_fail (string != NULL, NULL);
578   g_return_val_if_fail (val != NULL, string);
579   
580   return g_string_insert_len (string, 0, val, -1);
581 }
582
583 GString*
584 g_string_prepend_len (GString     *string,
585                       const gchar *val,
586                       gssize       len)    
587 {
588   g_return_val_if_fail (string != NULL, NULL);
589   g_return_val_if_fail (val != NULL, string);
590
591   return g_string_insert_len (string, 0, val, len);
592 }
593
594 GString*
595 g_string_prepend_c (GString *string,
596                     gchar    c)
597 {  
598   g_return_val_if_fail (string != NULL, NULL);
599   
600   return g_string_insert_c (string, 0, c);
601 }
602
603 /**
604  * g_string_prepend_unichar:
605  * @string: a #GString.
606  * @wc: a Unicode character.
607  * 
608  * Converts a Unicode character into UTF-8, and prepends it
609  * to the string.
610  * 
611  * Return value: @string.
612  **/
613 GString*
614 g_string_prepend_unichar (GString  *string,
615                           gunichar  wc)
616 {  
617   g_return_val_if_fail (string != NULL, NULL);
618   
619   return g_string_insert_unichar (string, 0, wc);
620 }
621
622 GString*
623 g_string_insert (GString     *string,
624                  gssize       pos,    
625                  const gchar *val)
626 {
627   g_return_val_if_fail (string != NULL, NULL);
628   g_return_val_if_fail (val != NULL, string);
629   if (pos >= 0)
630     g_return_val_if_fail (pos <= string->len, string);
631   
632   return g_string_insert_len (string, pos, val, -1);
633 }
634
635 GString*
636 g_string_insert_c (GString *string,
637                    gssize   pos,    
638                    gchar    c)
639 {
640   g_return_val_if_fail (string != NULL, NULL);
641
642   g_string_maybe_expand (string, 1);
643
644   if (pos < 0)
645     pos = string->len;
646   else
647     g_return_val_if_fail (pos <= string->len, string);
648   
649   /* If not just an append, move the old stuff */
650   if (pos < string->len)
651     g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
652
653   string->str[pos] = c;
654
655   string->len += 1;
656
657   string->str[string->len] = 0;
658
659   return string;
660 }
661
662 /**
663  * g_string_insert_unichar:
664  * @string: a #GString
665  * @pos: the position at which to insert character, or -1 to
666  *       append at the end of the string.
667  * @wc: a Unicode character
668  * 
669  * Converts a Unicode character into UTF-8, and insert it
670  * into the string at the given position.
671  * 
672  * Return value: @string
673  **/
674 GString*
675 g_string_insert_unichar (GString *string,
676                          gssize   pos,    
677                          gunichar wc)
678 {  
679   gchar buf[6];
680   gint charlen;
681
682   /* We could be somewhat more efficient here by computing
683    * the length, adding the space, then converting into that
684    * space, by cut-and-pasting the internals of g_unichar_to_utf8.
685    */
686   g_return_val_if_fail (string != NULL, NULL);
687
688   charlen = g_unichar_to_utf8 (wc, buf);
689   return g_string_insert_len (string, pos, buf, charlen);
690 }
691
692 GString*
693 g_string_erase (GString *string,
694                 gssize   pos,
695                 gssize   len)
696 {
697   g_return_val_if_fail (string != NULL, NULL);
698   g_return_val_if_fail (pos >= 0, string);
699   g_return_val_if_fail (pos <= string->len, string);
700
701   if (len < 0)
702     len = string->len - pos;
703   else
704     {
705       g_return_val_if_fail (pos + len <= string->len, string);
706
707       if (pos + len < string->len)
708         g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
709     }
710
711   string->len -= len;
712   
713   string->str[string->len] = 0;
714
715   return string;
716 }
717
718 /**
719  * g_string_ascii_down:
720  * @string: a GString
721  * 
722  * Converts all upper case ASCII letters to lower case ASCII letters.
723  * 
724  * Return value: passed-in @string pointer, with all the upper case
725  *               characters converted to lower case in place, with
726  *               semantics that exactly match g_ascii_tolower.
727  **/
728 GString*
729 g_string_ascii_down (GString *string)
730 {
731   gchar *s;
732   gint n;
733
734   g_return_val_if_fail (string != NULL, NULL);
735
736   n = string->len;
737   s = string->str;
738
739   while (n)
740     {
741       *s = g_ascii_tolower (*s);
742       s++;
743       n--;
744     }
745
746   return string;
747 }
748
749 /**
750  * g_string_ascii_up:
751  * @string: a GString
752  * 
753  * Converts all lower case ASCII letters to upper case ASCII letters.
754  * 
755  * Return value: passed-in @string pointer, with all the lower case
756  *               characters converted to upper case in place, with
757  *               semantics that exactly match g_ascii_toupper.
758  **/
759 GString*
760 g_string_ascii_up (GString *string)
761 {
762   gchar *s;
763   gint n;
764
765   g_return_val_if_fail (string != NULL, NULL);
766
767   n = string->len;
768   s = string->str;
769
770   while (n)
771     {
772       *s = g_ascii_toupper (*s);
773       s++;
774       n--;
775     }
776
777   return string;
778 }
779
780 /**
781  * g_string_down:
782  * @string: a #GString
783  *  
784  * Converts a #GString to lowercase.
785  *
786  * Returns: the #GString.
787  *
788  * Deprecated: This function uses the locale-specific tolower() function, 
789  * which is almost never the right thing. Use g_string_ascii_down() or 
790  * g_utf8_strdown() instead.
791  */
792 GString*
793 g_string_down (GString *string)
794 {
795   guchar *s;
796   glong n;
797
798   g_return_val_if_fail (string != NULL, NULL);
799
800   n = string->len;    
801   s = (guchar *) string->str;
802
803   while (n)
804     {
805       if (isupper (*s))
806         *s = tolower (*s);
807       s++;
808       n--;
809     }
810
811   return string;
812 }
813
814 /**
815  * g_string_up:
816  * @string: a #GString 
817  * 
818  * Converts a #GString to uppercase.
819  * 
820  * Return value: the #GString
821  *
822  * Deprecated: This function uses the locale-specific toupper() function, 
823  * which is almost never the right thing. Use g_string_ascii_up() or 
824  * g_utf8_strup() instead.
825  **/
826 GString*
827 g_string_up (GString *string)
828 {
829   guchar *s;
830   glong n;
831
832   g_return_val_if_fail (string != NULL, NULL);
833
834   n = string->len;
835   s = (guchar *) string->str;
836
837   while (n)
838     {
839       if (islower (*s))
840         *s = toupper (*s);
841       s++;
842       n--;
843     }
844
845   return string;
846 }
847
848 static void
849 g_string_append_printf_internal (GString     *string,
850                                  const gchar *fmt,
851                                  va_list      args)
852 {
853   gchar *buffer;
854   gint length;
855   
856   length = g_vasprintf (&buffer, fmt, args);
857   g_string_append_len (string, buffer, length);
858   g_free (buffer);
859 }
860
861 void
862 g_string_printf (GString *string,
863                  const gchar *fmt,
864                  ...)
865 {
866   va_list args;
867
868   g_string_truncate (string, 0);
869
870   va_start (args, fmt);
871   g_string_append_printf_internal (string, fmt, args);
872   va_end (args);
873 }
874
875 void
876 g_string_append_printf (GString *string,
877                         const gchar *fmt,
878                         ...)
879 {
880   va_list args;
881
882   va_start (args, fmt);
883   g_string_append_printf_internal (string, fmt, args);
884   va_end (args);
885 }
886
887 #define __G_STRING_C__
888 #include "galiasdef.c"