21#include "vcardproperty_p.h"
24#include "icalerror_p.h"
27#include "icaltypes_p.h"
34struct vcardcomponent_impl {
37 vcardproperty *versionp;
38 icalpvl_list properties;
39 icalpvl_elem property_iterator;
40 icalpvl_list components;
41 icalpvl_elem component_iterator;
42 struct vcardcomponent_impl *parent;
45static void vcardcomponent_add_children(vcardcomponent *impl, va_list args)
49 while ((vp = va_arg(args,
void *)) != 0) {
69 memset(comp, 0,
sizeof(vcardcomponent));
71 comp->id = ICAL_STRUCTURE_TYPE_COMPONENT;
73 comp->properties = icalpvl_newlist();
74 comp->components = icalpvl_newlist();
81 return vcardcomponent_new_impl(
kind);
85#pragma clang diagnostic push
86#pragma clang diagnostic ignored "-Wvarargs"
92 vcardcomponent *impl = vcardcomponent_new_impl(
kind);
99 vcardcomponent_add_children(impl, args);
104#if defined(__clang__)
105#pragma clang diagnostic pop
115 vcardcomponent *clone;
116 const vcardproperty *p;
119 icalerror_check_arg_rz((old != 0),
"component");
121 clone = vcardcomponent_new_impl(old->kind);
127 for (itr = icalpvl_head(old->properties); itr != 0; itr = icalpvl_next(itr)) {
128 p = (vcardproperty *)icalpvl_data(itr);
137 vcardcomponent *comp;
139 icalerror_check_arg_rv((c != 0),
"component");
141 if (c->parent != 0) {
145 if (c->properties != 0) {
147 while ((prop = icalpvl_pop(c->properties)) != 0) {
151 icalpvl_free(c->properties);
154 while ((comp = icalpvl_data(icalpvl_head(c->components))) != 0) {
159 icalpvl_free(c->components);
163 c->property_iterator = 0;
165 c->component_iterator = 0;
166 c->id = ICAL_STRUCTURE_TYPE_COMPONENT_EMPTY;
186 size_t buf_size = 1024;
191 const char newline[] =
"\r\n";
197 const char *kind_string = NULL;
199 icalerror_check_arg_rz((comp != 0),
"component");
201 "component kind is VCARD_NO_COMPONENT");
205 icalerror_check_arg_rz((kind_string != 0),
"Unknown kind of component");
219 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
220 p = (vcardproperty *)icalpvl_data(itr);
222 icalerror_assert((p != 0),
"Got a null property");
230 for (itr = icalpvl_head(comp->components); itr != 0; itr = icalpvl_next(itr)) {
231 c = (vcardcomponent *)icalpvl_data(itr);
234 if (tmp_buf != NULL) {
252 if ((component->id == ICAL_STRUCTURE_TYPE_COMPONENT) && (component->kind !=
VCARD_NO_COMPONENT)) {
263 return component->kind;
268 const vcardcomponent *impl = component;
270 icalerror_check_arg_rz((component != 0),
"component");
272 return (impl->id == ICAL_STRUCTURE_TYPE_COMPONENT);
277 icalerror_check_arg_rv((comp != 0),
"component");
278 icalerror_check_arg_rv((property != 0),
"property");
281 "The property has already been added to a vcard. "
282 "Remove the property with vcardcomponent_remove_property "
283 "before calling vcardcomponent_add_property");
287 icalpvl_push(comp->properties, property);
290 comp->versionp = property;
296 icalpvl_elem itr, next_itr;
298 icalerror_check_arg_rv((comp != 0),
"component");
299 icalerror_check_arg_rv((property != 0),
"property");
309 for (itr = icalpvl_head(comp->properties); itr != 0; itr = next_itr) {
310 next_itr = icalpvl_next(itr);
312 if (icalpvl_data(itr) == (
void *)property) {
313 if (comp->property_iterator == itr) {
314 comp->property_iterator = icalpvl_next(itr);
317 (void)icalpvl_remove(comp->properties, itr);
331 icalerror_check_arg_rz((comp != 0),
"component");
337 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
338 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
369 icalerror_check_arg_rz((comp != 0),
"card");
371 if (comp->property_iterator == 0) {
375 return (vcardproperty *)icalpvl_data(comp->property_iterator);
381 icalerror_check_arg_rz((c != 0),
"card");
383 for (c->property_iterator = icalpvl_head(c->properties);
384 c->property_iterator != 0;
385 c->property_iterator = icalpvl_next(c->property_iterator)) {
386 vcardproperty *p = (vcardproperty *)icalpvl_data(c->property_iterator);
398 icalerror_check_arg_rz((c != 0),
"card");
400 if (c->property_iterator == 0) {
404 for (c->property_iterator = icalpvl_next(c->property_iterator);
405 c->property_iterator != 0;
406 c->property_iterator = icalpvl_next(c->property_iterator)) {
407 vcardproperty *p = (vcardproperty *)icalpvl_data(c->property_iterator);
422 icalerror_check_arg_rv((parent != 0),
"parent");
423 icalerror_check_arg_rv((child != 0),
"child");
425 if (child->parent != 0) {
429 child->parent = parent;
431 icalpvl_push(parent->components, child);
435 vcardcomponent *child)
437 icalpvl_elem itr, next_itr;
439 icalerror_check_arg_rv((parent != 0),
"parent");
440 icalerror_check_arg_rv((child != 0),
"child");
442 for (itr = icalpvl_head(parent->components); itr != 0; itr = next_itr) {
443 next_itr = icalpvl_next(itr);
445 if (icalpvl_data(itr) == (
void *)child) {
446 if (parent->component_iterator == itr) {
450 parent->component_iterator = icalpvl_next(parent->component_iterator);
452 (void)icalpvl_remove(parent->components, itr);
465 icalerror_check_arg_rz((component != 0),
"component");
467 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
479 icalerror_check_arg_rz((component != 0),
"component");
481 if (component->component_iterator == 0) {
485 return (vcardcomponent *)icalpvl_data(component->component_iterator);
491 icalerror_check_arg_rz((c != 0),
"component");
493 for (c->component_iterator = icalpvl_head(c->components);
494 c->component_iterator != 0;
495 c->component_iterator = icalpvl_next(c->component_iterator)) {
496 vcardcomponent *p = (vcardcomponent *)icalpvl_data(c->component_iterator);
509 icalerror_check_arg_rz((c != 0),
"component");
511 if (c->component_iterator == 0) {
515 for (c->component_iterator = icalpvl_next(c->component_iterator);
516 c->component_iterator != 0;
517 c->component_iterator = icalpvl_next(c->component_iterator)) {
518 vcardcomponent *p = (vcardcomponent *)icalpvl_data(c->component_iterator);
530 icalerror_check_arg_rz(comp != 0,
"comp");
539 icalerror_check_arg_rz((comp != 0),
"card");
541 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
542 const vcardproperty *p = (vcardproperty *)icalpvl_data(itr);
553 icalpvl_elem itr, next_itr;
555 icalerror_check_arg_rv((comp != 0),
"comp");
557 for (itr = icalpvl_head(comp->properties); itr != 0; itr = next_itr) {
558 vcardproperty *p = (vcardproperty *)icalpvl_data(itr);
559 next_itr = icalpvl_next(itr);
568struct vcardcomponent_kind_map {
573static const struct vcardcomponent_kind_map component_map[] = {
586 if (component_map[i].
kind ==
kind) {
599 if (component_map[i].
kind ==
kind) {
600 return component_map[i].name;
616 if (strncasecmp(
string, component_map[i].name, strlen(component_map[i].name)) == 0) {
617 return component_map[i].kind;
624static int strcmpsafe(
const char *a,
const char *b)
626 return strcmp((a == NULL ?
"" : a),
627 (b == NULL ?
"" : b));
630static int prop_compare(
void *a,
void *b)
632 const vcardproperty *p1 = (vcardproperty *)a;
633 const vcardproperty *p2 = (vcardproperty *)b;
636 int r = (int)(k1 - k2);
660 vcardcomponent *c1, vcardcomponent *c2)
677static int comp_compare(
void *a,
void *b)
679 vcardcomponent *c1 = (vcardcomponent *)a;
680 vcardcomponent *c2 = (vcardcomponent *)b;
683 int r = (int)(k1 - k2);
697 r = prop_kind_compare(prop_kinds[i], c1, c2);
715 icalpvl_list sorted_props = icalpvl_newlist();
716 icalpvl_list sorted_comps = icalpvl_newlist();
721 while ((prop = icalpvl_pop(comp->properties)) != 0) {
722 int nparams, remove = 0;
746 icalpvl_insert_ordered(sorted_props, prop_compare, prop);
750 icalpvl_free(comp->properties);
751 comp->properties = sorted_props;
754 while ((sub = icalpvl_pop(comp->components)) != 0) {
756 icalpvl_insert_ordered(sorted_comps, comp_compare, sub);
759 icalpvl_free(comp->components);
760 comp->components = sorted_comps;
763#define UUID_PREFIX "urn:uuid:"
764#define UUID_PREFIX_LEN 9
766static void comp_to_v4(vcardcomponent *impl)
768 icalpvl_elem itr, next;
770 for (itr = icalpvl_head(impl->properties); itr != 0; itr = next) {
771 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
778 next = icalpvl_next(itr);
824 if (name && !strcasecmp(name,
"X-APPLE-OMIT-YEAR")) {
841 int n = snprintf(NULL, 0,
"geo:%s,%s",
844 size_t size = (size_t)n + 1;
846 snprintf(buf, size,
"geo:%s,%s",
862 char *mediatype = NULL;
888 size_t size = strlen(mediatype);
889 char *buf_ptr = mediatype + size;
892 for (c = mediatype; *c; c++) {
893 *c = (char)tolower((
int)*c);
907 if (data && !strchr(data,
':')) {
909 size_t size = strlen(data) + 7;
936 }
else if (mediatype) {
948 if (!strncasecmp(data,
"urn:uuid:", 9) ||
949 !strncasecmp(data,
"mailto:", 7) ||
950 !strncasecmp(data,
"http://", 7) ||
951 !strncasecmp(data,
"https://", 8) ||
952 !strncasecmp(data,
"ldap://", 7) ||
953 !strncasecmp(data,
"ldaps://", 8)) {
968 if (!strncasecmp(xname,
"X-ADDRESSBOOKSERVER-", 20)) {
972 char *buf = NULL, *buf_ptr;
982 buf_size = strlen(valstr) + 1;
1014 vcardproperty *prop;
1018static void comp_to_v3(vcardcomponent *impl)
1023 icalpvl_elem itr, next;
1025 for (itr = icalpvl_head(impl->properties); itr != 0; itr = next) {
1026 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
1032 char *subtype = NULL;
1033 const char *mediatype, *uri, *xname = NULL;
1035 next = icalpvl_next(itr);
1042 struct pref_prop *pp = pref_props[pkind];
1048 pref_props[pkind] = pp;
1049 }
else if (level < pp->level) {
1060 subtype = (
char *)strchr(mediatype,
'/');
1066 for (c = subtype; *c; c++) {
1067 *c = (char)toupper((
int)*c);
1091 if (dt.
year == -1) {
1095 "X-APPLE-OMIT-YEAR",
1098 if (dt.
hour != -1) {
1115 if (geo.
uri && !strncmp(geo.
uri,
"geo:", 4)) {
1119 const char *lat = buf + 4;
1120 char *lon = strchr(buf + 4,
',');
1145 if (uri && !strncmp(
"data:", uri, 5)) {
1147 char *base64, *data = NULL;
1150 mediatype = buf + 5;
1151 base64 = (
char *)strstr(mediatype,
";base64,");
1160 data = (
char *)strchr(mediatype,
',');
1166 subtype = (
char *)strchr(mediatype,
'/');
1171 for (c = ++subtype; *c; c++) {
1172 *c = (char)toupper((
int)*c);
1189 xname =
"X-ADDRESSBOOKSERVER-KIND";
1198 size_t buf_size = strlen(
UUID_PREFIX) + strlen(xval) + 1;
1204 xname =
"X-ADDRESSBOOKSERVER-MEMBER";
1219 if (uri && !strncmp(uri,
"tel:", 4)) {
1250 struct pref_prop *pp = pref_props[pkind];
1268 icalerror_check_arg_rv((impl != 0),
"component");
1270 "component kind is VCARD_NO_COMPONENT");
1280 for (itr = icalpvl_head(impl->components); itr != 0; itr = icalpvl_next(itr)) {
1281 vcardcomponent *c = (vcardcomponent *)icalpvl_data(itr);
1292 if (comp->versionp == 0) {
1296 if (comp->versionp == 0) {
1306 vcardproperty *prop;
1308 icalerror_check_arg_rz(comp != 0,
"comp");
1321 vcardproperty *prop;
1323 icalerror_check_arg_rz(comp != 0,
"comp");
enum icalrequeststatus kind
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Error handling for libical.
void icalmemory_free_buffer(void *buf)
Releases a buffer.
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
void icalmemory_append_decoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
void icalmemory_append_string(char **buf, char **pos, size_t *buf_size, const char *string)
Appends a string to a buffer.
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
void icalmemory_append_encoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
void icalmemory_append_char(char **buf, char **pos, size_t *buf_size, char ch)
Appends a character to a buffer.
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Common memory management routines.
struct vcardgeotype::@162201204342263205067330224176321027032342016274 coords
void vcardcomponent_strip_errors(vcardcomponent *comp)
Removes all X-LIC-ERROR properties.
void vcardcomponent_remove_property(vcardcomponent *comp, vcardproperty *property)
void vcardcomponent_add_property(vcardcomponent *comp, vcardproperty *property)
void vcardcomponent_remove_component(vcardcomponent *parent, vcardcomponent *child)
bool vcardcomponent_is_valid(const vcardcomponent *component)
vcardcomponent_kind vcardcomponent_string_to_kind(const char *string)
enum vcardproperty_version vcardcomponent_get_version(vcardcomponent *comp)
vcardproperty * vcardcomponent_get_next_property(vcardcomponent *c, vcardproperty_kind kind)
bool vcardcomponent_kind_is_valid(const vcardcomponent_kind kind)
vcardcomponent * vcardcomponent_get_first_component(vcardcomponent *c, vcardcomponent_kind kind)
vcardcomponent_kind vcardcomponent_isa(const vcardcomponent *component)
int vcardcomponent_check_restrictions(vcardcomponent *comp)
void vcardcomponent_add_component(vcardcomponent *parent, vcardcomponent *child)
char * vcardcomponent_as_vcard_string_r(vcardcomponent *comp)
vcardcomponent * vcardcomponent_clone(const vcardcomponent *old)
Deeply clones an vcard. Returns a pointer to the memory for the newly cloned vcard.
const char * vcardcomponent_kind_to_string(vcardcomponent_kind kind)
vcardproperty ** vcardcomponent_get_properties(vcardcomponent *comp, vcardproperty_kind kind)
int vcardcomponent_count_errors(vcardcomponent *comp)
Returns the number of errors encountered parsing the data.
bool vcardcomponent_isa_component(const void *component)
const char * vcardcomponent_get_uid(vcardcomponent *comp)
int vcardcomponent_count_properties(vcardcomponent *comp, vcardproperty_kind kind, int ignore_alts)
void vcardcomponent_transform(vcardcomponent *impl, vcardproperty_version version)
void vcardcomponent_free(vcardcomponent *c)
char * vcardcomponent_as_vcard_string(vcardcomponent *comp)
vcardcomponent * vcardcomponent_vanew(vcardcomponent_kind kind,...)
Constructor.
vcardcomponent * vcardcomponent_get_current_component(vcardcomponent *component)
const char * vcardcomponent_get_fn(vcardcomponent *comp)
vcardcomponent * vcardcomponent_new(vcardcomponent_kind kind)
Constructor.
vcardcomponent * vcardcomponent_new_from_string(const char *str)
Constructor.
void vcardcomponent_normalize(vcardcomponent *comp)
Normalizes (reorders and sorts the properties) the specified vcard comp.
vcardcomponent * vcardcomponent_get_next_component(vcardcomponent *c, vcardcomponent_kind kind)
int vcardcomponent_count_components(vcardcomponent *component, vcardcomponent_kind kind)
vcardproperty * vcardcomponent_get_current_property(vcardcomponent *comp)
vcardproperty * vcardcomponent_get_first_property(vcardcomponent *c, vcardproperty_kind kind)
Defines the data structure representing vCard components.
vcardcomponent * vcardproperty_get_parent(const vcardproperty *property)
Returns the parent vcard for the specified property.
void vcardproperty_set_parent(vcardproperty *property, vcardcomponent *comp)
Sets the parent vcard for the specified vcardproperty property.
vcardparameter * vcardparameter_new_mediatype(const char *v)
const char * vcardparameter_get_mediatype(const vcardparameter *value)
struct vcardparameter_impl vcardparameter
vcardenumarray * vcardparameter_get_type(const vcardparameter *value)
int vcardparameter_get_pref(const vcardparameter *value)
vcardparameter * vcardparameter_new_encoding(vcardparameter_encoding v)
const char * vcardparameter_get_altid(const vcardparameter *value)
vcardparameter * vcardparameter_new_pref(int v)
@ VCARD_ENCODING_PARAMETER
@ VCARD_MEDIATYPE_PARAMETER
void vcardproperty_set_version(vcardproperty *prop, enum vcardproperty_version v)
const char * vcardproperty_get_fn(const vcardproperty *prop)
enum vcardproperty_version vcardproperty_get_version(const vcardproperty *prop)
enum vcardproperty_kindenum vcardproperty_get_kind(const vcardproperty *prop)
vcardtimetype vcardproperty_get_bday(const vcardproperty *prop)
@ VCARD_XLICERROR_PROPERTY
@ VCARD_DEATHDATE_PROPERTY
@ VCARD_NICKNAME_PROPERTY
@ VCARD_ANNIVERSARY_PROPERTY
vcardproperty * vcardproperty_new_x(const char *v)
const char * vcardproperty_get_uid(const vcardproperty *prop)
void vcardproperty_set_bday(vcardproperty *prop, vcardtimetype v)
struct vcardvalue_impl vcardvalue
void vcardvalue_set_uri(vcardvalue *value, const char *v)
void vcardvalue_set_geo(vcardvalue *value, vcardgeotype v)
const char * vcardvalue_get_uri(const vcardvalue *value)
vcardgeotype vcardvalue_get_geo(const vcardvalue *value)
void vcardvalue_set_text(vcardvalue *value, const char *v)
const char * vcardvalue_get_text(const vcardvalue *value)
icalenumarray_element vcardenumarray_element
#define vcardenumarray_element_at(array, position)
#define vcardenumarray_size(array)
#define vcardenumarray_remove_element_at(array, position)
icalenumarray vcardenumarray
#define vcardenumarray_find(array, needle)
const char * vcardparameter_get_xname(const vcardparameter *param)
Returns the X-name of param.
vcardcomponent * vcardparser_parse_string(const char *str)
Line-oriented parsing vCard format.
vcardproperty * vcardproperty_new(vcardproperty_kind kind)
void vcardproperty_set_parameter_from_string(vcardproperty *prop, const char *name, const char *value)
void vcardproperty_set_x_name(vcardproperty *prop, const char *name)
void vcardproperty_free(vcardproperty *p)
void vcardproperty_set_value_from_string(vcardproperty *prop, const char *str, const char *type)
void vcardproperty_normalize(vcardproperty *prop)
const char * vcardproperty_get_value_as_string(const vcardproperty *prop)
void vcardproperty_remove_parameter_by_ref(vcardproperty *prop, vcardparameter *parameter)
Removes the specified parameter reference from the property.
const char * vcardproperty_get_x_name(const vcardproperty *prop)
int vcardproperty_count_parameters(const vcardproperty *prop)
bool vcardproperty_isa_property(void *property)
vcardparameter * vcardproperty_get_first_parameter(vcardproperty *p, vcardparameter_kind kind)
vcardvalue * vcardproperty_get_value(const vcardproperty *prop)
void vcardproperty_add_type_parameter(vcardproperty *prop, vcardenumarray_element *type)
vcardproperty * vcardproperty_clone(const vcardproperty *old)
Deeply clones an vcardproperty.
void vcardproperty_remove_parameter_by_kind(vcardproperty *prop, vcardparameter_kind kind)
Removes all parameters with the specified kind.
void vcardproperty_add_parameter(vcardproperty *p, vcardparameter *parameter)
char * vcardproperty_as_vcard_string_r(vcardproperty *prop)
vcardproperty_kind vcardproperty_isa(const vcardproperty *p)
vcardparameter * vcardproperty_get_next_parameter(vcardproperty *p, vcardparameter_kind kind)
vcardproperty_kind vcardproperty_string_to_kind(const char *string)
Functions to check if a vcardcomponent meets the restrictions imposed by the standard.
bool vcardrestriction_check(vcardcomponent *comp)
Checks if a given VCARD meets all the restrictions imposed by the standard.
#define vcardstrarray_find(array, needle)
#define vcardstrarray_size(array)
#define vcardstrarray_new(increment_size)
#define vcardstrarray_append(array, elem)
#define vcardstrarray_free(array)
icalstrarray vcardstrarray
const char * vcardvalue_as_vcard_string(const vcardvalue *value)
vcardvalue_kind vcardvalue_isa(const vcardvalue *value)
Defines the data structure representing vCard values.