icalerrorenum icaldirset_next_cluster(icaldirset* dset) { char path[ICAL_PATH_MAX]; if (dset->directory_iterator == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return ICAL_INTERNAL_ERROR; } dset->directory_iterator = pvl_next(dset->directory_iterator); if (dset->directory_iterator == 0){ /* There are no more clusters */ if(dset->cluster != 0){ icalcluster_free(dset->cluster); dset->cluster = 0; } return ICAL_NO_ERROR; } snprintf(path,sizeof(path),"%s/%s", dset->dir,(char*)pvl_data(dset->directory_iterator)); icalcluster_free(dset->cluster); dset->cluster = icalfileset_produce_icalcluster(path); return icalerrno; }
int *icalspanlist_as_freebusy_matrix(icalspanlist *sl, int delta_t) { pvl_elem itr; time_t spanduration_secs; int *matrix; time_t 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) { time_t offset_start = s->start / delta_t - sl_start / delta_t; time_t offset_end = (s->end - 1) / delta_t - sl_start / delta_t + 1; time_t i; if (offset_end >= matrix_slots) offset_end = matrix_slots - 1; for (i = offset_start; i < offset_end; i++) { matrix[i]++; } } } return matrix; }
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; }
void pvl_apply(pvl_list l,pvl_applyf f, void *v) { pvl_elem e; for (e=pvl_head(l); e!= 0; e = pvl_next(e)) { (*f)(((struct pvl_elem_t *)e)->d,v); } }
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_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; }
void pvl_clear(pvl_list l) { pvl_elem e = pvl_head(l); pvl_elem next; if (e == 0) { return; } while(e != 0) { next = pvl_next(e); pvl_remove(l,e); e = next; } }
pvl_elem pvl_find(pvl_list l,pvl_findf f,void* v) { pvl_elem e; for (e=pvl_head(l); e!= 0; e = pvl_next(e)) { if ( (*f)(((struct pvl_elem_t *)e)->d,v) == 1) { /* Save this elem for a call to find_next */ ((struct pvl_list_t *)l)->p = e; return e; } } return 0; }
void icalgauge_dump(icalgauge* gauge) { pvl_elem p; printf("--- Select ---\n"); for(p = pvl_head(gauge->select);p!=0;p=pvl_next(p)){ struct icalgauge_where *w = pvl_data(p); if(w->comp != ICAL_NO_COMPONENT){ printf("%s ",icalenum_component_kind_to_string(w->comp)); } if(w->prop != ICAL_NO_PROPERTY){ printf("%s ",icalenum_property_kind_to_string(w->prop)); } if (w->compare != ICALGAUGECOMPARE_NONE){ printf("%d ",w->compare); } if (w->value!=0){ printf("%s",w->value); } printf("\n"); } printf("--- From ---\n"); for(p = pvl_head(gauge->from);p!=0;p=pvl_next(p)){ icalcomponent_kind k = (icalcomponent_kind)pvl_data(p); printf("%s\n",icalenum_component_kind_to_string(k)); } printf("--- Where ---\n"); for(p = pvl_head(gauge->where);p!=0;p=pvl_next(p)){ struct icalgauge_where *w = pvl_data(p); if(w->logic != ICALGAUGELOGIC_NONE){ printf("%d ",w->logic); } if(w->comp != ICAL_NO_COMPONENT){ printf("%s ",icalenum_component_kind_to_string(w->comp)); } if(w->prop != ICAL_NO_PROPERTY){ printf("%s ",icalenum_property_kind_to_string(w->prop)); } if (w->compare != ICALGAUGECOMPARE_NONE){ printf("%d ",w->compare); } if (w->value!=0){ printf("%s",w->value); } printf("\n"); } }
int icalgauge_compare(icalgauge* gauge,icalcomponent* comp) { icalcomponent *inner; int local_pass = 0; int last_clause = 1, this_clause = 1; pvl_elem e; icalcomponent_kind kind; icalproperty *rrule; int compare_recur = 0; icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); if (gauge == 0 || comp == 0) return 0; inner = icalcomponent_get_first_real_component(comp); if(inner == 0){ /* Wally Yau: our component is not always wrapped with * a <VCALENDAR>. It's not an error. * icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); * return 0; */ kind = icalcomponent_isa(comp); if(kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT || kind == ICAL_VJOURNAL_COMPONENT || kind == ICAL_VQUERY_COMPONENT || kind == ICAL_VAGENDA_COMPONENT){ inner = comp; } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } inner = comp; } /* Check that this component is one of the FROM types */ local_pass = 0; for(e = pvl_head(gauge->from);e!=0;e=pvl_next(e)){ icalcomponent_kind k = (icalcomponent_kind)pvl_data(e); if(k == icalcomponent_isa(inner)){ local_pass=1; } } if(local_pass == 0){ return 0; } /**** Check each where clause against the component ****/ for(e = pvl_head(gauge->where);e!=0;e=pvl_next(e)){ struct icalgauge_where *w = pvl_data(e); icalcomponent *sub_comp; icalvalue *v; icalproperty *prop; icalvalue_kind vk; if(w->prop == ICAL_NO_PROPERTY || w->value == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } /* First, create a value from the gauge */ vk = icalenum_property_kind_to_value_kind(w->prop); if(vk == ICAL_NO_VALUE){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } if (w->compare == ICALGAUGECOMPARE_ISNULL || w->compare == ICALGAUGECOMPARE_ISNOTNULL) v = icalvalue_new(vk); else v = icalvalue_new_from_string(vk,w->value); if (v == 0){ /* Keep error set by icalvalue_from-string*/ return 0; } /* Now find the corresponding property in the component, descending into a sub-component if necessary */ if(w->comp == ICAL_NO_COMPONENT){ sub_comp = inner; } else { sub_comp = icalcomponent_get_first_component(inner,w->comp); if(sub_comp == 0){ return 0; } } /* check if it is a recurring */ rrule = icalcomponent_get_first_property(sub_comp,ICAL_RRULE_PROPERTY); if (gauge->expand && rrule) { if (w->prop == ICAL_DTSTART_PROPERTY || w->prop == ICAL_DTEND_PROPERTY || w->prop == ICAL_DUE_PROPERTY){ /** needs to use recurrence-id to do comparison */ compare_recur = 1; } } this_clause = 0; local_pass = (w->compare == ICALGAUGECOMPARE_ISNULL) ? 1 : 0; for(prop = icalcomponent_get_first_property(sub_comp,w->prop); prop != 0; prop = icalcomponent_get_next_property(sub_comp,w->prop)){ icalvalue* prop_value; icalgaugecompare relation; if (w->compare == ICALGAUGECOMPARE_ISNULL) { local_pass = 0; break; } if (w->compare == ICALGAUGECOMPARE_ISNOTNULL) { local_pass = 1; break; } if (compare_recur) { icalproperty *p = icalcomponent_get_first_property(sub_comp, ICAL_RECURRENCEID_PROPERTY); prop_value = icalproperty_get_value(p); } else /* prop value from this component */ prop_value = icalproperty_get_value(prop); relation = (icalgaugecompare)icalvalue_compare(prop_value,v); if (relation == w->compare){ local_pass++; } else if (w->compare == ICALGAUGECOMPARE_LESSEQUAL && ( relation == ICALGAUGECOMPARE_LESS || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_GREATEREQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_NOTEQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_LESS)) { local_pass++; } else { local_pass = 0; } } this_clause = local_pass > 0 ? 1 : 0; /* Now look at the logic operator for this clause to see how the value should be merge with the previous clause */ if(w->logic == ICALGAUGELOGIC_AND){ last_clause = this_clause && last_clause; } else if(w->logic == ICALGAUGELOGIC_OR) { last_clause = this_clause || last_clause; } else { last_clause = this_clause; } icalvalue_free(v); }/**** check next one in where clause ****/ return last_clause; }
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; }
icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) { icalset *data = NULL; icalset *ret = NULL; #ifdef _DLOPEN_TEST pvl_elem e; icalset *impl; if (!icalset_init_done) icalset_init(); for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) { impl = (icalset*)pvl_data(e); if (impl->kind == kind) break; } if (e == 0) { icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); return(NULL); } data = (icalset*)malloc(impl->size); if (data == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); errno = ENOMEM; return 0; } /* The first member of the derived class must be an icalset. */ memset(data,0,impl->size); /* *data = *impl; */ memcpy(data, impl, sizeof(icalset)); data->dsn = strdup(dsn); #else switch(kind) { case ICAL_FILE_SET: data = (icalset*) malloc(sizeof(icalfileset)); if (data == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); errno = ENOMEM; return 0; } memset(data,0,sizeof(icalfileset)); *data = icalset_fileset_init; break; case ICAL_DIR_SET: data = (icalset*) malloc(sizeof(icaldirset)); if (data == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); errno = ENOMEM; return 0; } memset(data,0,sizeof(icaldirset)); *data = icalset_dirset_init; break; #ifdef WITH_BDB4 case ICAL_BDB_SET: data = (icalset*) malloc(sizeof(icalbdbset)); if (data == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); errno = ENOMEM; return 0; } memset(data,0,sizeof(icalbdbset)); *data = icalset_bdbset_init; break; #endif default: icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); /** unimplemented **/ return(NULL); } if ( data == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } data->kind = kind; data->dsn = strdup(dsn); #endif /** call the implementation specific initializer **/ if ((ret = data->init(data, dsn, options)) == NULL) icalset_free(data); return ret; }