2006-08-19 Aaron Bockover <abockover@novell.com>
[mono.git] / eglib / src / gstring.c
1 /*
2  * String functions
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@novell.com)
6  *   Aaron Bockover (abockover@novell.com)
7  *
8  * (C) 2006 Novell, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining
11  * a copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sublicense, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  */
29 #define _GNU_SOURCE
30 #include <stdio.h>
31 #include <glib.h>
32
33 #define GROW_IF_NECESSARY(s,l) { \
34         if(s->len + l >= s->allocated_len) { \
35                 s->allocated_len = (s->allocated_len + l + 16) * 2; \
36                 s->str = g_realloc(s->str, s->allocated_len); \
37         } \
38 }
39
40 GString *
41 g_string_new_len (const gchar *init, gssize len)
42 {
43         GString *ret = g_new (GString, 1);
44
45         ret->len = len < 0 ? strlen(init) : len;
46         ret->allocated_len = MAX(ret->len + 1, 16);
47         ret->str = g_malloc(ret->allocated_len);
48         memcpy(ret->str, init, ret->len);
49         ret->str[ret->len] = 0;
50
51         return ret;
52 }
53
54 GString *
55 g_string_new (const gchar *init)
56 {
57         return g_string_new_len(init, -1);
58 }
59
60 GString *
61 g_string_sized_new (gsize default_size)
62 {
63         GString *ret = g_new (GString, 1);
64
65         ret->str = g_malloc (default_size);
66         ret->str [0] = 0;
67         ret->len = 0;
68         ret->allocated_len = default_size;
69
70         return ret;
71 }
72
73 gchar *
74 g_string_free (GString *string, gboolean free_segment)
75 {
76         gchar *data;
77         
78         g_return_val_if_fail (string != NULL, NULL);
79
80         data = string->str;
81         g_free(string);
82         
83         if(!free_segment) {
84                 return data;
85         }
86
87         g_free(data);
88         return NULL;
89 }
90
91 GString *
92 g_string_append_len (GString *string, const gchar *val, gssize len)
93 {
94         g_return_val_if_fail(string != NULL, NULL);
95         g_return_val_if_fail(val != NULL, string);
96
97         if(len < 0) {
98                 len = strlen(val);
99         }
100
101         GROW_IF_NECESSARY(string, len);
102         memcpy(string->str + string->len, val, len);
103         string->len += len;
104         string->str[string->len] = 0;
105
106         return string;
107 }
108
109 GString *
110 g_string_append (GString *string, const gchar *val)
111 {
112         g_return_val_if_fail(string != NULL, NULL);
113         g_return_val_if_fail(val != NULL, string);
114
115         return g_string_append_len(string, val, -1);
116 }
117
118 GString *
119 g_string_append_c (GString *string, gchar c)
120 {
121         g_return_val_if_fail(string != NULL, NULL);
122
123         GROW_IF_NECESSARY(string, 1);
124         
125         string->str[string->len] = c;
126         string->str[string->len + 1] = 0;
127         string->len++;
128
129         return string;
130 }
131
132 GString *
133 g_string_prepend (GString *string, const gchar *val)
134 {
135         gssize len;
136         
137         g_return_val_if_fail (string != NULL, string);
138         g_return_val_if_fail (val != NULL, string);
139
140         len = strlen (val);
141         
142         GROW_IF_NECESSARY(string, len); 
143         memmove(string->str + len, string->str, string->len + 1);
144         memcpy(string->str, val, len);
145
146         return string;
147 }
148
149 void
150 g_string_append_printf (GString *string, const gchar *format, ...)
151 {
152         char *ret;
153         va_list args;
154         
155         g_return_if_fail (string != NULL);
156         g_return_if_fail (format != NULL);
157
158         va_start (args, format);
159         ret = g_strdup_vprintf (format, args);
160         va_end (args);
161         g_string_append (string, ret);
162
163         free (ret);
164 }
165
166 void
167 g_string_printf (GString *string, const gchar *format, ...)
168 {
169         va_list args;
170         
171         g_return_if_fail (string != NULL);
172         g_return_if_fail (format != NULL);
173
174         g_free (string->str);
175         
176         va_start (args, format);
177         string->str = g_strdup_vprintf (format, args);
178         va_end (args);
179
180         string->len = strlen (string->str);
181         string->allocated_len = string->len+1;
182 }
183
184 GString *
185 g_string_truncate (GString *string, gsize len)
186 {
187         g_return_val_if_fail (string != NULL, string);
188
189         /* Silent return */
190         if (len < 0 || len >= string->len) {
191                 return string;
192         }
193         
194         string->len = len;
195         string->str[len] = 0;
196         return string;
197 }
198