In corlib/System.Runtime.InteropServices:
[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 #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         ret->len = len < 0 ? strlen(init) : len;
45         ret->allocated_len = MAX(ret->len + 1, 16);
46         ret->str = g_malloc(ret->allocated_len);
47         memcpy(ret->str, init, ret->len);
48         ret->str[ret->len] = 0;
49
50         return ret;
51 }
52
53 GString *
54 g_string_new (const gchar *init)
55 {
56         return g_string_new_len(init, -1);
57 }
58
59 GString *
60 g_string_sized_new (gsize default_size)
61 {
62         GString *ret = g_new (GString, 1);
63
64         ret->str = g_malloc (default_size);
65         ret->str [0] = 0;
66         ret->len = 0;
67         ret->allocated_len = default_size;
68
69         return ret;
70 }
71
72 gchar *
73 g_string_free (GString *string, gboolean free_segment)
74 {
75         gchar *data;
76         
77         g_return_val_if_fail (string != NULL, NULL);
78
79         data = string->str;
80         g_free(string);
81         
82         if(!free_segment) {
83                 return data;
84         }
85
86         g_free(data);
87         return NULL;
88 }
89
90 GString *
91 g_string_append_len (GString *string, const gchar *val, gssize len)
92 {
93         g_return_val_if_fail(string != NULL, NULL);
94         g_return_val_if_fail(val != NULL, string);
95
96         if(len < 0) {
97                 len = strlen(val);
98         }
99
100         GROW_IF_NECESSARY(string, len);
101         memcpy(string->str + string->len, val, len);
102         string->len += len;
103         string->str[string->len] = 0;
104
105         return string;
106 }
107
108 GString *
109 g_string_append (GString *string, const gchar *val)
110 {
111         g_return_val_if_fail(string != NULL, NULL);
112         g_return_val_if_fail(val != NULL, string);
113
114         return g_string_append_len(string, val, -1);
115 }
116
117 GString *
118 g_string_append_c (GString *string, gchar c)
119 {
120         g_return_val_if_fail(string != NULL, NULL);
121
122         GROW_IF_NECESSARY(string, 1);
123         
124         string->str[string->len] = c;
125         string->str[string->len + 1] = 0;
126         string->len++;
127
128         return string;
129 }
130
131 GString *
132 g_string_prepend (GString *string, const gchar *val)
133 {
134         gssize len;
135         
136         g_return_val_if_fail (string != NULL, string);
137         g_return_val_if_fail (val != NULL, string);
138
139         len = strlen (val);
140         
141         GROW_IF_NECESSARY(string, len); 
142         memmove(string->str + len, string->str, string->len + 1);
143         memcpy(string->str, val, len);
144
145         return string;
146 }
147
148 void
149 g_string_append_printf (GString *string, const gchar *format, ...)
150 {
151         char *ret;
152         va_list args;
153         
154         g_return_if_fail (string != NULL);
155         g_return_if_fail (format != NULL);
156
157         va_start (args, format);
158         ret = g_strdup_vprintf (format, args);
159         va_end (args);
160         g_string_append (string, ret);
161
162         free (ret);
163 }
164
165 void
166 g_string_printf (GString *string, const gchar *format, ...)
167 {
168         va_list args;
169         
170         g_return_if_fail (string != NULL);
171         g_return_if_fail (format != NULL);
172
173         g_free (string->str);
174         
175         va_start (args, format);
176         string->str = g_strdup_vprintf (format, args);
177         va_end (args);
178
179         string->len = strlen (string->str);
180         string->allocated_len = string->len+1;
181 }
182
183 GString *
184 g_string_truncate (GString *string, gsize len)
185 {
186         g_return_val_if_fail (string != NULL, string);
187
188         /* Silent return */
189         if (len < 0 || len >= string->len) {
190                 return string;
191         }
192         
193         string->len = len;
194         string->str[len] = 0;
195         return string;
196 }
197