From b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 26 Jun 2004 19:01:18 +0000 Subject: Initial revision --- (limited to 'libical/src/libicalss/icalspanlist.c') diff --git a/libical/src/libicalss/icalspanlist.c b/libical/src/libicalss/icalspanlist.c new file mode 100644 index 0000000..cab6a81 --- a/dev/null +++ b/libical/src/libicalss/icalspanlist.c @@ -0,0 +1,309 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalspanlist.c + CREATOR: ebusboom 23 aug 2000 + + $Id$ + $Locker$ + + (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/ + + + ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ical.h" +#include "icalspanlist.h" +#include "pvl.h" +#include /* for free and malloc */ + +struct icalspanlist_impl { + pvl_list spans; +}; + +int compare_span(void* a, void* b) +{ + struct icaltime_span *span_a = (struct icaltime_span *)a ; + struct icaltime_span *span_b = (struct icaltime_span *)b ; + + if(span_a->start == span_b->start){ + return 0; + } else if(span_a->start < span_b->start){ + return -1; + } else { /*if(span_a->start > span->b.start)*/ + return 1; + } +} + +icalcomponent* icalspanlist_get_inner(icalcomponent* comp) +{ + if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){ + return icalcomponent_get_first_real_component(comp); + } else { + return comp; + } +} + + +void print_span(int c, struct icaltime_span span ); + + +/* Make a free list from a set of component */ +icalspanlist* icalspanlist_new(icalset *set, + struct icaltimetype start, + struct icaltimetype end) +{ + struct icaltime_span range; + pvl_elem itr; + icalcomponent *c,*inner; + icalcomponent_kind kind, inner_kind; + struct icalspanlist_impl *sl; + struct icaltime_span *freetime; + + if ( ( sl = (struct icalspanlist_impl*) + malloc(sizeof(struct icalspanlist_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + sl->spans = pvl_newlist(); + + range.start = icaltime_as_timet(start); + range.end = icaltime_as_timet(end); + + printf("Range start: %s",ctime(&range.start)); + printf("Range end : %s",ctime(&range.end)); + + + /* Get a list of spans of busy time from the events in the set + and order the spans based on the start time */ + + for(c = icalset_get_first_component(set); + c != 0; + c = icalset_get_next_component(set)){ + + struct icaltime_span span; + + kind = icalcomponent_isa(c); + inner = icalcomponent_get_inner(c); + + if(!inner){ + continue; + } + + inner_kind = icalcomponent_isa(inner); + + if( kind != ICAL_VEVENT_COMPONENT && + inner_kind != ICAL_VEVENT_COMPONENT){ + continue; + } + + icalerror_clear_errno(); + + span = icalcomponent_get_span(c); + span.is_busy = 1; + + if(icalerrno != ICAL_NO_ERROR){ + continue; + } + + if ((range.start < span.end && icaltime_is_null_time(end)) || + (range.start < span.end && range.end > span.start )){ + + struct icaltime_span *s; + + if ((s=(struct icaltime_span *) + malloc(sizeof(struct icaltime_span))) == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + memcpy(s,&span,sizeof(span)); + + pvl_insert_ordered(sl->spans,compare_span,(void*)s); + + } + } + + /* Now Fill in the free time spans. loop through the spans. if the + start of the range is not within the span, create a free entry + that runs from the start of the range to the start of the + span. */ + + for( itr = pvl_head(sl->spans); + itr != 0; + itr = pvl_next(itr)) + { + struct icaltime_span *s = (icalproperty*)pvl_data(itr); + + if ((freetime=(struct icaltime_span *) + malloc(sizeof(struct icaltime_span))) == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + if(range.start < s->start){ + freetime->start = range.start; + freetime->end = s->start; + + freetime->is_busy = 0; + + + pvl_insert_ordered(sl->spans,compare_span,(void*)freetime); + } else { + free(freetime); + } + + range.start = s->end; + } + + /* If the end of the range is null, then assume that everything + after the last item in the calendar is open and add a span + that indicates this */ + + if( icaltime_is_null_time(end)){ + struct icaltime_span* last_span; + + last_span = pvl_data(pvl_tail(sl->spans)); + + if (last_span != 0){ + + if ((freetime=(struct icaltime_span *) + malloc(sizeof(struct icaltime_span))) == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + freetime->is_busy = 0; + freetime->start = last_span->end; + freetime->end = freetime->start; + pvl_insert_ordered(sl->spans,compare_span,(void*)freetime); + } + } + + + return sl; + +} + +void icalspanlist_free(icalspanlist* s) +{ + struct icaltime_span *span; + struct icalspanlist_impl* impl = (struct icalspanlist_impl*)s; + + while( (span=pvl_pop(impl->spans)) != 0){ + free(span); + } + + pvl_free(impl->spans); + + impl->spans = 0; +} + + +void icalspanlist_dump(icalspanlist* s){ + + int i = 0; + struct icalspanlist_impl* sl = (struct icalspanlist_impl*)s; + pvl_elem itr; + + for( itr = pvl_head(sl->spans); + itr != 0; + itr = pvl_next(itr)) + { + struct icaltime_span *s = (icalproperty*)pvl_data(itr); + + printf("#%02d %d start: %s",++i,s->is_busy,ctime(&s->start)); + printf(" end : %s",ctime(&s->end)); + + } +} + +icalcomponent* icalspanlist_make_free_list(icalspanlist* sl); +icalcomponent* icalspanlist_make_busy_list(icalspanlist* sl); + +struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl, + struct icaltimetype t) +{ + struct icalspanlist_impl* impl = (struct icalspanlist_impl*)sl; + pvl_elem itr; + struct icalperiodtype period; + struct icaltime_span *s; + + time_t rangett= icaltime_as_timet(t); + + period.start = icaltime_null_time(); + period.end = icaltime_null_time(); + + /* Is the reference time before the first span? If so, assume + that the reference time is free */ + itr = pvl_head(impl->spans); + s = (icalproperty*)pvl_data(itr); + + if (s == 0){ + /* No elements in span */ + return period; + } + + if(rangett start ){ + /* End of period is start of first span if span is busy, end + of the span if it is free */ + period.start = t; + + if (s->is_busy == 0){ + period.end = icaltime_from_timet(s->start,0); + } else { + period.end = icaltime_from_timet(s->end,0); + } + + return period; + } + + /* Otherwise, find the first free span that contains the + reference time. */ + + for( itr = pvl_head(impl->spans); + itr != 0; + itr = pvl_next(itr)) + { + s = (icalproperty*)pvl_data(itr); + + if(s->is_busy == 0 && s->start >= rangett && + ( rangett < s->end || s->end == s->start)){ + + if (rangett < s->start){ + period.start = icaltime_from_timet(s->start,0); + } else { + period.start = icaltime_from_timet(rangett,0); + } + + period.end = icaltime_from_timet(s->end,0); + + return period; + } + + } + + period.start = icaltime_null_time(); + period.end = icaltime_null_time(); + + return period; +} + +struct icalperiodtype icalspanlist_next_busy_time(icalspanlist* sl, + struct icaltimetype t); + -- cgit v0.9.0.2