1 /*
2 * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
3 *
4 * This library is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 #include "evolution-data-server-config.h"
19
20 /**
21 * SECTION:e-cal-component-parameter-bag
22 * @short_description: An ECalComponentParameterBag structure
23 * @include: libecal/libecal.h
24 *
25 * Contains functions to work with the #ECalComponentParameterBag structure.
26 **/
27
28 #include "e-cal-component-parameter-bag.h"
29
30 G_DEFINE_BOXED_TYPE (ECalComponentParameterBag, e_cal_component_parameter_bag, e_cal_component_parameter_bag_copy, e_cal_component_parameter_bag_free)
31
32 struct _ECalComponentParameterBag {
33 GPtrArray *parameters; /* ICalParameter * */
34 };
35
36 /**
37 * e_cal_component_parameter_bag_new:
38 *
39 * Creates a new #ECalComponentParameterBag. Free the structure
40 * with e_cal_component_parameter_bag_free(), when no longer needed.
41 *
42 * Returns: (transfer full): a newly allocated #ECalComponentParameterBag
43 *
44 * Since: 3.34
45 **/
46 ECalComponentParameterBag *
e_cal_component_parameter_bag_new(void)47 e_cal_component_parameter_bag_new (void)
48 {
49 ECalComponentParameterBag *bag;
50
51 bag = g_slice_new0 (ECalComponentParameterBag);
52 bag->parameters = g_ptr_array_new_with_free_func (g_object_unref);
53
54 return bag;
55 }
56
57 /**
58 * e_cal_component_parameter_bag_new_from_property:
59 * @property: an #ICalProperty containing the parameters to fill the bag with
60 * @func: (nullable) (scope call): an optional %ECalComponentParameterBagFilterFunc callback
61 * @user_data: (closure func): user data for the @func
62 *
63 * Creates a new #ECalComponentParameterBag, filled with parameters
64 * from the @property, for which the @func returned %TRUE. When
65 * the @func is %NULL, all the parameters are included.
66 *
67 * Free the structure with e_cal_component_parameter_bag_free(), when no longer needed.
68 *
69 * Returns: (transfer full): a newly allocated #ECalComponentParameterBag
70 *
71 * Since: 3.34
72 **/
73 ECalComponentParameterBag *
e_cal_component_parameter_bag_new_from_property(const ICalProperty * property,ECalComponentParameterBagFilterFunc func,gpointer user_data)74 e_cal_component_parameter_bag_new_from_property (const ICalProperty *property,
75 ECalComponentParameterBagFilterFunc func,
76 gpointer user_data)
77 {
78 ECalComponentParameterBag *bag;
79
80 bag = e_cal_component_parameter_bag_new ();
81
82 e_cal_component_parameter_bag_set_from_property (bag, property, func, user_data);
83
84 return bag;
85 }
86
87 /**
88 * e_cal_component_parameter_bag_copy:
89 * @bag: (not nullable): an #ECalComponentParameterBag
90 *
91 * Returns a newly allocated copy of @bag, which should be freed with
92 * e_cal_component_parameter_bag_free(), when no longer needed.
93 *
94 * Returns: (transfer full): a newly allocated copy of @bag
95 *
96 * Since: 3.34
97 **/
98 ECalComponentParameterBag *
e_cal_component_parameter_bag_copy(const ECalComponentParameterBag * bag)99 e_cal_component_parameter_bag_copy (const ECalComponentParameterBag *bag)
100 {
101 ECalComponentParameterBag *copy;
102
103 g_return_val_if_fail (bag != NULL, NULL);
104
105 copy = e_cal_component_parameter_bag_new ();
106
107 e_cal_component_parameter_bag_assign (copy, bag);
108
109 return copy;
110 }
111
112 /**
113 * e_cal_component_parameter_bag_free: (skip)
114 * @bag: (type ECalComponentParameterBag) (nullable): an #ECalComponentParameterBag to free
115 *
116 * Free @bag, previously created by e_cal_component_parameter_bag_new(),
117 * e_cal_component_parameter_bag_new_from_component() or
118 * e_cal_component_parameter_bag_copy(). The function does nothing, if @bag
119 * is %NULL.
120 *
121 * Since: 3.34
122 **/
123 void
e_cal_component_parameter_bag_free(gpointer bag)124 e_cal_component_parameter_bag_free (gpointer bag)
125 {
126 ECalComponentParameterBag *bg = bag;
127
128 if (bg) {
129 g_ptr_array_unref (bg->parameters);
130 g_slice_free (ECalComponentParameterBag, bg);
131 }
132 }
133
134 /**
135 * e_cal_component_parameter_bag_set_from_property:
136 * @bag: an #ECalComponentParameterBag
137 * @property: an #ICalProperty containing the parameters to fill the @bag with
138 * @func: (nullable) (scope call): an optional %ECalComponentParameterBagFilterFunc callback
139 * @user_data: (closure func): user data for the @func
140 *
141 * Fills the @bag with parameters from the @property, for which the @func
142 * returned %TRUE. When the @func is %NULL, all the parameters are included.
143 * The @bag content is cleared before any parameter is added.
144 *
145 * Since: 3.34
146 **/
147 void
e_cal_component_parameter_bag_set_from_property(ECalComponentParameterBag * bag,const ICalProperty * property,ECalComponentParameterBagFilterFunc func,gpointer user_data)148 e_cal_component_parameter_bag_set_from_property (ECalComponentParameterBag *bag,
149 const ICalProperty *property,
150 ECalComponentParameterBagFilterFunc func,
151 gpointer user_data)
152 {
153 ICalProperty *prop = (ICalProperty *) property;
154 ICalParameter *param;
155
156 g_return_if_fail (bag != NULL);
157 g_return_if_fail (I_CAL_IS_PROPERTY ((ICalProperty *) property));
158
159 e_cal_component_parameter_bag_clear (bag);
160
161 for (param = i_cal_property_get_first_parameter (prop, I_CAL_ANY_PARAMETER);
162 param;
163 g_object_unref (param), param = i_cal_property_get_next_parameter (prop, I_CAL_ANY_PARAMETER)) {
164 if (!func || func (param, user_data)) {
165 e_cal_component_parameter_bag_add (bag, param);
166 }
167 }
168 }
169
170 /**
171 * e_cal_component_parameter_bag_fill_property:
172 * @bag: an #ECalComponentParameterBag
173 * @property: an #ICalProperty
174 *
175 * Adds all the stored parameters in the @bag to the @property.
176 * The function replaces any existing parameter with the new value,
177 * if any such exists. Otherwise the parameter is added.
178 *
179 * Since: 3.34
180 **/
181 void
e_cal_component_parameter_bag_fill_property(const ECalComponentParameterBag * bag,ICalProperty * property)182 e_cal_component_parameter_bag_fill_property (const ECalComponentParameterBag *bag,
183 ICalProperty *property)
184 {
185 guint ii;
186
187 g_return_if_fail (bag != NULL);
188 g_return_if_fail (I_CAL_IS_PROPERTY (property));
189
190 for (ii = 0; ii < bag->parameters->len; ii++) {
191 ICalParameter *param = g_ptr_array_index (bag->parameters, ii);
192
193 if (param)
194 i_cal_property_take_parameter (property, i_cal_parameter_clone (param));
195 }
196 }
197
198 /**
199 * e_cal_component_parameter_bag_assign:
200 * @bag: a destination #ECalComponentParameterBag
201 * @src_bag: a source #ECalComponentParameterBag
202 *
203 * Assigns content of the @src_bag into the @bag.
204 *
205 * Since: 3.34
206 **/
207 void
e_cal_component_parameter_bag_assign(ECalComponentParameterBag * bag,const ECalComponentParameterBag * src_bag)208 e_cal_component_parameter_bag_assign (ECalComponentParameterBag *bag,
209 const ECalComponentParameterBag *src_bag)
210 {
211 guint count, ii;
212
213 g_return_if_fail (bag != NULL);
214 g_return_if_fail (src_bag != NULL);
215
216 e_cal_component_parameter_bag_clear (bag);
217 count = e_cal_component_parameter_bag_get_count (src_bag);
218
219 if (count) {
220 for (ii = 0; ii < count; ii++) {
221 ICalParameter *param;
222
223 param = e_cal_component_parameter_bag_get (src_bag, ii);
224
225 e_cal_component_parameter_bag_add (bag, param);
226 }
227 }
228 }
229
230 /**
231 * e_cal_component_parameter_bag_add:
232 * @bag: an #ECalComponentParameterBag
233 * @param: an #ICalParameter
234 *
235 * Adds a copy of the @param into the @bag.
236 *
237 * Since: 3.34
238 **/
239 void
e_cal_component_parameter_bag_add(ECalComponentParameterBag * bag,const ICalParameter * param)240 e_cal_component_parameter_bag_add (ECalComponentParameterBag *bag,
241 const ICalParameter *param)
242 {
243 g_return_if_fail (bag != NULL);
244 g_return_if_fail (I_CAL_IS_PARAMETER ((ICalParameter *) param));
245
246 e_cal_component_parameter_bag_take (bag,
247 i_cal_parameter_clone ((ICalParameter *) param));
248 }
249
250 /**
251 * e_cal_component_parameter_bag_take:
252 * @bag: an #ECalComponentParameterBag
253 * @param: (transfer full): an #ICalParameter
254 *
255 * Adds the @param into the @bag and assumes ownership of the @param.
256 *
257 * Since: 3.34
258 **/
259 void
e_cal_component_parameter_bag_take(ECalComponentParameterBag * bag,ICalParameter * param)260 e_cal_component_parameter_bag_take (ECalComponentParameterBag *bag,
261 ICalParameter *param)
262 {
263 g_return_if_fail (bag != NULL);
264 g_return_if_fail (I_CAL_IS_PARAMETER (param));
265
266 g_ptr_array_add (bag->parameters, param);
267 }
268
269 /**
270 * e_cal_component_parameter_bag_get_count:
271 * @bag: an #ECalComponentParameterBag
272 *
273 * Returns: how many parameters are stored in the @bag
274 *
275 * Since: 3.34
276 **/
277 guint
e_cal_component_parameter_bag_get_count(const ECalComponentParameterBag * bag)278 e_cal_component_parameter_bag_get_count (const ECalComponentParameterBag *bag)
279 {
280 g_return_val_if_fail (bag != NULL, 0);
281 g_return_val_if_fail (bag->parameters != NULL, 0);
282
283 return bag->parameters->len;
284 }
285
286 /**
287 * e_cal_component_parameter_bag_get:
288 * @bag: an #ECalComponentParameterBag
289 * @index: an index of the parameter to get
290 *
291 * Returns the #ICalParameter at the given @index. If the @index is
292 * out of bounds (not lower than e_cal_component_parameter_bag_get_count()),
293 * then %NULL is returned.
294 *
295 * The returned parameter is owned by the @bag and should not be freed
296 * by the caller.
297 *
298 * Returns: (transfer none) (nullable): the #ICalParameter at the given @index,
299 * or %NULL on error
300 *
301 * Since: 3.34
302 **/
303 ICalParameter *
e_cal_component_parameter_bag_get(const ECalComponentParameterBag * bag,guint index)304 e_cal_component_parameter_bag_get (const ECalComponentParameterBag *bag,
305 guint index)
306 {
307 g_return_val_if_fail (bag != NULL, NULL);
308 g_return_val_if_fail (bag->parameters != NULL, NULL);
309
310 if (index >= bag->parameters->len)
311 return NULL;
312
313 return g_ptr_array_index (bag->parameters, index);
314 }
315
316 /**
317 * e_cal_component_parameter_bag_get_first_by_kind:
318 * @bag: an #ECalComponentParameterBag
319 * @kind: an #ICalParameterKind to search for
320 *
321 * Returns: the index of the first parameter of the given @kind, or value
322 * out of bounds, if such parameter cannot be found
323 *
324 * Since: 3.34
325 **/
326 guint
e_cal_component_parameter_bag_get_first_by_kind(const ECalComponentParameterBag * bag,ICalParameterKind kind)327 e_cal_component_parameter_bag_get_first_by_kind (const ECalComponentParameterBag *bag,
328 ICalParameterKind kind)
329 {
330 guint index;
331
332 g_return_val_if_fail (bag != NULL, ~0);
333 g_return_val_if_fail (bag->parameters != NULL, ~0);
334
335 for (index = 0; index < bag->parameters->len; index++) {
336 ICalParameter *param;
337
338 param = g_ptr_array_index (bag->parameters, index);
339 if (param && i_cal_parameter_isa (param) == kind)
340 return index;
341 }
342
343 return ~0;
344 }
345
346 /**
347 * e_cal_component_parameter_bag_remove:
348 * @bag: an #ECalComponentParameterBag
349 * @index: an index of the parameter to remove
350 *
351 * Removes the #ICalParameter at the given @index. If the @index is
352 * out of bounds (not lower than e_cal_component_parameter_bag_get_count()),
353 * then the function does nothing.
354 *
355 * Since: 3.34
356 **/
357 void
e_cal_component_parameter_bag_remove(ECalComponentParameterBag * bag,guint index)358 e_cal_component_parameter_bag_remove (ECalComponentParameterBag *bag,
359 guint index)
360 {
361 g_return_if_fail (bag != NULL);
362 g_return_if_fail (bag->parameters != NULL);
363
364 if (index < bag->parameters->len)
365 g_ptr_array_remove_index (bag->parameters, index);
366 }
367
368 /**
369 * e_cal_component_parameter_bag_remove_by_kind:
370 * @bag: an #ECalComponentParameterBag
371 * @kind: an #ICalParameterKind to remove
372 * @all: %TRUE to remove all parameters of the @kind, or %FALSE to only the first
373 *
374 * Removes the first or all (depending on the @all) parameters of the given @kind.
375 *
376 * Returns: how many parameters had been removed
377 *
378 * Since: 3.34
379 **/
380 guint
e_cal_component_parameter_bag_remove_by_kind(ECalComponentParameterBag * bag,ICalParameterKind kind,gboolean all)381 e_cal_component_parameter_bag_remove_by_kind (ECalComponentParameterBag *bag,
382 ICalParameterKind kind,
383 gboolean all)
384 {
385 guint index, count = 0;
386
387 g_return_val_if_fail (bag != NULL, 0);
388 g_return_val_if_fail (bag->parameters != NULL, 0);
389
390 index = 0;
391 while (index < bag->parameters->len) {
392 ICalParameter *param;
393
394 param = g_ptr_array_index (bag->parameters, index);
395 if (param && i_cal_parameter_isa (param) == kind) {
396 g_ptr_array_remove_index (bag->parameters, index);
397 count++;
398
399 if (!all)
400 break;
401 } else {
402 index++;
403 }
404 }
405
406 return count;
407 }
408
409 /**
410 * e_cal_component_parameter_bag_clear:
411 * @bag: an #ECalComponentParameterBag
412 *
413 * Removes all parameters from the @bag, thus it doesn't contain any
414 * parameter after this function returns.
415 *
416 * Since: 3.34
417 **/
418 void
e_cal_component_parameter_bag_clear(ECalComponentParameterBag * bag)419 e_cal_component_parameter_bag_clear (ECalComponentParameterBag *bag)
420 {
421 g_return_if_fail (bag != NULL);
422 g_return_if_fail (bag->parameters != NULL);
423
424 g_ptr_array_set_size (bag->parameters, 0);
425 }
426