19#include "icalerror_p.h"
26#include "icaltime_p.h"
33struct icalcomponent_impl {
37 icalpvl_list properties;
38 icalpvl_elem property_iterator;
39 icalpvl_list components;
40 icalpvl_elem component_iterator;
41 struct icalcomponent_impl *parent;
51static void icalcomponent_add_children(icalcomponent *impl, va_list args);
54static void icalcomponent_merge_vtimezone(icalcomponent *comp,
55 icalcomponent *vtimezone, icalarray *tzids_to_rename);
56static void icalcomponent_handle_conflicting_vtimezones(icalcomponent *comp,
57 icalcomponent *vtimezone,
58 icalproperty *tzid_prop,
60 icalarray *tzids_to_rename);
61static size_t icalcomponent_get_tzid_prefix_len(
const char *tzid);
62static void icalcomponent_rename_tzids(icalcomponent *comp, icalarray *rename_table);
63static void icalcomponent_rename_tzids_callback(icalparameter *param,
void *data);
64static int icalcomponent_compare_vtimezones(icalcomponent *vtimezone1, icalcomponent *vtimezone2);
65static int icalcomponent_compare_timezone_fn(
const void *elem1,
const void *elem2);
67void icalcomponent_add_children(icalcomponent *impl, va_list args)
71 while ((vp = va_arg(args,
void *)) != 0) {
96 memset(comp, 0,
sizeof(icalcomponent));
98 strcpy(comp->id,
"comp");
101 comp->properties = icalpvl_newlist();
102 comp->components = icalpvl_newlist();
103 comp->timezones_sorted = 1;
110 return icalcomponent_new_impl(kind);
119 icalcomponent *impl = icalcomponent_new_impl(kind);
125 va_start(args, kind);
126 icalcomponent_add_children(impl, args);
139 icalcomponent *clone;
140 const icalcomponent *c;
141 const icalproperty *p;
144 icalerror_check_arg_rz((old != 0),
"component");
146 clone = icalcomponent_new_impl(old->kind);
156 for (itr = icalpvl_head(old->properties); itr != 0; itr = icalpvl_next(itr)) {
157 p = (icalproperty *)icalpvl_data(itr);
161 for (itr = icalpvl_head(old->components); itr != 0; itr = icalpvl_next(itr)) {
162 c = (icalcomponent *)icalpvl_data(itr);
195 icalerror_check_arg_rv((c != 0),
"component");
197 if (c->parent != 0) {
201 if (c->properties != 0) {
203 while ((prop = icalpvl_pop(c->properties)) != 0) {
207 icalpvl_free(c->properties);
210 while ((comp = icalpvl_data(icalpvl_head(c->components))) != 0) {
215 icalpvl_free(c->components);
219 icaltimezone_array_free(c->timezones);
224 c->property_iterator = 0;
226 c->component_iterator = 0;
248 size_t buf_size = 1024;
253 const char newline[] =
"\r\n";
255 const icalcomponent *c;
259 const char *kind_string;
261 icalerror_check_arg_rz((component != 0),
"component");
262 icalerror_check_arg_rz((kind !=
ICAL_NO_COMPONENT),
"component kind is ICAL_NO_COMPONENT");
265 kind_string = component->x_name;
270 icalerror_check_arg_rz((kind_string != 0),
"Unknown kind of component");
283 for (itr = icalpvl_head(component->properties); itr != 0; itr = icalpvl_next(itr)) {
286 p = (icalproperty *)icalpvl_data(itr);
288 icalerror_assert((p != 0),
"Got a null property");
295 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
298 c = (icalcomponent *)icalpvl_data(itr);
301 if (tmp_buf != NULL) {
317 if ((strcmp(component->id,
"comp") == 0) && component->kind !=
ICAL_NO_COMPONENT) {
328 return component->kind;
333 const icalcomponent *impl = component;
335 icalerror_check_arg_rz((component != 0),
"component");
337 if (strcmp(impl->id,
"comp") == 0) {
346 icalerror_check_arg_rv((name != 0),
"name");
347 icalerror_check_arg_rv((comp != 0),
"comp");
352 if (comp->x_name == 0) {
359 icalerror_check_arg_rz((comp != 0),
"comp");
366 icalerror_check_arg_rv((name != 0),
"name");
367 icalerror_check_arg_rv((comp != 0),
"comp");
373 if (comp->x_name == 0) {
380 icalerror_check_arg_rz((comp != 0),
"comp");
397 const char *component_name = 0;
398 size_t buf_size = 256;
402 icalerror_check_arg_rz((comp != 0),
"comp");
409 component_name = comp->x_name;
414 if (component_name == 0) {
430 icalerror_check_arg_rv((component != 0),
"component");
431 icalerror_check_arg_rv((property != 0),
"property");
434 "The property has already been added to a component. "
435 "Remove the property with icalcomponent_remove_property "
436 "before calling icalcomponent_add_property");
440 icalpvl_push(component->properties, property);
445 icalpvl_elem itr, next_itr;
447 icalerror_check_arg_rv((component != 0),
"component");
448 icalerror_check_arg_rv((property != 0),
"property");
454 for (itr = icalpvl_head(component->properties); itr != 0; itr = next_itr) {
455 next_itr = icalpvl_next(itr);
457 if (icalpvl_data(itr) == (
void *)property) {
458 if (component->property_iterator == itr) {
459 component->property_iterator = icalpvl_next(itr);
462 (void)icalpvl_remove(component->properties, itr);
470 icalpvl_elem itr, next_itr;
472 icalerror_check_arg_rv((component != 0),
"component");
474 for (itr = icalpvl_head(component->properties); itr != 0; itr = next_itr) {
475 next_itr = icalpvl_next(itr);
477 icalproperty *
property = icalpvl_data(itr);
479 if (component->property_iterator == itr) {
480 component->property_iterator = icalpvl_next(itr);
483 (void)icalpvl_remove(component->properties, itr);
495 icalerror_check_arg_rz((component != 0),
"component");
497 for (itr = icalpvl_head(component->properties); itr != 0; itr = icalpvl_next(itr)) {
498 if (kind ==
icalproperty_isa((icalproperty *)icalpvl_data(itr)) || kind == ICAL_ANY_PROPERTY) {
508 icalerror_check_arg_rz((component != 0),
"component");
510 if (component->property_iterator == 0) {
514 return (icalproperty *)icalpvl_data(component->property_iterator);
519 icalerror_check_arg_rz((c != 0),
"component");
521 for (c->property_iterator = icalpvl_head(c->properties);
522 c->property_iterator != 0; c->property_iterator = icalpvl_next(c->property_iterator)) {
523 icalproperty *p = (icalproperty *)icalpvl_data(c->property_iterator);
534 icalerror_check_arg_rz((c != 0),
"component");
536 if (c->property_iterator == 0) {
540 for (c->property_iterator = icalpvl_next(c->property_iterator);
541 c->property_iterator != 0; c->property_iterator = icalpvl_next(c->property_iterator)) {
542 icalproperty *p = (icalproperty *)icalpvl_data(c->property_iterator);
554 icalerror_check_arg_rv((parent != 0),
"parent");
555 icalerror_check_arg_rv((child != 0),
"child");
557 if (child->parent != 0) {
561 child->parent = parent;
565 icalpvl_push(parent->components, child);
568 icalpvl_unshift(parent->components, child);
573 if (!parent->timezones) {
574 parent->timezones = icaltimezone_array_new();
577 if (parent->timezones) {
578 icaltimezone_array_append_from_vtimezone(parent->timezones, child);
582 parent->timezones_sorted = 0;
588 icalpvl_elem itr, next_itr;
590 icalerror_check_arg_rv((parent != 0),
"parent");
591 icalerror_check_arg_rv((child != 0),
"child");
596 size_t i, num_elements;
598 num_elements = parent->timezones ? parent->timezones->num_elements : 0;
599 for (i = 0; i < num_elements; i++) {
609 for (itr = icalpvl_head(parent->components); itr != 0; itr = next_itr) {
610 next_itr = icalpvl_next(itr);
612 if (icalpvl_data(itr) == (
void *)child) {
613 if (parent->component_iterator == itr) {
617 parent->component_iterator = icalpvl_next(parent->component_iterator);
619 (void)icalpvl_remove(parent->components, itr);
631 icalerror_check_arg_rz((component != 0),
"component");
633 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
645 icalerror_check_arg_rz((component != 0),
"component");
647 if (component->component_iterator == 0) {
651 return (icalcomponent *)icalpvl_data(component->component_iterator);
656 icalerror_check_arg_rz((c != 0),
"component");
658 for (c->component_iterator = icalpvl_head(c->components);
659 c->component_iterator != 0; c->component_iterator = icalpvl_next(c->component_iterator)) {
660 icalcomponent *p = (icalcomponent *)icalpvl_data(c->component_iterator);
672 icalerror_check_arg_rz((c != 0),
"component");
674 if (c->component_iterator == 0) {
678 for (c->component_iterator = icalpvl_next(c->component_iterator);
679 c->component_iterator != 0; c->component_iterator = icalpvl_next(c->component_iterator)) {
680 icalcomponent *p = (icalcomponent *)icalpvl_data(c->component_iterator);
693 icalcomponent *cin = (icalcomponent *)c;
715 const icalcomponent *inner;
785 icalproperty *exdate, *exrule;
786 icalpvl_elem property_iterator;
793 property_iterator = comp->property_iterator;
804 comp->property_iterator = property_iterator;
827 comp->property_iterator = property_iterator;
842 comp->property_iterator = property_iterator;
854static bool icalcomponent_is_busy(icalcomponent *comp)
856 const icalproperty *transp;
857 enum icalproperty_status status;
869 switch (icalvalue_get_transp(transp_val)) {
870 case ICAL_TRANSP_OPAQUE:
871 case ICAL_TRANSP_OPAQUENOCONFLICT:
872 case ICAL_TRANSP_NONE:
875 case ICAL_TRANSP_TRANSPARENT:
876 case ICAL_TRANSP_TRANSPARENTNOCONFLICT:
885 if (ret && status != ICAL_STATUS_NONE) {
887 case ICAL_STATUS_CANCELLED:
888 case ICAL_STATUS_TENTATIVE:
900 struct icaltimetype ret = t;
910 return icaltime_with_time(t, 0, 0, 0);
915 icaltime_span ret = {0};
932 icaltime_span ret = {0};
961static int icaldatetimeperiod_start_compare(
const void *a,
const void *b)
973 void (*callback)(icalcomponent *comp,
974 const struct icaltime_span *span,
979 icaltime_span recurspan, basespan, limit_span,
980 rrule_span, rdate_span;
981 icaltime_t limit_start, limit_end, last_start;
986 size_t rdate_idx = 0;
988 icalproperty *rrule, *rdate;
989 icalpvl_elem property_iterator;
991 if (comp == NULL || callback == NULL) {
1014 basespan = icaltime_span_new(dtstart, dtend, 1);
1016 basespan.is_busy = icalcomponent_is_busy(comp);
1022 start = icaltime_at_midnight(start);
1031 end = icaltime_at_midnight(end);
1037#if (SIZEOF_ICALTIME_T > 4)
1038 limit_end = (icaltime_t)LONG_MAX;
1040 limit_end = (icaltime_t)INT_MAX;
1043 limit_span.start = limit_start;
1044 limit_span.end = limit_end;
1046 rrule_span.start = rdate_span.start =
1047 last_start = end_timet + 1;
1052 if ((rrule == NULL) &&
1054 last_start = basespan.start;
1056 if (icaltime_span_overlaps(&basespan, &limit_span)) {
1057 (*callback)(comp, &basespan, callback_data);
1064 icalrecur_iterator *rrule_itr = NULL;
1065 if (rrule != NULL) {
1071 if (recur->
count == 0) {
1084 rrule_span = icaltime_span_from_time(rrule_time, dtduration);
1095 rdate_period = icalproperty_get_rdate(rdate);
1098 if (rdates->num_elements > 0) {
1101 rdate_span = icaltime_span_from_datetimeperiod(rdate_period, dtduration);
1105 if (rdate_idx >= rdates->num_elements ||
1107 rrule_span.start < rdate_span.start)) {
1109 recurspan = rrule_span;
1110 recur_time = rrule_time;
1114 rrule_span = icaltime_span_from_time(rrule_time, dtduration);
1118 recurspan = rdate_span;
1119 recur_time = rdate_period.
time;
1125 if (rdate_idx < rdates->num_elements) {
1127 rdate_span = icaltime_span_from_datetimeperiod(rdate_period, dtduration);
1131 if (recurspan.start > end_timet) {
1135 if (last_start == recurspan.start) {
1138 last_start = recurspan.start;
1141 property_iterator = comp->property_iterator;
1144 &dtstart, &recur_time)) {
1146 if (icaltime_span_overlaps(&recurspan, &limit_span)) {
1147 (*callback)(comp, &recurspan, callback_data);
1150 comp->property_iterator = property_iterator;
1155 if (rrule_itr != NULL) {
1162 icalerror_check_arg_rz(comp != 0,
"comp");
1171 icalerror_check_arg_rz((component != 0),
"component");
1173 for (itr = icalpvl_head(component->properties); itr != 0; itr = icalpvl_next(itr)) {
1174 const icalproperty *p = (icalproperty *)icalpvl_data(itr);
1180 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
1181 icalcomponent *c = (icalcomponent *)icalpvl_data(itr);
1190 icalpvl_elem itr, next_itr;
1192 icalerror_check_arg_rv((component != 0),
"component");
1194 for (itr = icalpvl_head(component->properties); itr != 0; itr = next_itr) {
1195 icalproperty *p = (icalproperty *)icalpvl_data(itr);
1196 next_itr = icalpvl_next(itr);
1204 for (itr = icalpvl_head(component->components); itr != 0; itr = icalpvl_next(itr)) {
1205 icalcomponent *c = (icalcomponent *)icalpvl_data(itr);
1213 icalproperty *p, *next_p;
1221 icalparameter *param =
1227 switch (icalparameter_get_xlicerrortype(param)) {
1228 case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: {
1232 case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: {
1236 case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: {
1240 case ICAL_XLICERRORTYPE_VALUEPARSEERROR: {
1244 case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: {
1254 rst.
debug = icalproperty_get_xlicerror(p);
1270icalcomponent *icalcomponent_get_parent(
const icalcomponent *component)
1272 return component->parent;
1275void icalcomponent_set_parent(icalcomponent *component, icalcomponent *parent)
1277 component->parent = parent;
1283static const icalpropiter icalpropiter_null = {ICAL_NO_PROPERTY, 0};
1285struct icalcomponent_kind_map {
1290static const struct icalcomponent_kind_map component_map[] = {
1346 if (component_map[i].kind == kind) {
1359 if (component_map[i].kind == kind) {
1360 return component_map[i].name;
1380 if (strncasecmp(
string, component_map[i].name, strlen(component_map[i].name)) == 0) {
1381 return component_map[i].kind;
1385 if (strncasecmp(
string,
"X-", 2) == 0) {
1409 icalerror_check_arg_re(component != 0,
"component", icalcompiter_null);
1411 for (i = icalpvl_head(component->components); i != 0; i = icalpvl_next(i)) {
1412 const icalcomponent *c = (icalcomponent *)icalpvl_data(i);
1421 return icalcompiter_null;
1431 icalerror_check_arg_re(component != 0,
"component", icalcompiter_null);
1433 for (i = icalpvl_tail(component->components); i != 0; i = icalpvl_prior(i)) {
1434 const icalcomponent *c = (icalcomponent *)icalpvl_data(i);
1437 itr.iter = icalpvl_next(i);
1443 return icalcompiter_null;
1448 icalerror_check_arg_rz((i != 0),
"i");
1454 for (i->iter = icalpvl_next(i->iter); i->iter != 0; i->iter = icalpvl_next(i->iter)) {
1455 const icalcomponent *c = (icalcomponent *)icalpvl_data(i->iter);
1467 icalerror_check_arg_rz((i != 0),
"i");
1473 for (i->iter = icalpvl_prior(i->iter); i->iter != 0; i->iter = icalpvl_prior(i->iter)) {
1474 const icalcomponent *c = (icalcomponent *)icalpvl_data(i->iter);
1486 icalerror_check_arg_rz((i != 0),
"i");
1492 return icalpvl_data(i->iter);
1497 icalerror_check_arg_re(component != 0,
"component", icalpropiter_null);
1501 for (i = icalpvl_head(component->properties); i != 0; i = icalpvl_next(i)) {
1502 const icalproperty *p = (icalproperty *)icalpvl_data(i);
1505 icalpropiter itr = {kind, i};
1510 return icalpropiter_null;
1519 return !((i->kind == ICAL_NO_PROPERTY) && (i->iter == 0));
1524 icalerror_check_arg_rz((i != 0),
"i");
1530 for (i->iter = icalpvl_next(i->iter); i->iter != 0; i->iter = icalpvl_next(i->iter)) {
1531 const icalproperty *p = (icalproperty *)icalpvl_data(i->iter);
1543 icalerror_check_arg_rz((i != 0),
"i");
1549 return icalpvl_data(i->iter);
1566 prop = icalproperty_new_method(method);
1570 icalproperty_set_method(prop, method);
1578 return ICAL_METHOD_NONE;
1581 return icalproperty_get_method(prop);
1585#define ICALSETUPSET(p_kind) \
1586 icalcomponent *inner; \
1587 icalproperty *prop; \
1588 icalerror_check_arg_rv(comp != 0, "comp"); \
1589 inner = icalcomponent_get_inner(comp); \
1591 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); \
1594 prop = icalcomponent_get_first_property(inner, p_kind);
1601 ICALSETUPSET(ICAL_DTSTART_PROPERTY);
1604 prop = icalproperty_new_dtstart(v);
1610 icalproperty_set_dtstart(prop, v);
1634 icalproperty *end_prop, *dur_prop;
1650 if (end_prop != 0 && dur_prop == 0) {
1652 }
else if (end_prop == 0 && dur_prop != 0) {
1658 duration = icalproperty_get_duration(dur_prop);
1664 }
else if (end_prop == 0 && dur_prop == 0) {
1690 ICALSETUPSET(ICAL_DTEND_PROPERTY);
1698 prop = icalproperty_new_dtend(v);
1704 icalproperty_set_dtend(prop, v);
1713 ICALSETUPSET(ICAL_DURATION_PROPERTY);
1721 prop = icalproperty_new_duration(v);
1724 icalproperty_set_duration(prop, v);
1732 icalproperty *end_prop, *dur_prop;
1751 if (dur_prop != 0 && end_prop == 0) {
1752 ret = icalproperty_get_duration(dur_prop);
1754 }
else if (end_prop != 0 && dur_prop == 0) {
1760 }
else if (end_prop == 0 && dur_prop == 0) {
1776 ICALSETUPSET(ICAL_DTSTAMP_PROPERTY);
1779 prop = icalproperty_new_dtstamp(v);
1783 icalproperty_set_dtstamp(prop, v);
1795 return icalproperty_get_dtstamp(prop);
1800 ICALSETUPSET(ICAL_SUMMARY_PROPERTY)
1803 prop = icalproperty_new_summary(v);
1807 icalproperty_set_summary(prop, v);
1812 icalcomponent *inner;
1815 icalerror_check_arg_rz(comp != 0,
"comp");
1830 return icalproperty_get_summary(prop);
1835 ICALSETUPSET(ICAL_COMMENT_PROPERTY);
1838 prop = icalproperty_new_comment(v);
1842 icalproperty_set_comment(prop, v);
1847 icalcomponent *inner;
1850 icalerror_check_arg_rz(comp != 0,
"comp");
1865 return icalproperty_get_comment(prop);
1870 ICALSETUPSET(ICAL_UID_PROPERTY);
1873 prop = icalproperty_new_uid(v);
1877 icalproperty_set_uid(prop, v);
1882 icalcomponent *inner;
1885 icalerror_check_arg_rz(comp != 0,
"comp");
1900 return icalproperty_get_uid(prop);
1907 ICALSETUPSET(ICAL_RECURRENCEID_PROPERTY);
1910 prop = icalproperty_new_recurrenceid(v);
1916 icalproperty_set_recurrenceid(prop, v);
1925 icalcomponent *inner;
1951 ICALSETUPSET(ICAL_DESCRIPTION_PROPERTY);
1954 prop = icalproperty_new_description(v);
1958 icalproperty_set_description(prop, v);
1963 icalcomponent *inner;
1966 icalerror_check_arg_rz(comp != 0,
"comp");
1981 return icalproperty_get_description(prop);
1986 ICALSETUPSET(ICAL_LOCATION_PROPERTY)
1989 prop = icalproperty_new_location(v);
1993 icalproperty_set_location(prop, v);
1998 icalcomponent *inner;
2001 icalerror_check_arg_rz(comp != 0,
"comp");
2016 return icalproperty_get_location(prop);
2021 ICALSETUPSET(ICAL_SEQUENCE_PROPERTY);
2024 prop = icalproperty_new_sequence(v);
2028 icalproperty_set_sequence(prop, v);
2033 icalcomponent *inner;
2036 icalerror_check_arg_rz(comp != 0,
"comp");
2051 return icalproperty_get_sequence(prop);
2056 ICALSETUPSET(ICAL_STATUS_PROPERTY);
2059 prop = icalproperty_new_status(v);
2063 icalproperty_set_status(prop, v);
2068 icalcomponent *inner;
2071 icalerror_check_arg_rz(comp != 0,
"comp");
2077 return ICAL_STATUS_NONE;
2083 return ICAL_STATUS_NONE;
2086 return icalproperty_get_status(prop);
2205 icalcomponent *subcomp, *next_subcomp;
2206 icalarray *tzids_to_rename;
2216 if (!tzids_to_rename) {
2225 icalcomponent_merge_vtimezone(comp, subcomp, tzids_to_rename);
2228 subcomp = next_subcomp;
2232 if (tzids_to_rename->num_elements != 0) {
2233 icalcomponent_rename_tzids(comp_to_merge, tzids_to_rename);
2236 for (
size_t i = 0; i < tzids_to_rename->num_elements; i++) {
2241 tzids_to_rename = 0;
2251 subcomp = next_subcomp;
2259static void icalcomponent_merge_vtimezone(icalcomponent *comp,
2260 icalcomponent *vtimezone, icalarray *tzids_to_rename)
2262 icalproperty *tzid_prop;
2273 tzid = icalproperty_get_tzid(tzid_prop);
2283 if (!existing_vtimezone) {
2291 if (tzid[0] ==
'/') {
2305 if (!icalcomponent_compare_vtimezones(comp, vtimezone)) {
2309 icalcomponent_handle_conflicting_vtimezones(comp, vtimezone, tzid_prop,
2310 tzid_copy, tzids_to_rename);
2315static void icalcomponent_handle_conflicting_vtimezones(icalcomponent *comp,
2316 icalcomponent *vtimezone,
2317 icalproperty *tzid_prop,
2319 icalarray *tzids_to_rename)
2322 size_t i, num_elements, tzid_len;
2323 char *new_tzid, suffix_buf[32];
2328 tzid_len = icalcomponent_get_tzid_prefix_len(tzid);
2337 num_elements = comp->timezones ? comp->timezones->num_elements : 0;
2338 for (i = 0; i < num_elements; i++) {
2340 const char *existing_tzid;
2341 size_t existing_tzid_len;
2347 existing_tzid_len = icalcomponent_get_tzid_prefix_len(existing_tzid);
2350 if (tzid_len == existing_tzid_len && !strncmp(tzid, existing_tzid, tzid_len)) {
2361 if (!existing_tzid_copy) {
2376 int suffix = atoi(existing_tzid + existing_tzid_len);
2377 if (max_suffix < suffix) {
2378 max_suffix = suffix;
2392 snprintf(suffix_buf,
sizeof(suffix_buf),
"%i", max_suffix + 1);
2393 const size_t len_new_tzid = tzid_len + strlen(suffix_buf) + 1;
2401 strncpy(new_tzid, tzid, tzid_len);
2402 strncpy(new_tzid + tzid_len, suffix_buf, len_new_tzid);
2403 new_tzid[len_new_tzid - 1] =
'\0';
2411static size_t icalcomponent_get_tzid_prefix_len(
const char *tzid)
2418 while (len > 0 && *p >=
'0' && *p <=
'9') {
2431static void icalcomponent_rename_tzids(icalcomponent *comp, icalarray *rename_table)
2436static void icalcomponent_rename_tzids_callback(icalparameter *param,
void *data)
2438 icalarray *rename_table = data;
2442 tzid = icalparameter_get_tzid(param);
2449 for (i = 0; i < rename_table->num_elements - 1; i += 2) {
2458 void (*callback)(icalparameter *param,
void *data),
2459 void *callback_data)
2462 icalcomponent *subcomp;
2471 if (kind == ICAL_DTSTART_PROPERTY ||
2472 kind == ICAL_DTEND_PROPERTY ||
2473 kind == ICAL_DUE_PROPERTY ||
2474 kind == ICAL_EXDATE_PROPERTY ||
2475 kind == ICAL_RDATE_PROPERTY) {
2478 (*callback)(param, callback_data);
2496 size_t lower, upper;
2498 if (!comp->timezones) {
2503 if (!comp->timezones_sorted) {
2504 icalarray_sort(comp->timezones, icalcomponent_compare_timezone_fn);
2505 comp->timezones_sorted = 1;
2510 upper = comp->timezones->num_elements;
2512 while (lower < upper) {
2513 size_t middle = (lower + upper) >> 1;
2516 if (zone_tzid != NULL) {
2517 int cmp = strcmp(tzid, zone_tzid);
2520 }
else if (cmp < 0) {
2534static int icalcomponent_compare_timezone_fn(
const void *elem1,
const void *elem2)
2537 const char *zone1_tzid = 0, *zone2_tzid = 0;
2545 if (zone1_is_valid && !zone2_is_valid) {
2548 if (!zone1_is_valid) {
2549 if (zone2_is_valid) {
2556 return strcmp(zone1_tzid, zone2_tzid);
2563static int icalcomponent_compare_vtimezones(icalcomponent *vtimezone1, icalcomponent *vtimezone2)
2565 icalproperty *prop1, *prop2;
2566 const char *tzid1, *tzid2;
2567 char *tzid2_copy, *string1, *string2;
2576 tzid1 = icalproperty_get_tzid(prop1);
2587 tzid2 = icalproperty_get_tzid(prop2);
2600 icalproperty_set_tzid(prop2, tzid1);
2616 cmp = strcmp(string1, string2);
2622 icalproperty_set_tzid(prop2, tzid2_copy);
2625 return (cmp == 0) ? 1 : 0;
2630 ICALSETUPSET(ICAL_RELCALID_PROPERTY);
2633 prop = icalproperty_new_relcalid(v);
2637 icalproperty_set_relcalid(prop, v);
2642 icalcomponent *inner;
2645 icalerror_check_arg_rz(comp != 0,
"comp");
2659 return icalproperty_get_relcalid(prop);
2670 if (due_prop != 0) {
2672 }
else if (dur_prop != 0) {
2693 if (due_prop == 0 && dur_prop == 0) {
2694 due_prop = icalproperty_new_due(v);
2696 }
else if (due_prop != 0) {
2697 icalproperty_set_due(due_prop, v);
2699 }
else if (dur_prop != 0) {
2706 icalproperty_set_duration(dur_prop, dur);
2714static int strcmpsafe(
const char *a,
const char *b)
2716 return strcmp((a == NULL ?
"" : a),
2717 (b == NULL ?
"" : b));
2720static int prop_compare(
void *a,
void *b)
2722 const icalproperty *p1 = (icalproperty *)a;
2723 const icalproperty *p2 = (icalproperty *)b;
2726 int r = (int)(k1 - k2);
2729 if (k1 == ICAL_X_PROPERTY) {
2743static inline int compare_nullptr(
const void *a,
const void *b)
2753static int comp_compare(
void *a,
void *b)
2755 icalcomponent *c1 = (icalcomponent *)a;
2756 icalcomponent *c2 = (icalcomponent *)b;
2759 int r = (int)(k1 - k2);
2763 (c1->x_name && c2->x_name)) {
2764 r = strcmp(c1->x_name, c2->x_name);
2779 const icalproperty *p1, *p2;
2784 ICAL_TRIGGER_PROPERTY);
2786 ICAL_TRIGGER_PROPERTY);
2792 ICAL_ACTION_PROPERTY);
2794 ICAL_ACTION_PROPERTY);
2799 r = compare_nullptr(p1, p2);
2803 r = compare_nullptr(p1, p2);
2810 ICAL_TZID_PROPERTY);
2812 ICAL_TZID_PROPERTY);
2817 r = compare_nullptr(p1, p2);
2824 ICAL_DTSTART_PROPERTY);
2826 ICAL_DTSTART_PROPERTY);
2832 r = compare_nullptr(p1, p2);
2838 ICAL_VOTER_PROPERTY);
2840 ICAL_VOTER_PROPERTY);
2846 r = compare_nullptr(p1, p2);
2852 ICAL_POLLITEMID_PROPERTY);
2854 ICAL_POLLITEMID_PROPERTY);
2860 r = compare_nullptr(p1, p2);
2886 icalpvl_list sorted_props;
2887 icalpvl_list sorted_comps;
2890 icalerror_check_arg(comp != 0,
"comp");
2895 sorted_props = icalpvl_newlist();
2896 sorted_comps = icalpvl_newlist();
2903 while ((++cnt < max_properties) && ((prop = icalpvl_pop(comp->properties)) != 0)) {
2904 int nparams, remove = 0;
2913 case ICAL_CALSCALE_PROPERTY:
2914 if (strcmp(
"GREGORIAN", icalproperty_get_calscale(prop)) == 0) {
2919 case ICAL_CLASS_PROPERTY:
2920 if (icalproperty_get_class(prop) == ICAL_CLASS_PUBLIC) {
2925 case ICAL_PRIORITY_PROPERTY:
2926 if (icalproperty_get_priority(prop) == 0) {
2931 case ICAL_TRANSP_PROPERTY:
2932 if (icalproperty_get_transp(prop) == ICAL_TRANSP_OPAQUE) {
2937 case ICAL_REPEAT_PROPERTY:
2938 if (icalproperty_get_repeat(prop) == 0) {
2943 case ICAL_SEQUENCE_PROPERTY:
2944 if (icalproperty_get_sequence(prop) == 0) {
2958 icalpvl_insert_ordered(sorted_props, prop_compare, prop);
2963 if (cnt == max_properties) {
2964 while ((prop = icalpvl_pop(comp->properties)) != 0) {
2970 icalpvl_free(comp->properties);
2971 comp->properties = sorted_props;
2974 while ((sub = icalpvl_pop(comp->components)) != 0) {
2976 icalpvl_insert_ordered(sorted_comps, comp_compare, sub);
2979 icalpvl_free(comp->components);
2980 comp->components = sorted_comps;
void * icalarray_element_at(icalarray *array, size_t position)
Access an array element.
void icalarray_free(icalarray *array)
void icalarray_sort(icalarray *array, int(*compare)(const void *, const void *))
Sorts the elements of an icalarray using the given comparison function.
void icalarray_append(icalarray *array, const void *element)
Appends an element to an array.
icalarray * icalarray_new(size_t element_size, size_t increment_size)
void icalarray_remove_element_at(icalarray *array, size_t position)
Removes a given element from an array.
void icalcomponent_remove_property_by_kind(icalcomponent *component, icalproperty_kind kind)
void icalcomponent_convert_errors(icalcomponent *component)
icalcomponent * icalcomponent_new_xstandard(void)
void icalcomponent_set_relcalid(icalcomponent *comp, const char *v)
bool icalcomponent_is_valid(const icalcomponent *component)
icalproperty * icalpropiter_deref(icalpropiter *i)
icalcomponent * icalcomponent_new_vagenda(void)
void icalcomponent_set_uid(icalcomponent *comp, const char *v)
icalcomponent_kind icalcomponent_string_to_kind(const char *string)
void icalcomponent_set_x_name(icalcomponent *comp, const char *name)
struct icaltimetype icalcomponent_get_dtend(icalcomponent *comp)
struct icaltimetype icalcomponent_get_dtstart(icalcomponent *comp)
icalcomponent * icalcomponent_new_vlocation(void)
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)
bool icalcomponent_check_restrictions(icalcomponent *comp)
icalcomponent * icalcomponent_new_vpoll(void)
int icalcomponent_count_properties(icalcomponent *component, icalproperty_kind kind)
icalcomponent * icalcomponent_new_vavailability(void)
icalcomponent * icalcomponent_new_xpatch(void)
icalproperty_method icalcomponent_get_method(icalcomponent *comp)
bool icalcompiter_is_valid(const icalcompiter *i)
icalcomponent * icalcomponent_new_vreply(void)
void icalcomponent_set_recurrenceid(icalcomponent *comp, struct icaltimetype v)
icalcomponent * icalcomponent_new_xvote(void)
struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent *comp)
icalcomponent * icalcompiter_next(icalcompiter *i)
void icalcomponent_set_location(icalcomponent *comp, const char *v)
const char * icalcomponent_get_description(icalcomponent *comp)
void icalcomponent_set_iana_name(icalcomponent *comp, const char *name)
icalcomponent * icalcomponent_get_next_component(icalcomponent *c, icalcomponent_kind kind)
icalcomponent * icalcomponent_get_first_component(icalcomponent *c, icalcomponent_kind kind)
void icalcomponent_set_dtstart(icalcomponent *comp, struct icaltimetype v)
void icalcomponent_set_dtstamp(icalcomponent *comp, struct icaltimetype v)
void icalcomponent_strip_errors(icalcomponent *component)
icalcomponent * icalcomponent_new_vcalendar(void)
void icalcomponent_normalize(icalcomponent *comp)
icalpropiter icalcomponent_begin_property(icalcomponent *component, icalproperty_kind kind)
icalcomponent * icalcomponent_get_current_component(icalcomponent *component)
void icalcomponent_remove_property(icalcomponent *component, icalproperty *property)
char * icalcomponent_as_ical_string(const icalcomponent *component)
const char * icalcomponent_kind_to_string(icalcomponent_kind kind)
enum icalproperty_status icalcomponent_get_status(icalcomponent *comp)
icalcomponent * icalcomponent_new_vjournal(void)
void icalcomponent_remove_component(icalcomponent *parent, icalcomponent *child)
icalcomponent * icalcomponent_new_vpatch(void)
icalcomponent * icalcomponent_new_vfreebusy(void)
icalproperty * icalpropiter_next(icalpropiter *i)
icalcomponent * icalcompiter_deref(icalcompiter *i)
icalcomponent * icalcomponent_vanew(icalcomponent_kind kind,...)
void icalcomponent_set_method(icalcomponent *comp, icalproperty_method method)
icalcomponent * icalcomponent_new(icalcomponent_kind kind)
void icalcomponent_set_summary(icalcomponent *comp, const char *v)
void icalcomponent_set_sequence(icalcomponent *comp, int v)
icalcomponent * icalcomponent_get_inner(icalcomponent *comp)
const char * icalcomponent_get_comment(icalcomponent *comp)
const char * icalcomponent_get_summary(icalcomponent *comp)
icaltime_span icalcomponent_get_span(icalcomponent *comp)
const char * icalcomponent_get_relcalid(icalcomponent *comp)
icalcomponent * icalcomponent_get_first_real_component(const icalcomponent *c)
icalcomponent * icalcomponent_new_vtimezone(void)
struct icaltimetype icalcomponent_get_due(icalcomponent *comp)
void icalcomponent_merge_component(icalcomponent *comp, icalcomponent *comp_to_merge)
bool icalpropiter_is_valid(const icalpropiter *i)
icalcomponent * icalcomponent_new_vresource(void)
bool icalproperty_recurrence_is_excluded(icalcomponent *comp, struct icaltimetype *dtstart, struct icaltimetype *recurtime)
Decides if a recurrence is acceptable.
const char * icalcomponent_get_x_name(const icalcomponent *comp)
int icalcomponent_count_errors(icalcomponent *component)
struct icaldurationtype icalcomponent_get_duration(icalcomponent *comp)
icalcomponent * icalcomponent_clone(const icalcomponent *old)
icalcomponent * icalcomponent_new_iana(const char *iana_name)
icalcomponent * icalcomponent_new_xavailable(void)
icalcomponent * icalcomponent_new_participant(void)
const char * icalcomponent_get_iana_name(const icalcomponent *comp)
icalproperty * icalcomponent_get_current_property(icalcomponent *component)
icaltimezone * icalcomponent_get_timezone(icalcomponent *comp, const char *tzid)
void icalcomponent_set_dtend(icalcomponent *comp, struct icaltimetype v)
const char * icalcomponent_get_uid(icalcomponent *comp)
int icalcomponent_get_sequence(icalcomponent *comp)
icalcompiter icalcomponent_end_component(icalcomponent *component, icalcomponent_kind kind)
const char * icalcomponent_get_component_name(const icalcomponent *comp)
icalcomponent * icalcomponent_new_xdaylight(void)
icalcomponent * icalcomponent_new_valarm(void)
icalcomponent * icalcomponent_new_x(const char *x_name)
void icalcomponent_add_property(icalcomponent *component, icalproperty *property)
void icalcomponent_set_duration(icalcomponent *comp, struct icaldurationtype v)
icalcompiter icalcomponent_begin_component(icalcomponent *component, icalcomponent_kind kind)
char * icalcomponent_as_ical_string_r(const icalcomponent *component)
icalcomponent_kind icalcomponent_isa(const icalcomponent *component)
icalcomponent * icalcompiter_prior(icalcompiter *i)
icalcomponent * icalcomponent_new_vtodo(void)
bool icalcomponent_kind_is_valid(const icalcomponent_kind kind)
char * icalcomponent_get_component_name_r(const icalcomponent *comp)
void icalcomponent_set_status(icalcomponent *comp, enum icalproperty_status v)
void icalcomponent_foreach_tzid(icalcomponent *comp, void(*callback)(icalparameter *param, void *data), void *callback_data)
const char * icalcomponent_get_location(icalcomponent *comp)
void icalcomponent_free(icalcomponent *c)
icalcomponent * icalcomponent_new_vevent(void)
void icalcomponent_set_due(icalcomponent *comp, struct icaltimetype v)
void icalcomponent_foreach_recurrence(icalcomponent *comp, struct icaltimetype start, struct icaltimetype end, void(*callback)(icalcomponent *comp, const struct icaltime_span *span, void *data), void *callback_data)
void icalcomponent_add_component(icalcomponent *parent, icalcomponent *child)
icalproperty * icalcomponent_get_next_property(icalcomponent *c, icalproperty_kind kind)
void icalcomponent_set_description(icalcomponent *comp, const char *v)
icalcomponent * icalcomponent_new_from_string(const char *str)
int icalcomponent_count_components(icalcomponent *component, icalcomponent_kind kind)
void icalcomponent_set_comment(icalcomponent *comp, const char *v)
icalcomponent * icalcomponent_new_vquery(void)
bool icalcomponent_isa_component(const void *component)
icalcomponent * icalcomponent_new_vvoter(void)
struct icaltimetype icalcomponent_get_dtstamp(icalcomponent *comp)
Defines the data structure for iCalendar components.
icalcomponent * icalproperty_get_parent(const icalproperty *property)
struct icaltimetype icalproperty_get_datetime_with_component(icalproperty *prop, icalcomponent *comp)
void icalproperty_set_parent(icalproperty *property, icalcomponent *component)
struct icaldurationtype icalduration_from_times(struct icaltimetype t1, struct icaltimetype t2)
Creates a duration from two icaltimetype endpoints.
struct icaltimetype icalduration_extend(struct icaltimetype t, struct icaldurationtype d)
Extends a time duration.
bool icaldurationtype_is_null_duration(struct icaldurationtype d)
Checks if a duration is a null duration.
struct icaldurationtype icaldurationtype_null_duration(void)
Creates a duration with zero length.
@ ICAL_XDAYLIGHT_COMPONENT
@ ICAL_VLOCATION_COMPONENT
@ ICAL_XSTANDARD_COMPONENT
@ ICAL_VFREEBUSY_COMPONENT
@ ICAL_PARTICIPANT_COMPONENT
@ ICAL_VCALENDAR_COMPONENT
@ ICAL_VAVAILABILITY_COMPONENT
@ ICAL_VSCHEDULE_COMPONENT
@ ICAL_VTIMEZONE_COMPONENT
@ ICAL_VJOURNAL_COMPONENT
@ ICAL_VCOMMAND_COMPONENT
@ ICAL_XLICMIMEPART_COMPONENT
@ ICAL_XAVAILABLE_COMPONENT
@ ICAL_XLICINVALID_COMPONENT
@ ICAL_VRESOURCE_COMPONENT
@ ICAL_3_2_INVPARAM_STATUS
@ ICAL_3_0_INVPROPNAME_STATUS
@ ICAL_3_1_INVPROPVAL_STATUS
@ ICAL_3_4_INVCOMP_STATUS
@ ICAL_3_3_INVPARAMVAL_STATUS
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Error handling for libical.
@ ICAL_MALFORMEDDATA_ERROR
size_t icallimit_get(icallimits_kind kind)
Defines the interface for getting/setting internal library limits.
void icalmemory_free_buffer(void *buf)
Releases a buffer.
char * icalmemory_strdup(const char *s)
Creates a duplicate of a 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_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Common memory management routines.
icalcomponent * icalparser_parse_string(const char *str)
Parses a string and returns the parsed icalcomponent.
icalvalue * icalproperty_get_value(const icalproperty *prop)
bool icalproperty_isa_property(void *property)
void icalproperty_free(icalproperty *p)
char * icalproperty_as_ical_string_r(icalproperty *prop)
icalproperty_kind icalproperty_isa(const icalproperty *p)
int icalproperty_count_parameters(const icalproperty *prop)
const char * icalproperty_get_value_as_string(const icalproperty *prop)
void icalproperty_remove_parameter_by_kind(icalproperty *prop, icalparameter_kind kind)
Removes all parameters with the specified kind.
icalparameter * icalproperty_get_first_parameter(icalproperty *p, icalparameter_kind kind)
void icalproperty_add_parameter(icalproperty *p, icalparameter *parameter)
void icalproperty_normalize(icalproperty *prop)
icalproperty * icalproperty_clone(const icalproperty *old)
const char * icalproperty_get_x_name(const icalproperty *prop)
void icalproperty_set_parameter(icalproperty *prop, icalparameter *parameter)
bool icalrecur_iterator_set_start(icalrecur_iterator *impl, struct icaltimetype start)
void icalrecur_iterator_free(icalrecur_iterator *impl)
icalrecur_iterator * icalrecur_iterator_new(struct icalrecurrencetype *rule, struct icaltimetype dtstart)
struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *impl)
Functions to check if an icalcomponent meets the restrictions imposed by the standard.
bool icalrestriction_check(icalcomponent *comp)
Checks if a given VCALENDAR meets all the restrictions imposed by the standard.
bool icaltime_is_date(const struct icaltimetype t)
const char * icaltime_get_tzid(const struct icaltimetype t)
bool icaltime_is_utc(const struct icaltimetype t)
int icaltime_compare_date_only(const struct icaltimetype a_in, const struct icaltimetype b_in)
bool icaltime_is_null_time(const struct icaltimetype t)
icaltime_t icaltime_as_timet_with_zone(const struct icaltimetype tt, const icaltimezone *zone)
int icaltime_compare(const struct icaltimetype a_in, const struct icaltimetype b_in)
struct icaltimetype icaltime_null_time(void)
icalcomponent * icaltimezone_get_component(icaltimezone *zone)
const char * icaltimezone_get_tzid(icaltimezone *zone)
icaltimezone * icaltimezone_get_utc_timezone(void)
void icaltimezone_free(icaltimezone *zone, int free_struct)
Frees all memory used for the icaltimezone.
Timezone handling routines.
struct _icaltimezone icaltimezone
struct icalperiodtype period
struct icaldurationtype duration
struct icaltimetype start
const icaltimezone * zone