aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libical/icalcomponent.c
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src/libical/icalcomponent.c')
-rw-r--r--libical/src/libical/icalcomponent.c1917
1 files changed, 0 insertions, 1917 deletions
diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c
deleted file mode 100644
index 64b2e0d97f..0000000000
--- a/libical/src/libical/icalcomponent.c
+++ /dev/null
@@ -1,1917 +0,0 @@
-/*======================================================================
- FILE: icalcomponent.c
- CREATOR: eric 28 April 1999
-
- $Id$
-
-
- (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of either:
-
- The LGPL as published by the Free Software Foundation, version
- 2.1, available at: http://www.fsf.org/copyleft/lesser.html
-
- Or:
-
- The Mozilla Public License Version 1.0. You may obtain a copy of
- the License at http://www.mozilla.org/MPL/
-
- The original code is icalcomponent.c
-
-======================================================================*/
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "icalcomponent.h"
-#include "pvl.h" /* "Pointer-to-void list" */
-#include "icalerror.h"
-#include "icalmemory.h"
-#include "icalenums.h"
-#include "icaltime.h"
-#include "icalarray.h"
-#include "icaltimezone.h"
-#include "icalduration.h"
-#include "icalperiod.h"
-#include "icalparser.h"
-
-#include <stdlib.h> /* for malloc */
-#include <stdarg.h> /* for va_list, etc */
-#include <errno.h>
-#include <assert.h>
-#include <stdio.h> /* for fprintf */
-#include <string.h> /* for strdup */
-
-#define MAX_TMP 1024
-
-struct icalcomponent_impl
-{
- char id[5];
- icalcomponent_kind kind;
- char* x_name;
- pvl_list properties;
- pvl_elem property_iterator;
- pvl_list components;
- pvl_elem component_iterator;
- icalcomponent* parent;
-
- /* An array of icaltimezone structs. We use this so we can do fast
- lookup of timezones using binary searches. timezones_sorted is
- set to 0 whenever we add a timezone, so we remember to sort the
- array before doing a binary search. */
- icalarray* timezones;
- int timezones_sorted;
-};
-
-/* icalproperty functions that only components get to use */
-void icalproperty_set_parent(icalproperty* property,
- icalcomponent* component);
-icalcomponent* icalproperty_get_parent(icalproperty* property);
-void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args);
-icalcomponent* icalcomponent_new_impl (icalcomponent_kind kind);
-int icalcomponent_property_sorter(void *a, void *b);
-
-static void icalcomponent_merge_vtimezone (icalcomponent *comp,
- icalcomponent *vtimezone,
- icalarray *tzids_to_rename);
-static void icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp,
- icalcomponent *vtimezone,
- icalproperty *tzid_prop,
- const char *tzid,
- icalarray *tzids_to_rename);
-static int icalcomponent_get_tzid_prefix_len (const char *tzid);
-static void icalcomponent_rename_tzids(icalcomponent* comp,
- icalarray* rename_table);
-static void icalcomponent_rename_tzids_callback(icalparameter *param,
- void *data);
-static int icalcomponent_compare_vtimezones (icalcomponent *vtimezone1,
- icalcomponent *vtimezone2);
-static int icalcomponent_compare_timezone_fn (const void *elem1,
- const void *elem2);
-
-
-void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args)
-{
- void* vp;
-
- while((vp = va_arg(args, void*)) != 0) {
-
- assert (icalcomponent_isa_component(vp) != 0 ||
- icalproperty_isa_property(vp) != 0 ) ;
-
- if (icalcomponent_isa_component(vp) != 0 ){
-
- icalcomponent_add_component((icalcomponent*)impl,
- (icalcomponent*)vp);
-
- } else if (icalproperty_isa_property(vp) != 0 ){
-
- icalcomponent_add_property((icalcomponent*)impl,
- (icalproperty*)vp);
- }
- }
-}
-
-icalcomponent*
-icalcomponent_new_impl (icalcomponent_kind kind)
-{
- struct icalcomponent_impl* comp;
-
- if ( ( comp = (struct icalcomponent_impl*)
- malloc(sizeof(struct icalcomponent_impl))) == 0) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return 0;
- }
-
- strcpy(comp->id,"comp");
-
- comp->kind = kind;
- comp->properties = pvl_newlist();
- comp->property_iterator = 0;
- comp->components = pvl_newlist();
- comp->component_iterator = 0;
- comp->x_name = 0;
- comp->parent = 0;
- comp->timezones = NULL;
- comp->timezones_sorted = 1;
-
- return comp;
-}
-
-icalcomponent*
-icalcomponent_new (icalcomponent_kind kind)
-{
- return (icalcomponent*)icalcomponent_new_impl(kind);
-}
-
-icalcomponent*
-icalcomponent_vanew (icalcomponent_kind kind, ...)
-{
- va_list args;
-
- struct icalcomponent_impl *impl = icalcomponent_new_impl(kind);
-
- if (impl == 0){
- return 0;
- }
-
- va_start(args,kind);
- icalcomponent_add_children(impl, args);
- va_end(args);
-
- return (icalcomponent*) impl;
-}
-
-icalcomponent* icalcomponent_new_from_string(char* str)
-{
- return icalparser_parse_string(str);
-}
-
-icalcomponent* icalcomponent_new_clone(icalcomponent* component)
-{
- struct icalcomponent_impl *old = (struct icalcomponent_impl*)component;
- struct icalcomponent_impl *new;
- icalproperty *p;
- icalcomponent *c;
- pvl_elem itr;
-
- icalerror_check_arg_rz( (component!=0), "component");
-
- new = icalcomponent_new_impl(old->kind);
-
- if (new == 0){
- return 0;
- }
-
-
- for( itr = pvl_head(old->properties);
- itr != 0;
- itr = pvl_next(itr))
- {
- p = (icalproperty*)pvl_data(itr);
- icalcomponent_add_property(new,icalproperty_new_clone(p));
- }
-
-
- for( itr = pvl_head(old->components);
- itr != 0;
- itr = pvl_next(itr))
- {
- c = (icalcomponent*)pvl_data(itr);
- icalcomponent_add_component(new,icalcomponent_new_clone(c));
- }
-
- return new;
-
-}
-
-
-void
-icalcomponent_free (icalcomponent* component)
-{
- icalproperty* prop;
- icalcomponent* comp;
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rv( (component!=0), "component");
-
-#ifdef ICAL_FREE_ON_LIST_IS_ERROR
- icalerror_assert( (c->parent ==0),"Tried to free a component that is still attached to a parent component");
-#else
- if(c->parent != 0){
- return;
- }
-#endif
-
- if(component != 0 ){
-
- while( (prop=pvl_pop(c->properties)) != 0){
- assert(prop != 0);
- icalproperty_set_parent(prop,0);
- icalproperty_free(prop);
- }
-
- pvl_free(c->properties);
-
- while( (comp=pvl_data(pvl_head(c->components))) != 0){
- assert(comp!=0);
- icalcomponent_remove_component(component,comp);
- icalcomponent_free(comp);
- }
-
- pvl_free(c->components);
-
- if (c->x_name != 0) {
- free(c->x_name);
- }
-
- if (c->timezones)
- icaltimezone_array_free (c->timezones);
-
- c->kind = ICAL_NO_COMPONENT;
- c->properties = 0;
- c->property_iterator = 0;
- c->components = 0;
- c->component_iterator = 0;
- c->x_name = 0;
- c->id[0] = 'X';
- c->timezones = NULL;
-
- free(c);
- }
-
-}
-
-char*
-icalcomponent_as_ical_string (icalcomponent* component)
-{
- char* buf, *out_buf;
- char* tmp_buf;
- size_t buf_size = 1024;
- char* buf_ptr = 0;
- pvl_elem itr;
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
-
-#ifdef ICAL_UNIX_NEWLINE
- char newline[] = "\n";
-#else
- char newline[] = "\r\n";
-#endif
-
- icalcomponent *c;
- icalproperty *p;
- icalcomponent_kind kind = icalcomponent_isa(component);
-
- const char* kind_string;
-
- buf = icalmemory_new_buffer(buf_size);
- buf_ptr = buf;
-
- icalerror_check_arg_rz( (component!=0), "component");
- icalerror_check_arg_rz( (kind!=ICAL_NO_COMPONENT), "component kind is ICAL_NO_COMPONENT");
-
- kind_string = icalenum_component_kind_to_string(kind);
-
- icalerror_check_arg_rz( (kind_string!=0),"Unknown kind of component");
-
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:");
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline);
-
-
-
- for( itr = pvl_head(impl->properties);
- itr != 0;
- itr = pvl_next(itr))
- {
- p = (icalproperty*)pvl_data(itr);
-
- icalerror_assert((p!=0),"Got a null property");
- tmp_buf = icalproperty_as_ical_string(p);
-
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf);
- }
-
-
- for( itr = pvl_head(impl->components);
- itr != 0;
- itr = pvl_next(itr))
- {
- c = (icalcomponent*)pvl_data(itr);
-
- tmp_buf = icalcomponent_as_ical_string(c);
-
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf);
-
- }
-
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:");
- icalmemory_append_string(&buf, &buf_ptr, &buf_size,
- icalenum_component_kind_to_string(kind));
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline);
-
- out_buf = icalmemory_tmp_copy(buf);
- free(buf);
-
- return out_buf;
-}
-
-
-int
-icalcomponent_is_valid (icalcomponent* component)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component;
-
-
- if ( (strcmp(impl->id,"comp") == 0) &&
- impl->kind != ICAL_NO_COMPONENT){
- return 1;
- } else {
- return 0;
- }
-
-}
-
-
-icalcomponent_kind
-icalcomponent_isa (icalcomponent* component)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component;
- icalerror_check_arg_rz( (component!=0), "component");
-
- if(component != 0)
- {
- return impl->kind;
- }
-
- return ICAL_NO_COMPONENT;
-}
-
-
-int
-icalcomponent_isa_component (void* component)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component;
-
- icalerror_check_arg_rz( (component!=0), "component");
-
- if (strcmp(impl->id,"comp") == 0) {
- return 1;
- } else {
- return 0;
- }
-
-}
-
-int icalcomponent_property_sorter(void *a, void *b)
-{
- icalproperty_kind kinda, kindb;
- const char *ksa, *ksb;
-
- kinda = icalproperty_isa((icalproperty*)a);
- kindb = icalproperty_isa((icalproperty*)b);
-
- ksa = icalenum_property_kind_to_string(kinda);
- ksb = icalenum_property_kind_to_string(kindb);
-
- return strcmp(ksa,ksb);
-}
-
-
-void
-icalcomponent_add_property (icalcomponent* component, icalproperty* property)
-{
- struct icalcomponent_impl *impl;
-
- icalerror_check_arg_rv( (component!=0), "component");
- icalerror_check_arg_rv( (property!=0), "property");
-
- impl = (struct icalcomponent_impl*)component;
-
- icalerror_assert( (!icalproperty_get_parent(property)),"The property has already been added to a component. Remove the property with icalcomponent_remove_property before calling icalcomponent_add_property");
-
- icalproperty_set_parent(property,component);
-
-#ifdef ICAL_INSERT_ORDERED
- pvl_insert_ordered(impl->properties,
- icalcomponent_property_sorter,property);
-#else
- pvl_push(impl->properties,property);
-#endif
-
-}
-
-
-void
-icalcomponent_remove_property (icalcomponent* component, icalproperty* property)
-{
- struct icalcomponent_impl *impl;
- pvl_elem itr, next_itr;
- struct icalproperty_impl *pimpl;
-
- icalerror_check_arg_rv( (component!=0), "component");
- icalerror_check_arg_rv( (property!=0), "property");
-
- impl = (struct icalcomponent_impl*)component;
-
- pimpl = (struct icalproperty_impl*)property;
-
- icalerror_assert( (icalproperty_get_parent(property)),"The property is not a member of a component");
-
-
- for( itr = pvl_head(impl->properties);
- itr != 0;
- itr = next_itr)
- {
- next_itr = pvl_next(itr);
-
- if( pvl_data(itr) == (void*)property ){
-
- if (impl->property_iterator == itr){
- impl->property_iterator = pvl_next(itr);
- }
-
- pvl_remove( impl->properties, itr);
- icalproperty_set_parent(property,0);
- }
- }
-}
-
-int
-icalcomponent_count_properties (icalcomponent* component,
- icalproperty_kind kind)
-{
- int count=0;
- pvl_elem itr;
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rz( (component!=0), "component");
-
- for( itr = pvl_head(impl->properties);
- itr != 0;
- itr = pvl_next(itr))
- {
- if(kind == icalproperty_isa((icalproperty*)pvl_data(itr)) ||
- kind == ICAL_ANY_PROPERTY){
- count++;
- }
- }
-
-
- return count;
-
-}
-
-icalproperty* icalcomponent_get_current_property (icalcomponent* component)
-{
-
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
- icalerror_check_arg_rz( (component!=0),"component");
-
- if ((c->property_iterator==0)){
- return 0;
- }
-
- return (icalproperty*) pvl_data(c->property_iterator);
-
-}
-
-icalproperty*
-icalcomponent_get_first_property (icalcomponent* component, icalproperty_kind kind)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
- icalerror_check_arg_rz( (component!=0),"component");
-
- for( c->property_iterator = pvl_head(c->properties);
- c->property_iterator != 0;
- c->property_iterator = pvl_next(c->property_iterator)) {
-
- icalproperty *p = (icalproperty*) pvl_data(c->property_iterator);
-
- if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) {
-
- return p;
- }
- }
- return 0;
-}
-
-icalproperty*
-icalcomponent_get_next_property (icalcomponent* component, icalproperty_kind kind)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
- icalerror_check_arg_rz( (component!=0),"component");
-
- if (c->property_iterator == 0){
- return 0;
- }
-
- for( c->property_iterator = pvl_next(c->property_iterator);
- c->property_iterator != 0;
- c->property_iterator = pvl_next(c->property_iterator)) {
-
- icalproperty *p = (icalproperty*) pvl_data(c->property_iterator);
-
- if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) {
-
- return p;
- }
- }
-
- return 0;
-}
-
-
-icalproperty**
-icalcomponent_get_properties (icalcomponent* component, icalproperty_kind kind);
-
-
-void
-icalcomponent_add_component (icalcomponent* parent, icalcomponent* child)
-{
- struct icalcomponent_impl *impl, *cimpl;
-
- icalerror_check_arg_rv( (parent!=0), "parent");
- icalerror_check_arg_rv( (child!=0), "child");
-
- impl = (struct icalcomponent_impl*)parent;
- cimpl = (struct icalcomponent_impl*)child;
-
- icalerror_assert( (cimpl->parent ==0),"The child component has already been added to a parent component. Remove the component with icalcomponent_remove_component before calling icalcomponent_add_component");
-
- cimpl->parent = parent;
-
- pvl_push(impl->components,child);
-
- /* If the new component is a VTIMEZONE, add it to our array. */
- if (cimpl->kind == ICAL_VTIMEZONE_COMPONENT) {
- /* FIXME: Currently we are also creating this array when loading in
- a builtin VTIMEZONE, when we don't need it. */
- if (!impl->timezones)
- impl->timezones = icaltimezone_array_new ();
-
- icaltimezone_array_append_from_vtimezone (impl->timezones, child);
-
- /* Flag that we need to sort it before doing any binary searches. */
- impl->timezones_sorted = 0;
- }
-}
-
-
-void
-icalcomponent_remove_component (icalcomponent* parent, icalcomponent* child)
-{
- struct icalcomponent_impl *impl,*cimpl;
- pvl_elem itr, next_itr;
-
- icalerror_check_arg_rv( (parent!=0), "parent");
- icalerror_check_arg_rv( (child!=0), "child");
-
- impl = (struct icalcomponent_impl*)parent;
- cimpl = (struct icalcomponent_impl*)child;
-
- /* If the component is a VTIMEZONE, remove it from our array as well. */
- if (cimpl->kind == ICAL_VTIMEZONE_COMPONENT) {
- icaltimezone *zone;
- int i, num_elements;
-
- num_elements = impl->timezones ? impl->timezones->num_elements : 0;
- for (i = 0; i < num_elements; i++) {
- zone = icalarray_element_at (impl->timezones, i);
- if (icaltimezone_get_component (zone) == child) {
- icaltimezone_free (zone, 0);
- icalarray_remove_element_at (impl->timezones, i);
- break;
- }
- }
- }
-
- for( itr = pvl_head(impl->components);
- itr != 0;
- itr = next_itr)
- {
- next_itr = pvl_next(itr);
-
- if( pvl_data(itr) == (void*)child ){
-
- if (impl->component_iterator == itr){
- /* Don't let the current iterator become invalid */
-
- /* HACK. The semantics for this are troubling. */
- impl->component_iterator =
- pvl_next(impl->component_iterator);
-
- }
- pvl_remove( impl->components, itr);
- cimpl->parent = 0;
- break;
- }
- }
-}
-
-
-int
-icalcomponent_count_components (icalcomponent* component,
- icalcomponent_kind kind)
-{
- int count=0;
- pvl_elem itr;
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rz( (component!=0), "component");
-
- for( itr = pvl_head(impl->components);
- itr != 0;
- itr = pvl_next(itr))
- {
- if(kind == icalcomponent_isa((icalcomponent*)pvl_data(itr)) ||
- kind == ICAL_ANY_COMPONENT){
- count++;
- }
- }
-
- return count;
-}
-
-icalcomponent*
-icalcomponent_get_current_component(icalcomponent* component)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rz( (component!=0),"component");
-
- if (c->component_iterator == 0){
- return 0;
- }
-
- return (icalcomponent*) pvl_data(c->component_iterator);
-}
-
-icalcomponent*
-icalcomponent_get_first_component (icalcomponent* component,
- icalcomponent_kind kind)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rz( (component!=0),"component");
-
- for( c->component_iterator = pvl_head(c->components);
- c->component_iterator != 0;
- c->component_iterator = pvl_next(c->component_iterator)) {
-
- icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator);
-
- if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) {
-
- return p;
- }
- }
-
- return 0;
-}
-
-
-icalcomponent*
-icalcomponent_get_next_component (icalcomponent* component, icalcomponent_kind kind)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- icalerror_check_arg_rz( (component!=0),"component");
-
- if (c->component_iterator == 0){
- return 0;
- }
-
- for( c->component_iterator = pvl_next(c->component_iterator);
- c->component_iterator != 0;
- c->component_iterator = pvl_next(c->component_iterator)) {
-
- icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator);
-
- if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) {
-
- return p;
- }
- }
-
- return 0;
-}
-
-icalcomponent* icalcomponent_get_first_real_component(icalcomponent *c)
-{
- icalcomponent *comp;
-
- for(comp = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT);
- comp != 0;
- comp = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT)){
-
- icalcomponent_kind kind = icalcomponent_isa(comp);
-
- if(kind == ICAL_VEVENT_COMPONENT ||
- kind == ICAL_VTODO_COMPONENT ||
- kind == ICAL_VJOURNAL_COMPONENT ){
- return comp;
- }
- }
- return 0;
-}
-
-struct icaltime_span icalcomponent_get_span(icalcomponent* comp)
-{
- icalcomponent *inner;
- icalproperty *p, *duration;
- icalcomponent_kind kind;
- struct icaltime_span span;
- struct icaltimetype start;
-
- span.start = 0;
- span.end = 0;
- span.is_busy= 1;
-
- /* initial Error checking */
-
-/* icalerror_check_arg_rz( (comp!=0),"comp");*/
-
- kind = icalcomponent_isa(comp);
-
- if(kind == ICAL_VCALENDAR_COMPONENT){
- inner = icalcomponent_get_first_real_component(comp);
-
- /* Maybe there is a VTIMEZONE in there */
- if (inner == 0){
- inner = icalcomponent_get_first_component(comp,
- ICAL_VTIMEZONE_COMPONENT);
- }
-
- } else {
- inner = comp;
- }
-
- if (inner == 0){
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/
- return span;
- }
-
- kind = icalcomponent_isa(inner);
-
- if( !( kind == ICAL_VEVENT_COMPONENT ||
- kind == ICAL_VJOURNAL_COMPONENT ||
- kind == ICAL_VTODO_COMPONENT ||
- kind == ICAL_VFREEBUSY_COMPONENT )) {
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/
- return span;
-
- }
-
-
-
- /* Get to work. starting with DTSTART */
-
- p = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY);
-
- if (p ==0 ) {
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- /*icalerror_warn("icalcomponent_get_span: component has no DTSTART time");*/
- return span;
- }
-
-
- start = icalproperty_get_dtstart(p);
-
- icalerror_clear_errno();
-
- /* FIXME: Needs updating to new icaltimezone functions. */
-#if 0
- span.start = icalcomponent_convert_time(p);
-#endif
-
-#ifdef TEST_CONVERT_TIME
- printf("convert time:\n %s %s",
- icalproperty_as_ical_string(p), ctime(&span.start));
-#endif
-
- if(icalerrno != ICAL_NO_ERROR){
- span.start = 0;
- return span;
- }
-
- /* The end time could be specified as either a DTEND or a DURATION */
- p = icalcomponent_get_first_property(inner, ICAL_DTEND_PROPERTY);
- duration = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY);
-
- if (p==0 && duration == 0 && start.is_date != 1) {
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- /*icalerror_warn("icalcomponent_get_span: component has neither DTEND nor DURATION time");*/
- span.start = 0;
- return span;
- }
-
- if (p!=0){
- /* FIXME: Needs updating to new icaltimezone functions. */
-#if 0
- span.end = icalcomponent_convert_time(p);
-#endif
- } else if (start.is_date == 1) {
- /* Duration is all day */
- span.end = span.start + 60*60*24;
- } else {
- /* Use the duration */
- struct icaldurationtype dur;
- time_t durt;
-
-
- dur = icalproperty_get_duration(duration);
-
- durt = icaldurationtype_as_int(dur);
- span.end = span.start+durt;
- }
-
- return span;
-
-}
-
-
-int icalcomponent_count_errors(icalcomponent* component)
-{
- int errors = 0;
- icalproperty *p;
- icalcomponent *c;
- pvl_elem itr;
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
-
- for( itr = pvl_head(impl->properties);
- itr != 0;
- itr = pvl_next(itr))
- {
- p = (icalproperty*)pvl_data(itr);
-
- if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY)
- {
- errors++;
- }
- }
-
-
- for( itr = pvl_head(impl->components);
- itr != 0;
- itr = pvl_next(itr))
- {
- c = (icalcomponent*)pvl_data(itr);
-
- errors += icalcomponent_count_errors(c);
-
- }
-
- return errors;
-}
-
-
-void icalcomponent_strip_errors(icalcomponent* component)
-{
- icalproperty *p;
- icalcomponent *c;
- pvl_elem itr, next_itr;
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
-
- for( itr = pvl_head(impl->properties);
- itr != 0;
- itr = next_itr)
- {
- p = (icalproperty*)pvl_data(itr);
- next_itr = pvl_next(itr);
-
- if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY)
- {
- icalcomponent_remove_property(component,p);
- }
- }
-
- for( itr = pvl_head(impl->components);
- itr != 0;
- itr = pvl_next(itr))
- {
- c = (icalcomponent*)pvl_data(itr);
- icalcomponent_strip_errors(c);
- }
-}
-
-/* Hack. This will change the state of the iterators */
-void icalcomponent_convert_errors(icalcomponent* component)
-{
- icalproperty *p, *next_p;
- icalcomponent *c;
-
- for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY);
- p != 0;
- p = next_p){
-
- next_p = icalcomponent_get_next_property(component,ICAL_ANY_PROPERTY);
-
- if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY)
- {
- struct icalreqstattype rst;
- icalparameter *param = icalproperty_get_first_parameter
- (p,ICAL_XLICERRORTYPE_PARAMETER);
-
- rst.code = ICAL_UNKNOWN_STATUS;
- rst.desc = 0;
-
- switch(icalparameter_get_xlicerrortype(param)){
-
- case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: {
- rst.code = ICAL_3_2_INVPARAM_STATUS;
- break;
- }
- case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: {
- rst.code = ICAL_3_3_INVPARAMVAL_STATUS;
- break;
- }
- case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: {
- rst.code = ICAL_3_0_INVPROPNAME_STATUS;
- break;
- }
- case ICAL_XLICERRORTYPE_VALUEPARSEERROR: {
- rst.code = ICAL_3_1_INVPROPVAL_STATUS;
- break;
- }
- case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: {
- rst.code = ICAL_3_4_INVCOMP_STATUS;
- break;
- }
-
- default: {
- }
- }
- if (rst.code != ICAL_UNKNOWN_STATUS){
-
- rst.debug = icalproperty_get_xlicerror(p);
- icalcomponent_add_property(component,
- icalproperty_new_requeststatus(
- icalreqstattype_as_string(rst)
- )
- );
-
- icalcomponent_remove_property(component,p);
- }
- }
- }
-
- for(c = icalcomponent_get_first_component(component,ICAL_ANY_COMPONENT);
- c != 0;
- c = icalcomponent_get_next_component(component,ICAL_ANY_COMPONENT)){
-
- icalcomponent_convert_errors(c);
- }
-}
-
-
-icalcomponent* icalcomponent_get_parent(icalcomponent* component)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- return c->parent;
-}
-
-void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent)
-{
- struct icalcomponent_impl *c = (struct icalcomponent_impl*)component;
-
- c->parent = parent;
-}
-
-icalcompiter icalcompiter_null = {ICAL_NO_COMPONENT,0};
-
-
-struct icalcomponent_kind_map {
- icalcomponent_kind kind;
- char name[20];
-};
-
-
-
-static struct icalcomponent_kind_map component_map[] =
-{
- { ICAL_VEVENT_COMPONENT, "VEVENT" },
- { ICAL_VTODO_COMPONENT, "VTODO" },
- { ICAL_VJOURNAL_COMPONENT, "VJOURNAL" },
- { ICAL_VCALENDAR_COMPONENT, "VCALENDAR" },
- { ICAL_VFREEBUSY_COMPONENT, "VFREEBUSY" },
- { ICAL_VTIMEZONE_COMPONENT, "VTIMEZONE" },
- { ICAL_VALARM_COMPONENT, "VALARM" },
- { ICAL_XSTANDARD_COMPONENT, "STANDARD" }, /*These are part of RFC2445 */
- { ICAL_XDAYLIGHT_COMPONENT, "DAYLIGHT" }, /*but are not really components*/
- { ICAL_X_COMPONENT, "X" },
- { ICAL_VSCHEDULE_COMPONENT, "SCHEDULE" },
-
- /* CAP components */
- { ICAL_VQUERY_COMPONENT, "VQUERY" },
- { ICAL_VCAR_COMPONENT, "VCAR" },
- { ICAL_VCOMMAND_COMPONENT, "VCOMMAND" },
-
- /* libical private components */
- { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" },
- { ICAL_XLICMIMEPART_COMPONENT, "X-LIC-MIME-PART" },
- { ICAL_ANY_COMPONENT, "ANY" },
- { ICAL_XROOT_COMPONENT, "XROOT" },
-
- /* End of list */
- { ICAL_NO_COMPONENT, "" },
-};
-
-
-
-const char* icalcomponent_kind_to_string(icalcomponent_kind kind)
-{
- int i;
-
- for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) {
- if (component_map[i].kind == kind) {
- return component_map[i].name;
- }
- }
-
- return 0;
-
-}
-
-icalcomponent_kind icalcomponent_string_to_kind(const char* string)
-{
- int i;
-
- if (string ==0 ) {
- return ICAL_NO_COMPONENT;
- }
-
- for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) {
- if (strcmp(component_map[i].name, string) == 0) {
- return component_map[i].kind;
- }
- }
-
- return ICAL_NO_COMPONENT;
-}
-
-
-
-icalcompiter
-icalcomponent_begin_component(icalcomponent* component,icalcomponent_kind kind)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
- icalcompiter itr;
- pvl_elem i;
-
- itr.kind = kind;
-
- icalerror_check_arg_re( (component!=0),"component",icalcompiter_null);
-
- for( i = pvl_head(impl->components); i != 0; i = pvl_next(i)) {
-
- icalcomponent *c = (icalcomponent*) pvl_data(i);
-
- if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) {
-
- itr.iter = i;
-
- return itr;
- }
- }
-
- return icalcompiter_null;
-}
-
-icalcompiter
-icalcomponent_end_component(icalcomponent* component,icalcomponent_kind kind)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component;
- icalcompiter itr;
- pvl_elem i;
-
- itr.kind = kind;
-
- icalerror_check_arg_re( (component!=0),"component",icalcompiter_null);
-
- for( i = pvl_tail(impl->components); i != 0; i = pvl_prior(i)) {
-
- icalcomponent *c = (icalcomponent*) pvl_data(i);
-
- if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) {
-
- itr.iter = pvl_next(i);
-
- return itr;
- }
- }
-
- return icalcompiter_null;;
-}
-
-
-icalcomponent* icalcompiter_next(icalcompiter* i)
-{
- if (i->iter == 0){
- return 0;
- }
-
- icalerror_check_arg_rz( (i!=0),"i");
-
- for( i->iter = pvl_next(i->iter);
- i->iter != 0;
- i->iter = pvl_next(i->iter)) {
-
- icalcomponent *c = (icalcomponent*) pvl_data(i->iter);
-
- if (icalcomponent_isa(c) == i->kind
- || i->kind == ICAL_ANY_COMPONENT) {
-
- return icalcompiter_deref(i);;
- }
- }
-
- return 0;
-
-}
-
-icalcomponent* icalcompiter_prior(icalcompiter* i)
-{
- if (i->iter == 0){
- return 0;
- }
-
- for( i->iter = pvl_prior(i->iter);
- i->iter != 0;
- i->iter = pvl_prior(i->iter)) {
-
- icalcomponent *c = (icalcomponent*) pvl_data(i->iter);
-
- if (icalcomponent_isa(c) == i->kind
- || i->kind == ICAL_ANY_COMPONENT) {
-
- return icalcompiter_deref(i);;
- }
- }
-
- return 0;
-
-}
-icalcomponent* icalcompiter_deref(icalcompiter* i)
-{
- if(i->iter ==0){
- return 0;
- }
-
- return pvl_data(i->iter);
-}
-
-icalcomponent* icalcomponent_get_inner(icalcomponent* comp)
-{
- if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){
- return icalcomponent_get_first_real_component(comp);
- } else {
- return comp;
- }
-}
-
-
-void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v)
-{
-
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY);
-
-
- if (prop == 0){
- prop = icalproperty_new_dtstart(v);
- icalcomponent_add_property(inner, prop);
- }
-
- icalproperty_set_dtstart(prop,v);
-
-}
-
-
-struct icaltimetype icalcomponent_get_dtstart(icalcomponent* comp)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
-
- if (prop == 0){
- return icaltime_null_time();
- }
-
- return icalproperty_get_dtstart(prop);
-}
-
-
-struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
-
- icalproperty *end_prop
- = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
-
- icalproperty *dur_prop
- = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY);
-
-
- if( end_prop == 0 && dur_prop == 0){
- return icaltime_null_time();
- } else if ( end_prop != 0) {
- return icalproperty_get_dtend(end_prop);
- } else if ( dur_prop != 0) {
-
- struct icaltimetype start =
- icalcomponent_get_dtstart(inner);
- struct icaldurationtype duration =
- icalproperty_get_duration(dur_prop);
-
- struct icaltimetype end = icaltime_add(start,duration);
-
- return end;
-
- } else {
- /* Error, both duration and dtend have been specified */
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- return icaltime_null_time();
-
- }
-
-}
-
-
-void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
-
- icalproperty *end_prop
- = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
-
- icalproperty *dur_prop
- = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY);
-
-
- if( end_prop == 0 && dur_prop == 0){
- end_prop = icalproperty_new_dtend(v);
- icalcomponent_add_property(inner,end_prop);
- } else if ( end_prop != 0) {
- icalproperty_set_dtend(end_prop,v);
- } else if ( dur_prop != 0) {
- struct icaltimetype start =
- icalcomponent_get_dtstart(inner);
-
- struct icaltimetype end =
- icalcomponent_get_dtend(inner);
-
- struct icaldurationtype dur
- = icaltime_subtract(end,start);
-
- icalproperty_set_duration(dur_prop,dur);
-
- } else {
- /* Error, both duration and dtend have been specified */
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- }
-}
-
-void icalcomponent_set_duration(icalcomponent* comp,
- struct icaldurationtype v)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
-
- icalproperty *end_prop
- = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
-
- icalproperty *dur_prop
- = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY);
-
-
- if( end_prop == 0 && dur_prop == 0){
- dur_prop = icalproperty_new_duration(v);
- icalcomponent_add_property(inner, dur_prop);
- } else if ( end_prop != 0) {
- struct icaltimetype start =
- icalcomponent_get_dtstart(inner);
-
- struct icaltimetype new_end = icaltime_add(start,v);
-
- icalproperty_set_dtend(end_prop,new_end);
-
- } else if ( dur_prop != 0) {
- icalproperty_set_duration(dur_prop,v);
- } else {
- /* Error, both duration and dtend have been specified */
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- }
-}
-
-struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
-
- icalproperty *end_prop
- = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
-
- icalproperty *dur_prop
- = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY);
-
- struct icaldurationtype null_duration;
- memset(&null_duration,0,sizeof(struct icaldurationtype));
-
-
- if( end_prop == 0 && dur_prop == 0){
- return null_duration;
- } else if ( end_prop != 0) {
- struct icaltimetype start =
- icalcomponent_get_dtstart(inner);
- time_t startt = icaltime_as_timet(start);
-
- struct icaltimetype end =
- icalcomponent_get_dtend(inner);
- time_t endt = icaltime_as_timet(end);
-
- return icaldurationtype_from_int(endt-startt);
- } else if ( dur_prop != 0) {
- return icalproperty_get_duration(dur_prop);
- } else {
- /* Error, both duration and dtend have been specified */
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- return null_duration;
- }
-}
-
-void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method)
-{
- icalproperty *prop
- = icalcomponent_get_first_property(comp, ICAL_METHOD_PROPERTY);
-
-
- if (prop == 0){
- prop = icalproperty_new_method(method);
- icalcomponent_add_property(comp, prop);
- }
-
- icalproperty_set_method(prop,method);
-
-}
-
-icalproperty_method icalcomponent_get_method(icalcomponent* comp)
-{
- icalproperty *prop
- = icalcomponent_get_first_property(comp,ICAL_METHOD_PROPERTY);
-
- if (prop == 0){
- return ICAL_METHOD_NONE;
- }
-
- return icalproperty_get_method(prop);
-}
-
-void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v)
-{
-
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner, ICAL_DTSTAMP_PROPERTY);
-
-
- if (prop == 0){
- prop = icalproperty_new_dtstamp(v);
- icalcomponent_add_property(inner, prop);
- }
-
- icalproperty_set_dtstamp(prop,v);
-
-}
-
-
-struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY);
-
- if (prop == 0){
- return icaltime_null_time();
- }
-
- return icalproperty_get_dtstamp(prop);
-}
-
-
-void icalcomponent_set_summary(icalcomponent* comp, const char* v)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner, ICAL_SUMMARY_PROPERTY);
-
- if (prop == 0){
- prop = icalproperty_new_summary(v);
- icalcomponent_add_property(inner, prop);
- }
-
- icalproperty_set_summary(prop,v);
-}
-
-
-const char* icalcomponent_get_summary(icalcomponent* comp)
-{
- icalcomponent *inner = icalcomponent_get_inner(comp);
- icalproperty *prop
- = icalcomponent_get_first_property(inner,ICAL_SUMMARY_PROPERTY);
-
- if (prop == 0){
- return 0;
- }
-
- return icalproperty_get_summary(prop);
-
-}
-
-void icalcomponent_set_comment(icalcomponent* comp, const char* v);
-const char* icalcomponent_get_comment(icalcomponent* comp);
-
-void icalcomponent_set_uid(icalcomponent* comp, const char* v);
-const char* icalcomponent_get_uid(icalcomponent* comp);
-
-void icalcomponent_set_recurrenceid(icalcomponent* comp,
- struct icaltimetype v);
-struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp);
-
-
-
-
-icalcomponent* icalcomponent_new_vcalendar()
-{
- return icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
-}
-icalcomponent* icalcomponent_new_vevent()
-{
- return icalcomponent_new(ICAL_VEVENT_COMPONENT);
-}
-icalcomponent* icalcomponent_new_vtodo()
-{
- return icalcomponent_new(ICAL_VTODO_COMPONENT);
-}
-icalcomponent* icalcomponent_new_vjournal()
-{
- return icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
-}
-icalcomponent* icalcomponent_new_valarm()
-{
- return icalcomponent_new(ICAL_VALARM_COMPONENT);
-}
-icalcomponent* icalcomponent_new_vfreebusy()
-{
- return icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
-}
-icalcomponent* icalcomponent_new_vtimezone()
-{
- return icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);
-}
-icalcomponent* icalcomponent_new_xstandard()
-{
- return icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
-}
-icalcomponent* icalcomponent_new_xdaylight()
-{
- return icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
-}
-
-
-/*
- * Timezone stuff.
- */
-
-/* This takes 2 VCALENDAR components and merges the second one into the first,
- resolving any problems with conflicting TZIDs. comp_to_merge will no
- longer exist after calling this function. */
-void icalcomponent_merge_component(icalcomponent* comp,
- icalcomponent* comp_to_merge)
-{
- icalcomponent *subcomp, *next_subcomp;
- icalarray *tzids_to_rename;
- int i;
-
- /* Check that both components are VCALENDAR components. */
- assert (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT);
- assert (icalcomponent_isa(comp_to_merge) == ICAL_VCALENDAR_COMPONENT);
-
- /* Step through each subcomponent of comp_to_merge, looking for VTIMEZONEs.
- For each VTIMEZONE found, check if we need to add it to comp and if we
- need to rename it and all TZID references to it. */
- tzids_to_rename = icalarray_new (sizeof (char*), 16);
- subcomp = icalcomponent_get_first_component (comp_to_merge,
- ICAL_VTIMEZONE_COMPONENT);
- while (subcomp) {
- next_subcomp = icalcomponent_get_next_component (comp_to_merge,
- ICAL_VTIMEZONE_COMPONENT);
- /* This will add the VTIMEZONE to comp, if necessary, and also update
- the array of TZIDs we need to rename. */
- icalcomponent_merge_vtimezone (comp, subcomp, tzids_to_rename);
- /* FIXME: Handle possible NEWFAILED error. */
-
- subcomp = next_subcomp;
- }
-
- /* If we need to do any renaming of TZIDs, do it now. */
- if (tzids_to_rename->num_elements != 0) {
- icalcomponent_rename_tzids (comp_to_merge, tzids_to_rename);
-
- /* Now free the tzids_to_rename array. */
- for (i = 0; i < tzids_to_rename->num_elements; i++) {
- free (icalarray_element_at (tzids_to_rename, i));
- }
- icalarray_free (tzids_to_rename);
- }
-
- /* Now move all the components from comp_to_merge to comp, excluding
- VTIMEZONE components. */
- subcomp = icalcomponent_get_first_component (comp_to_merge,
- ICAL_ANY_COMPONENT);
- while (subcomp) {
- next_subcomp = icalcomponent_get_next_component (comp_to_merge,
- ICAL_ANY_COMPONENT);
- if (icalcomponent_isa(subcomp) != ICAL_VTIMEZONE_COMPONENT) {
- icalcomponent_remove_component (comp_to_merge, subcomp);
- icalcomponent_add_component (comp, subcomp);
- }
- subcomp = next_subcomp;
- }
-
- /* Free comp_to_merge. We have moved most of the subcomponents over to
- comp now. */
- icalcomponent_free (comp_to_merge);
-}
-
-
-static void icalcomponent_merge_vtimezone (icalcomponent *comp,
- icalcomponent *vtimezone,
- icalarray *tzids_to_rename)
-{
- icalproperty *tzid_prop;
- const char *tzid;
- char *tzid_copy;
- icaltimezone *existing_vtimezone;
-
- /* Get the TZID of the VTIMEZONE. */
- tzid_prop = icalcomponent_get_first_property (vtimezone, ICAL_TZID_PROPERTY);
- if (!tzid_prop)
- return;
-
- tzid = icalproperty_get_tzid (tzid_prop);
- if (!tzid)
- return;
-
- /* See if there is already a VTIMEZONE in comp with the same TZID. */
- existing_vtimezone = icalcomponent_get_timezone (comp, tzid);
-
- /* If there is no existing VTIMEZONE with the same TZID, we can just move
- the VTIMEZONE to comp and return. */
- if (!existing_vtimezone) {
- icalcomponent_remove_component (icalcomponent_get_parent (vtimezone),
- vtimezone);
- icalcomponent_add_component (comp, vtimezone);
- return;
- }
-
- /* If the TZID has a '/' prefix, then we don't have to worry about the
- clashing TZIDs, as they are supposed to be exactly the same VTIMEZONE. */
- if (tzid[0] == '/')
- return;
-
- /* Now we have two VTIMEZONEs with the same TZID (which isn't a globally
- unique one), so we compare the VTIMEZONE components to see if they are
- the same. If they are, we don't need to do anything. We make a copy of
- the tzid, since the parameter may get modified in these calls. */
- tzid_copy = strdup (tzid);
- if (!tzid_copy) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return;
- }
-
- if (!icalcomponent_compare_vtimezones (existing_vtimezone, vtimezone)) {
- /* FIXME: Handle possible NEWFAILED error. */
-
- /* Now we have two different VTIMEZONEs with the same TZID. */
- icalcomponent_handle_conflicting_vtimezones (comp, vtimezone, tzid_prop,
- tzid_copy, tzids_to_rename);
- }
- free (tzid_copy);
-}
-
-
-static void
-icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp,
- icalcomponent *vtimezone,
- icalproperty *tzid_prop,
- const char *tzid,
- icalarray *tzids_to_rename)
-{
- struct icalcomponent_impl *impl = (struct icalcomponent_impl*)comp;
- int tzid_len, i, suffix, max_suffix = 0, num_elements;
- char *tzid_copy, *new_tzid, suffix_buf[32];
-
- /* Find the length of the TZID without any trailing digits. */
- tzid_len = icalcomponent_get_tzid_prefix_len (tzid);
-
- /* Step through each of the VTIMEZONEs in comp. We may already have the
- clashing VTIMEZONE in the calendar, but it may have been renamed
- (i.e. a unique number added on the end of the TZID, e.g. 'London2').
- So we compare the new VTIMEZONE with any VTIMEZONEs that have the
- same prefix (e.g. 'London'). If it matches any of those, we have to
- rename the TZIDs to that TZID, else we rename to a new TZID, using
- the biggest numeric suffix found + 1. */
- num_elements = impl->timezones ? impl->timezones->num_elements : 0;
- for (i = 0; i < num_elements; i++) {
- icaltimezone *zone;
- char *existing_tzid, *existing_tzid_copy;
- int existing_tzid_len;
-
- zone = icalarray_element_at (impl->timezones, i);
- existing_tzid = icaltimezone_get_tzid (zone);
-
- /* Find the length of the TZID without any trailing digits. */
- existing_tzid_len = icalcomponent_get_tzid_prefix_len (existing_tzid);
-
- /* Check if we have the same prefix. */
- if (tzid_len == existing_tzid_len
- && !strncmp (tzid, existing_tzid, tzid_len)) {
- /* Compare the VTIMEZONEs. */
- if (icalcomponent_compare_vtimezones (icaltimezone_get_component (zone),
- vtimezone)) {
- /* The VTIMEZONEs match, so we can use the existing VTIMEZONE. But
- we have to rename TZIDs to this TZID. */
- tzid_copy = strdup (tzid);
- existing_tzid_copy = strdup (existing_tzid);
- if (!tzid_copy || !existing_tzid_copy) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- } else {
- icalarray_append (tzids_to_rename, tzid_copy);
- icalarray_append (tzids_to_rename, existing_tzid_copy);
- }
- return;
- } else {
- /* FIXME: Handle possible NEWFAILED error. */
-
- /* Convert the suffix to an integer and remember the maximum numeric
- suffix found. */
- suffix = atoi (existing_tzid + existing_tzid_len);
- if (max_suffix < suffix)
- max_suffix = suffix;
- }
- }
- }
-
- /* We didn't find a VTIMEZONE that matched, so we have to rename the TZID,
- using the maximum numerical suffix found + 1. */
- tzid_copy = strdup (tzid);
- sprintf (suffix_buf, "%i", max_suffix + 1);
- new_tzid = malloc (tzid_len + strlen (suffix_buf) + 1);
- if (!new_tzid || !tzid_copy) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return;
- }
-
- strncpy (new_tzid, tzid, tzid_len);
- strcpy (new_tzid + tzid_len, suffix_buf);
- icalarray_append (tzids_to_rename, tzid_copy);
- icalarray_append (tzids_to_rename, new_tzid);
-}
-
-
-/* Returns the length of the TZID, without any trailing digits. */
-static int icalcomponent_get_tzid_prefix_len (const char *tzid)
-{
- int len;
- const char *p;
-
- len = strlen (tzid);
- p = tzid + len - 1;
- while (len > 0 && *p >= '0' && *p <= '9') {
- p--;
- len--;
- }
-
- return len;
-}
-
-
-/* Renames all references to the given TZIDs to a new name. rename_table
- contains pairs of strings - a current TZID, and the new TZID to rename it
- to. */
-static void icalcomponent_rename_tzids(icalcomponent* comp,
- icalarray* rename_table)
-{
- icalcomponent_foreach_tzid (comp, icalcomponent_rename_tzids_callback,
- rename_table);
-}
-
-
-static void icalcomponent_rename_tzids_callback(icalparameter *param, void *data)
-{
- icalarray *rename_table = data;
- const char *tzid;
- int i;
-
- tzid = icalparameter_get_tzid (param);
- if (!tzid)
- return;
-
- /* Step through the rename table to see if the current TZID matches
- any of the ones we want to rename. */
- for (i = 0; i < rename_table->num_elements - 1; i += 2) {
- if (!strcmp (tzid, icalarray_element_at (rename_table, i))) {
- icalparameter_set_tzid (param, icalarray_element_at (rename_table, i + 1));
- break;
- }
- }
-}
-
-
-/* Calls the given function for each TZID parameter found in the component. */
-void icalcomponent_foreach_tzid(icalcomponent* comp,
- void (*callback)(icalparameter *param, void *data),
- void *callback_data)
-{
- icalproperty *prop;
- icalproperty_kind kind;
- icalparameter *param;
- icalcomponent *subcomp;
-
- /* First look for any TZID parameters used in this component itself. */
- prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY);
- while (prop) {
- kind = icalproperty_isa (prop);
-
- /* These are the only properties that can have a TZID. Note that
- COMPLETED, CREATED, DTSTAMP & LASTMODIFIED must be in UTC. */
- if (kind == ICAL_DTSTART_PROPERTY || kind == ICAL_DTEND_PROPERTY
- || kind == ICAL_DUE_PROPERTY || kind == ICAL_EXDATE_PROPERTY
- || kind == ICAL_RDATE_PROPERTY) {
- param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
- if (param)
- (*callback) (param, callback_data);
- }
-
- prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY);
- }
-
- /* Now recursively check child components. */
- subcomp = icalcomponent_get_first_component (comp, ICAL_ANY_COMPONENT);
- while (subcomp) {
- icalcomponent_foreach_tzid (subcomp, callback, callback_data);
- subcomp = icalcomponent_get_next_component (comp, ICAL_ANY_COMPONENT);
- }
-}
-
-
-
-/* Returns the icaltimezone from the component corresponding to the given
- TZID, or NULL if the component does not have a corresponding VTIMEZONE. */
-icaltimezone* icalcomponent_get_timezone(icalcomponent* comp, const char *tzid)
-{
- struct icalcomponent_impl *impl;
- icaltimezone *zone;
- int lower, upper, middle, cmp;
- char *zone_tzid;
-
- impl = (struct icalcomponent_impl*)comp;
-
- if (!impl->timezones)
- return NULL;
-
- /* Sort the array if necessary (by the TZID string). */
- if (!impl->timezones_sorted) {
- icalarray_sort (impl->timezones, icalcomponent_compare_timezone_fn);
- impl->timezones_sorted = 1;
- }
-
- /* Do a simple binary search. */
- lower = middle = 0;
- upper = impl->timezones->num_elements;
-
- while (lower < upper) {
- middle = (lower + upper) >> 1;
- zone = icalarray_element_at (impl->timezones, middle);
- zone_tzid = icaltimezone_get_tzid (zone);
- cmp = strcmp (tzid, zone_tzid);
- if (cmp == 0)
- return zone;
- else if (cmp < 0)
- upper = middle;
- else
- lower = middle + 1;
- }
-
- return NULL;
-}
-
-
-/* A function to compare 2 icaltimezone elements, used for qsort(). */
-static int icalcomponent_compare_timezone_fn (const void *elem1,
- const void *elem2)
-{
- icaltimezone *zone1, *zone2;
- const char *zone1_tzid, *zone2_tzid;
- int retval;
-
- zone1 = (icaltimezone*) elem1;
- zone2 = (icaltimezone*) elem2;
-
- zone1_tzid = icaltimezone_get_tzid (zone1);
- zone2_tzid = icaltimezone_get_tzid (zone2);
-
- return strcmp (zone1_tzid, zone2_tzid);
-}
-
-
-/* Compares 2 VTIMEZONE components to see if they match, ignoring their TZIDs.
- It returns 1 if they match, 0 if they don't, or -1 on error. */
-static int icalcomponent_compare_vtimezones (icalcomponent *vtimezone1,
- icalcomponent *vtimezone2)
-{
- icalproperty *prop1, *prop2;
- const char *tzid1, *tzid2;
- char *tzid2_copy, *string1, *string2;
- int cmp;
-
- /* Get the TZID property of the first VTIMEZONE. */
- prop1 = icalcomponent_get_first_property (vtimezone1, ICAL_TZID_PROPERTY);
- if (!prop1)
- return -1;
-
- tzid1 = icalproperty_get_tzid (prop1);
- if (!tzid1)
- return -1;
-
- /* Get the TZID property of the second VTIMEZONE. */
- prop2 = icalcomponent_get_first_property (vtimezone2, ICAL_TZID_PROPERTY);
- if (!prop2)
- return -1;
-
- tzid2 = icalproperty_get_tzid (prop2);
- if (!tzid2)
- return -1;
-
- /* Copy the second TZID, and set the property to the same as the first
- TZID, since we don't care if these match of not. */
- tzid2_copy = strdup (tzid2);
- if (!tzid2_copy) {
- icalerror_set_errno (ICAL_NEWFAILED_ERROR);
- return 0;
- }
-
- icalproperty_set_tzid (prop2, tzid1);
-
- /* Now convert both VTIMEZONEs to strings and compare them. */
- string1 = icalcomponent_as_ical_string (vtimezone1);
- if (!string1) {
- free (tzid2_copy);
- return -1;
- }
-
- string2 = icalcomponent_as_ical_string (vtimezone2);
- if (!string2) {
- free (string1);
- free (tzid2_copy);
- return -1;
- }
-
- cmp = strcmp (string1, string2);
-
- free (string1);
- free (string2);
-
- /* Now reset the second TZID. */
- icalproperty_set_tzid (prop2, tzid2_copy);
- free (tzid2_copy);
-
- return (cmp == 0) ? 1 : 0;
-}