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