1 /**
2 * @file vcomponent_cxx.cpp
3 * @author fnguyen (12/10/01)
4 * @brief Implementation of C++ Wrapper for icalcomponent.c
5 *
6 * (C) COPYRIGHT 2001, Critical Path
7
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of either:
10
11 The LGPL as published by the Free Software Foundation, version
12 2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.html
13
14 Or:
15
16 The Mozilla Public License Version 2.0. You may obtain a copy of
17 the License at https://www.mozilla.org/MPL/
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "vcomponent_cxx.h"
25 #include "icalparameter_cxx.h"
26 #include "icalproperty_cxx.h"
27 #include "icalvalue_cxx.h"
28 using namespace LibICal;
29
30 extern "C" {
31 #include "icalmemory.h"
32 }
33
34 #include <cstdlib>
35
VComponent()36 VComponent::VComponent() : imp(icalcomponent_new(ICAL_ANY_COMPONENT))
37 {
38 }
39
VComponent(const VComponent & v)40 VComponent::VComponent(const VComponent &v) : imp(icalcomponent_new_clone(v.imp))
41 {
42 if (imp == NULL) {
43 throw icalerrno;
44 }
45 }
46
operator =(const VComponent & v)47 VComponent &VComponent::operator=(const VComponent &v)
48 {
49 if (this == &v) {
50 return *this;
51 }
52
53 if (imp != NULL) {
54 icalcomponent_free(imp);
55 imp = icalcomponent_new_clone(v.imp);
56 if (imp == NULL) {
57 throw icalerrno;
58 }
59 }
60
61 return *this;
62 }
63
detach()64 void VComponent::detach()
65 {
66 imp = NULL;
67 }
68
~VComponent()69 VComponent::~VComponent()
70 {
71 if (imp != NULL) {
72 icalcomponent_free(imp);
73 }
74 }
75
VComponent(icalcomponent * v)76 VComponent::VComponent(icalcomponent *v) : imp(v)
77 {
78 }
79
80 /* char* returned is in the ring buffer. caller doesn't have to free it */
quote_ical_string(char * str)81 char *VComponent::quote_ical_string(char *str)
82 {
83 const char *p;
84 size_t buf_sz;
85 buf_sz = strlen(str) * 2; // assume worse case scenarios.
86 // otherwise, we have to parse the string and count \ */
87 char *out = static_cast<char *>(icalmemory_new_buffer(buf_sz)); /* memory from the ring buf */
88 char *pout;
89
90 if (out == 0) {
91 return 0;
92 }
93
94 pout = out;
95
96 for (p = str; *p != 0; p++) {
97
98 if (*p == '\\') {
99 *pout++ = '\\';
100 }
101 *pout++ = *p;
102 }
103 *pout++ = '\0';
104
105 return out;
106 }
107
108 /**
109 * @brief Constructor
110 *
111 * Create a new VComponent from a string.
112 *
113 * @exception ICAL_MALFORMEDDATA_ERROR
114 * Catch this error if you
115 *
116 */
VComponent(const std::string & str)117 VComponent::VComponent(const std::string &str)
118 : imp(icalcomponent_new_from_string(str.c_str()))
119 {
120 if (imp == NULL) {
121 if (! icalerrno) {
122 icalerrno = ICAL_BADARG_ERROR;
123 }
124 throw icalerrno;
125 }
126 }
127
VComponent(const icalcomponent_kind & kind)128 VComponent::VComponent(const icalcomponent_kind &kind) : imp(icalcomponent_new(kind))
129 {
130 if (imp == NULL) {
131 throw icalerrno;
132 }
133 }
134
as_ical_string()135 std::string VComponent::as_ical_string()
136 {
137 char *str = icalcomponent_as_ical_string(imp);
138
139 if (str == NULL) {
140 throw icalerrno;
141 }
142
143 return (str);
144 }
145
is_valid()146 bool VComponent::is_valid()
147 {
148 if (imp == NULL) {
149 return false;
150 }
151 return (icalcomponent_is_valid(imp) != 0);
152 }
153
isa()154 icalcomponent_kind VComponent::isa()
155 {
156 return icalcomponent_isa(imp);
157 }
158
isa_component(void * component)159 int VComponent::isa_component(void *component)
160 {
161 return icalcomponent_isa_component(component);
162 }
163
new_from_string(const std::string & str)164 void VComponent::new_from_string(const std::string &str)
165 {
166 if (imp != NULL) {
167 icalcomponent_free(imp);
168 }
169 imp = icalcomponent_new_from_string(str.c_str());
170 }
171
172 /* Working with properties */
add_property(ICalProperty * property)173 void VComponent::add_property(ICalProperty *property)
174 {
175 icalcomponent_add_property(imp, *property);
176 }
177
remove_property(ICalProperty * property)178 void VComponent::remove_property(ICalProperty *property)
179 {
180 icalcomponent_remove_property(imp, *property);
181 icalproperty_free(*property);
182 property->detach(); // set imp to null, it's free already.
183 }
184
count_properties(const icalproperty_kind & kind)185 int VComponent::count_properties(const icalproperty_kind &kind)
186 {
187 return icalcomponent_count_properties(imp, kind);
188 }
189
190 /* Iterate through the properties */
get_current_property()191 ICalProperty *VComponent::get_current_property()
192 {
193 icalproperty *t = icalcomponent_get_current_property(imp);
194 return ((t != NULL) ? new ICalProperty(t) : NULL);
195 }
196
get_first_property(const icalproperty_kind & kind)197 ICalProperty *VComponent::get_first_property(const icalproperty_kind &kind)
198 {
199 icalproperty *t = icalcomponent_get_first_property(imp, kind);
200 return ((t != NULL) ? new ICalProperty(t) : NULL);
201 }
202
get_next_property(const icalproperty_kind & kind)203 ICalProperty *VComponent::get_next_property(const icalproperty_kind &kind)
204 {
205 icalproperty *t = icalcomponent_get_next_property(imp, kind);
206 return ((t != NULL) ? new ICalProperty(t) : NULL);
207 }
208
209 /* Working with components */
210 /* Return the first VEVENT, VTODO or VJOURNAL sub-component if it is one of those types */
get_inner()211 VComponent *VComponent::get_inner()
212 {
213 return new VComponent(icalcomponent_get_inner(imp));
214 }
215
add_component(VComponent * child)216 void VComponent::add_component(VComponent *child)
217 {
218 icalcomponent_add_component(imp, *child);
219 }
220
remove_component(VComponent * child)221 void VComponent::remove_component(VComponent *child)
222 {
223 icalcomponent_remove_component(imp, *child);
224 }
225
count_components(const icalcomponent_kind & kind)226 int VComponent::count_components(const icalcomponent_kind &kind)
227 {
228 return icalcomponent_count_components(imp, kind);
229 }
230
231 /* Iteration Routines. There are two forms of iterators, internal and
232 external. The internal ones came first, and are almost completely
233 sufficient, but they fail badly when you want to construct a loop that
234 removes components from the container.
235 */
236
237 /* Iterate through components */
get_current_component()238 VComponent *VComponent::get_current_component()
239 {
240 icalcomponent *t = icalcomponent_get_current_component(imp);
241 return ((t != NULL) ? new VComponent(t) : NULL);
242 }
243
get_first_component(const icalcomponent_kind & kind)244 VComponent *VComponent::get_first_component(const icalcomponent_kind &kind)
245 {
246 VComponent *result = NULL;
247 icalcomponent *t = icalcomponent_get_first_component(imp, kind);
248 if (t != NULL) {
249 switch (kind) {
250 case ICAL_VALARM_COMPONENT:
251 result = new VAlarm(t);
252 break;
253 case ICAL_VCALENDAR_COMPONENT:
254 result = new VCalendar(t);
255 break;
256 case ICAL_VEVENT_COMPONENT:
257 result = new VEvent(t);
258 break;
259 case ICAL_VQUERY_COMPONENT:
260 result = new VQuery(t);
261 break;
262 case ICAL_VTODO_COMPONENT:
263 result = new VToDo(t);
264 break;
265 case ICAL_VAGENDA_COMPONENT:
266 result = new VAgenda(t);
267 break;
268 default:
269 result = new VComponent(t);
270 }
271 }
272
273 return (result);
274 }
275
get_next_component(const icalcomponent_kind & kind)276 VComponent *VComponent::get_next_component(const icalcomponent_kind &kind)
277 {
278 VComponent *result = NULL;
279 icalcomponent *t = icalcomponent_get_next_component(imp, kind);
280 if (t != NULL) {
281 switch (kind) {
282 case ICAL_VALARM_COMPONENT:
283 result = new VAlarm(t);
284 break;
285 case ICAL_VCALENDAR_COMPONENT:
286 result = new VCalendar(t);
287 break;
288 case ICAL_VEVENT_COMPONENT:
289 result = new VEvent(t);
290 break;
291 case ICAL_VQUERY_COMPONENT:
292 result = new VQuery(t);
293 break;
294 case ICAL_VTODO_COMPONENT:
295 result = new VToDo(t);
296 break;
297 case ICAL_VAGENDA_COMPONENT:
298 result = new VAgenda(t);
299 break;
300 default:
301 result = new VComponent(t);
302 }
303 }
304
305 return (result);
306 }
307
308 /* Using external iterators */
begin_component(const icalcomponent_kind & kind)309 icalcompiter VComponent::begin_component(const icalcomponent_kind &kind)
310 {
311 return icalcomponent_begin_component(imp, kind);
312 }
313
end_component(const icalcomponent_kind & kind)314 icalcompiter VComponent::end_component(const icalcomponent_kind &kind)
315 {
316 return icalcomponent_end_component(imp, kind);
317 }
318
next(icalcompiter * i)319 VComponent *VComponent::next(icalcompiter *i)
320 {
321 return reinterpret_cast<VComponent *>(icalcompiter_next(i));
322 }
323
prev(icalcompiter * i)324 VComponent *VComponent::prev(icalcompiter *i)
325 {
326 return reinterpret_cast<VComponent *>(icalcompiter_prior(i));
327 }
328
current(icalcompiter * i)329 VComponent *VComponent::current(icalcompiter *i)
330 {
331 return reinterpret_cast<VComponent *>(icalcompiter_deref(i));
332 }
333
334 /* Working with embedded error properties */
count_errors()335 int VComponent::count_errors()
336 {
337 return icalcomponent_count_errors(imp);
338 }
339
340 /* Remove all X-LIC-ERROR properties*/
strip_errors()341 void VComponent::strip_errors()
342 {
343 icalcomponent_strip_errors(imp);
344 }
345
346 /* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/
convert_errors()347 void VComponent::convert_errors()
348 {
349 icalcomponent_convert_errors(imp);
350 }
351
352 /* Kind conversion routines */
string_to_kind(const std::string & str)353 icalcomponent_kind VComponent::string_to_kind(const std::string &str)
354 {
355 return icalcomponent_string_to_kind(str.c_str());
356 }
357
kind_to_string(const icalcomponent_kind & kind)358 std::string VComponent::kind_to_string(const icalcomponent_kind &kind)
359 {
360 return static_cast<std::string>(icalcomponent_kind_to_string(kind));
361 }
362
get_dtstart() const363 struct icaltimetype VComponent::get_dtstart() const {
364 return icalcomponent_get_dtstart(imp);
365 }
366
set_dtstart(const struct icaltimetype & v)367 void VComponent::set_dtstart(const struct icaltimetype &v)
368 {
369 icalcomponent_set_dtstart(imp, v);
370 }
371
372 /* For the icalcomponent routines only, dtend and duration are tied
373 together. If you call the set routine for one and the other exists,
374 the routine will calculate the change to the other. That is, if
375 there is a DTEND and you call set_duration, the routine will modify
376 DTEND to be the sum of DTSTART and the duration. If you call a get
377 routine for one and the other exists, the routine will calculate
378 the return value. If you call a set routine and neither exists, the
379 routine will create the apcompriate comperty.
380 */
381
get_dtend() const382 struct icaltimetype VComponent::get_dtend() const {
383 return icalcomponent_get_dtend(imp);
384 }
385
set_dtend(const struct icaltimetype & v)386 void VComponent::set_dtend(const struct icaltimetype &v)
387 {
388 icalcomponent_set_dtend(imp, v);
389 }
390
get_due() const391 struct icaltimetype VComponent::get_due() const {
392 return icalcomponent_get_due(imp);
393 }
394
set_due(const struct icaltimetype & v)395 void VComponent::set_due(const struct icaltimetype &v)
396 {
397 icalcomponent_set_due(imp, v);
398 }
399
get_duration() const400 struct icaldurationtype VComponent::get_duration() const {
401 return icalcomponent_get_duration(imp);
402 }
403
set_duration(const struct icaldurationtype & v)404 void VComponent::set_duration(const struct icaldurationtype &v)
405 {
406 icalcomponent_set_duration(imp, v);
407 }
408
get_method() const409 icalproperty_method VComponent::get_method() const
410 {
411 return icalcomponent_get_method(imp);
412 }
413
set_method(const icalproperty_method & method)414 void VComponent::set_method(const icalproperty_method &method)
415 {
416 icalcomponent_set_method(imp, method);
417 }
418
get_dtstamp() const419 struct icaltimetype VComponent::get_dtstamp() const {
420 return icalcomponent_get_dtstamp(imp);
421 }
422
set_dtstamp(const struct icaltimetype & v)423 void VComponent::set_dtstamp(const struct icaltimetype &v)
424 {
425 icalcomponent_set_dtstamp(imp, v);
426 }
427
get_summary() const428 std::string VComponent::get_summary() const
429 {
430 return static_cast<std::string>(icalcomponent_get_summary(imp));
431 }
432
set_summary(const std::string & v)433 void VComponent::set_summary(const std::string &v)
434 {
435 icalcomponent_set_summary(imp, v.c_str());
436 }
437
get_location() const438 std::string VComponent::get_location() const
439 {
440 return static_cast<std::string>(icalcomponent_get_location(imp));
441 }
442
set_location(const std::string & v)443 void VComponent::set_location(const std::string &v)
444 {
445 icalcomponent_set_location(imp, v.c_str());
446 }
447
get_description() const448 std::string VComponent::get_description() const
449 {
450 return static_cast<std::string>(icalcomponent_get_description(imp));
451 }
452
set_description(const std::string & v)453 void VComponent::set_description(const std::string &v)
454 {
455 icalcomponent_set_description(imp, v.c_str());
456 }
457
get_comment() const458 std::string VComponent::get_comment() const
459 {
460 return static_cast<std::string>(icalcomponent_get_comment(imp));
461 }
462
set_comment(const std::string & v)463 void VComponent::set_comment(const std::string &v)
464 {
465 icalcomponent_set_comment(imp, v.c_str());
466 }
467
get_uid() const468 std::string VComponent::get_uid() const
469 {
470 return static_cast<std::string>(icalcomponent_get_uid(imp));
471 }
472
set_uid(const std::string & v)473 void VComponent::set_uid(const std::string &v)
474 {
475 icalcomponent_set_uid(imp, v.c_str());
476 }
477
get_relcalid() const478 std::string VComponent::get_relcalid() const
479 {
480 return static_cast<std::string>(icalcomponent_get_relcalid(imp));
481 }
482
set_relcalid(const std::string & v)483 void VComponent::set_relcalid(const std::string &v)
484 {
485 icalcomponent_set_relcalid(imp, v.c_str());
486 }
487
get_recurrenceid() const488 struct icaltimetype VComponent::get_recurrenceid() const {
489 return icalcomponent_get_recurrenceid(imp);
490 }
491
set_recurrenceid(const struct icaltimetype & v)492 void VComponent::set_recurrenceid(const struct icaltimetype &v)
493 {
494 icalcomponent_set_recurrenceid(imp, v);
495 }
496
get_sequence() const497 int VComponent::get_sequence() const
498 {
499 return icalcomponent_get_sequence(imp);
500 }
501
set_sequence(const int & v)502 void VComponent::set_sequence(const int &v)
503 {
504 icalcomponent_set_sequence(imp, v);
505 }
506
get_status() const507 int VComponent::get_status() const
508 {
509 return icalcomponent_get_status(imp);
510 }
511
set_status(const enum icalproperty_status & v)512 void VComponent::set_status(const enum icalproperty_status &v)
513 {
514 icalcomponent_set_status(imp, v);
515 }
516
517 /* For VCOMPONENT: Return a reference to the first VEVENT, VTODO, or VJOURNAL */
get_first_real_component()518 VComponent *VComponent::get_first_real_component()
519 {
520 return reinterpret_cast<VComponent *>(icalcomponent_get_first_real_component(imp));
521 }
522
523 /* For VEVENT, VTODO, VJOURNAL and VTIMEZONE: report the start and end
524 times of an event in UTC */
get_span()525 struct icaltime_span VComponent::get_span()
526 {
527 return icalcomponent_get_span(imp);
528 }
529
recurrence_is_excluded(struct icaltimetype * dtstart,struct icaltimetype * recurtime)530 int VComponent::recurrence_is_excluded(struct icaltimetype *dtstart,
531 struct icaltimetype *recurtime)
532 {
533 return icalproperty_recurrence_is_excluded(imp, dtstart, recurtime);
534 }
535
536 /* Internal operations. They are private, and you should not be using them. */
get_parent()537 VComponent *VComponent::get_parent()
538 {
539 return new VComponent(icalcomponent_get_parent(imp));
540 }
541
set_parent(VComponent * parent)542 void VComponent::set_parent(VComponent *parent)
543 {
544 icalcomponent_set_parent(imp, *parent);
545 }
546
547 /* ignoreValue means remove properties even if the data doesn't match */
remove(VComponent & fromVC,bool ignoreValue)548 bool VComponent::remove(VComponent &fromVC, bool ignoreValue)
549 {
550 /* the two components must be the same kind */
551 if (this->isa() != fromVC.isa()) {
552 return false;
553 }
554
555 /* properties first */
556 ICalPropertyTmpPtr propToBeRemoved;
557 for (propToBeRemoved = fromVC.get_first_property(ICAL_ANY_PROPERTY);
558 propToBeRemoved != NULL;
559 propToBeRemoved = fromVC.get_next_property(ICAL_ANY_PROPERTY)) {
560
561 /* loop through properties from this component */
562 ICalPropertyTmpPtr next;
563 ICalPropertyTmpPtr p;
564 for (p = this->get_first_property(propToBeRemoved->isa()); p != NULL; p = next) {
565 next = this->get_next_property(propToBeRemoved->isa());
566 if (ignoreValue) {
567 this->remove_property(p);
568 } else {
569 if (p == propToBeRemoved) {
570 this->remove_property(p);
571 break;
572 }
573 }
574 }
575 }
576
577 /* components next - should remove by UID */
578 VComponentTmpPtr comp;
579 for (comp = fromVC.get_first_component(ICAL_ANY_COMPONENT); comp != NULL;
580 comp = fromVC.get_next_component(ICAL_ANY_COMPONENT)) {
581 const std::string fromCompUid = comp->get_uid();
582 VComponentTmpPtr c;
583 for (c = this->get_first_component(comp->isa()); c != NULL;
584 c = this->get_next_component(comp->isa())) {
585 if (strcmp(fromCompUid.c_str(), c->get_uid().c_str()) == 0) {
586 // recursively go down the components
587 c->remove(*comp, ignoreValue);
588 // if all properties are removed and there is no sub-components, then
589 // remove this compoent
590 if ((c->count_properties(ICAL_ANY_PROPERTY) == 0) &&
591 (c->count_components(ICAL_ANY_COMPONENT) == 0)) {
592 this->remove_component(c);
593 }
594 break;
595 }
596 }
597 }
598
599 return true;
600 }
601
602 /* removeMissing == true: remove properties that are missing from fromC */
603 /* todo: only change the first occurrence of the property */
604 /* todo: removeMissing is not implemented */
update(VComponent & fromC,bool removeMissing)605 bool VComponent::update(VComponent &fromC, bool removeMissing)
606 {
607 /* make sure they are the same kind */
608 if (this->isa() != fromC.isa()) {
609 return false;
610 }
611
612 /* property first */
613 ICalPropertyTmpPtr prop;
614 for (prop = fromC.get_first_property(ICAL_ANY_PROPERTY); prop != NULL;
615 prop = fromC.get_next_property(ICAL_ANY_PROPERTY)) {
616 ICalPropertyTmpPtr thisProp;
617 thisProp = this->get_first_property(prop->isa());
618 if (thisProp == NULL) {
619 thisProp = new ICalProperty(prop->isa());
620 this->add_property(thisProp);
621 }
622 ICalValue *tempValue = prop->get_value();
623 ICalValue *value = new ICalValue(*tempValue); // clone the value
624 thisProp->set_value(*value);
625 delete tempValue;
626 delete value;
627 }
628
629 /* recursively updating sub-components */
630 VComponentTmpPtr comp;
631 for (comp = fromC.get_first_component(ICAL_ANY_COMPONENT); comp != NULL;
632 comp = fromC.get_next_component(ICAL_ANY_COMPONENT)) {
633 VComponentTmpPtr thisComp;
634 thisComp = this->get_first_component(comp->isa());
635 if (thisComp == NULL) {
636 thisComp = new VComponent(comp->isa());
637 this->add_component(thisComp);
638 }
639 bool err = thisComp->update(*comp, removeMissing);
640 if (!err) {
641 return false;
642 }
643 }
644 return true;
645 }
646
647 /* add components and property. recursively goes down child components */
add(VComponent & fromC)648 bool VComponent::add(VComponent &fromC)
649 {
650 /* make sure the kind are the same */
651 if (this->isa() != fromC.isa()) {
652 return false;
653 }
654
655 /* properties first */
656 ICalPropertyTmpPtr prop;
657 for (prop = fromC.get_first_property(ICAL_ANY_PROPERTY); prop != NULL;
658 prop = fromC.get_next_property(ICAL_ANY_PROPERTY)) {
659 /* clone another property */
660 ICalProperty *p = new ICalProperty(*prop);
661 add_property(p);
662 delete p;
663 }
664
665 /* sub-components next */
666 bool err = false;
667 VComponentTmpPtr comp;
668 for (comp = fromC.get_first_component(ICAL_ANY_COMPONENT); comp != NULL;
669 comp = fromC.get_next_component(ICAL_ANY_COMPONENT)) {
670 VComponent *c = new VComponent(comp->isa());
671 err = c->add(*comp);
672 _unused(err);
673 add_component(c);
674 delete c;
675 }
676
677 return true;
678 }
679
VCalendar()680 VCalendar::VCalendar() : VComponent(icalcomponent_new_vcalendar())
681 {
682 }
683
VCalendar(const VCalendar & v)684 VCalendar::VCalendar(const VCalendar &v) : VComponent(v)
685 {
686 }
687
operator =(const VCalendar & v)688 VCalendar &VCalendar::operator=(const VCalendar &v)
689 {
690 if (this == &v) {
691 return *this;
692 }
693 VComponent::operator=(v);
694
695 return *this;
696 }
697
~VCalendar()698 VCalendar::~VCalendar()
699 {
700 }
701
VCalendar(icalcomponent * v)702 VCalendar::VCalendar(icalcomponent *v) : VComponent(v)
703 {
704 }
705
VCalendar(const std::string & str)706 VCalendar::VCalendar(const std::string &str) : VComponent(str)
707 {
708 }
709
710 /* VEvent */
711
VEvent()712 VEvent::VEvent() : VComponent(icalcomponent_new_vevent())
713 {
714 }
715
VEvent(const VEvent & v)716 VEvent::VEvent(const VEvent &v) : VComponent(v)
717 {
718 }
719
operator =(const VEvent & v)720 VEvent &VEvent::operator=(const VEvent &v)
721 {
722 if (this == &v) {
723 return *this;
724 }
725 VComponent::operator=(v);
726
727 return *this;
728 }
729
~VEvent()730 VEvent::~VEvent()
731 {
732 }
733
VEvent(icalcomponent * v)734 VEvent::VEvent(icalcomponent *v) : VComponent(v)
735 {
736 }
737
VEvent(const std::string & str)738 VEvent::VEvent(const std::string &str) : VComponent(str)
739 {
740 }
741
742 /* VTodo */
743
VToDo()744 VToDo::VToDo() : VComponent(icalcomponent_new_vtodo())
745 {
746 }
747
VToDo(const VToDo & v)748 VToDo::VToDo(const VToDo &v) : VComponent(v)
749 {
750 }
751
operator =(const VToDo & v)752 VToDo &VToDo::operator=(const VToDo &v)
753 {
754 if (this == &v) {
755 return *this;
756 }
757 VComponent::operator=(v);
758
759 return *this;
760 }
761
~VToDo()762 VToDo::~VToDo()
763 {
764 }
765
VToDo(icalcomponent * v)766 VToDo::VToDo(icalcomponent *v) : VComponent(v)
767 {
768 }
769
VToDo(const std::string & str)770 VToDo::VToDo(const std::string &str) : VComponent(str)
771 {
772 }
773
774 /* VAgenda */
775
VAgenda()776 VAgenda::VAgenda() : VComponent(icalcomponent_new_vagenda())
777 {
778 }
779
VAgenda(const VAgenda & v)780 VAgenda::VAgenda(const VAgenda &v) : VComponent(v)
781 {
782 }
783
operator =(const VAgenda & v)784 VAgenda &VAgenda::operator=(const VAgenda &v)
785 {
786 if (this == &v) {
787 return *this;
788 }
789 VComponent::operator=(v);
790
791 return *this;
792 }
793
~VAgenda()794 VAgenda::~VAgenda()
795 {
796 }
797
VAgenda(icalcomponent * v)798 VAgenda::VAgenda(icalcomponent *v) : VComponent(v)
799 {
800 }
801
VAgenda(const std::string & str)802 VAgenda::VAgenda(const std::string &str) : VComponent(str)
803 {
804 }
805
806 /* VQuery */
807
VQuery()808 VQuery::VQuery() : VComponent(icalcomponent_new_vquery())
809 {
810 }
811
VQuery(const VQuery & v)812 VQuery::VQuery(const VQuery &v) : VComponent(v)
813 {
814 }
815
operator =(const VQuery & v)816 VQuery &VQuery::operator=(const VQuery &v)
817 {
818 if (this == &v) {
819 return *this;
820 }
821 VComponent::operator=(v);
822
823 return *this;
824 }
825
~VQuery()826 VQuery::~VQuery()
827 {
828 }
829
VQuery(icalcomponent * v)830 VQuery::VQuery(icalcomponent *v) : VComponent(v)
831 {
832 }
833
VQuery(const std::string & str)834 VQuery::VQuery(const std::string &str) : VComponent(str)
835 {
836 }
837
838 /* VJournal */
839
VJournal()840 VJournal::VJournal() : VComponent(icalcomponent_new_vjournal())
841 {
842 }
843
VJournal(const VJournal & v)844 VJournal::VJournal(const VJournal &v) : VComponent(v)
845 {
846 }
847
operator =(const VJournal & v)848 VJournal &VJournal::operator=(const VJournal &v)
849 {
850 if (this == &v) {
851 return *this;
852 }
853 VComponent::operator=(v);
854
855 return *this;
856 }
857
~VJournal()858 VJournal::~VJournal()
859 {
860 }
861
VJournal(icalcomponent * v)862 VJournal::VJournal(icalcomponent *v) : VComponent(v)
863 {
864 }
865
VJournal(const std::string & str)866 VJournal::VJournal(const std::string &str) : VComponent(str)
867 {
868 }
869
870 /* VAlarm */
871
VAlarm()872 VAlarm::VAlarm() : VComponent(icalcomponent_new_valarm())
873 {
874 }
875
VAlarm(const VAlarm & v)876 VAlarm::VAlarm(const VAlarm &v) : VComponent(v)
877 {
878 }
879
operator =(const VAlarm & v)880 VAlarm &VAlarm::operator=(const VAlarm &v)
881 {
882 if (this == &v) {
883 return *this;
884 }
885 VComponent::operator=(v);
886
887 return *this;
888 }
889
~VAlarm()890 VAlarm::~VAlarm()
891 {
892 }
893
VAlarm(icalcomponent * v)894 VAlarm::VAlarm(icalcomponent *v) : VComponent(v)
895 {
896 }
897
VAlarm(const std::string & str)898 VAlarm::VAlarm(const std::string &str) : VComponent(str)
899 {
900 }
901
getTriggerTime(VComponent & c,struct icaltriggertype * tr)902 icalrequeststatus VAlarm::getTriggerTime(VComponent &c, struct icaltriggertype *tr)
903 {
904 ICalPropertyTmpPtr trigger_prop = this->get_first_property(ICAL_TRIGGER_PROPERTY);
905
906 // all VALARMs must have a TRIGGER
907 if (trigger_prop == NULL) {
908 return ICAL_3_1_INVPROPVAL_STATUS;
909 }
910
911 *tr = trigger_prop->get_trigger();
912
913 if (icaltime_is_null_time(tr->time) == 1) {
914 struct icaltimetype tt = icaltime_null_time();
915
916 // relative time trigger
917
918 // TRIGGER;RELATED=END:P5M 5 minutes after END
919 // TRIGGER;RELATED=START:-P15M 15 minutes before START
920 // get RELATED parameter
921
922 ICalParameter *related_param = trigger_prop->get_first_parameter(ICAL_RELATED_PARAMETER);
923
924 if ((related_param != NULL) && related_param->is_valid()) {
925
926 // get RELATED parameter value
927 icalparameter_related related = related_param->get_related();
928
929 if (related != 0) {
930 switch (related) {
931 case ICAL_RELATED_END:
932 if (c.isa() == ICAL_VEVENT_COMPONENT) {
933 tt = c.get_dtend();
934
935 // If a recurrenceid exists, use that to calculate the
936 // dtend from the dtstart.
937 struct icaltimetype recur_time = c.get_recurrenceid();
938 if (icaltime_is_null_time(recur_time) != 1) {
939 struct icaldurationtype dur = icaltime_subtract(c.get_dtstart(), tt);
940 tt = icaltime_add(recur_time, dur);
941 }
942 } else if (c.isa() == ICAL_VTODO_COMPONENT) {
943 tt = c.get_due();
944 struct icaltimetype recur_time = c.get_recurrenceid();
945 if (icaltime_is_null_time(recur_time) != 1) {
946 tt = recur_time;
947 }
948 }
949 // @@@ TODO: if not DTEND or DUE, then DTSTART and DURATION must be present
950 break;
951 case ICAL_RELATED_START:
952 case ICAL_RELATED_X:
953 case ICAL_RELATED_NONE:
954 default:
955 tt = c.get_dtstart();
956 struct icaltimetype recur_time = c.get_recurrenceid();
957 if (icaltime_is_null_time(recur_time) != 1) {
958 tt = recur_time;
959 }
960 break;
961 }
962 }
963 } else { // no RELATED explicitly specified, the default is
964 // relative to the start of an event or to-do, rfc2445
965 // if no RELATED, we are forced to use dtstart for VEVENT,
966 // due for VTODO to calculate trigger time.
967 // If a recur time exists, use that. Recur time trumps dtstart or due.
968 struct icaltimetype recur_time = c.get_recurrenceid();
969 if (icaltime_is_null_time(recur_time) != 1) {
970 tt = recur_time;
971 } else if (c.isa() == ICAL_VEVENT_COMPONENT) {
972 tt = c.get_dtstart();
973 } else if (c.isa() == ICAL_VTODO_COMPONENT) {
974 tt = c.get_due();
975 }
976 }
977
978 delete related_param;
979
980 // malformed? encapsulating VEVENT or VTODO MUST have DTSTART/DTEND
981 if (icaltime_is_null_time(tt) == 1) {
982 return ICAL_3_1_INVPROPVAL_STATUS;
983 };
984
985 // now offset using tr.duration
986 tr->time = icaltime_add(tt, tr->duration);
987 }
988 // else absolute time trigger
989
990 return ICAL_2_0_SUCCESS_STATUS;
991 }
992
993 /* VFreeBusy */
994
VFreeBusy()995 VFreeBusy::VFreeBusy() : VComponent(icalcomponent_new_vfreebusy())
996 {
997 }
998
VFreeBusy(const VFreeBusy & v)999 VFreeBusy::VFreeBusy(const VFreeBusy &v) : VComponent(v)
1000 {
1001 }
1002
operator =(const VFreeBusy & v)1003 VFreeBusy &VFreeBusy::operator=(const VFreeBusy &v)
1004 {
1005 if (this == &v) {
1006 return *this;
1007 }
1008 VComponent::operator=(v);
1009
1010 return *this;
1011 }
1012
~VFreeBusy()1013 VFreeBusy::~VFreeBusy()
1014 {
1015 }
1016
VFreeBusy(icalcomponent * v)1017 VFreeBusy::VFreeBusy(icalcomponent *v) : VComponent(v)
1018 {
1019 }
1020
VFreeBusy(const std::string & str)1021 VFreeBusy::VFreeBusy(const std::string &str) : VComponent(str)
1022 {
1023 }
1024
1025 /* VTimezone */
1026
VTimezone()1027 VTimezone::VTimezone() : VComponent(icalcomponent_new_vtimezone())
1028 {
1029 }
1030
VTimezone(const VTimezone & v)1031 VTimezone::VTimezone(const VTimezone &v) : VComponent(v)
1032 {
1033 }
1034
operator =(const VTimezone & v)1035 VTimezone &VTimezone::operator=(const VTimezone &v)
1036 {
1037 if (this == &v) {
1038 return *this;
1039 }
1040 VComponent::operator=(v);
1041
1042 return *this;
1043 }
1044
~VTimezone()1045 VTimezone::~VTimezone()
1046 {
1047 }
1048
VTimezone(icalcomponent * v)1049 VTimezone::VTimezone(icalcomponent *v) : VComponent(v)
1050 {
1051 }
1052
VTimezone(const std::string & str)1053 VTimezone::VTimezone(const std::string &str) : VComponent(str)
1054 {
1055 }
1056
1057 /* XStandard */
1058
XStandard()1059 XStandard::XStandard() : VComponent(icalcomponent_new_xstandard())
1060 {
1061 }
1062
XStandard(const XStandard & v)1063 XStandard::XStandard(const XStandard &v) : VComponent(v)
1064 {
1065 }
1066
operator =(const XStandard & v)1067 XStandard &XStandard::operator=(const XStandard &v)
1068 {
1069 if (this == &v) {
1070 return *this;
1071 }
1072 VComponent::operator=(v);
1073
1074 return *this;
1075 }
1076
~XStandard()1077 XStandard::~XStandard()
1078 {
1079 }
1080
XStandard(icalcomponent * v)1081 XStandard::XStandard(icalcomponent *v) : VComponent(v)
1082 {
1083 }
1084
XStandard(const std::string & str)1085 XStandard::XStandard(const std::string &str) : VComponent(str)
1086 {
1087 }
1088
1089 /* XDaylight */
1090
XDaylight()1091 XDaylight::XDaylight() : VComponent(icalcomponent_new_xdaylight())
1092 {
1093 }
1094
XDaylight(const XDaylight & v)1095 XDaylight::XDaylight(const XDaylight &v) : VComponent(v)
1096 {
1097 }
1098
operator =(const XDaylight & v)1099 XDaylight &XDaylight::operator=(const XDaylight &v)
1100 {
1101 if (this == &v) {
1102 return *this;
1103 }
1104 VComponent::operator=(v);
1105
1106 return *this;
1107 }
1108
~XDaylight()1109 XDaylight::~XDaylight()
1110 {
1111 }
1112
XDaylight(icalcomponent * v)1113 XDaylight::XDaylight(icalcomponent *v) : VComponent(v)
1114 {
1115 }
1116
XDaylight(const std::string & str)1117 XDaylight::XDaylight(const std::string &str) : VComponent(str)
1118 {
1119 }
1120