Libical API Documentation 4.0 STABLE VERSION Visit the v3.0 documentation
Loading...
Searching...
No Matches
icalparameter.c
Go to the documentation of this file.
1/*======================================================================
2 FILE: icalparameter.c
3 CREATOR: eric 09 May 1999
4
5 SPDX-FileCopyrightText: 2000, Eric Busboom <eric@civicknowledge.com>
6 SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
7
8 The original code is icalderivedparameters.{c,h}
9
10 Contributions from:
11 Graham Davison <g.m.davison@computer.org>
12======================================================================*/
13
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include "icalparameter.h"
24#include "icalparameterimpl.h"
25#include "icalerror_p.h"
26#include "icalmemory.h"
27
28#include <errno.h>
29#include <stdlib.h>
30
32LIBICAL_ICAL_EXPORT struct icalparameter_impl *icalparameter_new_impl(icalparameter_kind kind)
33{
34 struct icalparameter_impl *v;
35
36 if ((v = (struct icalparameter_impl *)icalmemory_new_buffer(sizeof(struct icalparameter_impl))) == 0) {
38 return 0;
39 }
40
41 memset(v, 0, sizeof(struct icalparameter_impl));
42
43 v->id = ICAL_STRUCTURE_TYPE_PARAMETER;
44 v->kind = kind;
45 v->value_kind = icalparameter_kind_value_kind(kind, &v->is_multivalued);
46
47 return v;
48}
50
51icalparameter *icalparameter_new(icalparameter_kind kind)
52{
53 struct icalparameter_impl *v = icalparameter_new_impl(kind);
54
55 return (icalparameter *)v;
56}
57
58void icalparameter_free(icalparameter *param)
59{
60 /* Comment out the following as it always triggers, even when parameter is non-zero
61 icalerror_check_arg_rv((parameter==0),"parameter");*/
62
63 if (param->parent != 0) {
64 return;
65 }
66
67 if (param->string != 0) {
68 icalmemory_free_buffer((void *)param->string);
69 } else if (param->values != 0) {
70 if (param->value_kind == ICAL_TEXT_VALUE) {
71 icalstrarray_free(param->values);
72 } else {
73 icalenumarray_free(param->values);
74 }
75 }
76
77 icalmemory_free_buffer((void *)param->x_name);
78
79 memset(param, 0, sizeof(icalparameter));
80
81 param->parent = 0;
82 param->id = ICAL_STRUCTURE_TYPE_PARAMETER_EMPTY;
84}
85
86icalparameter *icalparameter_clone(const icalparameter *old)
87{
88 struct icalparameter_impl *clone;
89
90 icalerror_check_arg_rz((old != 0), "param");
91
92 clone = icalparameter_new_impl(old->kind);
93
94 if (clone == 0) {
95 return 0;
96 }
97
98 memcpy(clone, old, sizeof(struct icalparameter_impl));
99
100 if (old->string != 0) {
101 clone->string = icalmemory_strdup(old->string);
102 if (clone->string == 0) {
103 clone->parent = 0;
104 icalparameter_free(clone);
105 return 0;
106 }
107 }
108
109 if (old->x_name != 0) {
110 clone->x_name = icalmemory_strdup(old->x_name);
111 if (clone->x_name == 0) {
112 clone->parent = 0;
113 icalparameter_free(clone);
114 return 0;
115 }
116 }
117
118 if (old->values != 0) {
119 clone->values = old->value_kind == ICAL_TEXT_VALUE ? icalstrarray_clone(old->values) : icalenumarray_clone(old->values);
120 if (clone->values == 0) {
121 clone->parent = 0;
122 icalparameter_free(clone);
123 return 0;
124 }
125 }
126
127 return clone;
128}
129
130icalparameter *icalparameter_new_from_string(const char *str)
131{
132 char *eq;
133 char *cpy;
134 icalparameter_kind kind;
135 icalparameter *param;
136
137 icalerror_check_arg_rz(str != 0, "str");
138
139 cpy = icalmemory_strdup(str);
140
141 if (cpy == 0) {
143 return 0;
144 }
145
146 eq = strchr(cpy, '=');
147
148 if (eq == 0) {
151 return 0;
152 }
153
154 *eq = '\0';
155
156 eq++;
157
159
160 if (kind == ICAL_NO_PARAMETER) {
163 return 0;
164 }
165
166 param = icalparameter_new_from_value_string(kind, eq);
167
168 if (kind == ICAL_X_PARAMETER) {
169 icalparameter_set_xname(param, cpy);
170 } else if (kind == ICAL_IANA_PARAMETER) {
171 icalparameter_set_iana_name(param, cpy);
172 }
173
175
176 return param;
177}
178
179char *icalparameter_as_ical_string(icalparameter *param)
180{
181 char *buf;
182
185 return buf;
186}
187
188/*
189 * - param = param-name "=" param-value
190 * - param-name = iana-token / x-token
191 * - param-value = paramtext /quoted-string
192 * - paramtext = *SAFE-CHAR
193 * - quoted-string= DQUOTE *QSAFE-CHAR DQUOTE
194 * - QSAFE-CHAR = any character except CTLs and DQUOTE
195 * - SAFE-CHAR = any character except CTLs, DQUOTE. ";", ":", ","
196 */
197char *icalparameter_as_ical_string_r(icalparameter *param)
198{
199 size_t buf_size = 1024;
200 char *buf;
201 char *buf_ptr;
202 const char *kind_string;
203
204 icalerror_check_arg_rz((param != 0), "parameter");
205
206 /* Create new buffer that we can append names, parameters and a
207 * value to, and reallocate as needed.
208 */
209
210 buf = icalmemory_new_buffer(buf_size);
211 buf_ptr = buf;
212
213 if (param->kind == ICAL_X_PARAMETER) {
214 icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalparameter_get_xname(param));
215 } else if (param->kind == ICAL_IANA_PARAMETER) {
216 icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalparameter_get_iana_name(param));
217 } else {
218 kind_string = icalparameter_kind_to_string(param->kind);
219
220 if (param->kind == ICAL_NO_PARAMETER ||
221 param->kind == ICAL_ANY_PARAMETER || kind_string == 0) {
224 return 0;
225 }
226
227 /* Put the parameter name into the string */
228 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
229 }
230
231 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
232
233 if (param->kind == ICAL_GAP_PARAMETER) {
234 char *str = icaldurationtype_as_ical_string_r(param->duration);
235
236 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
238 } else if (param->string != 0) {
239 icalmemory_append_encoded_string(&buf, &buf_ptr, &buf_size, param->string);
240 } else if (param->data != 0) {
241 const char *str = icalparameter_enum_to_string(param->data);
242
243 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
244 } else if (param->values != 0) {
245 size_t i;
246 const char *sep = "";
247
248 for (i = 0; i < param->values->num_elements; i++) {
249 icalmemory_append_string(&buf, &buf_ptr, &buf_size, sep);
250
251 if (param->value_kind == ICAL_TEXT_VALUE) {
252 const char *str = icalstrarray_element_at(param->values, i);
253
255 &buf_size, str);
256 } else {
257 const icalenumarray_element *elem =
258 icalenumarray_element_at(param->values, i);
259 if (elem->xvalue != 0) {
261 &buf_size, elem->xvalue);
262 } else {
263 const char *str = icalparameter_enum_to_string(elem->val);
264
265 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
266 }
267 }
268 sep = ",";
269 }
270 } else {
273 return 0;
274 }
275
276 return buf;
277}
278
279icalparameter_kind icalparameter_isa(const icalparameter *parameter)
280{
281 if (parameter == 0) {
282 return ICAL_NO_PARAMETER;
283 }
284
285 return parameter->kind;
286}
287
288bool icalparameter_isa_parameter(void *parameter)
289{
290 const struct icalparameter_impl *impl = (struct icalparameter_impl *)parameter;
291
292 if (parameter == 0) {
293 return false;
294 }
295
296 return (impl->id == ICAL_STRUCTURE_TYPE_PARAMETER);
297}
298
299void icalparameter_set_xname(icalparameter *param, const char *v)
300{
301 icalerror_check_arg_rv((param != 0), "param");
302 icalerror_check_arg_rv((v != 0), "v");
303
304 icalmemory_free_buffer((void *)param->x_name);
305 param->x_name = icalmemory_strdup(v);
306
307 if (param->x_name == 0) {
308 errno = ENOMEM;
309 }
310}
311
312const char *icalparameter_get_xname(const icalparameter *param)
313{
314 icalerror_check_arg_rz((param != 0), "param");
315
316 return param->x_name;
317}
318
319void icalparameter_set_xvalue(icalparameter *param, const char *v)
320{
321 icalerror_check_arg_rv((param != 0), "param");
322 icalerror_check_arg_rv((v != 0), "v");
323
324 icalmemory_free_buffer((void *)param->string);
325 param->string = icalmemory_strdup(v);
326
327 if (param->string == 0) {
328 errno = ENOMEM;
329 }
330}
331
332const char *icalparameter_get_xvalue(const icalparameter *param)
333{
334 icalerror_check_arg_rz((param != 0), "param");
335
336 return param->string;
337}
338
339void icalparameter_set_iana_value(icalparameter *param, const char *v)
340{
341 icalparameter_set_xvalue(param, v);
342}
343
344const char *icalparameter_get_iana_value(const icalparameter *param)
345{
346 return icalparameter_get_xvalue(param);
347}
348
349void icalparameter_set_iana_name(icalparameter *param, const char *v)
350{
351 icalparameter_set_xname(param, v);
352}
353
354const char *icalparameter_get_iana_name(const icalparameter *param)
355{
356 return icalparameter_get_xname(param);
357}
358
359void icalparameter_set_parent(icalparameter *param, icalproperty *property)
360{
361 icalerror_check_arg_rv((param != 0), "param");
362
363 param->parent = property;
364}
365
366icalproperty *icalparameter_get_parent(const icalparameter *param)
367{
368 icalerror_check_arg_rz((param != 0), "param");
369
370 return param->parent;
371}
372
373bool icalparameter_has_same_name(const icalparameter *param1, const icalparameter *param2)
374{
375 icalparameter_kind kind1;
376 icalparameter_kind kind2;
377 const char *name1;
378 const char *name2;
379
380 icalerror_check_arg_rz((param1 != 0), "param1");
381 icalerror_check_arg_rz((param2 != 0), "param2");
382
383 kind1 = icalparameter_isa(param1);
384 kind2 = icalparameter_isa(param2);
385
386 if (kind1 != kind2) {
387 return false;
388 }
389
390 if (kind1 == ICAL_X_PARAMETER) {
391 name1 = icalparameter_get_xname(param1);
392 name2 = icalparameter_get_xname(param2);
393 if (strcasecmp(name1, name2) != 0) {
394 return false;
395 }
396 } else if (kind1 == ICAL_IANA_PARAMETER) {
397 name1 = icalparameter_get_iana_name(param1);
398 name2 = icalparameter_get_iana_name(param2);
399 if (strcasecmp(name1, name2) != 0) {
400 return false;
401 }
402 }
403 return true;
404}
405
406bool icalparameter_is_multivalued(const icalparameter *param)
407{
408 icalerror_check_arg_rz((param != 0), "param");
409
410 return param->is_multivalued;
411}
412
414{
415 char *in, *out;
416
417 for (in = out = value; *in; in++, out++) {
418 int found_escaped_char = 0;
419
420 if (*in == '^') {
421 switch (*(in + 1)) {
422 case 'n':
423 *out = '\n';
424 found_escaped_char = 1;
425 break;
426 case '^':
427 *out = '^';
428 found_escaped_char = 1;
429 break;
430
431 case '\'':
432 *out = '"';
433 found_escaped_char = 1;
434 break;
435 default:
436 break;
437 }
438 }
439
440 if (found_escaped_char) {
441 ++in;
442 } else {
443 *out = *in;
444 }
445 }
446
447 while (*out) {
448 *out++ = '\0';
449 }
450}
451
452/* Everything below this line is machine generated. Do not edit. */
453/* ALTREP */
char * icaldurationtype_as_ical_string_r(struct icaldurationtype d)
void icalenumarray_free(icalenumarray *array)
Frees this array's memory and all its elements.
icalenumarray * icalenumarray_clone(icalenumarray *array)
Clones the array and all its elements.
const icalenumarray_element * icalenumarray_element_at(icalenumarray *array, size_t position)
Accesses an element stored in the array.
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Definition icalerror.c:90
@ ICAL_NEWFAILED_ERROR
Definition icalerror.h:50
@ ICAL_BADARG_ERROR
Definition icalerror.h:47
@ ICAL_MALFORMEDDATA_ERROR
Definition icalerror.h:59
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition icalmemory.c:355
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
Definition icalmemory.c:242
void icalmemory_append_string(char **buf, char **pos, size_t *buf_size, const char *string)
Appends a string to a buffer.
Definition icalmemory.c:365
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
Definition icalmemory.c:315
void icalmemory_append_encoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
Definition icalmemory.c:478
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Definition icalmemory.c:158
Common memory management routines.
bool icalparameter_isa_parameter(void *parameter)
icalproperty * icalparameter_get_parent(const icalparameter *param)
void icalparameter_free(icalparameter *param)
Frees an icalparameter object.
const char * icalparameter_get_xvalue(const icalparameter *param)
Returns the X-value of param.
icalparameter * icalparameter_new(icalparameter_kind kind)
Creates new icalparameter object.
bool icalparameter_is_multivalued(const icalparameter *param)
void icalparameter_set_xname(icalparameter *param, const char *v)
Sets the X-name of param to v.
char * icalparameter_as_ical_string_r(icalparameter *param)
Converts icalparameter into a string representation according to RFC5445/RFC6868.
icalparameter * icalparameter_new_from_string(const char *str)
Creates new icalparameter object from string.
const char * icalparameter_get_xname(const icalparameter *param)
Returns the X-name of param.
icalparameter_kind icalparameter_isa(const icalparameter *parameter)
icalparameter * icalparameter_clone(const icalparameter *old)
Creates new icalparameter as a clone of the given one.
bool icalparameter_has_same_name(const icalparameter *param1, const icalparameter *param2)
Determines if two parameters have the same name.
void icalparameter_decode_value(char *value)
void icalparameter_set_iana_name(icalparameter *param, const char *v)
Sets the IANA name of param to v.
void icalparameter_set_xvalue(icalparameter *param, const char *v)
Sets the X-value of param to v.
const char * icalparameter_get_iana_value(const icalparameter *param)
Returns the IANA value of param.
void icalparameter_set_parent(icalparameter *param, icalproperty *property)
const char * icalparameter_get_iana_name(const icalparameter *param)
Returns the IANA name of param.
void icalparameter_set_iana_value(icalparameter *param, const char *v)
Sets the IANA value of param to v.
char * icalparameter_as_ical_string(icalparameter *param)
Converts icalparameter into a string representation.
Defines the data structure representing iCalendar parameters.
icalparameter_kind icalparameter_string_to_kind(const char *string)
Returns the icalparameter_kind for a given string.
icalvalue_kind icalparameter_kind_value_kind(const icalparameter_kind kind, int *is_multivalued)
const char * icalparameter_kind_to_string(icalparameter_kind kind)
Returns a string representing the given icalparameter_kind.
icalparameter * icalparameter_new_from_value_string(icalparameter_kind kind, const char *value)
Creates new icalparameter of a given kind with a given value.
const char * icalstrarray_element_at(icalstrarray *array, size_t position)
Accesses a string stored in the array.
icalstrarray * icalstrarray_clone(icalstrarray *array)
Clones the array and all its elements.
void icalstrarray_free(icalstrarray *array)
Frees this array's memory and all its elements.