[runtime] Move eglib into mono/eglib so it becomes a convenience library similar...
[mono.git] / mono / eglib / 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 #include <stdio.h>
30 #include <glib.h>
31
32 #define GROW_IF_NECESSARY(s,l) { \
33         if(s->len + l >= s->allocated_len) { \
34                 s->allocated_len = (s->allocated_len + l + 16) * 2; \
35                 s->str = g_realloc(s->str, s->allocated_len); \
36         } \
37 }
38
39 GString *
40 g_string_new_len (const gchar *init, gssize len)
41 {
42         GString *ret = g_new (GString, 1);
43
44         if (init == NULL)
45                 ret->len = 0;
46         else
47                 ret->len = len < 0 ? strlen(init) : len;
48         ret->allocated_len = MAX(ret->len + 1, 16);
49         ret->str = g_malloc(ret->allocated_len);
50         if (init)
51                 memcpy(ret->str, init, ret->len);
52         ret->str[ret->len] = 0;
53
54         return ret;
55 }
56
57 GString *
58 g_string_new (const gchar *init)
59 {
60         return g_string_new_len(init, -1);
61 }
62
63 GString *
64 g_string_sized_new (gsize default_size)
65 {
66         GString *ret = g_new (GString, 1);
67
68         ret->str = g_malloc (default_size);
69         ret->str [0] = 0;
70         ret->len = 0;
71         ret->allocated_len = default_size;
72
73         return ret;
74 }
75
76 gchar *
77 g_string_free (GString *string, gboolean free_segment)
78 {
79         gchar *data;
80         
81         g_return_val_if_fail (string != NULL, NULL);
82
83         data = string->str;
84         g_free(string);
85         
86         if(!free_segment) {
87                 return data;
88         }
89
90         g_free(data);
91         return NULL;
92 }
93
94 GString *
95 g_string_append_len (GString *string, const gchar *val, gssize len)
96 {
97         g_return_val_if_fail(string != NULL, NULL);
98         g_return_val_if_fail(val != NULL, string);
99
100         if(len < 0) {
101                 len = strlen(val);
102         }
103
104         GROW_IF_NECESSARY(string, len);
105         memcpy(string->str + string->len, val, len);
106         string->len += len;
107         string->str[string->len] = 0;
108
109         return string;
110 }
111
112 GString *
113 g_string_append (GString *string, const gchar *val)
114 {
115         g_return_val_if_fail(string != NULL, NULL);
116         g_return_val_if_fail(val != NULL, string);
117
118         return g_string_append_len(string, val, -1);
119 }
120
121 GString *
122 g_string_append_c (GString *string, gchar c)
123 {
124         g_return_val_if_fail(string != NULL, NULL);
125
126         GROW_IF_NECESSARY(string, 1);
127         
128         string->str[string->len] = c;
129         string->str[string->len + 1] = 0;
130         string->len++;
131
132         return string;
133 }
134
135 GString *
136 g_string_append_unichar (GString *string, gunichar c)
137 {
138         gchar utf8[6];
139         gint len;
140         
141         g_return_val_if_fail (string != NULL, NULL);
142         
143         if ((len = g_unichar_to_utf8 (c, utf8)) <= 0)
144                 return string;
145         
146         return g_string_append_len (string, utf8, len);
147 }
148
149 GString *
150 g_string_prepend (GString *string, const gchar *val)
151 {
152         gssize len;
153         
154         g_return_val_if_fail (string != NULL, string);
155         g_return_val_if_fail (val != NULL, string);
156
157         len = strlen (val);
158         
159         GROW_IF_NECESSARY(string, len); 
160         memmove(string->str + len, string->str, string->len + 1);
161         memcpy(string->str, val, len);
162
163         return string;
164 }
165
166 GString *
167 g_string_insert (GString *string, gssize pos, const gchar *val)
168 {
169         gssize len;
170         
171         g_return_val_if_fail (string != NULL, string);
172         g_return_val_if_fail (val != NULL, string);
173         g_return_val_if_fail (pos <= string->len, string);
174
175         len = strlen (val);
176         
177         GROW_IF_NECESSARY(string, len); 
178         memmove(string->str + pos + len, string->str + pos, string->len - pos - len + 1);
179         memcpy(string->str + pos, val, len);
180
181         return string;
182 }
183
184 void
185 g_string_append_printf (GString *string, const gchar *format, ...)
186 {
187         char *ret;
188         va_list args;
189         
190         g_return_if_fail (string != NULL);
191         g_return_if_fail (format != NULL);
192
193         va_start (args, format);
194         ret = g_strdup_vprintf (format, args);
195         va_end (args);
196         g_string_append (string, ret);
197
198         g_free (ret);
199 }
200
201 void
202 g_string_append_vprintf (GString *string, const gchar *format, va_list args)
203 {
204         char *ret;
205
206         g_return_if_fail (string != NULL);
207         g_return_if_fail (format != NULL);
208
209         ret = g_strdup_vprintf (format, args);
210         g_string_append (string, ret);
211         g_free (ret);
212 }
213
214 void
215 g_string_printf (GString *string, const gchar *format, ...)
216 {
217         va_list args;
218         
219         g_return_if_fail (string != NULL);
220         g_return_if_fail (format != NULL);
221
222         g_free (string->str);
223         
224         va_start (args, format);
225         string->str = g_strdup_vprintf (format, args);
226         va_end (args);
227
228         string->len = strlen (string->str);
229         string->allocated_len = string->len+1;
230 }
231
232 GString *
233 g_string_truncate (GString *string, gsize len)
234 {
235         g_return_val_if_fail (string != NULL, string);
236
237         /* Silent return */
238         if (len >= string->len)
239                 return string;
240         
241         string->len = len;
242         string->str[len] = 0;
243         return string;
244 }
245
246 GString *
247 g_string_set_size (GString *string, gsize len)
248 {
249         g_return_val_if_fail (string != NULL, string);
250
251         GROW_IF_NECESSARY(string, len);
252         
253         string->len = len;
254         string->str[len] = 0;
255         return string;
256 }
257
258 GString *
259 g_string_erase (GString *string, gssize pos, gssize len)
260 {
261         g_return_val_if_fail (string != NULL, string);
262
263         /* Silent return */
264         if (pos >= string->len)
265                 return string;
266
267         if (len == -1 || (pos + len) >= string->len) {
268                 string->str[pos] = 0;
269         }
270         else {
271                 memmove (string->str + pos, string->str + pos + len, string->len - (pos + len) + 1);
272                 string->len -= len;
273         }
274
275         return string;
276 }