21#include "vcardproperty_p.h"
24#include "icalerror_p.h"
33struct vcardcomponent_impl {
35 vcardcomponent_kind kind;
36 vcardproperty *versionp;
37 icalpvl_list properties;
38 icalpvl_elem property_iterator;
39 icalpvl_list components;
40 icalpvl_elem component_iterator;
41 struct vcardcomponent_impl *parent;
44static void vcardcomponent_add_children(vcardcomponent *impl, va_list args)
48 while ((vp = va_arg(args,
void *)) != 0) {
49 icalassert(vcardproperty_isa_property(vp) != 0);
51 vcardcomponent_add_property(impl, (vcardproperty *)vp);
55static vcardcomponent *vcardcomponent_new_impl(vcardcomponent_kind kind)
59 if (!vcardcomponent_kind_is_valid(kind)) {
68 memset(comp, 0,
sizeof(vcardcomponent));
70 strcpy(comp->id,
"comp");
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
110 return vcardparser_parse_string(str);
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);
135void vcardcomponent_free(vcardcomponent *c)
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) {
149 vcardproperty_free(prop);
151 icalpvl_free(c->properties);
154 while ((comp = icalpvl_data(icalpvl_head(c->components))) != 0) {
155 vcardcomponent_remove_component(c, comp);
156 vcardcomponent_free(comp);
159 icalpvl_free(c->components);
161 c->kind = VCARD_NO_COMPONENT;
163 c->property_iterator = 0;
165 c->component_iterator = 0;
171char *vcardcomponent_as_vcard_string(vcardcomponent *comp)
175 buf = vcardcomponent_as_vcard_string_r(comp);
182char *vcardcomponent_as_vcard_string_r(vcardcomponent *comp)
186 size_t buf_size = 1024;
191 const char newline[] =
"\r\n";
195 vcardcomponent_kind kind = vcardcomponent_isa(comp);
197 const char *kind_string = NULL;
199 icalerror_check_arg_rz((comp != 0),
"component");
200 icalerror_check_arg_rz((kind != VCARD_NO_COMPONENT),
201 "component kind is VCARD_NO_COMPONENT");
203 kind_string = vcardcomponent_kind_to_string(kind);
205 icalerror_check_arg_rz((kind_string != 0),
"Unknown kind of component");
214 if (kind != VCARD_XROOT_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");
223 tmp_buf = vcardproperty_as_vcard_string_r(p);
230 for (itr = icalpvl_head(comp->components); itr != 0; itr = icalpvl_next(itr)) {
231 c = (vcardcomponent *)icalpvl_data(itr);
233 tmp_buf = vcardcomponent_as_vcard_string_r(c);
234 if (tmp_buf != NULL) {
240 if (kind != VCARD_XROOT_COMPONENT) {
249bool vcardcomponent_is_valid(
const vcardcomponent *component)
252 if ((strcmp(component->id,
"comp") == 0) && (component->kind != VCARD_NO_COMPONENT)) {
259vcardcomponent_kind vcardcomponent_isa(
const vcardcomponent *component)
261 icalerror_check_arg_rx((component != 0),
"component", VCARD_NO_COMPONENT);
263 return component->kind;
266bool vcardcomponent_isa_component(
const void *component)
268 const vcardcomponent *impl = component;
270 icalerror_check_arg_rz((component != 0),
"component");
272 return (strcmp(impl->id,
"comp") == 0);
275void vcardcomponent_add_property(vcardcomponent *comp, vcardproperty *property)
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);
289 if (vcardproperty_isa(property) == VCARD_VERSION_PROPERTY) {
290 comp->versionp = property;
294void vcardcomponent_remove_property(vcardcomponent *comp, vcardproperty *property)
296 icalpvl_elem itr, next_itr;
298 icalerror_check_arg_rv((comp != 0),
"component");
299 icalerror_check_arg_rv((property != 0),
"property");
305 if (vcardproperty_isa(property) == VCARD_VERSION_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);
323int vcardcomponent_count_properties(vcardcomponent *comp,
324 vcardproperty_kind kind,
329 vcardstrarray *altids = NULL;
331 icalerror_check_arg_rz((comp != 0),
"component");
334 altids = vcardstrarray_new(2);
337 for (itr = icalpvl_head(comp->properties); itr != 0; itr = icalpvl_next(itr)) {
338 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
340 if (kind == VCARD_ANY_PROPERTY || kind == vcardproperty_isa(prop)) {
343 vcardparameter *param =
344 vcardproperty_get_first_parameter(prop,
345 VCARD_ALTID_PARAMETER);
347 const char *altid = vcardparameter_get_altid(param);
349 if (vcardstrarray_find(altids, altid) >= vcardstrarray_size(altids)) {
353 vcardstrarray_append(altids, altid);
361 vcardstrarray_free(altids);
367vcardproperty *vcardcomponent_get_current_property(vcardcomponent *comp)
369 icalerror_check_arg_rz((comp != 0),
"card");
371 if (comp->property_iterator == 0) {
375 return (vcardproperty *)icalpvl_data(comp->property_iterator);
378vcardproperty *vcardcomponent_get_first_property(vcardcomponent *c,
379 vcardproperty_kind kind)
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);
388 if (vcardproperty_isa(p) == kind || kind == VCARD_ANY_PROPERTY) {
395vcardproperty *vcardcomponent_get_next_property(vcardcomponent *c,
396 vcardproperty_kind kind)
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);
409 if (vcardproperty_isa(p) == kind || kind == VCARD_ANY_PROPERTY) {
417vcardproperty **vcardcomponent_get_properties(vcardcomponent *comp,
418 vcardproperty_kind kind);
420void vcardcomponent_add_component(vcardcomponent *parent, vcardcomponent *child)
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);
434void vcardcomponent_remove_component(vcardcomponent *parent,
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);
459int vcardcomponent_count_components(vcardcomponent *component,
460 vcardcomponent_kind kind)
465 icalerror_check_arg_rz((component != 0),
"component");
467 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
468 if (kind == VCARD_ANY_COMPONENT ||
469 kind == vcardcomponent_isa((vcardcomponent *)icalpvl_data(itr))) {
477vcardcomponent *vcardcomponent_get_current_component(vcardcomponent *component)
479 icalerror_check_arg_rz((component != 0),
"component");
481 if (component->component_iterator == 0) {
485 return (vcardcomponent *)icalpvl_data(component->component_iterator);
488vcardcomponent *vcardcomponent_get_first_component(vcardcomponent *c,
489 vcardcomponent_kind kind)
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);
498 if (vcardcomponent_isa(p) == kind || kind == VCARD_ANY_COMPONENT) {
506vcardcomponent *vcardcomponent_get_next_component(vcardcomponent *c,
507 vcardcomponent_kind kind)
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);
520 if (vcardcomponent_isa(p) == kind || kind == VCARD_ANY_COMPONENT) {
528int vcardcomponent_check_restrictions(vcardcomponent *comp)
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);
543 if (vcardproperty_isa(p) == VCARD_XLICERROR_PROPERTY) {
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);
561 if (vcardproperty_isa(p) == VCARD_XLICERROR_PROPERTY) {
562 vcardcomponent_remove_property(comp, p);
563 vcardproperty_free(p);
568struct vcardcomponent_kind_map {
569 vcardcomponent_kind kind;
573static const struct vcardcomponent_kind_map component_map[] = {
574 {VCARD_XROOT_COMPONENT,
"XROOT"},
575 {VCARD_VCARD_COMPONENT,
"VCARD"},
578 {VCARD_NO_COMPONENT,
""},
581bool vcardcomponent_kind_is_valid(
const vcardcomponent_kind kind)
586 if (component_map[i].kind == kind) {
589 }
while (component_map[i++].kind != VCARD_NO_COMPONENT);
594const char *vcardcomponent_kind_to_string(vcardcomponent_kind kind)
598 for (i = 0; component_map[i].kind != VCARD_NO_COMPONENT; i++) {
599 if (component_map[i].kind == kind) {
600 return component_map[i].name;
607vcardcomponent_kind vcardcomponent_string_to_kind(
const char *
string)
612 return VCARD_NO_COMPONENT;
615 for (i = 0; component_map[i].kind != VCARD_NO_COMPONENT; i++) {
616 if (strncasecmp(
string, component_map[i].name, strlen(component_map[i].name)) == 0) {
617 return component_map[i].kind;
621 return VCARD_NO_COMPONENT;
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;
634 vcardproperty_kind k1 = vcardproperty_isa(p1);
635 vcardproperty_kind k2 = vcardproperty_isa(p2);
636 int r = (int)(k1 - k2);
639 if (k1 == VCARD_X_PROPERTY) {
640 r = strcmp(vcardproperty_get_x_name(p1),
641 vcardproperty_get_x_name(p2));
645 r = strcmpsafe(vcardproperty_get_value_as_string(p1),
646 vcardproperty_get_value_as_string(p2));
650 else if (k1 == VCARD_VERSION_PROPERTY) {
652 }
else if (k2 == VCARD_VERSION_PROPERTY) {
659static int prop_kind_compare(vcardproperty_kind kind,
660 vcardcomponent *c1, vcardcomponent *c2)
662 const vcardproperty *p1 = vcardcomponent_get_first_property(c1, kind);
663 const vcardproperty *p2 = vcardcomponent_get_first_property(c2, kind);
666 return strcmpsafe(vcardproperty_get_value_as_string(p1),
667 vcardproperty_get_value_as_string(p2));
677static int comp_compare(
void *a,
void *b)
679 vcardcomponent *c1 = (vcardcomponent *)a;
680 vcardcomponent *c2 = (vcardcomponent *)b;
681 vcardcomponent_kind k1 = vcardcomponent_isa(c1);
682 vcardcomponent_kind k2 = vcardcomponent_isa(c2);
683 int r = (int)(k1 - k2);
686 if (k1 == VCARD_VCARD_COMPONENT) {
687 vcardproperty_kind prop_kinds[] = {
688 VCARD_VERSION_PROPERTY,
691 VCARD_NICKNAME_PROPERTY,
696 for (
int i = 0; r == 0 && prop_kinds[i] != VCARD_NO_PROPERTY; i++) {
697 r = prop_kind_compare(prop_kinds[i], c1, c2);
702 r = prop_kind_compare(VCARD_UID_PROPERTY, 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;
726 nparams = vcardproperty_count_parameters(prop);
730 switch (vcardproperty_isa(prop)) {
731 case VCARD_KIND_PROPERTY:
732 if (vcardproperty_get_kind(prop) == VCARD_KIND_INDIVIDUAL) {
744 vcardproperty_free(prop);
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);
772 vcardproperty_kind pkind = vcardproperty_isa(prop);
773 vcardvalue *value = vcardproperty_get_value(prop);
774 vcardvalue_kind vkind = vcardvalue_isa(value);
775 vcardparameter *param;
776 vcardenumarray *types = NULL;
778 next = icalpvl_next(itr);
781 for (param = vcardproperty_get_first_parameter(prop,
782 VCARD_TYPE_PARAMETER);
784 param = vcardproperty_get_next_parameter(prop,
785 VCARD_TYPE_PARAMETER)) {
786 vcardenumarray_element pref = {VCARD_TYPE_PREF, NULL};
789 types = vcardparameter_get_type(param);
790 i = vcardenumarray_find(types, &pref);
791 if (i < vcardenumarray_size(types)) {
792 vcardenumarray_remove_element_at(types, i);
793 if (!vcardenumarray_size(types)) {
797 param = vcardproperty_get_first_parameter(prop,
798 VCARD_PREF_PARAMETER);
800 param = vcardparameter_new_pref(1);
801 vcardproperty_add_parameter(prop, param);
809 case VCARD_VERSION_PROPERTY:
810 vcardproperty_set_version(prop, VCARD_VERSION_40);
813 case VCARD_BDAY_PROPERTY:
814 case VCARD_DEATHDATE_PROPERTY:
815 case VCARD_ANNIVERSARY_PROPERTY:
816 for (param = vcardproperty_get_first_parameter(prop,
819 param = vcardproperty_get_next_parameter(prop,
820 VCARD_X_PARAMETER)) {
824 if (name && !strcasecmp(name,
"X-APPLE-OMIT-YEAR")) {
828 vcardproperty_set_bday(prop, dt);
835 case VCARD_GEO_PROPERTY:
836 if (vkind != VCARD_X_VALUE) {
841 int n = snprintf(NULL, 0,
"geo:%s,%s",
842 geo.coords.lat, geo.coords.lon);
844 size_t size = (size_t)n + 1;
846 snprintf(buf, size,
"geo:%s,%s",
847 geo.coords.lat, geo.coords.lon);
850 geo.coords.lat[0] =
'\0';
851 geo.coords.lon[0] =
'\0';
852 vcardvalue_set_geo(value, geo);
858 case VCARD_KEY_PROPERTY:
859 case VCARD_LOGO_PROPERTY:
860 case VCARD_PHOTO_PROPERTY:
861 case VCARD_SOUND_PROPERTY: {
862 char *mediatype = NULL;
863 param = vcardproperty_get_first_parameter(prop,
864 VCARD_TYPE_PARAMETER);
866 types = vcardparameter_get_type(param);
867 for (
size_t i = 0; i < vcardenumarray_size(types); i++) {
868 const vcardenumarray_element *type =
869 vcardenumarray_element_at(types, i);
876 case VCARD_LOGO_PROPERTY:
877 case VCARD_PHOTO_PROPERTY:
880 case VCARD_SOUND_PROPERTY:
888 size_t size = strlen(mediatype);
889 char *buf_ptr = mediatype + size;
892 for (c = mediatype; *c; c++) {
893 *c = (char)tolower((
int)*c);
897 vcardenumarray_remove_element_at(types, i);
898 if (!vcardenumarray_size(types)) {
906 const char *data = vcardvalue_get_uri(value);
907 if (data && !strchr(data,
':')) {
909 size_t size = strlen(data) + 7;
911 param = vcardproperty_get_first_parameter(prop,
912 VCARD_ENCODING_PARAMETER);
932 value->kind = VCARD_URI_VALUE;
933 vcardvalue_set_uri(value, buf);
936 }
else if (mediatype) {
937 param = vcardparameter_new_mediatype(mediatype);
938 vcardproperty_add_parameter(prop, param);
945 case VCARD_UID_PROPERTY: {
947 const char *data = vcardvalue_get_text(value);
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)) {
954 value->kind = VCARD_URI_VALUE;
956 VCARD_VALUE_PARAMETER);
959 value->kind = VCARD_TEXT_VALUE;
964 case VCARD_X_PROPERTY: {
966 const char *xname = vcardproperty_get_x_name(prop);
968 if (!strncasecmp(xname,
"X-ADDRESSBOOKSERVER-", 20)) {
969 vcardproperty_kind kind = vcardproperty_string_to_kind(xname + 20);
970 const char *valstr = vcardvalue_as_vcard_string(value);
972 char *buf = NULL, *buf_ptr;
976 case VCARD_MEMBER_PROPERTY:
978 if (!strncmp(valstr, UUID_PREFIX, UUID_PREFIX_LEN)) {
979 valstr += UUID_PREFIX_LEN;
982 buf_size = strlen(valstr) + 1;
990 case VCARD_KIND_PROPERTY:
991 new = vcardproperty_new(kind);
992 vcardproperty_set_value_from_string(
new, valstr,
"NO");
993 vcardcomponent_add_property(impl,
new);
994 vcardcomponent_remove_property(impl, prop);
995 vcardproperty_free(prop);
1014 vcardproperty *prop;
1018static void comp_to_v3(vcardcomponent *impl)
1020 struct pref_prop *pref_props[VCARD_NO_PROPERTY] = {0};
1021 vcardenumarray_element type;
1022 vcardproperty_kind pkind;
1023 icalpvl_elem itr, next;
1025 for (itr = icalpvl_head(impl->properties); itr != 0; itr = next) {
1026 vcardproperty *prop = (vcardproperty *)icalpvl_data(itr);
1027 vcardparameter *val_param =
1028 vcardproperty_get_first_parameter(prop, VCARD_VALUE_PARAMETER);
1029 vcardvalue *value = vcardproperty_get_value(prop);
1030 vcardvalue_kind vkind = vcardvalue_isa(value);
1031 vcardparameter *param;
1032 char *subtype = NULL;
1033 const char *mediatype, *uri, *xname = NULL;
1035 next = icalpvl_next(itr);
1038 pkind = vcardproperty_isa(prop);
1039 param = vcardproperty_get_first_parameter(prop, VCARD_PREF_PARAMETER);
1040 if (param && pkind != VCARD_X_PROPERTY) {
1041 int level = vcardparameter_get_pref(param);
1042 struct pref_prop *pp = pref_props[pkind];
1048 pref_props[pkind] = pp;
1049 }
else if (level < pp->level) {
1056 param = vcardproperty_get_first_parameter(prop,
1057 VCARD_MEDIATYPE_PARAMETER);
1059 mediatype = vcardparameter_get_mediatype(param);
1060 subtype = (
char *)strchr(mediatype,
'/');
1066 for (c = subtype; *c; c++) {
1067 *c = (char)toupper((
int)*c);
1071 type.
val = VCARD_TYPE_NONE;
1073 vcardproperty_add_type_parameter(prop, &type);
1082 case VCARD_VERSION_PROPERTY:
1083 vcardproperty_set_version(prop, VCARD_VERSION_30);
1086 case VCARD_BDAY_PROPERTY:
1087 case VCARD_DEATHDATE_PROPERTY:
1088 case VCARD_ANNIVERSARY_PROPERTY: {
1091 if (dt.year == -1) {
1094 vcardproperty_set_parameter_from_string(prop,
1095 "X-APPLE-OMIT-YEAR",
1098 if (dt.hour != -1) {
1099 if (dt.second == -1) {
1101 if (dt.minute == -1) {
1107 vcardproperty_set_bday(prop, dt);
1111 case VCARD_GEO_PROPERTY:
1112 if (vkind != VCARD_X_VALUE) {
1115 if (geo.uri && !strncmp(geo.uri,
"geo:", 4)) {
1119 const char *lat = buf + 4;
1120 char *lon = strchr(buf + 4,
',');
1125 strncpy(geo.coords.lat, lat, VCARD_GEO_LEN - 1);
1126 geo.coords.lat[VCARD_GEO_LEN - 1] =
'\0';
1127 strncpy(geo.coords.lon, lon, VCARD_GEO_LEN - 1);
1128 geo.coords.lon[VCARD_GEO_LEN - 1] =
'\0';
1130 geo.coords.lat[0] =
'\0';
1131 geo.coords.lon[0] =
'\0';
1134 vcardvalue_set_geo(value, geo);
1140 case VCARD_KEY_PROPERTY:
1141 case VCARD_LOGO_PROPERTY:
1142 case VCARD_PHOTO_PROPERTY:
1143 case VCARD_SOUND_PROPERTY:
1144 uri = vcardvalue_get_uri(value);
1145 if (uri && !strncmp(
"data:", uri, 5)) {
1147 char *base64, *data = NULL;
1150 mediatype = buf + 5;
1151 base64 = (
char *)strstr(mediatype,
";base64,");
1154 param = vcardparameter_new_encoding(VCARD_ENCODING_B);
1155 vcardproperty_add_parameter(prop, param);
1160 data = (
char *)strchr(mediatype,
',');
1166 subtype = (
char *)strchr(mediatype,
'/');
1171 for (c = ++subtype; *c; c++) {
1172 *c = (char)toupper((
int)*c);
1176 type.
val = VCARD_VERSION_NONE;
1178 vcardproperty_add_type_parameter(prop, &type);
1181 value->kind = VCARD_TEXT_VALUE;
1182 vcardvalue_set_text(value, data ? data :
"");
1187 case VCARD_KIND_PROPERTY:
1189 xname =
"X-ADDRESSBOOKSERVER-KIND";
1193 case VCARD_MEMBER_PROPERTY: {
1196 const char *xval = vcardvalue_as_vcard_string(value);
1198 size_t buf_size = strlen(UUID_PREFIX) + strlen(xval) + 1;
1204 xname =
"X-ADDRESSBOOKSERVER-MEMBER";
1208 vcardproperty *xprop = vcardproperty_new_x(xval);
1209 vcardproperty_set_x_name(xprop, xname);
1210 vcardcomponent_add_property(impl, xprop);
1211 vcardcomponent_remove_property(impl, prop);
1212 vcardproperty_free(prop);
1217 case VCARD_TEL_PROPERTY:
1218 uri = vcardvalue_get_uri(value);
1219 if (uri && !strncmp(uri,
"tel:", 4)) {
1223 value->kind = VCARD_TEXT_VALUE;
1224 vcardvalue_set_text(value, buf);
1234 case VCARD_UID_PROPERTY:
1236 value->kind = VCARD_TEXT_VALUE;
1249 for (pkind = 0; pkind < VCARD_NO_PROPERTY; ++pkind) {
1250 struct pref_prop *pp = pref_props[pkind];
1253 type.
val = VCARD_TYPE_PREF;
1256 vcardproperty_add_type_parameter(pp->prop, &type);
1262void vcardcomponent_transform(vcardcomponent *impl,
1263 vcardproperty_version version)
1266 vcardcomponent_kind kind = vcardcomponent_isa(impl);
1268 icalerror_check_arg_rv((impl != 0),
"component");
1269 icalerror_check_arg_rv((kind != VCARD_NO_COMPONENT),
1270 "component kind is VCARD_NO_COMPONENT");
1272 if (kind == VCARD_VCARD_COMPONENT) {
1273 if (version == VCARD_VERSION_40) {
1280 for (itr = icalpvl_head(impl->components); itr != 0; itr = icalpvl_next(itr)) {
1281 vcardcomponent *c = (vcardcomponent *)icalpvl_data(itr);
1282 vcardcomponent_transform(c, version);
1288enum vcardproperty_version vcardcomponent_get_version(vcardcomponent *comp)
1290 icalerror_check_arg_rx(comp != 0,
"comp", VCARD_VERSION_NONE);
1292 if (comp->versionp == 0) {
1294 vcardcomponent_get_first_property(comp, VCARD_VERSION_PROPERTY);
1296 if (comp->versionp == 0) {
1297 return VCARD_VERSION_NONE;
1301 return vcardproperty_get_version(comp->versionp);
1304const char *vcardcomponent_get_uid(vcardcomponent *comp)
1306 vcardproperty *prop;
1308 icalerror_check_arg_rz(comp != 0,
"comp");
1310 prop = vcardcomponent_get_first_property(comp, VCARD_UID_PROPERTY);
1316 return vcardproperty_get_uid(prop);
1319const char *vcardcomponent_get_fn(vcardcomponent *comp)
1321 vcardproperty *prop;
1323 icalerror_check_arg_rz(comp != 0,
"comp");
1325 prop = vcardcomponent_get_first_property(comp, VCARD_FN_PROPERTY);
1331 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.