21#include "vcardproperty_p.h"
24#include "icalerror_p.h"
33struct vcardcomponent_impl {
35 vcardcomponent_kind kind;
36 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) {
50 icalassert(vcardproperty_isa_property(vp) != 0);
52 vcardcomponent_add_property(impl, (vcardproperty *)vp);
56static vcardcomponent *vcardcomponent_new_impl(vcardcomponent_kind kind)
60 if (!vcardcomponent_kind_is_valid(kind)) {
69 memset(comp, 0,
sizeof(vcardcomponent));
71 strcpy(comp->id,
"comp");
74 comp->properties = icalpvl_newlist();
75 comp->components = icalpvl_newlist();
82 return vcardcomponent_new_impl(kind);
86#pragma clang diagnostic push
87#pragma clang diagnostic ignored "-Wvarargs"
93 vcardcomponent *impl = vcardcomponent_new_impl(kind);
100 vcardcomponent_add_children(impl, args);
105#if defined(__clang__)
106#pragma clang diagnostic pop
111 return vcardparser_parse_string(str);
116 vcardcomponent *clone;
117 const vcardproperty *p;
120 icalerror_check_arg_rz((old != 0),
"component");
122 clone = vcardcomponent_new_impl(old->kind);
128 for (itr = icalpvl_head(old->properties); itr != 0; itr = icalpvl_next(itr)) {
129 p = (vcardproperty *)icalpvl_data(itr);
136void vcardcomponent_free(vcardcomponent *c)
138 vcardcomponent *comp;
140 icalerror_check_arg_rv((c != 0),
"component");
142 if (c->parent != 0) {
146 if (c->properties != 0) {
148 while ((prop = icalpvl_pop(c->properties)) != 0) {
150 vcardproperty_free(prop);
152 icalpvl_free(c->properties);
155 while ((comp = icalpvl_data(icalpvl_head(c->components))) != 0) {
156 vcardcomponent_remove_component(c, comp);
157 vcardcomponent_free(comp);
160 icalpvl_free(c->components);
162 if (c->x_name != 0) {
166 c->kind = VCARD_NO_COMPONENT;
168 c->property_iterator = 0;
170 c->component_iterator = 0;
177char *vcardcomponent_as_vcard_string(vcardcomponent *comp)
181 buf = vcardcomponent_as_vcard_string_r(comp);
188char *vcardcomponent_as_vcard_string_r(vcardcomponent *comp)
192 size_t buf_size = 1024;
197 const char newline[] =
"\r\n";
201 vcardcomponent_kind kind = vcardcomponent_isa(comp);
203 const char *kind_string = NULL;
205 icalerror_check_arg_rz((comp != 0),
"component");
206 icalerror_check_arg_rz((kind != VCARD_NO_COMPONENT),
207 "component kind is VCARD_NO_COMPONENT");
209 if (kind != VCARD_X_COMPONENT) {
210 kind_string = vcardcomponent_kind_to_string(kind);
212 kind_string = comp->x_name;
215 icalerror_check_arg_rz((kind_string != 0),
"Unknown kind of component");
224 if (kind != VCARD_XROOT_COMPONENT) {
229 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
230 p = (vcardproperty *)icalpvl_data(itr);
232 icalerror_assert((p != 0),
"Got a null property");
233 tmp_buf = vcardproperty_as_vcard_string_r(p);
240 for (itr = icalpvl_head(comp->components); itr != 0; itr = icalpvl_next(itr)) {
241 c = (vcardcomponent *)icalpvl_data(itr);
243 tmp_buf = vcardcomponent_as_vcard_string_r(c);
244 if (tmp_buf != NULL) {
250 if (kind != VCARD_XROOT_COMPONENT) {
259bool vcardcomponent_is_valid(
const vcardcomponent *component)
262 if ((strcmp(component->id,
"comp") == 0) && (component->kind != VCARD_NO_COMPONENT)) {
269vcardcomponent_kind vcardcomponent_isa(
const vcardcomponent *component)
271 icalerror_check_arg_rx((component != 0),
"component", VCARD_NO_COMPONENT);
273 return component->kind;
276bool vcardcomponent_isa_component(
const void *component)
278 const vcardcomponent *impl = component;
280 icalerror_check_arg_rz((component != 0),
"component");
282 return (strcmp(impl->id,
"comp") == 0);
285void vcardcomponent_add_property(vcardcomponent *comp, vcardproperty *property)
287 icalerror_check_arg_rv((comp != 0),
"component");
288 icalerror_check_arg_rv((property != 0),
"property");
291 "The property has already been added to a vcard. "
292 "Remove the property with vcardcomponent_remove_property "
293 "before calling vcardcomponent_add_property");
297 icalpvl_push(comp->properties, property);
299 if (vcardproperty_isa(property) == VCARD_VERSION_PROPERTY) {
300 comp->versionp = property;
304void vcardcomponent_remove_property(vcardcomponent *comp, vcardproperty *property)
306 icalpvl_elem itr, next_itr;
308 icalerror_check_arg_rv((comp != 0),
"component");
309 icalerror_check_arg_rv((property != 0),
"property");
315 if (vcardproperty_isa(property) == VCARD_VERSION_PROPERTY) {
319 for (itr = icalpvl_head(comp->properties); itr != 0; itr = next_itr) {
320 next_itr = icalpvl_next(itr);
322 if (icalpvl_data(itr) == (
void *)property) {
323 if (comp->property_iterator == itr) {
324 comp->property_iterator = icalpvl_next(itr);
327 (void)icalpvl_remove(comp->properties, itr);
333int vcardcomponent_count_properties(vcardcomponent *comp,
334 vcardproperty_kind kind,
339 vcardstrarray *altids = NULL;
341 icalerror_check_arg_rz((comp != 0),
"component");
344 altids = vcardstrarray_new(2);
347 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
348 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
350 if (kind == VCARD_ANY_PROPERTY || kind == vcardproperty_isa(prop)) {
353 vcardparameter *param =
354 vcardproperty_get_first_parameter(prop,
355 VCARD_ALTID_PARAMETER);
357 const char *altid = vcardparameter_get_altid(param);
359 if (vcardstrarray_find(altids, altid) >= vcardstrarray_size(altids)) {
363 vcardstrarray_append(altids, altid);
371 vcardstrarray_free(altids);
377vcardproperty *vcardcomponent_get_current_property(vcardcomponent *comp)
379 icalerror_check_arg_rz((comp != 0),
"card");
381 if (comp->property_iterator == 0) {
385 return (vcardproperty *)icalpvl_data(comp->property_iterator);
388vcardproperty *vcardcomponent_get_first_property(vcardcomponent *c,
389 vcardproperty_kind kind)
391 icalerror_check_arg_rz((c != 0),
"card");
393 for (c->property_iterator = icalpvl_head(c->properties);
394 c->property_iterator != 0;
395 c->property_iterator = icalpvl_next(c->property_iterator)) {
396 vcardproperty *p = (vcardproperty *)icalpvl_data(c->property_iterator);
398 if (vcardproperty_isa(p) == kind || kind == VCARD_ANY_PROPERTY) {
405vcardproperty *vcardcomponent_get_next_property(vcardcomponent *c,
406 vcardproperty_kind kind)
408 icalerror_check_arg_rz((c != 0),
"card");
410 if (c->property_iterator == 0) {
414 for (c->property_iterator = icalpvl_next(c->property_iterator);
415 c->property_iterator != 0;
416 c->property_iterator = icalpvl_next(c->property_iterator)) {
417 vcardproperty *p = (vcardproperty *)icalpvl_data(c->property_iterator);
419 if (vcardproperty_isa(p) == kind || kind == VCARD_ANY_PROPERTY) {
427vcardproperty **vcardcomponent_get_properties(vcardcomponent *comp,
428 vcardproperty_kind kind);
430void vcardcomponent_add_component(vcardcomponent *parent, vcardcomponent *child)
432 icalerror_check_arg_rv((parent != 0),
"parent");
433 icalerror_check_arg_rv((child != 0),
"child");
435 if (child->parent != 0) {
439 child->parent = parent;
441 icalpvl_push(parent->components, child);
444void vcardcomponent_remove_component(vcardcomponent *parent,
445 vcardcomponent *child)
447 icalpvl_elem itr, next_itr;
449 icalerror_check_arg_rv((parent != 0),
"parent");
450 icalerror_check_arg_rv((child != 0),
"child");
452 for (itr = icalpvl_head(parent->components); itr != 0; itr = next_itr) {
453 next_itr = icalpvl_next(itr);
455 if (icalpvl_data(itr) == (
void *)child) {
456 if (parent->component_iterator == itr) {
460 parent->component_iterator = icalpvl_next(parent->component_iterator);
462 (void)icalpvl_remove(parent->components, itr);
469int vcardcomponent_count_components(vcardcomponent *component,
470 vcardcomponent_kind kind)
475 icalerror_check_arg_rz((component != 0),
"component");
477 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
478 if (kind == VCARD_ANY_COMPONENT ||
479 kind == vcardcomponent_isa((vcardcomponent *)icalpvl_data(itr))) {
487vcardcomponent *vcardcomponent_get_current_component(vcardcomponent *component)
489 icalerror_check_arg_rz((component != 0),
"component");
491 if (component->component_iterator == 0) {
495 return (vcardcomponent *)icalpvl_data(component->component_iterator);
498vcardcomponent *vcardcomponent_get_first_component(vcardcomponent *c,
499 vcardcomponent_kind kind)
501 icalerror_check_arg_rz((c != 0),
"component");
503 for (c->component_iterator = icalpvl_head(c->components);
504 c->component_iterator != 0;
505 c->component_iterator = icalpvl_next(c->component_iterator)) {
506 vcardcomponent *p = (vcardcomponent *)icalpvl_data(c->component_iterator);
508 if (vcardcomponent_isa(p) == kind || kind == VCARD_ANY_COMPONENT) {
516vcardcomponent *vcardcomponent_get_next_component(vcardcomponent *c,
517 vcardcomponent_kind kind)
519 icalerror_check_arg_rz((c != 0),
"component");
521 if (c->component_iterator == 0) {
525 for (c->component_iterator = icalpvl_next(c->component_iterator);
526 c->component_iterator != 0;
527 c->component_iterator = icalpvl_next(c->component_iterator)) {
528 vcardcomponent *p = (vcardcomponent *)icalpvl_data(c->component_iterator);
530 if (vcardcomponent_isa(p) == kind || kind == VCARD_ANY_COMPONENT) {
538int vcardcomponent_check_restrictions(vcardcomponent *comp)
540 icalerror_check_arg_rz(comp != 0,
"comp");
549 icalerror_check_arg_rz((comp != 0),
"card");
551 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
552 const vcardproperty *p = (vcardproperty *)icalpvl_data(itr);
553 if (vcardproperty_isa(p) == VCARD_XLICERROR_PROPERTY) {
563 icalpvl_elem itr, next_itr;
565 icalerror_check_arg_rv((comp != 0),
"comp");
567 for (itr = icalpvl_head(comp->properties); itr != 0; itr = next_itr) {
568 vcardproperty *p = (vcardproperty *)icalpvl_data(itr);
569 next_itr = icalpvl_next(itr);
571 if (vcardproperty_isa(p) == VCARD_XLICERROR_PROPERTY) {
572 vcardcomponent_remove_property(comp, p);
573 vcardproperty_free(p);
578struct vcardcomponent_kind_map {
579 vcardcomponent_kind kind;
583static const struct vcardcomponent_kind_map component_map[] = {
584 {VCARD_XROOT_COMPONENT,
"XROOT"},
585 {VCARD_VCARD_COMPONENT,
"VCARD"},
588 {VCARD_NO_COMPONENT,
""},
591bool vcardcomponent_kind_is_valid(
const vcardcomponent_kind kind)
596 if (component_map[i].kind == kind) {
599 }
while (component_map[i++].kind != VCARD_NO_COMPONENT);
604const char *vcardcomponent_kind_to_string(vcardcomponent_kind kind)
608 for (i = 0; component_map[i].kind != VCARD_NO_COMPONENT; i++) {
609 if (component_map[i].kind == kind) {
610 return component_map[i].name;
617vcardcomponent_kind vcardcomponent_string_to_kind(
const char *
string)
622 return VCARD_NO_COMPONENT;
625 for (i = 0; component_map[i].kind != VCARD_NO_COMPONENT; i++) {
626 if (strncasecmp(
string, component_map[i].name, strlen(component_map[i].name)) == 0) {
627 return component_map[i].kind;
631 return VCARD_NO_COMPONENT;
634static int strcmpsafe(
const char *a,
const char *b)
636 return strcmp((a == NULL ?
"" : a),
637 (b == NULL ?
"" : b));
640static int prop_compare(
void *a,
void *b)
642 const vcardproperty *p1 = (vcardproperty *)a;
643 const vcardproperty *p2 = (vcardproperty *)b;
644 vcardproperty_kind k1 = vcardproperty_isa(p1);
645 vcardproperty_kind k2 = vcardproperty_isa(p2);
646 int r = (int)(k1 - k2);
649 if (k1 == VCARD_X_PROPERTY) {
650 r = strcmp(vcardproperty_get_x_name(p1),
651 vcardproperty_get_x_name(p2));
655 r = strcmpsafe(vcardproperty_get_value_as_string(p1),
656 vcardproperty_get_value_as_string(p2));
660 else if (k1 == VCARD_VERSION_PROPERTY) {
662 }
else if (k2 == VCARD_VERSION_PROPERTY) {
669static int prop_kind_compare(vcardproperty_kind kind,
670 vcardcomponent *c1, vcardcomponent *c2)
672 const vcardproperty *p1 = vcardcomponent_get_first_property(c1, kind);
673 const vcardproperty *p2 = vcardcomponent_get_first_property(c2, kind);
676 return strcmpsafe(vcardproperty_get_value_as_string(p1),
677 vcardproperty_get_value_as_string(p2));
687static int comp_compare(
void *a,
void *b)
689 vcardcomponent *c1 = (vcardcomponent *)a;
690 vcardcomponent *c2 = (vcardcomponent *)b;
691 vcardcomponent_kind k1 = vcardcomponent_isa(c1);
692 vcardcomponent_kind k2 = vcardcomponent_isa(c2);
693 int r = (int)(k1 - k2);
696 if (k1 == VCARD_VCARD_COMPONENT) {
697 vcardproperty_kind prop_kinds[] = {
698 VCARD_VERSION_PROPERTY,
701 VCARD_NICKNAME_PROPERTY,
706 for (
int i = 0; r == 0 && prop_kinds[i] != VCARD_NO_PROPERTY; i++) {
707 r = prop_kind_compare(prop_kinds[i], c1, c2);
710 r = strcmp(c1->x_name, c2->x_name);
714 r = prop_kind_compare(VCARD_UID_PROPERTY, c1, c2);
727 icalpvl_list sorted_props = icalpvl_newlist();
728 icalpvl_list sorted_comps = icalpvl_newlist();
733 while ((prop = icalpvl_pop(comp->properties)) != 0) {
734 int nparams, remove = 0;
738 nparams = vcardproperty_count_parameters(prop);
742 switch (vcardproperty_isa(prop)) {
743 case VCARD_KIND_PROPERTY:
744 if (vcardproperty_get_kind(prop) == VCARD_KIND_INDIVIDUAL) {
756 vcardproperty_free(prop);
758 icalpvl_insert_ordered(sorted_props, prop_compare, prop);
762 icalpvl_free(comp->properties);
763 comp->properties = sorted_props;
766 while ((sub = icalpvl_pop(comp->components)) != 0) {
768 icalpvl_insert_ordered(sorted_comps, comp_compare, sub);
771 icalpvl_free(comp->components);
772 comp->components = sorted_comps;
775#define UUID_PREFIX "urn:uuid:"
776#define UUID_PREFIX_LEN 9
778static void comp_to_v4(vcardcomponent *impl)
780 icalpvl_elem itr, next;
782 for (itr = icalpvl_head(impl->properties); itr != 0; itr = next) {
783 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
784 vcardproperty_kind pkind = vcardproperty_isa(prop);
785 vcardvalue *value = vcardproperty_get_value(prop);
786 vcardvalue_kind vkind = vcardvalue_isa(value);
787 vcardparameter *param;
788 vcardenumarray *types = NULL;
790 next = icalpvl_next(itr);
793 for (param = vcardproperty_get_first_parameter(prop,
794 VCARD_TYPE_PARAMETER);
796 param = vcardproperty_get_next_parameter(prop,
797 VCARD_TYPE_PARAMETER)) {
798 vcardenumarray_element pref = {VCARD_TYPE_PREF, NULL};
801 types = vcardparameter_get_type(param);
802 i = vcardenumarray_find(types, &pref);
803 if (i < vcardenumarray_size(types)) {
804 vcardenumarray_remove_element_at(types, i);
805 if (!vcardenumarray_size(types)) {
809 param = vcardproperty_get_first_parameter(prop,
810 VCARD_PREF_PARAMETER);
812 param = vcardparameter_new_pref(1);
813 vcardproperty_add_parameter(prop, param);
821 case VCARD_VERSION_PROPERTY:
822 vcardproperty_set_version(prop, VCARD_VERSION_40);
825 case VCARD_BDAY_PROPERTY:
826 case VCARD_DEATHDATE_PROPERTY:
827 case VCARD_ANNIVERSARY_PROPERTY:
828 for (param = vcardproperty_get_first_parameter(prop,
831 param = vcardproperty_get_next_parameter(prop,
832 VCARD_X_PARAMETER)) {
836 if (name && !strcasecmp(name,
"X-APPLE-OMIT-YEAR")) {
840 vcardproperty_set_bday(prop, dt);
847 case VCARD_GEO_PROPERTY:
848 if (vkind != VCARD_X_VALUE) {
853 int n = snprintf(NULL, 0,
"geo:%s,%s",
854 geo.coords.lat, geo.coords.lon);
856 size_t size = (size_t)n + 1;
858 snprintf(buf, size,
"geo:%s,%s",
859 geo.coords.lat, geo.coords.lon);
862 geo.coords.lat[0] =
'\0';
863 geo.coords.lon[0] =
'\0';
864 vcardvalue_set_geo(value, geo);
870 case VCARD_KEY_PROPERTY:
871 case VCARD_LOGO_PROPERTY:
872 case VCARD_PHOTO_PROPERTY:
873 case VCARD_SOUND_PROPERTY: {
874 char *mediatype = NULL;
875 param = vcardproperty_get_first_parameter(prop,
876 VCARD_TYPE_PARAMETER);
878 types = vcardparameter_get_type(param);
879 for (
size_t i = 0; i < vcardenumarray_size(types); i++) {
880 const vcardenumarray_element *type =
881 vcardenumarray_element_at(types, i);
888 case VCARD_LOGO_PROPERTY:
889 case VCARD_PHOTO_PROPERTY:
892 case VCARD_SOUND_PROPERTY:
900 size_t size = strlen(mediatype);
901 char *buf_ptr = mediatype + size;
904 for (c = mediatype; *c; c++) {
905 *c = (char)tolower((
int)*c);
909 vcardenumarray_remove_element_at(types, i);
910 if (!vcardenumarray_size(types)) {
918 const char *data = vcardvalue_get_uri(value);
919 if (data && !strchr(data,
':')) {
921 size_t size = strlen(data) + 7;
923 param = vcardproperty_get_first_parameter(prop,
924 VCARD_ENCODING_PARAMETER);
944 value->kind = VCARD_URI_VALUE;
945 vcardvalue_set_uri(value, buf);
948 }
else if (mediatype) {
949 param = vcardparameter_new_mediatype(mediatype);
950 vcardproperty_add_parameter(prop, param);
957 case VCARD_UID_PROPERTY: {
959 const char *data = vcardvalue_get_text(value);
960 if (!strncasecmp(data,
"urn:uuid:", 9) ||
961 !strncasecmp(data,
"mailto:", 7) ||
962 !strncasecmp(data,
"http://", 7) ||
963 !strncasecmp(data,
"https://", 8) ||
964 !strncasecmp(data,
"ldap://", 7) ||
965 !strncasecmp(data,
"ldaps://", 8)) {
966 value->kind = VCARD_URI_VALUE;
968 VCARD_VALUE_PARAMETER);
971 value->kind = VCARD_TEXT_VALUE;
976 case VCARD_X_PROPERTY: {
978 const char *xname = vcardproperty_get_x_name(prop);
980 if (!strncasecmp(xname,
"X-ADDRESSBOOKSERVER-", 20)) {
981 vcardproperty_kind kind = vcardproperty_string_to_kind(xname + 20);
982 const char *valstr = vcardvalue_as_vcard_string(value);
984 char *buf = NULL, *buf_ptr;
988 case VCARD_MEMBER_PROPERTY:
990 if (!strncmp(valstr, UUID_PREFIX, UUID_PREFIX_LEN)) {
991 valstr += UUID_PREFIX_LEN;
994 buf_size = strlen(valstr) + 1;
1002 case VCARD_KIND_PROPERTY:
1003 new = vcardproperty_new(kind);
1004 vcardproperty_set_value_from_string(
new, valstr,
"NO");
1005 vcardcomponent_add_property(impl,
new);
1006 vcardcomponent_remove_property(impl, prop);
1007 vcardproperty_free(prop);
1026 vcardproperty *prop;
1030static void comp_to_v3(vcardcomponent *impl)
1032 struct pref_prop *pref_props[VCARD_NO_PROPERTY] = {0};
1033 vcardenumarray_element type;
1034 vcardproperty_kind pkind;
1035 icalpvl_elem itr, next;
1037 for (itr = icalpvl_head(impl->properties); itr != 0; itr = next) {
1038 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
1039 vcardparameter *val_param =
1040 vcardproperty_get_first_parameter(prop, VCARD_VALUE_PARAMETER);
1041 vcardvalue *value = vcardproperty_get_value(prop);
1042 vcardvalue_kind vkind = vcardvalue_isa(value);
1043 vcardparameter *param;
1044 char *subtype = NULL;
1045 const char *mediatype, *uri, *xname = NULL;
1047 next = icalpvl_next(itr);
1050 pkind = vcardproperty_isa(prop);
1051 param = vcardproperty_get_first_parameter(prop, VCARD_PREF_PARAMETER);
1052 if (param && pkind != VCARD_X_PROPERTY) {
1053 int level = vcardparameter_get_pref(param);
1054 struct pref_prop *pp = pref_props[pkind];
1060 pref_props[pkind] = pp;
1061 }
else if (level < pp->level) {
1068 param = vcardproperty_get_first_parameter(prop,
1069 VCARD_MEDIATYPE_PARAMETER);
1071 mediatype = vcardparameter_get_mediatype(param);
1072 subtype = strchr(mediatype,
'/');
1078 for (c = subtype; *c; c++) {
1079 *c = (char)toupper((
int)*c);
1083 type.
val = VCARD_TYPE_NONE;
1085 vcardproperty_add_type_parameter(prop, &type);
1094 case VCARD_VERSION_PROPERTY:
1095 vcardproperty_set_version(prop, VCARD_VERSION_30);
1098 case VCARD_BDAY_PROPERTY:
1099 case VCARD_DEATHDATE_PROPERTY:
1100 case VCARD_ANNIVERSARY_PROPERTY: {
1103 if (dt.year == -1) {
1106 vcardproperty_set_parameter_from_string(prop,
1107 "X-APPLE-OMIT-YEAR",
1110 if (dt.hour != -1) {
1111 if (dt.second == -1) {
1113 if (dt.minute == -1) {
1119 vcardproperty_set_bday(prop, dt);
1123 case VCARD_GEO_PROPERTY:
1124 if (vkind != VCARD_X_VALUE) {
1127 if (geo.uri && !strncmp(geo.uri,
"geo:", 4)) {
1131 const char *lat = buf + 4;
1132 char *lon = strchr(buf + 4,
',');
1137 strncpy(geo.coords.lat, lat, VCARD_GEO_LEN - 1);
1138 geo.coords.lat[VCARD_GEO_LEN - 1] =
'\0';
1139 strncpy(geo.coords.lon, lon, VCARD_GEO_LEN - 1);
1140 geo.coords.lon[VCARD_GEO_LEN - 1] =
'\0';
1142 geo.coords.lat[0] =
'\0';
1143 geo.coords.lon[0] =
'\0';
1146 vcardvalue_set_geo(value, geo);
1152 case VCARD_KEY_PROPERTY:
1153 case VCARD_LOGO_PROPERTY:
1154 case VCARD_PHOTO_PROPERTY:
1155 case VCARD_SOUND_PROPERTY:
1156 uri = vcardvalue_get_uri(value);
1157 if (uri && !strncmp(
"data:", uri, 5)) {
1159 char *base64, *data = NULL;
1162 mediatype = buf + 5;
1163 base64 = strstr(mediatype,
";base64,");
1166 param = vcardparameter_new_encoding(VCARD_ENCODING_B);
1167 vcardproperty_add_parameter(prop, param);
1172 data = strchr(mediatype,
',');
1178 subtype = strchr(mediatype,
'/');
1183 for (c = ++subtype; *c; c++) {
1184 *c = (char)toupper((
int)*c);
1188 type.
val = VCARD_VERSION_NONE;
1190 vcardproperty_add_type_parameter(prop, &type);
1193 value->kind = VCARD_TEXT_VALUE;
1194 vcardvalue_set_text(value, data ? data :
"");
1199 case VCARD_KIND_PROPERTY:
1201 xname =
"X-ADDRESSBOOKSERVER-KIND";
1205 case VCARD_MEMBER_PROPERTY: {
1208 const char *xval = vcardvalue_as_vcard_string(value);
1210 size_t buf_size = strlen(UUID_PREFIX) + strlen(xval) + 1;
1216 xname =
"X-ADDRESSBOOKSERVER-MEMBER";
1220 vcardproperty *xprop = vcardproperty_new_x(xval);
1221 vcardproperty_set_x_name(xprop, xname);
1222 vcardcomponent_add_property(impl, xprop);
1223 vcardcomponent_remove_property(impl, prop);
1224 vcardproperty_free(prop);
1229 case VCARD_TEL_PROPERTY:
1230 uri = vcardvalue_get_uri(value);
1231 if (uri && !strncmp(uri,
"tel:", 4)) {
1235 value->kind = VCARD_TEXT_VALUE;
1236 vcardvalue_set_text(value, buf);
1246 case VCARD_UID_PROPERTY:
1248 value->kind = VCARD_TEXT_VALUE;
1261 for (pkind = 0; pkind < VCARD_NO_PROPERTY; ++pkind) {
1262 struct pref_prop *pp = pref_props[pkind];
1265 type.
val = VCARD_TYPE_PREF;
1268 vcardproperty_add_type_parameter(pp->prop, &type);
1274void vcardcomponent_transform(vcardcomponent *impl,
1275 vcardproperty_version version)
1278 vcardcomponent_kind kind = vcardcomponent_isa(impl);
1280 icalerror_check_arg_rv((impl != 0),
"component");
1281 icalerror_check_arg_rv((kind != VCARD_NO_COMPONENT),
1282 "component kind is VCARD_NO_COMPONENT");
1284 if (kind == VCARD_VCARD_COMPONENT) {
1285 if (version == VCARD_VERSION_40) {
1292 for (itr = icalpvl_head(impl->components); itr != 0; itr = icalpvl_next(itr)) {
1293 vcardcomponent *c = (vcardcomponent *)icalpvl_data(itr);
1294 vcardcomponent_transform(c, version);
1300enum vcardproperty_version vcardcomponent_get_version(vcardcomponent *comp)
1302 icalerror_check_arg_rx(comp != 0,
"comp", VCARD_VERSION_NONE);
1304 if (comp->versionp == 0) {
1306 vcardcomponent_get_first_property(comp, VCARD_VERSION_PROPERTY);
1308 if (comp->versionp == 0) {
1309 return VCARD_VERSION_NONE;
1313 return vcardproperty_get_version(comp->versionp);
1316const char *vcardcomponent_get_uid(vcardcomponent *comp)
1318 vcardproperty *prop;
1320 icalerror_check_arg_rz(comp != 0,
"comp");
1322 prop = vcardcomponent_get_first_property(comp, VCARD_UID_PROPERTY);
1328 return vcardproperty_get_uid(prop);
1331const char *vcardcomponent_get_fn(vcardcomponent *comp)
1333 vcardproperty *prop;
1335 icalerror_check_arg_rz(comp != 0,
"comp");
1337 prop = vcardcomponent_get_first_property(comp, VCARD_FN_PROPERTY);
1343 return vcardproperty_get_fn(prop);
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.
void vcardcomponent_strip_errors(vcardcomponent *comp)
Removes all X-LIC-ERROR properties.
vcardcomponent * vcardcomponent_clone(const vcardcomponent *old)
Deeply clones an vcard. Returns a pointer to the memory for the newly cloned vcard.
int vcardcomponent_count_errors(vcardcomponent *comp)
Returns the number of errors encountered parsing the data.
vcardcomponent * vcardcomponent_vanew(vcardcomponent_kind kind,...)
Constructor.
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.
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.
const char * vcardparameter_get_xname(const vcardparameter *param)
Returns the X-name of param.
Line-oriented parsing vCard format.
void vcardproperty_normalize(vcardproperty *prop)
void vcardproperty_remove_parameter_by_ref(vcardproperty *prop, vcardparameter *parameter)
Removes the specified parameter reference from the property.
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.
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.
Defines the data structure representing vCard values.