Libical API Documentation 4.0 UNRELEASED Go to the stable 3.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 strcpy(v->id, "para");
44
45 v->kind = kind;
46 v->value_kind = icalparameter_kind_value_kind(kind, &v->is_multivalued);
47
48 return v;
49}
51
52icalparameter *icalparameter_new(icalparameter_kind kind)
53{
54 struct icalparameter_impl *v = icalparameter_new_impl(kind);
55
56 return (icalparameter *)v;
57}
58
59void icalparameter_free(icalparameter *param)
60{
61 /* Comment out the following as it always triggers, even when parameter is non-zero
62 icalerror_check_arg_rv((parameter==0),"parameter");*/
63
64 if (param->parent != 0) {
65 return;
66 }
67
68 if (param->string != 0) {
69 icalmemory_free_buffer((void *)param->string);
70 } else if (param->values != 0) {
71 if (param->value_kind == ICAL_TEXT_VALUE) {
72 icalstrarray_free(param->values);
73 } else {
74 icalenumarray_free(param->values);
75 }
76 }
77
78 icalmemory_free_buffer((void *)param->x_name);
79
80 memset(param, 0, sizeof(icalparameter));
81
82 param->parent = 0;
83 param->id[0] = 'X';
85}
86
87icalparameter *icalparameter_clone(const icalparameter *old)
88{
89 struct icalparameter_impl *clone;
90
91 icalerror_check_arg_rz((old != 0), "param");
92
93 clone = icalparameter_new_impl(old->kind);
94
95 if (clone == 0) {
96 return 0;
97 }
98
99 memcpy(clone, old, sizeof(struct icalparameter_impl));
100
101 if (old->string != 0) {
102 clone->string = icalmemory_strdup(old->string);
103 if (clone->string == 0) {
104 clone->parent = 0;
105 icalparameter_free(clone);
106 return 0;
107 }
108 }
109
110 if (old->x_name != 0) {
111 clone->x_name = icalmemory_strdup(old->x_name);
112 if (clone->x_name == 0) {
113 clone->parent = 0;
114 icalparameter_free(clone);
115 return 0;
116 }
117 }
118
119 if (old->values != 0) {
120 clone->values = old->value_kind == ICAL_TEXT_VALUE ? icalstrarray_clone(old->values) : icalenumarray_clone(old->values);
121 if (clone->values == 0) {
122 clone->parent = 0;
123 icalparameter_free(clone);
124 return 0;
125 }
126 }
127
128 return clone;
129}
130
131icalparameter *icalparameter_new_from_string(const char *str)
132{
133 char *eq;
134 char *cpy;
135 icalparameter_kind kind;
136 icalparameter *param;
137
138 icalerror_check_arg_rz(str != 0, "str");
139
140 cpy = icalmemory_strdup(str);
141
142 if (cpy == 0) {
144 return 0;
145 }
146
147 eq = strchr(cpy, '=');
148
149 if (eq == 0) {
152 return 0;
153 }
154
155 *eq = '\0';
156
157 eq++;
158
160
161 if (kind == ICAL_NO_PARAMETER) {
164 return 0;
165 }
166
167 param = icalparameter_new_from_value_string(kind, eq);
168
169 if (kind == ICAL_X_PARAMETER) {
170 icalparameter_set_xname(param, cpy);
171 } else if (kind == ICAL_IANA_PARAMETER) {
172 icalparameter_set_iana_name(param, cpy);
173 }
174
176
177 return param;
178}
179
180char *icalparameter_as_ical_string(icalparameter *param)
181{
182 char *buf;
183
186 return buf;
187}
188
189/*
190 * - param = param-name "=" param-value
191 * - param-name = iana-token / x-token
192 * - param-value = paramtext /quoted-string
193 * - paramtext = *SAFE-CHAR
194 * - quoted-string= DQUOTE *QSAFE-CHAR DQUOTE
195 * - QSAFE-CHAR = any character except CTLs and DQUOTE
196 * - SAFE-CHAR = any character except CTLs, DQUOTE. ";", ":", ","
197 */
198char *icalparameter_as_ical_string_r(icalparameter *param)
199{
200 size_t buf_size = 1024;
201 char *buf;
202 char *buf_ptr;
203 const char *kind_string;
204
205 icalerror_check_arg_rz((param != 0), "parameter");
206
207 /* Create new buffer that we can append names, parameters and a
208 * value to, and reallocate as needed.
209 */
210
211 buf = icalmemory_new_buffer(buf_size);
212 buf_ptr = buf;
213
214 if (param->kind == ICAL_X_PARAMETER) {
215 icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalparameter_get_xname(param));
216 } else if (param->kind == ICAL_IANA_PARAMETER) {
217 icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalparameter_get_iana_name(param));
218 } else {
219 kind_string = icalparameter_kind_to_string(param->kind);
220
221 if (param->kind == ICAL_NO_PARAMETER ||
222 param->kind == ICAL_ANY_PARAMETER || kind_string == 0) {
225 return 0;
226 }
227
228 /* Put the parameter name into the string */
229 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
230 }
231
232 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
233
234 if (param->kind == ICAL_GAP_PARAMETER) {
235 char *str = icaldurationtype_as_ical_string_r(param->duration);
236
237 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
239 } else if (param->string != 0) {
240 icalmemory_append_encoded_string(&buf, &buf_ptr, &buf_size, param->string);
241 } else if (param->data != 0) {
242 const char *str = icalparameter_enum_to_string(param->data);
243
244 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
245 } else if (param->values != 0) {
246 size_t i;
247 const char *sep = "";
248
249 for (i = 0; i < param->values->num_elements; i++) {
250 icalmemory_append_string(&buf, &buf_ptr, &buf_size, sep);
251
252 if (param->value_kind == ICAL_TEXT_VALUE) {
253 const char *str = icalstrarray_element_at(param->values, i);
254
256 &buf_size, str);
257 } else {
258 const icalenumarray_element *elem =
259 icalenumarray_element_at(param->values, i);
260 if (elem->xvalue != 0) {
262 &buf_size, elem->xvalue);
263 } else {
264 const char *str = icalparameter_enum_to_string(elem->val);
265
266 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
267 }
268 }
269 sep = ",";
270 }
271 } else {
274 return 0;
275 }
276
277 return buf;
278}
279
280icalparameter_kind icalparameter_isa(const icalparameter *parameter)
281{
282 if (parameter == 0) {
283 return ICAL_NO_PARAMETER;
284 }
285
286 return parameter->kind;
287}
288
289bool icalparameter_isa_parameter(void *parameter)
290{
291 const struct icalparameter_impl *impl = (struct icalparameter_impl *)parameter;
292
293 if (parameter == 0) {
294 return false;
295 }
296
297 if (strcmp(impl->id, "para") == 0) {
298 return true;
299 } else {
300 return false;
301 }
302}
303
304void icalparameter_set_xname(icalparameter *param, const char *v)
305{
306 icalerror_check_arg_rv((param != 0), "param");
307 icalerror_check_arg_rv((v != 0), "v");
308
309 icalmemory_free_buffer((void *)param->x_name);
310 param->x_name = icalmemory_strdup(v);
311
312 if (param->x_name == 0) {
313 errno = ENOMEM;
314 }
315}
316
317const char *icalparameter_get_xname(const icalparameter *param)
318{
319 icalerror_check_arg_rz((param != 0), "param");
320
321 return param->x_name;
322}
323
324void icalparameter_set_xvalue(icalparameter *param, const char *v)
325{
326 icalerror_check_arg_rv((param != 0), "param");
327 icalerror_check_arg_rv((v != 0), "v");
328
329 icalmemory_free_buffer((void *)param->string);
330 param->string = icalmemory_strdup(v);
331
332 if (param->string == 0) {
333 errno = ENOMEM;
334 }
335}
336
337const char *icalparameter_get_xvalue(const icalparameter *param)
338{
339 icalerror_check_arg_rz((param != 0), "param");
340
341 return param->string;
342}
343
344void icalparameter_set_iana_value(icalparameter *param, const char *v)
345{
346 icalparameter_set_xvalue(param, v);
347}
348
349const char *icalparameter_get_iana_value(const icalparameter *param)
350{
351 return icalparameter_get_xvalue(param);
352}
353
354void icalparameter_set_iana_name(icalparameter *param, const char *v)
355{
356 icalparameter_set_xname(param, v);
357}
358
359const char *icalparameter_get_iana_name(const icalparameter *param)
360{
361 return icalparameter_get_xname(param);
362}
363
364void icalparameter_set_parent(icalparameter *param, icalproperty *property)
365{
366 icalerror_check_arg_rv((param != 0), "param");
367
368 param->parent = property;
369}
370
371icalproperty *icalparameter_get_parent(const icalparameter *param)
372{
373 icalerror_check_arg_rz((param != 0), "param");
374
375 return param->parent;
376}
377
378bool icalparameter_has_same_name(const icalparameter *param1, const icalparameter *param2)
379{
380 icalparameter_kind kind1;
381 icalparameter_kind kind2;
382 const char *name1;
383 const char *name2;
384
385 icalerror_check_arg_rz((param1 != 0), "param1");
386 icalerror_check_arg_rz((param2 != 0), "param2");
387
388 kind1 = icalparameter_isa(param1);
389 kind2 = icalparameter_isa(param2);
390
391 if (kind1 != kind2) {
392 return false;
393 }
394
395 if (kind1 == ICAL_X_PARAMETER) {
396 name1 = icalparameter_get_xname(param1);
397 name2 = icalparameter_get_xname(param2);
398 if (strcasecmp(name1, name2) != 0) {
399 return false;
400 }
401 } else if (kind1 == ICAL_IANA_PARAMETER) {
402 name1 = icalparameter_get_iana_name(param1);
403 name2 = icalparameter_get_iana_name(param2);
404 if (strcasecmp(name1, name2) != 0) {
405 return false;
406 }
407 }
408 return true;
409}
410
411bool icalparameter_is_multivalued(const icalparameter *param)
412{
413 icalerror_check_arg_rz((param != 0), "param");
414
415 return param->is_multivalued;
416}
417
419{
420 char *in, *out;
421
422 for (in = out = value; *in; in++, out++) {
423 int found_escaped_char = 0;
424
425 if (*in == '^') {
426 switch (*(in + 1)) {
427 case 'n':
428 *out = '\n';
429 found_escaped_char = 1;
430 break;
431 case '^':
432 *out = '^';
433 found_escaped_char = 1;
434 break;
435
436 case '\'':
437 *out = '"';
438 found_escaped_char = 1;
439 break;
440 default:
441 break;
442 }
443 }
444
445 if (found_escaped_char) {
446 ++in;
447 } else {
448 *out = *in;
449 }
450 }
451
452 while (*out) {
453 *out++ = '\0';
454 }
455}
456
457/* Everything below this line is machine generated. Do not edit. */
458/* 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:56
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition icalmemory.c:353
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
Definition icalmemory.c:240
void icalmemory_append_string(char **buf, char **pos, size_t *buf_size, const char *string)
Appends a string to a buffer.
Definition icalmemory.c:363
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
Definition icalmemory.c:313
void icalmemory_append_encoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
Definition icalmemory.c:476
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Definition icalmemory.c:156
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.