summaryrefslogtreecommitdiffabout
path: root/libical/src/libicalss/icalspanlist.c
Unidiff
Diffstat (limited to 'libical/src/libicalss/icalspanlist.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libicalss/icalspanlist.c309
1 files changed, 309 insertions, 0 deletions
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 @@
1/* -*- Mode: C -*-
2 ======================================================================
3 FILE: icalspanlist.c
4 CREATOR: ebusboom 23 aug 2000
5
6 $Id$
7 $Locker$
8
9 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of either:
13
14 The LGPL as published by the Free Software Foundation, version
15 2.1, available at: http://www.fsf.org/copyleft/lesser.html
16
17 Or:
18
19 The Mozilla Public License Version 1.0. You may obtain a copy of
20 the License at http://www.mozilla.org/MPL/
21
22
23 ======================================================================*/
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include "ical.h"
30#include "icalspanlist.h"
31#include "pvl.h"
32#include <stdlib.h> /* for free and malloc */
33
34struct icalspanlist_impl {
35 pvl_list spans;
36};
37
38int compare_span(void* a, void* b)
39{
40 struct icaltime_span *span_a = (struct icaltime_span *)a ;
41 struct icaltime_span *span_b = (struct icaltime_span *)b ;
42
43 if(span_a->start == span_b->start){
44 return 0;
45 } else if(span_a->start < span_b->start){
46 return -1;
47 } else { /*if(span_a->start > span->b.start)*/
48 return 1;
49 }
50}
51
52icalcomponent* icalspanlist_get_inner(icalcomponent* comp)
53{
54 if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){
55 return icalcomponent_get_first_real_component(comp);
56 } else {
57 return comp;
58 }
59}
60
61
62void print_span(int c, struct icaltime_span span );
63
64
65/* Make a free list from a set of component */
66icalspanlist* icalspanlist_new(icalset *set,
67 struct icaltimetype start,
68 struct icaltimetype end)
69{
70 struct icaltime_span range;
71 pvl_elem itr;
72 icalcomponent *c,*inner;
73 icalcomponent_kind kind, inner_kind;
74 struct icalspanlist_impl *sl;
75 struct icaltime_span *freetime;
76
77 if ( ( sl = (struct icalspanlist_impl*)
78 malloc(sizeof(struct icalspanlist_impl))) == 0) {
79 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
80 return 0;
81 }
82
83 sl->spans = pvl_newlist();
84
85 range.start = icaltime_as_timet(start);
86 range.end = icaltime_as_timet(end);
87
88 printf("Range start: %s",ctime(&range.start));
89 printf("Range end : %s",ctime(&range.end));
90
91
92 /* Get a list of spans of busy time from the events in the set
93 and order the spans based on the start time */
94
95 for(c = icalset_get_first_component(set);
96 c != 0;
97 c = icalset_get_next_component(set)){
98
99 struct icaltime_span span;
100
101 kind = icalcomponent_isa(c);
102 inner = icalcomponent_get_inner(c);
103
104 if(!inner){
105 continue;
106 }
107
108 inner_kind = icalcomponent_isa(inner);
109
110 if( kind != ICAL_VEVENT_COMPONENT &&
111 inner_kind != ICAL_VEVENT_COMPONENT){
112 continue;
113 }
114
115 icalerror_clear_errno();
116
117 span = icalcomponent_get_span(c);
118 span.is_busy = 1;
119
120 if(icalerrno != ICAL_NO_ERROR){
121 continue;
122 }
123
124 if ((range.start < span.end && icaltime_is_null_time(end)) ||
125 (range.start < span.end && range.end > span.start )){
126
127 struct icaltime_span *s;
128
129 if ((s=(struct icaltime_span *)
130 malloc(sizeof(struct icaltime_span))) == 0){
131 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
132 return 0;
133 }
134
135 memcpy(s,&span,sizeof(span));
136
137 pvl_insert_ordered(sl->spans,compare_span,(void*)s);
138
139 }
140 }
141
142 /* Now Fill in the free time spans. loop through the spans. if the
143 start of the range is not within the span, create a free entry
144 that runs from the start of the range to the start of the
145 span. */
146
147 for( itr = pvl_head(sl->spans);
148 itr != 0;
149 itr = pvl_next(itr))
150 {
151 struct icaltime_span *s = (icalproperty*)pvl_data(itr);
152
153 if ((freetime=(struct icaltime_span *)
154 malloc(sizeof(struct icaltime_span))) == 0){
155 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
156 return 0;
157 }
158
159 if(range.start < s->start){
160 freetime->start = range.start;
161 freetime->end = s->start;
162
163 freetime->is_busy = 0;
164
165
166 pvl_insert_ordered(sl->spans,compare_span,(void*)freetime);
167 } else {
168 free(freetime);
169 }
170
171 range.start = s->end;
172 }
173
174 /* If the end of the range is null, then assume that everything
175 after the last item in the calendar is open and add a span
176 that indicates this */
177
178 if( icaltime_is_null_time(end)){
179 struct icaltime_span* last_span;
180
181 last_span = pvl_data(pvl_tail(sl->spans));
182
183 if (last_span != 0){
184
185 if ((freetime=(struct icaltime_span *)
186 malloc(sizeof(struct icaltime_span))) == 0){
187 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
188 return 0;
189 }
190
191 freetime->is_busy = 0;
192 freetime->start = last_span->end;
193 freetime->end = freetime->start;
194 pvl_insert_ordered(sl->spans,compare_span,(void*)freetime);
195 }
196 }
197
198
199 return sl;
200
201}
202
203void icalspanlist_free(icalspanlist* s)
204{
205 struct icaltime_span *span;
206 struct icalspanlist_impl* impl = (struct icalspanlist_impl*)s;
207
208 while( (span=pvl_pop(impl->spans)) != 0){
209 free(span);
210 }
211
212 pvl_free(impl->spans);
213
214 impl->spans = 0;
215}
216
217
218void icalspanlist_dump(icalspanlist* s){
219
220 int i = 0;
221 struct icalspanlist_impl* sl = (struct icalspanlist_impl*)s;
222 pvl_elem itr;
223
224 for( itr = pvl_head(sl->spans);
225 itr != 0;
226 itr = pvl_next(itr))
227 {
228 struct icaltime_span *s = (icalproperty*)pvl_data(itr);
229
230 printf("#%02d %d start: %s",++i,s->is_busy,ctime(&s->start));
231 printf(" end : %s",ctime(&s->end));
232
233 }
234}
235
236icalcomponent* icalspanlist_make_free_list(icalspanlist* sl);
237icalcomponent* icalspanlist_make_busy_list(icalspanlist* sl);
238
239struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl,
240 struct icaltimetype t)
241{
242 struct icalspanlist_impl* impl = (struct icalspanlist_impl*)sl;
243 pvl_elem itr;
244 struct icalperiodtype period;
245 struct icaltime_span *s;
246
247 time_t rangett= icaltime_as_timet(t);
248
249 period.start = icaltime_null_time();
250 period.end = icaltime_null_time();
251
252 /* Is the reference time before the first span? If so, assume
253 that the reference time is free */
254 itr = pvl_head(impl->spans);
255 s = (icalproperty*)pvl_data(itr);
256
257 if (s == 0){
258 /* No elements in span */
259 return period;
260 }
261
262 if(rangett <s->start ){
263 /* End of period is start of first span if span is busy, end
264 of the span if it is free */
265 period.start = t;
266
267 if (s->is_busy == 0){
268 period.end = icaltime_from_timet(s->start,0);
269 } else {
270 period.end = icaltime_from_timet(s->end,0);
271 }
272
273 return period;
274 }
275
276 /* Otherwise, find the first free span that contains the
277 reference time. */
278
279 for( itr = pvl_head(impl->spans);
280 itr != 0;
281 itr = pvl_next(itr))
282 {
283 s = (icalproperty*)pvl_data(itr);
284
285 if(s->is_busy == 0 && s->start >= rangett &&
286 ( rangett < s->end || s->end == s->start)){
287
288 if (rangett < s->start){
289 period.start = icaltime_from_timet(s->start,0);
290 } else {
291 period.start = icaltime_from_timet(rangett,0);
292 }
293
294 period.end = icaltime_from_timet(s->end,0);
295
296 return period;
297 }
298
299 }
300
301 period.start = icaltime_null_time();
302 period.end = icaltime_null_time();
303
304 return period;
305}
306
307struct icalperiodtype icalspanlist_next_busy_time(icalspanlist* sl,
308 struct icaltimetype t);
309