Diffstat (limited to 'libical/src/libical/icalcomponent.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libical/src/libical/icalcomponent.c | 1488 |
1 files changed, 1488 insertions, 0 deletions
diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c new file mode 100644 index 0000000..af0d3ec --- a/dev/null +++ b/libical/src/libical/icalcomponent.c | |||
@@ -0,0 +1,1488 @@ | |||
1 | /*====================================================================== | ||
2 | FILE: icalcomponent.c | ||
3 | CREATOR: eric 28 April 1999 | ||
4 | |||
5 | $Id$ | ||
6 | |||
7 | |||
8 | (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of either: | ||
12 | |||
13 | The LGPL as published by the Free Software Foundation, version | ||
14 | 2.1, available at: http://www.fsf.org/copyleft/lesser.html | ||
15 | |||
16 | Or: | ||
17 | |||
18 | The Mozilla Public License Version 1.0. You may obtain a copy of | ||
19 | the License at http://www.mozilla.org/MPL/ | ||
20 | |||
21 | The original code is icalcomponent.c | ||
22 | |||
23 | ======================================================================*/ | ||
24 | |||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | #include "config.h" | ||
28 | #endif | ||
29 | |||
30 | #include "icalcomponent.h" | ||
31 | #include "pvl.h" /* "Pointer-to-void list" */ | ||
32 | #include "icalerror.h" | ||
33 | #include "icalmemory.h" | ||
34 | #include "icalenums.h" | ||
35 | #include "icaltime.h" | ||
36 | #include "icalduration.h" | ||
37 | #include "icalperiod.h" | ||
38 | #include "icalparser.h" | ||
39 | |||
40 | #include <stdlib.h> /* for malloc */ | ||
41 | #include <stdarg.h> /* for va_list, etc */ | ||
42 | #include <errno.h> | ||
43 | #include <assert.h> | ||
44 | #include <stdio.h> /* for fprintf */ | ||
45 | #include <string.h> | ||
46 | |||
47 | #define MAX_TMP 1024 | ||
48 | |||
49 | struct icalcomponent_impl | ||
50 | { | ||
51 | char id[5]; | ||
52 | icalcomponent_kind kind; | ||
53 | char* x_name; | ||
54 | pvl_list properties; | ||
55 | pvl_elem property_iterator; | ||
56 | pvl_list components; | ||
57 | pvl_elem component_iterator; | ||
58 | icalcomponent* parent; | ||
59 | }; | ||
60 | |||
61 | /* icalproperty functions that only components get to use */ | ||
62 | void icalproperty_set_parent(icalproperty* property, | ||
63 | icalcomponent* component); | ||
64 | icalcomponent* icalproperty_get_parent(icalproperty* property); | ||
65 | void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args); | ||
66 | icalcomponent* icalcomponent_new_impl (icalcomponent_kind kind); | ||
67 | int icalcomponent_property_sorter(void *a, void *b); | ||
68 | |||
69 | |||
70 | void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args) | ||
71 | { | ||
72 | void* vp; | ||
73 | |||
74 | while((vp = va_arg(args, void*)) != 0) { | ||
75 | |||
76 | assert (icalcomponent_isa_component(vp) != 0 || | ||
77 | icalproperty_isa_property(vp) != 0 ) ; | ||
78 | |||
79 | if (icalcomponent_isa_component(vp) != 0 ){ | ||
80 | |||
81 | icalcomponent_add_component((icalcomponent*)impl, | ||
82 | (icalcomponent*)vp); | ||
83 | |||
84 | } else if (icalproperty_isa_property(vp) != 0 ){ | ||
85 | |||
86 | icalcomponent_add_property((icalcomponent*)impl, | ||
87 | (icalproperty*)vp); | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | icalcomponent* | ||
93 | icalcomponent_new_impl (icalcomponent_kind kind) | ||
94 | { | ||
95 | struct icalcomponent_impl* comp; | ||
96 | |||
97 | if ( ( comp = (struct icalcomponent_impl*) | ||
98 | malloc(sizeof(struct icalcomponent_impl))) == 0) { | ||
99 | icalerror_set_errno(ICAL_NEWFAILED_ERROR); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | strcpy(comp->id,"comp"); | ||
104 | |||
105 | comp->kind = kind; | ||
106 | comp->properties = pvl_newlist(); | ||
107 | comp->property_iterator = 0; | ||
108 | comp->components = pvl_newlist(); | ||
109 | comp->component_iterator = 0; | ||
110 | comp->x_name = 0; | ||
111 | comp->parent = 0; | ||
112 | |||
113 | return comp; | ||
114 | } | ||
115 | |||
116 | icalcomponent* | ||
117 | icalcomponent_new (icalcomponent_kind kind) | ||
118 | { | ||
119 | return (icalcomponent*)icalcomponent_new_impl(kind); | ||
120 | } | ||
121 | |||
122 | icalcomponent* | ||
123 | icalcomponent_vanew (icalcomponent_kind kind, ...) | ||
124 | { | ||
125 | va_list args; | ||
126 | |||
127 | struct icalcomponent_impl *impl = icalcomponent_new_impl(kind); | ||
128 | |||
129 | if (impl == 0){ | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | va_start(args,kind); | ||
134 | icalcomponent_add_children(impl, args); | ||
135 | va_end(args); | ||
136 | |||
137 | return (icalcomponent*) impl; | ||
138 | } | ||
139 | |||
140 | icalcomponent* icalcomponent_new_from_string(char* str) | ||
141 | { | ||
142 | return icalparser_parse_string(str); | ||
143 | } | ||
144 | |||
145 | icalcomponent* icalcomponent_new_clone(icalcomponent* component) | ||
146 | { | ||
147 | struct icalcomponent_impl *old = (struct icalcomponent_impl*)component; | ||
148 | struct icalcomponent_impl *new; | ||
149 | icalproperty *p; | ||
150 | icalcomponent *c; | ||
151 | pvl_elem itr; | ||
152 | |||
153 | icalerror_check_arg_rz( (component!=0), "component"); | ||
154 | |||
155 | new = icalcomponent_new_impl(old->kind); | ||
156 | |||
157 | if (new == 0){ | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | |||
162 | for( itr = pvl_head(old->properties); | ||
163 | itr != 0; | ||
164 | itr = pvl_next(itr)) | ||
165 | { | ||
166 | p = (icalproperty*)pvl_data(itr); | ||
167 | icalcomponent_add_property(new,icalproperty_new_clone(p)); | ||
168 | } | ||
169 | |||
170 | |||
171 | for( itr = pvl_head(old->components); | ||
172 | itr != 0; | ||
173 | itr = pvl_next(itr)) | ||
174 | { | ||
175 | c = (icalcomponent*)pvl_data(itr); | ||
176 | icalcomponent_add_component(new,icalcomponent_new_clone(c)); | ||
177 | } | ||
178 | |||
179 | return new; | ||
180 | |||
181 | } | ||
182 | |||
183 | |||
184 | void | ||
185 | icalcomponent_free (icalcomponent* component) | ||
186 | { | ||
187 | icalproperty* prop; | ||
188 | icalcomponent* comp; | ||
189 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
190 | |||
191 | icalerror_check_arg_rv( (component!=0), "component"); | ||
192 | |||
193 | #ifdef ICAL_FREE_ON_LIST_IS_ERROR | ||
194 | icalerror_assert( (c->parent ==0),"Tried to free a component that is still attached to a parent component"); | ||
195 | #else | ||
196 | if(c->parent != 0){ | ||
197 | return; | ||
198 | } | ||
199 | #endif | ||
200 | |||
201 | if(component != 0 ){ | ||
202 | |||
203 | while( (prop=pvl_pop(c->properties)) != 0){ | ||
204 | assert(prop != 0); | ||
205 | icalproperty_set_parent(prop,0); | ||
206 | icalproperty_free(prop); | ||
207 | } | ||
208 | |||
209 | pvl_free(c->properties); | ||
210 | |||
211 | while( (comp=pvl_data(pvl_head(c->components))) != 0){ | ||
212 | assert(comp!=0); | ||
213 | icalcomponent_remove_component(component,comp); | ||
214 | icalcomponent_free(comp); | ||
215 | } | ||
216 | |||
217 | pvl_free(c->components); | ||
218 | |||
219 | if (c->x_name != 0) { | ||
220 | free(c->x_name); | ||
221 | } | ||
222 | |||
223 | c->kind = ICAL_NO_COMPONENT; | ||
224 | c->properties = 0; | ||
225 | c->property_iterator = 0; | ||
226 | c->components = 0; | ||
227 | c->component_iterator = 0; | ||
228 | c->x_name = 0; | ||
229 | c->id[0] = 'X'; | ||
230 | |||
231 | free(c); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | char* | ||
236 | icalcomponent_as_ical_string (icalcomponent* component) | ||
237 | { | ||
238 | char* buf, *out_buf; | ||
239 | const char* tmp_buf; | ||
240 | size_t buf_size = 1024; | ||
241 | char* buf_ptr = 0; | ||
242 | pvl_elem itr; | ||
243 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
244 | |||
245 | #ifdef ICAL_UNIX_NEWLINE | ||
246 | char newline[] = "\n"; | ||
247 | #else | ||
248 | char newline[] = "\n"; | ||
249 | #endif | ||
250 | icalcomponent *c; | ||
251 | icalproperty *p; | ||
252 | icalcomponent_kind kind = icalcomponent_isa(component); | ||
253 | |||
254 | const char* kind_string; | ||
255 | |||
256 | buf = icalmemory_new_buffer(buf_size); | ||
257 | buf_ptr = buf; | ||
258 | |||
259 | icalerror_check_arg_rz( (component!=0), "component"); | ||
260 | icalerror_check_arg_rz( (kind!=ICAL_NO_COMPONENT), "component kind is ICAL_NO_COMPONENT"); | ||
261 | |||
262 | kind_string = icalcomponent_kind_to_string(kind); | ||
263 | |||
264 | icalerror_check_arg_rz( (kind_string!=0),"Unknown kind of component"); | ||
265 | |||
266 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:"); | ||
267 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); | ||
268 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); | ||
269 | |||
270 | |||
271 | for( itr = pvl_head(impl->properties); | ||
272 | itr != 0; | ||
273 | itr = pvl_next(itr)) | ||
274 | { | ||
275 | // printf("3333calcomponent_as_ical_string System Timezone2: %s %s \n", *tzname, getenv("TZ") ); | ||
276 | |||
277 | p = (icalproperty*)pvl_data(itr); | ||
278 | |||
279 | icalerror_assert((p!=0),"Got a null property"); | ||
280 | tmp_buf = icalproperty_as_ical_string(p); | ||
281 | |||
282 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf); | ||
283 | } | ||
284 | |||
285 | |||
286 | for( itr = pvl_head(impl->components); | ||
287 | itr != 0; | ||
288 | itr = pvl_next(itr)) | ||
289 | { | ||
290 | |||
291 | c = (icalcomponent*)pvl_data(itr); | ||
292 | |||
293 | tmp_buf = icalcomponent_as_ical_string(c); | ||
294 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf); | ||
295 | |||
296 | } | ||
297 | |||
298 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:"); //tzset(); | ||
299 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, | ||
300 | icalcomponent_kind_to_string(kind)); | ||
301 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); //tzset(); | ||
302 | |||
303 | out_buf = icalmemory_tmp_copy(buf); | ||
304 | free(buf); | ||
305 | |||
306 | return out_buf; | ||
307 | } | ||
308 | |||
309 | |||
310 | int | ||
311 | icalcomponent_is_valid (icalcomponent* component) | ||
312 | { | ||
313 | struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; | ||
314 | |||
315 | |||
316 | if ( (strcmp(impl->id,"comp") == 0) && | ||
317 | impl->kind != ICAL_NO_COMPONENT){ | ||
318 | return 1; | ||
319 | } else { | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | } | ||
324 | |||
325 | |||
326 | icalcomponent_kind | ||
327 | icalcomponent_isa (icalcomponent* component) | ||
328 | { | ||
329 | struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; | ||
330 | icalerror_check_arg_rz( (component!=0), "component"); | ||
331 | |||
332 | if(component != 0) | ||
333 | { | ||
334 | return impl->kind; | ||
335 | } | ||
336 | |||
337 | return ICAL_NO_COMPONENT; | ||
338 | } | ||
339 | |||
340 | |||
341 | int | ||
342 | icalcomponent_isa_component (void* component) | ||
343 | { | ||
344 | struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; | ||
345 | |||
346 | icalerror_check_arg_rz( (component!=0), "component"); | ||
347 | |||
348 | if (strcmp(impl->id,"comp") == 0) { | ||
349 | return 1; | ||
350 | } else { | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | } | ||
355 | |||
356 | int icalcomponent_property_sorter(void *a, void *b) | ||
357 | { | ||
358 | icalproperty_kind kinda, kindb; | ||
359 | const char *ksa, *ksb; | ||
360 | |||
361 | kinda = icalproperty_isa((icalproperty*)a); | ||
362 | kindb = icalproperty_isa((icalproperty*)b); | ||
363 | |||
364 | ksa = icalproperty_kind_to_string(kinda); | ||
365 | ksb = icalproperty_kind_to_string(kindb); | ||
366 | |||
367 | return strcmp(ksa,ksb); | ||
368 | } | ||
369 | |||
370 | |||
371 | void | ||
372 | icalcomponent_add_property (icalcomponent* component, icalproperty* property) | ||
373 | { | ||
374 | struct icalcomponent_impl *impl; | ||
375 | |||
376 | icalerror_check_arg_rv( (component!=0), "component"); | ||
377 | icalerror_check_arg_rv( (property!=0), "property"); | ||
378 | |||
379 | impl = (struct icalcomponent_impl*)component; | ||
380 | |||
381 | 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"); | ||
382 | |||
383 | icalproperty_set_parent(property,component); | ||
384 | |||
385 | #ifdef ICAL_INSERT_ORDERED | ||
386 | pvl_insert_ordered(impl->properties, | ||
387 | icalcomponent_property_sorter,property); | ||
388 | #else | ||
389 | pvl_push(impl->properties,property); | ||
390 | #endif | ||
391 | |||
392 | } | ||
393 | |||
394 | |||
395 | void | ||
396 | icalcomponent_remove_property (icalcomponent* component, icalproperty* property) | ||
397 | { | ||
398 | struct icalcomponent_impl *impl; | ||
399 | pvl_elem itr, next_itr; | ||
400 | struct icalproperty_impl *pimpl; | ||
401 | |||
402 | icalerror_check_arg_rv( (component!=0), "component"); | ||
403 | icalerror_check_arg_rv( (property!=0), "property"); | ||
404 | |||
405 | impl = (struct icalcomponent_impl*)component; | ||
406 | |||
407 | pimpl = (struct icalproperty_impl*)property; | ||
408 | |||
409 | icalerror_assert( (icalproperty_get_parent(property)),"The property is not a member of a component"); | ||
410 | |||
411 | |||
412 | for( itr = pvl_head(impl->properties); | ||
413 | itr != 0; | ||
414 | itr = next_itr) | ||
415 | { | ||
416 | next_itr = pvl_next(itr); | ||
417 | |||
418 | if( pvl_data(itr) == (void*)property ){ | ||
419 | |||
420 | if (impl->property_iterator == itr){ | ||
421 | impl->property_iterator = pvl_next(itr); | ||
422 | } | ||
423 | |||
424 | pvl_remove( impl->properties, itr); | ||
425 | icalproperty_set_parent(property,0); | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
430 | int | ||
431 | icalcomponent_count_properties (icalcomponent* component, | ||
432 | icalproperty_kind kind) | ||
433 | { | ||
434 | int count=0; | ||
435 | pvl_elem itr; | ||
436 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
437 | |||
438 | icalerror_check_arg_rz( (component!=0), "component"); | ||
439 | |||
440 | for( itr = pvl_head(impl->properties); | ||
441 | itr != 0; | ||
442 | itr = pvl_next(itr)) | ||
443 | { | ||
444 | if(kind == icalproperty_isa((icalproperty*)pvl_data(itr)) || | ||
445 | kind == ICAL_ANY_PROPERTY){ | ||
446 | count++; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | |||
451 | return count; | ||
452 | |||
453 | } | ||
454 | |||
455 | icalproperty* icalcomponent_get_current_property (icalcomponent* component) | ||
456 | { | ||
457 | |||
458 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
459 | icalerror_check_arg_rz( (component!=0),"component"); | ||
460 | |||
461 | if ((c->property_iterator==0)){ | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | return (icalproperty*) pvl_data(c->property_iterator); | ||
466 | |||
467 | } | ||
468 | |||
469 | icalproperty* | ||
470 | icalcomponent_get_first_property (icalcomponent* component, icalproperty_kind kind) | ||
471 | { | ||
472 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
473 | icalerror_check_arg_rz( (component!=0),"component"); | ||
474 | |||
475 | for( c->property_iterator = pvl_head(c->properties); | ||
476 | c->property_iterator != 0; | ||
477 | c->property_iterator = pvl_next(c->property_iterator)) { | ||
478 | |||
479 | icalproperty *p = (icalproperty*) pvl_data(c->property_iterator); | ||
480 | |||
481 | if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) { | ||
482 | |||
483 | return p; | ||
484 | } | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | icalproperty* | ||
490 | icalcomponent_get_next_property (icalcomponent* component, icalproperty_kind kind) | ||
491 | { | ||
492 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
493 | icalerror_check_arg_rz( (component!=0),"component"); | ||
494 | |||
495 | if (c->property_iterator == 0){ | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | for( c->property_iterator = pvl_next(c->property_iterator); | ||
500 | c->property_iterator != 0; | ||
501 | c->property_iterator = pvl_next(c->property_iterator)) { | ||
502 | |||
503 | icalproperty *p = (icalproperty*) pvl_data(c->property_iterator); | ||
504 | |||
505 | if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) { | ||
506 | |||
507 | return p; | ||
508 | } | ||
509 | } | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | |||
515 | icalproperty** | ||
516 | icalcomponent_get_properties (icalcomponent* component, icalproperty_kind kind); | ||
517 | |||
518 | |||
519 | void | ||
520 | icalcomponent_add_component (icalcomponent* parent, icalcomponent* child) | ||
521 | { | ||
522 | struct icalcomponent_impl *impl, *cimpl; | ||
523 | |||
524 | icalerror_check_arg_rv( (parent!=0), "parent"); | ||
525 | icalerror_check_arg_rv( (child!=0), "child"); | ||
526 | |||
527 | impl = (struct icalcomponent_impl*)parent; | ||
528 | cimpl = (struct icalcomponent_impl*)child; | ||
529 | |||
530 | if (cimpl->parent !=0) { | ||
531 | icalerror_set_errno(ICAL_USAGE_ERROR); | ||
532 | } | ||
533 | |||
534 | cimpl->parent = parent; | ||
535 | |||
536 | pvl_push(impl->components,child); | ||
537 | } | ||
538 | |||
539 | |||
540 | void | ||
541 | icalcomponent_remove_component (icalcomponent* parent, icalcomponent* child) | ||
542 | { | ||
543 | struct icalcomponent_impl *impl,*cimpl; | ||
544 | pvl_elem itr, next_itr; | ||
545 | |||
546 | icalerror_check_arg_rv( (parent!=0), "parent"); | ||
547 | icalerror_check_arg_rv( (child!=0), "child"); | ||
548 | |||
549 | impl = (struct icalcomponent_impl*)parent; | ||
550 | cimpl = (struct icalcomponent_impl*)child; | ||
551 | |||
552 | for( itr = pvl_head(impl->components); | ||
553 | itr != 0; | ||
554 | itr = next_itr) | ||
555 | { | ||
556 | next_itr = pvl_next(itr); | ||
557 | |||
558 | if( pvl_data(itr) == (void*)child ){ | ||
559 | |||
560 | if (impl->component_iterator == itr){ | ||
561 | /* Don't let the current iterator become invalid */ | ||
562 | |||
563 | /* HACK. The semantics for this are troubling. */ | ||
564 | impl->component_iterator = | ||
565 | pvl_next(impl->component_iterator); | ||
566 | |||
567 | } | ||
568 | pvl_remove( impl->components, itr); | ||
569 | cimpl->parent = 0; | ||
570 | break; | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | |||
575 | |||
576 | int | ||
577 | icalcomponent_count_components (icalcomponent* component, | ||
578 | icalcomponent_kind kind) | ||
579 | { | ||
580 | int count=0; | ||
581 | pvl_elem itr; | ||
582 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
583 | |||
584 | icalerror_check_arg_rz( (component!=0), "component"); | ||
585 | |||
586 | for( itr = pvl_head(impl->components); | ||
587 | itr != 0; | ||
588 | itr = pvl_next(itr)) | ||
589 | { | ||
590 | if(kind == icalcomponent_isa((icalcomponent*)pvl_data(itr)) || | ||
591 | kind == ICAL_ANY_COMPONENT){ | ||
592 | count++; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | return count; | ||
597 | } | ||
598 | |||
599 | icalcomponent* | ||
600 | icalcomponent_get_current_component(icalcomponent* component) | ||
601 | { | ||
602 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
603 | |||
604 | icalerror_check_arg_rz( (component!=0),"component"); | ||
605 | |||
606 | if (c->component_iterator == 0){ | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | return (icalcomponent*) pvl_data(c->component_iterator); | ||
611 | } | ||
612 | |||
613 | icalcomponent* | ||
614 | icalcomponent_get_first_component (icalcomponent* component, | ||
615 | icalcomponent_kind kind) | ||
616 | { | ||
617 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
618 | |||
619 | icalerror_check_arg_rz( (component!=0),"component"); | ||
620 | |||
621 | for( c->component_iterator = pvl_head(c->components); | ||
622 | c->component_iterator != 0; | ||
623 | c->component_iterator = pvl_next(c->component_iterator)) { | ||
624 | |||
625 | icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator); | ||
626 | |||
627 | if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) { | ||
628 | |||
629 | return p; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | |||
637 | icalcomponent* | ||
638 | icalcomponent_get_next_component (icalcomponent* component, icalcomponent_kind kind) | ||
639 | { | ||
640 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
641 | |||
642 | icalerror_check_arg_rz( (component!=0),"component"); | ||
643 | |||
644 | if (c->component_iterator == 0){ | ||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | for( c->component_iterator = pvl_next(c->component_iterator); | ||
649 | c->component_iterator != 0; | ||
650 | c->component_iterator = pvl_next(c->component_iterator)) { | ||
651 | |||
652 | icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator); | ||
653 | |||
654 | if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) { | ||
655 | |||
656 | return p; | ||
657 | } | ||
658 | } | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | icalcomponent* icalcomponent_get_first_real_component(icalcomponent *c) | ||
664 | { | ||
665 | icalcomponent *comp; | ||
666 | |||
667 | for(comp = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT); | ||
668 | comp != 0; | ||
669 | comp = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT)){ | ||
670 | |||
671 | icalcomponent_kind kind = icalcomponent_isa(comp); | ||
672 | |||
673 | if(kind == ICAL_VEVENT_COMPONENT || | ||
674 | kind == ICAL_VTODO_COMPONENT || | ||
675 | kind == ICAL_VJOURNAL_COMPONENT || | ||
676 | kind == ICAL_VFREEBUSY_COMPONENT ){ | ||
677 | return comp; | ||
678 | } | ||
679 | } | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | time_t icalcomponent_convert_time(icalproperty *p) | ||
684 | { | ||
685 | struct icaltimetype sict; | ||
686 | time_t convt; | ||
687 | icalproperty *tzp; | ||
688 | |||
689 | |||
690 | /* Though it says _dtstart, it will work for dtend too */ | ||
691 | sict = icalproperty_get_dtstart(p); | ||
692 | |||
693 | tzp = icalproperty_get_first_parameter(p,ICAL_TZID_PARAMETER); | ||
694 | |||
695 | if (sict.is_utc == 1 && tzp != 0){ | ||
696 | icalerror_warn("icalcomponent_get_span: component has a UTC DTSTART with a timezone specified "); | ||
697 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | if(sict.is_utc == 1){ | ||
702 | /* _as_timet will use gmtime() to do the conversion */ | ||
703 | convt = icaltime_as_timet(sict); | ||
704 | |||
705 | #ifdef TEST_CONVERT_TIME | ||
706 | printf("convert time: use as_timet:\n %s\n %s", | ||
707 | icalproperty_as_ical_string(p), ctime(&convt)); | ||
708 | #endif | ||
709 | |||
710 | } else if (sict.is_utc == 0 && tzp == 0 ) { | ||
711 | time_t offset; | ||
712 | |||
713 | /* _as_timet will use localtime() to do the conversion */ | ||
714 | convt = icaltime_as_timet(sict); | ||
715 | offset = icaltime_utc_offset(sict,0); | ||
716 | convt += offset; | ||
717 | |||
718 | #ifdef TEST_CONVERT_TIME | ||
719 | printf("convert time: use as_timet and adjust:\n %s\n %s", | ||
720 | icalproperty_as_ical_string(p), ctime(&convt)); | ||
721 | #endif | ||
722 | } else { | ||
723 | /* Convert the time to UTC for the named timezone*/ | ||
724 | const char* timezone = icalparameter_get_tzid(tzp); | ||
725 | convt = icaltime_as_timet(icaltime_as_utc(sict,timezone)); | ||
726 | |||
727 | #ifdef TEST_CONVERT_TIME | ||
728 | printf("convert time: use _as_utc:\n %s\n %s", | ||
729 | icalproperty_as_ical_string(p), ctime(&convt)); | ||
730 | #endif | ||
731 | } | ||
732 | |||
733 | return convt; | ||
734 | } | ||
735 | struct icaltime_span icalcomponent_get_span(icalcomponent* comp) | ||
736 | { | ||
737 | icalcomponent *inner; | ||
738 | icalproperty *p, *duration; | ||
739 | icalcomponent_kind kind; | ||
740 | struct icaltime_span span; | ||
741 | struct icaltimetype start; | ||
742 | |||
743 | span.start = 0; | ||
744 | span.end = 0; | ||
745 | span.is_busy= 1; | ||
746 | |||
747 | /* initial Error checking */ | ||
748 | |||
749 | /* icalerror_check_arg_rz( (comp!=0),"comp");*/ | ||
750 | |||
751 | kind = icalcomponent_isa(comp); | ||
752 | |||
753 | if(kind == ICAL_VCALENDAR_COMPONENT){ | ||
754 | inner = icalcomponent_get_first_real_component(comp); | ||
755 | |||
756 | /* Maybe there is a VTIMEZONE in there */ | ||
757 | if (inner == 0){ | ||
758 | inner = icalcomponent_get_first_component(comp, | ||
759 | ICAL_VTIMEZONE_COMPONENT); | ||
760 | } | ||
761 | |||
762 | } else { | ||
763 | inner = comp; | ||
764 | } | ||
765 | |||
766 | if (inner == 0){ | ||
767 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
768 | /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/ | ||
769 | return span; | ||
770 | } | ||
771 | |||
772 | kind = icalcomponent_isa(inner); | ||
773 | |||
774 | if( !( kind == ICAL_VEVENT_COMPONENT || | ||
775 | kind == ICAL_VJOURNAL_COMPONENT || | ||
776 | kind == ICAL_VTODO_COMPONENT || | ||
777 | kind == ICAL_VFREEBUSY_COMPONENT )) { | ||
778 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
779 | /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/ | ||
780 | return span; | ||
781 | |||
782 | } | ||
783 | |||
784 | |||
785 | |||
786 | /* Get to work. starting with DTSTART */ | ||
787 | |||
788 | p = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY); | ||
789 | |||
790 | if (p ==0 ) { | ||
791 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
792 | /*icalerror_warn("icalcomponent_get_span: component has no DTSTART time");*/ | ||
793 | return span; | ||
794 | } | ||
795 | |||
796 | |||
797 | start = icalproperty_get_dtstart(p); | ||
798 | |||
799 | icalerror_clear_errno(); | ||
800 | |||
801 | span.start = icalcomponent_convert_time(p); | ||
802 | |||
803 | #ifdef TEST_CONVERT_TIME | ||
804 | printf("convert time:\n %s %s", | ||
805 | icalproperty_as_ical_string(p), ctime(&span.start)); | ||
806 | #endif | ||
807 | |||
808 | if(icalerrno != ICAL_NO_ERROR){ | ||
809 | span.start = 0; | ||
810 | return span; | ||
811 | } | ||
812 | |||
813 | /* The end time could be specified as either a DTEND or a DURATION */ | ||
814 | p = icalcomponent_get_first_property(inner, ICAL_DTEND_PROPERTY); | ||
815 | duration = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); | ||
816 | |||
817 | if (p==0 && duration == 0 && start.is_date != 1) { | ||
818 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
819 | /*icalerror_warn("icalcomponent_get_span: component has neither DTEND nor DURATION time");*/ | ||
820 | span.start = 0; | ||
821 | return span; | ||
822 | } | ||
823 | |||
824 | if (p!=0){ | ||
825 | span.end = icalcomponent_convert_time(p); | ||
826 | } else if (start.is_date == 1) { | ||
827 | /* Duration is all day */ | ||
828 | span.end = span.start + 60*60*24; | ||
829 | } else { | ||
830 | /* Use the duration */ | ||
831 | struct icaldurationtype dur; | ||
832 | time_t durt; | ||
833 | |||
834 | |||
835 | dur = icalproperty_get_duration(duration); | ||
836 | |||
837 | durt = icaldurationtype_as_int(dur); | ||
838 | span.end = span.start+durt; | ||
839 | } | ||
840 | |||
841 | return span; | ||
842 | |||
843 | } | ||
844 | |||
845 | |||
846 | int icalcomponent_count_errors(icalcomponent* component) | ||
847 | { | ||
848 | int errors = 0; | ||
849 | icalproperty *p; | ||
850 | icalcomponent *c; | ||
851 | pvl_elem itr; | ||
852 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
853 | |||
854 | for( itr = pvl_head(impl->properties); | ||
855 | itr != 0; | ||
856 | itr = pvl_next(itr)) | ||
857 | { | ||
858 | p = (icalproperty*)pvl_data(itr); | ||
859 | |||
860 | if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) | ||
861 | { | ||
862 | errors++; | ||
863 | } | ||
864 | } | ||
865 | |||
866 | |||
867 | for( itr = pvl_head(impl->components); | ||
868 | itr != 0; | ||
869 | itr = pvl_next(itr)) | ||
870 | { | ||
871 | c = (icalcomponent*)pvl_data(itr); | ||
872 | |||
873 | errors += icalcomponent_count_errors(c); | ||
874 | |||
875 | } | ||
876 | |||
877 | return errors; | ||
878 | } | ||
879 | |||
880 | |||
881 | void icalcomponent_strip_errors(icalcomponent* component) | ||
882 | { | ||
883 | icalproperty *p; | ||
884 | icalcomponent *c; | ||
885 | pvl_elem itr, next_itr; | ||
886 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
887 | |||
888 | for( itr = pvl_head(impl->properties); | ||
889 | itr != 0; | ||
890 | itr = next_itr) | ||
891 | { | ||
892 | p = (icalproperty*)pvl_data(itr); | ||
893 | next_itr = pvl_next(itr); | ||
894 | |||
895 | if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) | ||
896 | { | ||
897 | icalcomponent_remove_property(component,p); | ||
898 | } | ||
899 | } | ||
900 | |||
901 | for( itr = pvl_head(impl->components); | ||
902 | itr != 0; | ||
903 | itr = pvl_next(itr)) | ||
904 | { | ||
905 | c = (icalcomponent*)pvl_data(itr); | ||
906 | icalcomponent_strip_errors(c); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | /* Hack. This will change the state of the iterators */ | ||
911 | void icalcomponent_convert_errors(icalcomponent* component) | ||
912 | { | ||
913 | icalproperty *p, *next_p; | ||
914 | icalcomponent *c; | ||
915 | |||
916 | for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); | ||
917 | p != 0; | ||
918 | p = next_p){ | ||
919 | |||
920 | next_p = icalcomponent_get_next_property(component,ICAL_ANY_PROPERTY); | ||
921 | |||
922 | if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) | ||
923 | { | ||
924 | struct icalreqstattype rst; | ||
925 | icalparameter *param = icalproperty_get_first_parameter | ||
926 | (p,ICAL_XLICERRORTYPE_PARAMETER); | ||
927 | |||
928 | rst.code = ICAL_UNKNOWN_STATUS; | ||
929 | rst.desc = 0; | ||
930 | |||
931 | switch(icalparameter_get_xlicerrortype(param)){ | ||
932 | |||
933 | case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: { | ||
934 | rst.code = ICAL_3_2_INVPARAM_STATUS; | ||
935 | break; | ||
936 | } | ||
937 | case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { | ||
938 | rst.code = ICAL_3_3_INVPARAMVAL_STATUS; | ||
939 | break; | ||
940 | } | ||
941 | case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: { | ||
942 | rst.code = ICAL_3_0_INVPROPNAME_STATUS; | ||
943 | break; | ||
944 | } | ||
945 | case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { | ||
946 | rst.code = ICAL_3_1_INVPROPVAL_STATUS; | ||
947 | break; | ||
948 | } | ||
949 | case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: { | ||
950 | rst.code = ICAL_3_4_INVCOMP_STATUS; | ||
951 | break; | ||
952 | } | ||
953 | |||
954 | default: { | ||
955 | } | ||
956 | } | ||
957 | if (rst.code != ICAL_UNKNOWN_STATUS){ | ||
958 | |||
959 | rst.debug = icalproperty_get_xlicerror(p); | ||
960 | icalcomponent_add_property(component, | ||
961 | icalproperty_new_requeststatus(rst)); | ||
962 | |||
963 | icalcomponent_remove_property(component,p); | ||
964 | } | ||
965 | } | ||
966 | } | ||
967 | |||
968 | for(c = icalcomponent_get_first_component(component,ICAL_ANY_COMPONENT); | ||
969 | c != 0; | ||
970 | c = icalcomponent_get_next_component(component,ICAL_ANY_COMPONENT)){ | ||
971 | |||
972 | icalcomponent_convert_errors(c); | ||
973 | } | ||
974 | } | ||
975 | |||
976 | |||
977 | icalcomponent* icalcomponent_get_parent(icalcomponent* component) | ||
978 | { | ||
979 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
980 | |||
981 | return c->parent; | ||
982 | } | ||
983 | |||
984 | void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent) | ||
985 | { | ||
986 | struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; | ||
987 | |||
988 | c->parent = parent; | ||
989 | } | ||
990 | |||
991 | icalcompiter icalcompiter_null = {ICAL_NO_COMPONENT,0}; | ||
992 | |||
993 | |||
994 | struct icalcomponent_kind_map { | ||
995 | icalcomponent_kind kind; | ||
996 | char name[20]; | ||
997 | }; | ||
998 | |||
999 | |||
1000 | |||
1001 | static struct icalcomponent_kind_map component_map[] = | ||
1002 | { | ||
1003 | { ICAL_VEVENT_COMPONENT, "VEVENT" }, | ||
1004 | { ICAL_VTODO_COMPONENT, "VTODO" }, | ||
1005 | { ICAL_VJOURNAL_COMPONENT, "VJOURNAL" }, | ||
1006 | { ICAL_VCALENDAR_COMPONENT, "VCALENDAR" }, | ||
1007 | { ICAL_VFREEBUSY_COMPONENT, "VFREEBUSY" }, | ||
1008 | { ICAL_VTIMEZONE_COMPONENT, "VTIMEZONE" }, | ||
1009 | { ICAL_VALARM_COMPONENT, "VALARM" }, | ||
1010 | { ICAL_XSTANDARD_COMPONENT, "STANDARD" }, /*These are part of RFC2445 */ | ||
1011 | { ICAL_XDAYLIGHT_COMPONENT, "DAYLIGHT" }, /*but are not really components*/ | ||
1012 | { ICAL_X_COMPONENT, "X" }, | ||
1013 | { ICAL_VSCHEDULE_COMPONENT, "SCHEDULE" }, | ||
1014 | |||
1015 | /* CAP components */ | ||
1016 | { ICAL_VQUERY_COMPONENT, "VQUERY" }, | ||
1017 | { ICAL_VCAR_COMPONENT, "VCAR" }, | ||
1018 | { ICAL_VCOMMAND_COMPONENT, "VCOMMAND" }, | ||
1019 | |||
1020 | /* libical private components */ | ||
1021 | { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, | ||
1022 | { ICAL_XLICMIMEPART_COMPONENT, "X-LIC-MIME-PART" }, | ||
1023 | { ICAL_ANY_COMPONENT, "ANY" }, | ||
1024 | { ICAL_XROOT_COMPONENT, "XROOT" }, | ||
1025 | |||
1026 | /* End of list */ | ||
1027 | { ICAL_NO_COMPONENT, "" }, | ||
1028 | }; | ||
1029 | |||
1030 | |||
1031 | |||
1032 | const char* icalcomponent_kind_to_string(icalcomponent_kind kind) | ||
1033 | { | ||
1034 | int i; | ||
1035 | |||
1036 | for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { | ||
1037 | if (component_map[i].kind == kind) { | ||
1038 | return component_map[i].name; | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | return 0; | ||
1043 | |||
1044 | } | ||
1045 | |||
1046 | icalcomponent_kind icalcomponent_string_to_kind(const char* string) | ||
1047 | { | ||
1048 | int i; | ||
1049 | |||
1050 | if (string ==0 ) { | ||
1051 | return ICAL_NO_COMPONENT; | ||
1052 | } | ||
1053 | |||
1054 | for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { | ||
1055 | if (strcmp(component_map[i].name, string) == 0) { | ||
1056 | return component_map[i].kind; | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | return ICAL_NO_COMPONENT; | ||
1061 | } | ||
1062 | |||
1063 | |||
1064 | |||
1065 | icalcompiter | ||
1066 | icalcomponent_begin_component(icalcomponent* component,icalcomponent_kind kind) | ||
1067 | { | ||
1068 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
1069 | icalcompiter itr = icalcompiter_null; | ||
1070 | pvl_elem i; | ||
1071 | |||
1072 | itr.kind = kind; | ||
1073 | |||
1074 | icalerror_check_arg_re( (component!=0),"component",icalcompiter_null); | ||
1075 | |||
1076 | for( i = pvl_head(impl->components); i != 0; i = pvl_next(itr.iter)) { | ||
1077 | |||
1078 | icalcomponent *c = (icalcomponent*) pvl_data(i); | ||
1079 | |||
1080 | if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) { | ||
1081 | |||
1082 | itr.iter = i; | ||
1083 | |||
1084 | return itr; | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | return icalcompiter_null; | ||
1089 | } | ||
1090 | |||
1091 | icalcompiter | ||
1092 | icalcomponent_end_component(icalcomponent* component,icalcomponent_kind kind) | ||
1093 | { | ||
1094 | struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; | ||
1095 | icalcompiter itr; | ||
1096 | pvl_elem i; | ||
1097 | |||
1098 | itr.kind = kind; | ||
1099 | |||
1100 | icalerror_check_arg_re( (component!=0),"component",icalcompiter_null); | ||
1101 | |||
1102 | for( i = pvl_tail(impl->components); i != 0; i = pvl_prior(i)) { | ||
1103 | |||
1104 | icalcomponent *c = (icalcomponent*) pvl_data(i); | ||
1105 | |||
1106 | if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) { | ||
1107 | |||
1108 | itr.iter = pvl_next(i); | ||
1109 | |||
1110 | return itr; | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | return icalcompiter_null;; | ||
1115 | } | ||
1116 | |||
1117 | |||
1118 | icalcomponent* icalcompiter_next(icalcompiter* i) | ||
1119 | { | ||
1120 | if (i->iter == 0){ | ||
1121 | return 0; | ||
1122 | } | ||
1123 | |||
1124 | icalerror_check_arg_rz( (i!=0),"i"); | ||
1125 | |||
1126 | for( i->iter = pvl_next(i->iter); | ||
1127 | i->iter != 0; | ||
1128 | i->iter = pvl_next(i->iter)) { | ||
1129 | |||
1130 | icalcomponent *c = (icalcomponent*) pvl_data(i->iter); | ||
1131 | |||
1132 | if (icalcomponent_isa(c) == i->kind | ||
1133 | || i->kind == ICAL_ANY_COMPONENT) { | ||
1134 | |||
1135 | return icalcompiter_deref(i);; | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | return 0; | ||
1140 | |||
1141 | } | ||
1142 | |||
1143 | icalcomponent* icalcompiter_prior(icalcompiter* i) | ||
1144 | { | ||
1145 | if (i->iter == 0){ | ||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1149 | for( i->iter = pvl_prior(i->iter); | ||
1150 | i->iter != 0; | ||
1151 | i->iter = pvl_prior(i->iter)) { | ||
1152 | |||
1153 | icalcomponent *c = (icalcomponent*) pvl_data(i->iter); | ||
1154 | |||
1155 | if (icalcomponent_isa(c) == i->kind | ||
1156 | || i->kind == ICAL_ANY_COMPONENT) { | ||
1157 | |||
1158 | return icalcompiter_deref(i);; | ||
1159 | } | ||
1160 | } | ||
1161 | |||
1162 | return 0; | ||
1163 | |||
1164 | } | ||
1165 | icalcomponent* icalcompiter_deref(icalcompiter* i) | ||
1166 | { | ||
1167 | if(i->iter ==0){ | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | return pvl_data(i->iter); | ||
1172 | } | ||
1173 | |||
1174 | icalcomponent* icalcomponent_get_inner(icalcomponent* comp) | ||
1175 | { | ||
1176 | if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){ | ||
1177 | return icalcomponent_get_first_real_component(comp); | ||
1178 | } else { | ||
1179 | return comp; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v) | ||
1185 | { | ||
1186 | |||
1187 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1188 | icalproperty *prop | ||
1189 | = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY); | ||
1190 | |||
1191 | |||
1192 | if (prop == 0){ | ||
1193 | prop = icalproperty_new_dtstart(v); | ||
1194 | icalcomponent_add_property(inner, prop); | ||
1195 | } | ||
1196 | |||
1197 | icalproperty_set_dtstart(prop,v); | ||
1198 | |||
1199 | } | ||
1200 | |||
1201 | |||
1202 | struct icaltimetype icalcomponent_get_dtstart(icalcomponent* comp) | ||
1203 | { | ||
1204 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1205 | icalproperty *prop | ||
1206 | = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); | ||
1207 | |||
1208 | if (prop == 0){ | ||
1209 | return icaltime_null_time(); | ||
1210 | } | ||
1211 | |||
1212 | return icalproperty_get_dtstart(prop); | ||
1213 | } | ||
1214 | |||
1215 | |||
1216 | struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp) | ||
1217 | { | ||
1218 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1219 | |||
1220 | icalproperty *end_prop | ||
1221 | = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); | ||
1222 | |||
1223 | icalproperty *dur_prop | ||
1224 | = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); | ||
1225 | |||
1226 | |||
1227 | if( end_prop == 0 && dur_prop == 0){ | ||
1228 | return icaltime_null_time(); | ||
1229 | } else if ( end_prop != 0) { | ||
1230 | return icalproperty_get_dtend(end_prop); | ||
1231 | } else if ( dur_prop != 0) { | ||
1232 | |||
1233 | struct icaltimetype start = | ||
1234 | icalcomponent_get_dtstart(inner); | ||
1235 | struct icaldurationtype duration = | ||
1236 | icalproperty_get_duration(dur_prop); | ||
1237 | |||
1238 | struct icaltimetype end = icaltime_add(start,duration); | ||
1239 | |||
1240 | return end; | ||
1241 | |||
1242 | } else { | ||
1243 | /* Error, both duration and dtend have been specified */ | ||
1244 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
1245 | return icaltime_null_time(); | ||
1246 | |||
1247 | } | ||
1248 | |||
1249 | } | ||
1250 | |||
1251 | |||
1252 | void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v) | ||
1253 | { | ||
1254 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1255 | |||
1256 | icalproperty *end_prop | ||
1257 | = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); | ||
1258 | |||
1259 | icalproperty *dur_prop | ||
1260 | = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); | ||
1261 | |||
1262 | |||
1263 | if( end_prop == 0 && dur_prop == 0){ | ||
1264 | end_prop = icalproperty_new_dtend(v); | ||
1265 | icalcomponent_add_property(inner,end_prop); | ||
1266 | } else if ( end_prop != 0) { | ||
1267 | icalproperty_set_dtend(end_prop,v); | ||
1268 | } else if ( dur_prop != 0) { | ||
1269 | struct icaltimetype start = | ||
1270 | icalcomponent_get_dtstart(inner); | ||
1271 | |||
1272 | struct icaltimetype end = | ||
1273 | icalcomponent_get_dtend(inner); | ||
1274 | |||
1275 | struct icaldurationtype dur | ||
1276 | = icaltime_subtract(end,start); | ||
1277 | |||
1278 | icalproperty_set_duration(dur_prop,dur); | ||
1279 | |||
1280 | } else { | ||
1281 | /* Error, both duration and dtend have been specified */ | ||
1282 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
1283 | } | ||
1284 | } | ||
1285 | |||
1286 | void icalcomponent_set_duration(icalcomponent* comp, | ||
1287 | struct icaldurationtype v) | ||
1288 | { | ||
1289 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1290 | |||
1291 | icalproperty *end_prop | ||
1292 | = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); | ||
1293 | |||
1294 | icalproperty *dur_prop | ||
1295 | = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); | ||
1296 | |||
1297 | |||
1298 | if( end_prop == 0 && dur_prop == 0){ | ||
1299 | dur_prop = icalproperty_new_duration(v); | ||
1300 | icalcomponent_add_property(inner, dur_prop); | ||
1301 | } else if ( end_prop != 0) { | ||
1302 | struct icaltimetype start = | ||
1303 | icalcomponent_get_dtstart(inner); | ||
1304 | |||
1305 | struct icaltimetype new_end = icaltime_add(start,v); | ||
1306 | |||
1307 | icalproperty_set_dtend(end_prop,new_end); | ||
1308 | |||
1309 | } else if ( dur_prop != 0) { | ||
1310 | icalproperty_set_duration(dur_prop,v); | ||
1311 | } else { | ||
1312 | /* Error, both duration and dtend have been specified */ | ||
1313 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1317 | struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp) | ||
1318 | { | ||
1319 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1320 | |||
1321 | icalproperty *end_prop | ||
1322 | = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); | ||
1323 | |||
1324 | icalproperty *dur_prop | ||
1325 | = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); | ||
1326 | |||
1327 | struct icaldurationtype null_duration; | ||
1328 | memset(&null_duration,0,sizeof(struct icaldurationtype)); | ||
1329 | |||
1330 | |||
1331 | if( end_prop == 0 && dur_prop == 0){ | ||
1332 | return null_duration; | ||
1333 | } else if ( end_prop != 0) { | ||
1334 | struct icaltimetype start = | ||
1335 | icalcomponent_get_dtstart(inner); | ||
1336 | time_t startt = icaltime_as_timet(start); | ||
1337 | |||
1338 | struct icaltimetype end = | ||
1339 | icalcomponent_get_dtend(inner); | ||
1340 | time_t endt = icaltime_as_timet(end); | ||
1341 | |||
1342 | return icaldurationtype_from_int(endt-startt); | ||
1343 | } else if ( dur_prop != 0) { | ||
1344 | return icalproperty_get_duration(dur_prop); | ||
1345 | } else { | ||
1346 | /* Error, both duration and dtend have been specified */ | ||
1347 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
1348 | return null_duration; | ||
1349 | } | ||
1350 | } | ||
1351 | |||
1352 | void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method) | ||
1353 | { | ||
1354 | icalproperty *prop | ||
1355 | = icalcomponent_get_first_property(comp, ICAL_METHOD_PROPERTY); | ||
1356 | |||
1357 | |||
1358 | if (prop == 0){ | ||
1359 | prop = icalproperty_new_method(method); | ||
1360 | icalcomponent_add_property(comp, prop); | ||
1361 | } | ||
1362 | |||
1363 | icalproperty_set_method(prop,method); | ||
1364 | |||
1365 | } | ||
1366 | |||
1367 | icalproperty_method icalcomponent_get_method(icalcomponent* comp) | ||
1368 | { | ||
1369 | icalproperty *prop | ||
1370 | = icalcomponent_get_first_property(comp,ICAL_METHOD_PROPERTY); | ||
1371 | |||
1372 | if (prop == 0){ | ||
1373 | return ICAL_METHOD_NONE; | ||
1374 | } | ||
1375 | |||
1376 | return icalproperty_get_method(prop); | ||
1377 | } | ||
1378 | |||
1379 | void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v) | ||
1380 | { | ||
1381 | |||
1382 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1383 | icalproperty *prop | ||
1384 | = icalcomponent_get_first_property(inner, ICAL_DTSTAMP_PROPERTY); | ||
1385 | |||
1386 | |||
1387 | if (prop == 0){ | ||
1388 | prop = icalproperty_new_dtstamp(v); | ||
1389 | icalcomponent_add_property(inner, prop); | ||
1390 | } | ||
1391 | |||
1392 | icalproperty_set_dtstamp(prop,v); | ||
1393 | |||
1394 | } | ||
1395 | |||
1396 | |||
1397 | struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp) | ||
1398 | { | ||
1399 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1400 | icalproperty *prop | ||
1401 | = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); | ||
1402 | |||
1403 | if (prop == 0){ | ||
1404 | return icaltime_null_time(); | ||
1405 | } | ||
1406 | |||
1407 | return icalproperty_get_dtstamp(prop); | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | void icalcomponent_set_summary(icalcomponent* comp, const char* v) | ||
1412 | { | ||
1413 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1414 | icalproperty *prop | ||
1415 | = icalcomponent_get_first_property(inner, ICAL_SUMMARY_PROPERTY); | ||
1416 | |||
1417 | if (prop == 0){ | ||
1418 | prop = icalproperty_new_summary(v); | ||
1419 | icalcomponent_add_property(inner, prop); | ||
1420 | } | ||
1421 | |||
1422 | icalproperty_set_summary(prop,v); | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | const char* icalcomponent_get_summary(icalcomponent* comp) | ||
1427 | { | ||
1428 | icalcomponent *inner = icalcomponent_get_inner(comp); | ||
1429 | icalproperty *prop | ||
1430 | = icalcomponent_get_first_property(inner,ICAL_SUMMARY_PROPERTY); | ||
1431 | |||
1432 | if (prop == 0){ | ||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | return icalproperty_get_summary(prop); | ||
1437 | |||
1438 | } | ||
1439 | |||
1440 | void icalcomponent_set_comment(icalcomponent* comp, const char* v); | ||
1441 | const char* icalcomponent_get_comment(icalcomponent* comp); | ||
1442 | |||
1443 | void icalcomponent_set_uid(icalcomponent* comp, const char* v); | ||
1444 | const char* icalcomponent_get_uid(icalcomponent* comp); | ||
1445 | |||
1446 | void icalcomponent_set_recurrenceid(icalcomponent* comp, | ||
1447 | struct icaltimetype v); | ||
1448 | struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp); | ||
1449 | |||
1450 | |||
1451 | |||
1452 | |||
1453 | icalcomponent* icalcomponent_new_vcalendar() | ||
1454 | { | ||
1455 | return icalcomponent_new(ICAL_VCALENDAR_COMPONENT); | ||
1456 | } | ||
1457 | icalcomponent* icalcomponent_new_vevent() | ||
1458 | { | ||
1459 | return icalcomponent_new(ICAL_VEVENT_COMPONENT); | ||
1460 | } | ||
1461 | icalcomponent* icalcomponent_new_vtodo() | ||
1462 | { | ||
1463 | return icalcomponent_new(ICAL_VTODO_COMPONENT); | ||
1464 | } | ||
1465 | icalcomponent* icalcomponent_new_vjournal() | ||
1466 | { | ||
1467 | return icalcomponent_new(ICAL_VJOURNAL_COMPONENT); | ||
1468 | } | ||
1469 | icalcomponent* icalcomponent_new_valarm() | ||
1470 | { | ||
1471 | return icalcomponent_new(ICAL_VALARM_COMPONENT); | ||
1472 | } | ||
1473 | icalcomponent* icalcomponent_new_vfreebusy() | ||
1474 | { | ||
1475 | return icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); | ||
1476 | } | ||
1477 | icalcomponent* icalcomponent_new_vtimezone() | ||
1478 | { | ||
1479 | return icalcomponent_new(ICAL_VTIMEZONE_COMPONENT); | ||
1480 | } | ||
1481 | icalcomponent* icalcomponent_new_xstandard() | ||
1482 | { | ||
1483 | return icalcomponent_new(ICAL_XSTANDARD_COMPONENT); | ||
1484 | } | ||
1485 | icalcomponent* icalcomponent_new_xdaylight() | ||
1486 | { | ||
1487 | return icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); | ||
1488 | } | ||