1 /*
2 * Copyright © 2020 Canonical Ltd.
3 * Copyright © 2021 Alexandros Theodotou
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include "gstrvbuilder.h"
24
25 #include "garray.h"
26 #include "gmem.h"
27 #include "gmessages.h"
28
29 /**
30 * GStrvBuilder:
31 *
32 * `GStrvBuilder` is a helper object to build a %NULL-terminated string arrays.
33 *
34 * The following example shows how to build a two element array:
35 *
36 * ```c
37 * g_autoptr(GStrvBuilder) builder = g_strv_builder_new ();
38 * g_strv_builder_add (builder, "hello");
39 * g_strv_builder_add (builder, "world");
40 * g_auto(GStrv) array = g_strv_builder_end (builder);
41 * ```
42 *
43 * Since: 2.68
44 */
45
46 struct _GStrvBuilder
47 {
48 GPtrArray array;
49 };
50
51 /**
52 * g_strv_builder_new:
53 *
54 * Creates a new #GStrvBuilder with a reference count of 1.
55 * Use g_strv_builder_unref() on the returned value when no longer needed.
56 *
57 * Returns: (transfer full): the new #GStrvBuilder
58 *
59 * Since: 2.68
60 */
61 GStrvBuilder *
62 g_strv_builder_new (void)
63 {
64 return (GStrvBuilder *) g_ptr_array_new_with_free_func (g_free);
65 }
66
67 /**
68 * g_strv_builder_unref:
69 * @builder: (transfer full): a #GStrvBuilder allocated by g_strv_builder_new()
70 *
71 * Decreases the reference count on @builder.
72 *
73 * In the event that there are no more references, releases all memory
74 * associated with the #GStrvBuilder.
75 *
76 * Since: 2.68
77 **/
78 void
79 g_strv_builder_unref (GStrvBuilder *builder)
80 {
81 g_ptr_array_unref (&builder->array);
82 }
83
84 /**
85 * g_strv_builder_ref:
86 * @builder: (transfer none): a #GStrvBuilder
87 *
88 * Atomically increments the reference count of @builder by one.
89 * This function is thread-safe and may be called from any thread.
90 *
91 * Returns: (transfer full): The passed in #GStrvBuilder
92 *
93 * Since: 2.68
94 */
95 GStrvBuilder *
96 g_strv_builder_ref (GStrvBuilder *builder)
97 {
98 return (GStrvBuilder *) g_ptr_array_ref (&builder->array);
99 }
100
101 /**
102 * g_strv_builder_add:
103 * @builder: a #GStrvBuilder
104 * @value: a string.
105 *
106 * Add a string to the end of the array.
107 *
108 * Since 2.68
109 */
110 void
111 g_strv_builder_add (GStrvBuilder *builder,
112 const char *value)
113 {
114 g_ptr_array_add (&builder->array, g_strdup (value));
115 }
116
117 /**
118 * g_strv_builder_addv:
119 * @builder: a #GStrvBuilder
120 * @value: (array zero-terminated=1): the vector of strings to add
121 *
122 * Appends all the strings in the given vector to the builder.
123 *
124 * Since 2.70
125 */
126 void
127 g_strv_builder_addv (GStrvBuilder *builder,
128 const char **value)
129 {
130 gsize i = 0;
131 g_return_if_fail (builder != NULL);
132 g_return_if_fail (value != NULL);
133 for (i = 0; value[i] != NULL; i++)
134 g_strv_builder_add (builder, value[i]);
135 }
136
137 /**
138 * g_strv_builder_add_many:
139 * @builder: a #GStrvBuilder
140 * @...: one or more strings followed by %NULL
141 *
142 * Appends all the given strings to the builder.
143 *
144 * Since 2.70
145 */
146 void
147 g_strv_builder_add_many (GStrvBuilder *builder,
148 ...)
149 {
150 va_list var_args;
151 const gchar *str;
152 g_return_if_fail (builder != NULL);
153 va_start (var_args, builder);
154 while ((str = va_arg (var_args, gchar *)) != NULL)
155 g_strv_builder_add (builder, str);
156 va_end (var_args);
157 }
158
159 /**
160 * g_strv_builder_take:
161 * @builder: a #GStrvBuilder
162 * @value: (transfer full): a string.
163 * Ownership of the string is transferred to the #GStrvBuilder
164 *
165 * Add a string to the end of the array. After @value belongs to the
166 * #GStrvBuilder and may no longer be modified by the caller.
167 *
168 * Since 2.80
169 */
170 void
171 g_strv_builder_take (GStrvBuilder *builder,
172 char *value)
173 {
174 g_ptr_array_add (&builder->array, value);
175 }
176
177 /**
178 * g_strv_builder_end:
179 * @builder: a #GStrvBuilder
180 *
181 * Ends the builder process and returns the constructed NULL-terminated string
182 * array. The returned value should be freed with g_strfreev() when no longer
183 * needed.
184 *
185 * Returns: (transfer full): the constructed string array.
186 *
187 * Since 2.68
188 */
189 GStrv
190 g_strv_builder_end (GStrvBuilder *builder)
191 {
192 /* Add NULL terminator */
193 g_ptr_array_add (&builder->array, NULL);
194 return (GStrv) g_ptr_array_steal (&builder->array, NULL);
195 }