aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libicalss/icalspanlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src/libicalss/icalspanlist.c')
-rw-r--r--libical/src/libicalss/icalspanlist.c567
1 files changed, 0 insertions, 567 deletions
diff --git a/libical/src/libicalss/icalspanlist.c b/libical/src/libicalss/icalspanlist.c
deleted file mode 100644
index 6c366fa5ba..0000000000
--- a/libical/src/libicalss/icalspanlist.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/* -*- 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 <libical/ical.h>
-#include "icalspanlist.h"
-
-#include <stdlib.h> /* for free and malloc */
-#include <string.h>
-
-struct icalspanlist_impl {
- pvl_list spans; /**< list of icaltime_span data **/
- struct icaltimetype start; /**< start time of span **/
- struct icaltimetype end; /**< end time of span **/
-};
-
-/** @brief Internal comparison function for two spans
- *
- * @param a a spanlist.
- * @param b another spanlist.
- *
- * @return -1, 0, 1 depending on the comparison of the start times.
- *
- * Used to insert spans into the tree in sorted order.
- */
-
-static 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;
- }
-}
-
-
-/** @brief callback function for collecting spanlists of a
- * series of events.
- *
- * @param comp A valid icalcomponent.
- * @param span The span to insert into data.
- * @param data The actual spanlist to insert into
- *
- * This callback is used by icalcomponent_foreach_recurrence()
- * to build up a spanlist.
- */
-
-static void icalspanlist_new_callback(icalcomponent *comp,
- struct icaltime_span *span,
- void *data)
-{
- icaltime_span *s;
- icalspanlist *sl = (icalspanlist*) data;
-
- if (span->is_busy == 0)
- return;
-
- if ((s=(icaltime_span *) malloc(sizeof(icaltime_span))) == 0) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return;
- }
-
- /** copy span data into allocated memory.. **/
- *s = *span;
- pvl_insert_ordered(sl->spans, compare_span, (void*)s);
-}
-
-
-
-/** @brief Make a free list from a set of VEVENT components.
- *
- * @param set A valid icalset containing VEVENTS
- * @param start The free list starts at this date/time
- * @param end The free list ends at this date/time
- *
- * @return A spanlist corresponding to the VEVENTS
- *
- * Given a set of components, a start time and an end time
- * return a spanlist that contains the free/busy times.
- */
-
-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;
- icalspanlist *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();
- sl->start = start;
- sl->end = end;
-
- range.start = icaltime_as_timet(start);
- range.end = icaltime_as_timet(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)){
-
- 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();
-
- icalcomponent_foreach_recurrence(c, start, end,
- icalspanlist_new_callback,
- (void*)sl);
-
- }
-
- /* 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 = (struct icaltime_span*)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 = (struct icaltime_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;
-}
-
-/** @brief Destructor.
- * @param s A valid icalspanlist
- *
- * Free memory associated with the spanlist
- */
-
-void icalspanlist_free(icalspanlist* s)
-{
- struct icaltime_span *span;
-
- if (s == NULL)
- return;
-
- while( (span=pvl_pop(s->spans)) != 0){
- free(span);
- }
-
- pvl_free(s->spans);
-
- s->spans = 0;
-
- free(s);
-}
-
-
-/** @brief (Debug) print out spanlist to stdout.
- * @param sl A valid icalspanlist.
- */
-
-void icalspanlist_dump(icalspanlist* sl){
- int i = 0;
- pvl_elem itr;
-
- for( itr = pvl_head(sl->spans);
- itr != 0;
- itr = pvl_next(itr))
- {
- struct icaltime_span *s = (struct icaltime_span*)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);
-
-
-/** @brief Find next free time span in a spanlist.
- *
- * @param sl The spanlist to search.
- * @param t The time to start looking.
- *
- * Given a spanlist and a time, find the next period of time
- * that is free
- */
-
-struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl,
- struct icaltimetype t)
-{
- 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();
-
- itr = pvl_head(sl->spans);
- s = (struct icaltime_span *)pvl_data(itr);
-
- if (s == 0){
- /* No elements in span */
- return period;
- }
-
- /* Is the reference time before the first span? If so, assume
- that the reference time is free */
- if(rangett <s->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 == 1){
- 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(sl->spans);
- itr != 0;
- itr = pvl_next(itr))
- {
- s = (struct icaltime_span *)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);
-
-
-/** @brief Returns an hour-by-hour array of free/busy times over a
- * given period.
- *
- * @param sl A valid icalspanlist
- * @param delta_t The time slice to divide by, in seconds. Default 3600.
- *
- * @return A pointer to an array of integers containing the number of
- * busy events in each delta_t time period. The final entry
- * contains the value -1.
- *
- * This calculation is somewhat tricky. This is due to the fact that
- * the time range contains the start time, but does not contain the
- * end time. To perform a proper calculation we subtract one second
- * off the end times to get a true containing time.
- *
- * Also note that if you supplying a spanlist that does not start or
- * end on a time boundary divisible by delta_t you may get results
- * that are not quite what you expect.
- */
-
-int* icalspanlist_as_freebusy_matrix(icalspanlist* sl, int delta_t) {
- pvl_elem itr;
- int spanduration_secs;
- int *matrix;
- int matrix_slots;
- time_t sl_start, sl_end;
-
- icalerror_check_arg_rz( (sl!=0), "spanlist");
-
- if (!delta_t)
- delta_t = 3600;
-
- /** calculate the start and end time as time_t **/
- sl_start = icaltime_as_timet_with_zone(sl->start, icaltimezone_get_utc_timezone());
- sl_end = icaltime_as_timet_with_zone(sl->end, icaltimezone_get_utc_timezone());
-
-
- /** insure that the time period falls on a time boundary divisable
- by delta_t */
-
- sl_start /= delta_t;
- sl_start *= delta_t;
-
- sl_end /= delta_t;
- sl_end *= delta_t;
-
-
- /** find the duration of this spanlist **/
- spanduration_secs = sl_end - sl_start;
-
-
- /** malloc our matrix, add one extra slot for a final -1 **/
- matrix_slots = spanduration_secs/delta_t + 1;
-
- matrix = (int*) malloc(sizeof(int) * matrix_slots);
- if (matrix == NULL) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return NULL;
- }
- memset(matrix, 0, sizeof(int) * matrix_slots);
- matrix[matrix_slots-1] = -1;
-
- /* loop through each span and mark the slots in the array */
-
- for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) {
- struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr);
-
- if (s->is_busy == 1) {
- int offset_start = s->start/delta_t - sl_start/delta_t;
- int offset_end = (s->end - 1) /delta_t - sl_start/delta_t + 1;
- int i;
-
- if (offset_end >= matrix_slots)
- offset_end = matrix_slots - 1;
-
- i = offset_start;
- for (i=offset_start; i < offset_end; i++) {
- matrix[i]++;
- }
- }
- }
- return matrix;
-}
-
-
-/** @brief Return a VFREEBUSY component for the corresponding spanlist
- *
- * @param sl A valid icalspanlist, from icalspanlist_new()
- * @param organizer The organizer specified as MAILTO:user@domain
- * @param attendee The attendee specified as MAILTO:user@domain
- *
- * @return A valid icalcomponent or NULL.
- *
- * This function returns a VFREEBUSY component for the given spanlist.
- * The start time is mapped to DTSTART, the end time to DTEND.
- * Each busy span is represented as a separate FREEBUSY entry.
- * An attendee parameter is required, and organizer parameter is
- * optional.
- */
-
-icalcomponent *icalspanlist_as_vfreebusy(icalspanlist* sl,
- const char* organizer,
- const char* attendee) {
- icalcomponent *comp;
- icalproperty *p;
- struct icaltimetype atime = icaltime_from_timet( time(0),0);
- pvl_elem itr;
- icaltimezone *utc_zone;
- icalparameter *param;
-
- if (!attendee) {
- icalerror_set_errno(ICAL_USAGE_ERROR);
- return 0;
- }
-
- utc_zone = icaltimezone_get_utc_timezone ();
-
- comp = icalcomponent_new_vfreebusy();
-
- icalcomponent_add_property(comp, icalproperty_new_dtstart(sl->start));
- icalcomponent_add_property(comp, icalproperty_new_dtend(sl->end));
- icalcomponent_add_property(comp, icalproperty_new_dtstamp(atime));
-
- if (organizer) {
- icalcomponent_add_property(comp, icalproperty_new_organizer(organizer));
- }
- icalcomponent_add_property(comp, icalproperty_new_attendee(attendee));
-
- /* now add the freebusy sections.. */
-
- for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) {
- struct icalperiodtype period;
- struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr);
-
- if (s->is_busy == 1) {
-
- period.start = icaltime_from_timet_with_zone (s->start, 0, utc_zone);
- period.end = icaltime_from_timet_with_zone (s->end, 0, utc_zone);
- period.duration = icaldurationtype_null_duration();
-
-
- p = icalproperty_new_freebusy(period);
- param = icalparameter_new_fbtype(ICAL_FBTYPE_BUSY);
- icalproperty_add_parameter(p, param);
-
- icalcomponent_add_property(comp, p);
- }
-
- }
-
- return comp;
-}
-
-
-/** @brief Return a spanlist corresponding to the VFREEBUSY portion of
- * an icalcomponent.
- *
- * @param c A valid icalcomponent.
- *
- * @return A valid icalspanlist or NULL if no VFREEBUSY section.
- *
- */
-
-
-icalspanlist *icalspanlist_from_vfreebusy(icalcomponent* comp)
-{
- icalcomponent *inner;
- icalproperty *prop;
- icalspanlist *sl;
-
- icalerror_check_arg_rz((comp != NULL), "comp");
-
- inner = icalcomponent_get_inner(comp);
- if (!inner) return NULL;
-
- if ( ( sl = (icalspanlist*) malloc(sizeof(icalspanlist))) == 0) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return 0;
- }
- sl->spans = pvl_newlist();
-
- /* cycle through each FREEBUSY property, adding to the spanlist */
- for (prop = icalcomponent_get_first_property(inner, ICAL_FREEBUSY_PROPERTY);
- prop != NULL;
- prop = icalcomponent_get_next_property(inner, ICAL_FREEBUSY_PROPERTY)) {
- icaltime_span *s = (icaltime_span *) malloc(sizeof(icaltime_span));
- icalparameter *param;
- struct icalperiodtype period;
- icalparameter_fbtype fbtype;
-
- if (s == 0) {
- icalerror_set_errno(ICAL_NEWFAILED_ERROR);
- return 0;
- }
-
- param = icalproperty_get_first_parameter(prop, ICAL_FBTYPE_PARAMETER);
- fbtype = (param) ? icalparameter_get_fbtype(param) : ICAL_FBTYPE_BUSY;
-
- switch (fbtype) {
- case ICAL_FBTYPE_FREE:
- case ICAL_FBTYPE_NONE:
- case ICAL_FBTYPE_X:
- s->is_busy = 1;
- default:
- s->is_busy = 0;
- }
-
- period = icalproperty_get_freebusy(prop);
- s->start = icaltime_as_timet_with_zone(period.start, icaltimezone_get_utc_timezone());
- s->end = icaltime_as_timet_with_zone(period.end, icaltimezone_get_utc_timezone());
-;
- pvl_insert_ordered(sl->spans, compare_span, (void*)s);
- }
- /** @todo calculate start/end limits.. fill in holes? **/
- return sl;
-}