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 #define _GNU_SOURCE
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <glib.h>
32 #include "gstring.h"
33
34 #define MY_MAXSIZE ((gsize)-1)
35
36 static inline gsize
nearest_power(gsize base,gsize num)37 nearest_power (gsize base, gsize num)
38 {
39 if (num > MY_MAXSIZE / 2)
40 {
41 return MY_MAXSIZE;
42 }
43 else
44 {
45 gsize n = base;
46
47 while (n < num)
48 n <<= 1;
49
50 return n;
51 }
52 }
53
54 static void
g_string_maybe_expand(GString * string,gsize len)55 g_string_maybe_expand (GString* string,
56 gsize len)
57 {
58 if (string->len + len >= string->allocated_len)
59 {
60 string->allocated_len = nearest_power (1, string->len + len + 1);
61 string->str = g_realloc (string->str, string->allocated_len);
62 }
63 }
64
65 /**
66 * g_string_overwrite:
67 * @string: a #GString
68 * @pos: the position at which to start overwriting
69 * @val: the string that will overwrite the @string starting at @pos
70 *
71 * Overwrites part of a string, lengthening it if necessary.
72 *
73 * Return value: @string
74 *
75 * Since: 2.14
76 **/
77 GString *
g_string_overwrite(GString * string,gsize pos,const gchar * val)78 g_string_overwrite (GString *string,
79 gsize pos,
80 const gchar *val)
81 {
82 g_return_val_if_fail (val != NULL, string);
83 return g_string_overwrite_len (string, pos, val, strlen (val));
84 }
85
86 /**
87 * g_string_overwrite_len:
88 * @string: a #GString
89 * @pos: the position at which to start overwriting
90 * @val: the string that will overwrite the @string starting at @pos
91 * @len: the number of bytes to write from @val
92 *
93 * Overwrites part of a string, lengthening it if necessary.
94 * This function will work with embedded nuls.
95 *
96 * Return value: @string
97 *
98 * Since: 2.14
99 **/
100 GString *
g_string_overwrite_len(GString * string,gsize pos,const gchar * val,gssize len)101 g_string_overwrite_len (GString *string,
102 gsize pos,
103 const gchar *val,
104 gssize len)
105 {
106 gsize end;
107
108 g_return_val_if_fail (string != NULL, NULL);
109
110 if (!len)
111 return string;
112
113 g_return_val_if_fail (val != NULL, string);
114 g_return_val_if_fail (pos <= string->len, string);
115
116 if (len < 0)
117 len = strlen (val);
118
119 end = pos + len;
120
121 if (end > string->len)
122 g_string_maybe_expand (string, end - string->len);
123
124 memcpy (string->str + pos, val, len);
125
126 if (end > string->len)
127 {
128 string->str[end] = '\0';
129 string->len = end;
130 }
131
132 return string;
133 }
134
135 /**
136 * g_string_append_vprintf:
137 * @string: a #GString
138 * @format: the string format. See the printf() documentation
139 * @args: the list of arguments to insert in the output
140 *
141 * Appends a formatted string onto the end of a #GString.
142 * This function is is similar to g_string_append_printf()
143 * except that the arguments to the format string are passed
144 * as a va_list.
145 *
146 * Since: 2.14
147 */
148 void
g_string_append_vprintf(GString * string,const gchar * format,va_list args)149 g_string_append_vprintf (GString *string,
150 const gchar *format,
151 va_list args)
152 {
153 gchar *buf;
154 gint len;
155
156 g_return_if_fail (string != NULL);
157 g_return_if_fail (format != NULL);
158
159 len = vasprintf (&buf, format, args);
160
161 if (len >= 0)
162 {
163 g_string_maybe_expand (string, len);
164 memcpy (string->str + string->len, buf, len + 1);
165 string->len += len;
166 g_free (buf);
167 }
168 }
169