Libical API Documentation 4.0 UNRELEASED Go to the stable 3.0 documentation
Loading...
Searching...
No Matches
vcardparameter.c
Go to the documentation of this file.
1/*======================================================================
2 FILE: vcardparameter.c
3 CREATOR: Ken Murchison 24 Aug 2022 <murch@fastmailteam.com>
4
5 SPDX-FileCopyrightText: 2022, Fastmail Pty. Ltd. (https://fastmail.com)
6 SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
7 ======================================================================*/
8
13
14#ifdef HAVE_CONFIG_H
15#include <config.h>
16#endif
17
18#include "vcardparameter.h"
19#include "vcardparameterimpl.h"
20#include "icalerror_p.h"
21#include "icalmemory.h"
22
23#include <errno.h>
24#include <stdlib.h>
25
26LIBICAL_VCARD_EXPORT struct vcardparameter_impl *vcardparameter_new_impl(vcardparameter_kind kind)
27{
28 struct vcardparameter_impl *v;
29
30 if ((v = (struct vcardparameter_impl *)icalmemory_new_buffer(sizeof(struct vcardparameter_impl))) == 0) {
32 return 0;
33 }
34
35 memset(v, 0, sizeof(struct vcardparameter_impl));
36
37 strcpy(v->id, "para");
38
39 v->kind = kind;
40 v->value_kind = vcardparameter_kind_value_kind(kind, &v->is_multivalued);
41
42 return v;
43}
44
45vcardparameter *vcardparameter_new(vcardparameter_kind kind)
46{
47 struct vcardparameter_impl *v = vcardparameter_new_impl(kind);
48
49 return (vcardparameter *)v;
50}
51
52void vcardparameter_free(vcardparameter *param)
53{
54 if (!param || param->parent != 0) {
55 return;
56 }
57
58 if (param->string != 0) {
59 icalmemory_free_buffer((void *)param->string);
60 } else if (param->values != 0) {
61 if (param->value_kind == VCARD_TEXT_VALUE) {
62 vcardstrarray_free(param->values);
63 } else {
64 vcardenumarray_free(param->values);
65 }
66 } else if (param->structured != 0) {
67 vcardstructured_unref(param->structured);
68 }
69
70 if (param->x_name != 0) {
71 icalmemory_free_buffer((void *)param->x_name);
72 }
73
74 memset(param, 0, sizeof(vcardparameter));
75
76 param->parent = 0;
77 param->id[0] = 'X';
79}
80
81vcardparameter *vcardparameter_clone(const vcardparameter *old)
82{
83 struct vcardparameter_impl *clone;
84
85 icalerror_check_arg_rz((old != 0), "param");
86
87 clone = vcardparameter_new_impl(old->kind);
88
89 if (clone == 0) {
90 return 0;
91 }
92
93 memcpy(clone, old, sizeof(struct vcardparameter_impl));
94
95 if (old->string != 0) {
96 clone->string = icalmemory_strdup(old->string);
97 if (clone->string == 0) {
98 clone->parent = 0;
100 return 0;
101 }
102 }
103
104 if (old->x_name != 0) {
105 clone->x_name = icalmemory_strdup(old->x_name);
106 if (clone->x_name == 0) {
107 clone->parent = 0;
108 vcardparameter_free(clone);
109 return 0;
110 }
111 }
112
113 if (old->values != 0) {
114 clone->values = old->value_kind == VCARD_TEXT_VALUE ? vcardstrarray_clone(old->values) : vcardenumarray_clone(old->values);
115 if (clone->values == 0) {
116 clone->parent = 0;
117 vcardparameter_free(clone);
118 return 0;
119 }
120 }
121
122 return clone;
123}
124
125vcardparameter *vcardparameter_new_from_string(const char *str)
126{
127 char *eq;
128 char *cpy;
129 vcardparameter_kind kind;
130 vcardparameter *param;
131
132 icalerror_check_arg_rz(str != 0, "str");
133
134 cpy = icalmemory_strdup(str);
135
136 if (cpy == 0) {
138 return 0;
139 }
140
141 eq = strchr(cpy, '=');
142
143 if (eq == 0) {
146 return 0;
147 }
148
149 *eq = '\0';
150
151 eq++;
152
154
155 if (kind == VCARD_NO_PARAMETER) {
158 return 0;
159 }
160
161 param = vcardparameter_new_from_value_string(kind, eq);
162
163 if (kind == VCARD_X_PARAMETER) {
164 vcardparameter_set_xname(param, cpy);
165 } else if (kind == VCARD_IANA_PARAMETER) {
167 }
168
170
171 return param;
172}
173
174char *vcardparameter_as_vcard_string(vcardparameter *param)
175{
176 char *buf;
177
180 return buf;
181}
182
183/*
184 * - param = param-name "=" param-value
185 * - param-name = iana-token / x-token
186 * - param-value = paramtext /quoted-string
187 * - paramtext = *SAFE-CHAR
188 * - quoted-string= DQUOTE *QSAFE-CHAR DQUOTE
189 * - QSAFE-CHAR = any character except CTLs and DQUOTE
190 * - SAFE-CHAR = any character except CTLs, DQUOTE. ";", ":", ","
191 */
192char *vcardparameter_as_vcard_string_r(vcardparameter *param)
193{
194 size_t buf_size = 1024;
195 char *buf;
196 char *buf_ptr;
197
198 icalerror_check_arg_rz((param != 0), "parameter");
199
200 /* Create new buffer that we can append names, parameters and a
201 * value to, and reallocate as needed.
202 */
203
204 buf = icalmemory_new_buffer(buf_size);
205 buf_ptr = buf;
206
207 if (param->kind == VCARD_X_PARAMETER) {
208 icalmemory_append_string(&buf, &buf_ptr,
209 &buf_size, vcardparameter_get_xname(param));
210 } else if (param->kind == VCARD_IANA_PARAMETER) {
211 icalmemory_append_string(&buf, &buf_ptr,
212 &buf_size, vcardparameter_get_iana_name(param));
213 } else {
214 const char *kind_string = vcardparameter_kind_to_string(param->kind);
215
216 if (param->kind == VCARD_NO_PARAMETER ||
217 param->kind == VCARD_ANY_PARAMETER || kind_string == 0) {
220 return 0;
221 }
222
223 /* Put the parameter name into the string */
224 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
225 }
226
227 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
228
229 if (param->string != 0) {
231 &buf_size, param->string);
232 } else if (param->data != 0) {
233 char *intbuf = NULL;
234 const char *str;
235
236 if (param->value_kind == VCARD_INTEGER_VALUE) {
237#define VCARD_INTEGER_LENGTH 21
238 intbuf = icalmemory_tmp_buffer(VCARD_INTEGER_LENGTH);
239 snprintf(intbuf, VCARD_INTEGER_LENGTH - 1, "%d", param->data);
240
241 str = intbuf;
242 } else {
243 str = vcardparameter_enum_to_string(param->data);
244 }
245
246 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
247
248 } else if (param->values != 0) {
249 size_t i;
250 const char *sep = "";
251
252 for (i = 0; i < param->values->num_elements; i++) {
253 icalmemory_append_string(&buf, &buf_ptr, &buf_size, sep);
254
255 if (param->value_kind == VCARD_TEXT_VALUE) {
256 const char *str = vcardstrarray_element_at(param->values, i);
257
259 &buf_size, str);
260 } else {
261 const vcardenumarray_element *elem =
262 vcardenumarray_element_at(param->values, i);
263 if (elem->xvalue != 0) {
265 &buf_size, elem->xvalue);
266 } else {
267 const char *str = vcardparameter_enum_to_string(elem->val);
268
269 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
270 }
271 }
272 sep = ",";
273 }
274 } else if (vcardparameter_is_structured(param)) {
275 char *str = vcardstructured_as_vcard_string_r(param->structured, 1);
276
277 icalmemory_append_encoded_string(&buf, &buf_ptr, &buf_size, str);
279 } else if (vcardtime_is_valid_time(param->date)) {
280 const char *str = vcardtime_as_vcard_string(param->date, 0);
281
282 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
283
284 } else {
287 return 0;
288 }
289
290 return buf;
291}
292
293vcardparameter_kind vcardparameter_isa(const vcardparameter *parameter)
294{
295 if (parameter == 0) {
296 return VCARD_NO_PARAMETER;
297 }
298
299 return parameter->kind;
300}
301
302bool vcardparameter_isa_parameter(void *parameter)
303{
304 const struct vcardparameter_impl *impl = (struct vcardparameter_impl *)parameter;
305
306 if (parameter == 0) {
307 return false;
308 }
309
310 if (strcmp(impl->id, "para") == 0) {
311 return true;
312 } else {
313 return false;
314 }
315}
316
317void vcardparameter_set_xname(vcardparameter *param, const char *v)
318{
319 icalerror_check_arg_rv((param != 0), "param");
320 icalerror_check_arg_rv((v != 0), "v");
321
322 if (param->x_name != 0) {
323 icalmemory_free_buffer((void *)param->x_name);
324 }
325
326 param->x_name = icalmemory_strdup(v);
327
328 if (param->x_name == 0) {
329 errno = ENOMEM;
330 }
331}
332
333const char *vcardparameter_get_xname(const vcardparameter *param)
334{
335 icalerror_check_arg_rz((param != 0), "param");
336
337 return param->x_name;
338}
339
340void vcardparameter_set_xvalue(vcardparameter *param, const char *v)
341{
342 icalerror_check_arg_rv((param != 0), "param");
343 icalerror_check_arg_rv((v != 0), "v");
344
345 if (param->string != 0) {
346 icalmemory_free_buffer((void *)param->string);
347 }
348
349 param->string = icalmemory_strdup(v);
350
351 if (param->string == 0) {
352 errno = ENOMEM;
353 }
354}
355
356const char *vcardparameter_get_xvalue(const vcardparameter *param)
357{
358 icalerror_check_arg_rz((param != 0), "param");
359
360 return param->string;
361}
362
363void vcardparameter_set_iana_value(vcardparameter *param, const char *v)
364{
366}
367
368const char *vcardparameter_get_iana_value(const vcardparameter *param)
369{
370 return vcardparameter_get_xvalue(param);
371}
372
373void vcardparameter_set_iana_name(vcardparameter *param, const char *v)
374{
375 vcardparameter_set_xname(param, v);
376}
377
378const char *vcardparameter_get_iana_name(const vcardparameter *param)
379{
380 return vcardparameter_get_xname(param);
381}
382
383void vcardparameter_set_parent(vcardparameter *param, vcardproperty *property)
384{
385 icalerror_check_arg_rv((param != 0), "param");
386
387 param->parent = property;
388}
389
390vcardproperty *vcardparameter_get_parent(const vcardparameter *param)
391{
392 icalerror_check_arg_rz((param != 0), "param");
393
394 return param->parent;
395}
396
397bool vcardparameter_has_same_name(const vcardparameter *param1, const vcardparameter *param2)
398{
399 vcardparameter_kind kind1;
400 vcardparameter_kind kind2;
401 const char *name1;
402 const char *name2;
403
404 icalerror_check_arg_rz((param1 != 0), "param1");
405 icalerror_check_arg_rz((param2 != 0), "param2");
406
407 kind1 = vcardparameter_isa(param1);
408 kind2 = vcardparameter_isa(param2);
409
410 if (kind1 != kind2) {
411 return false;
412 }
413
414 if (kind1 == VCARD_X_PARAMETER) {
415 name1 = vcardparameter_get_xname(param1);
416 name2 = vcardparameter_get_xname(param2);
417 if (strcasecmp(name1, name2) != 0) {
418 return false;
419 }
420 } else if (kind1 == VCARD_IANA_PARAMETER) {
421 name1 = vcardparameter_get_iana_name(param1);
422 name2 = vcardparameter_get_iana_name(param2);
423 if (strcasecmp(name1, name2) != 0) {
424 return false;
425 }
426 }
427 return true;
428}
429
430bool vcardparameter_is_multivalued(const vcardparameter *param)
431{
432 icalerror_check_arg_rz((param != 0), "param");
433
434 return param->is_multivalued;
435}
436
437bool vcardparameter_is_structured(const vcardparameter *param)
438{
439 icalerror_check_arg_rz((param != 0), "param");
440
441 return (param->value_kind == VCARD_STRUCTURED_VALUE);
442}
443
444/* Everything below this line is machine generated. Do not edit. */
445/* ALTREP */
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
void * icalmemory_tmp_buffer(size_t size)
Creates a new temporary buffer on the ring and returns it.
Definition icalmemory.c:180
Common memory management routines.
vcardparameter * vcardparameter_new_from_string(const char *str)
Creates new vcardparameter object from string.
bool vcardparameter_has_same_name(const vcardparameter *param1, const vcardparameter *param2)
Determines if two parameters have the same name.
char * vcardparameter_as_vcard_string(vcardparameter *param)
Converts vcardparameter into a string representation.
void vcardparameter_set_xname(vcardparameter *param, const char *v)
Sets the X-name of param to v.
const char * vcardparameter_get_iana_value(const vcardparameter *param)
Returns the IANA value of param.
void vcardparameter_free(vcardparameter *param)
Frees an vcardparameter object.
void vcardparameter_set_iana_value(vcardparameter *param, const char *v)
Sets the IANA value of param to v.
const char * vcardparameter_get_iana_name(const vcardparameter *param)
Returns the IANA name of param.
void vcardparameter_set_parent(vcardparameter *param, vcardproperty *property)
bool vcardparameter_isa_parameter(void *parameter)
vcardparameter_kind vcardparameter_isa(const vcardparameter *parameter)
vcardproperty * vcardparameter_get_parent(const vcardparameter *param)
void vcardparameter_set_iana_name(vcardparameter *param, const char *v)
Sets the IANA name of param to v.
vcardparameter * vcardparameter_clone(const vcardparameter *old)
Creates new vcardparameter as a clone of the given one.
void vcardparameter_set_xvalue(vcardparameter *param, const char *v)
Sets the X-value of param to v.
const char * vcardparameter_get_xvalue(const vcardparameter *param)
Returns the X-value of param.
const char * vcardparameter_get_xname(const vcardparameter *param)
Returns the X-name of param.
vcardparameter * vcardparameter_new(vcardparameter_kind kind)
Creates new vcardparameter object.
char * vcardparameter_as_vcard_string_r(vcardparameter *param)
Converts vcardparameter into an string representation according to RFC5445/RFC6868.
Defines the data structure representing vCard parameters.
const char * vcardparameter_kind_to_string(vcardparameter_kind kind)
Returns a string representing the given vcardparameter_kind.
vcardparameter * vcardparameter_new_from_value_string(vcardparameter_kind kind, const char *value)
Creates new vcardparameter of a given kind with a given value.
vcardparameter_kind vcardparameter_string_to_kind(const char *string)
Returns the vcardparameter_kind for a given string.
void vcardstructured_unref(vcardstructuredtype *st)
Decrements the reference count of the vcardstructuredtype.
char * vcardstructured_as_vcard_string_r(const vcardstructuredtype *st, bool is_param)
Formats a vcardstructuredtype as a vCard property or parameter value.
Definition vcardvalue.c:783