forked from sourcesimian/uICAL
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcalendariter.cpp
More file actions
110 lines (101 loc) · 3.4 KB
/
Copy pathcalendariter.cpp
File metadata and controls
110 lines (101 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*############################################################################
# Copyright (c) 2020 Source Simian : https://github.com/sourcesimian/uICAL #
############################################################################*/
#include "uICAL/cppstl.h"
#include "uICAL/types.h"
#include "uICAL/error.h"
#include "uICAL/util.h"
#include "uICAL/logging.h"
#include "uICAL/calendar.h"
#include "uICAL/calendarentry.h"
#include "uICAL/calendariter.h"
#include "uICAL/tzmap.h"
#include "uICAL/vevent.h"
#include "uICAL/veventiter.h"
#include "uICAL/vline.h"
#include "uICAL/vlinestream.h"
#include "uICAL/vobject.h"
#include "uICAL/vobjectstream.h"
namespace uICAL
{
CalendarIter::CalendarIter(const Calendar_ptr cal, const DateTime &begin, const DateTime &end)
: cal(cal)
{
if (begin.valid() && end.valid() && end < begin)
{
log_error("Begin and end describe a negative range: %s -> %s", begin.as_str().c_str(), end.as_str().c_str());
throw ValueError("Begin and end describe a negative range");
}
for (auto ev : this->cal->events)
{
VEventIter_ptr evIt = new_ptr<VEventIter>(ev, begin, end);
if (evIt->next())
{ // Initialise and filter
this->events.push_back(evIt);
}
}
}
bool CalendarIter::next_unchecked()
{
if (this->events.size() == 0)
{
return false;
}
// Get the next event
auto minIt = this->events.begin();
this->currentEvent = (*minIt)->event();
this->currentEntry = (*minIt)->entry();
// Get the next entry within the event
if (!(*minIt)->next())
{
this->events.erase(minIt);
}
return true;
}
bool CalendarIter::next()
{
bool got_result = false;
while (true)
{
got_result = next_unchecked();
if (!got_result)
{
break;
}
VEvent_ptr event = this->currentEvent;
CalendarEntry_ptr entry = this->currentEntry;
CalendarIter::recurence_id_t recurence_id = std::make_tuple(event->uid, entry->start());
// If we already have seen this event, don't add it again
if (this->recurence_id_set.count(recurence_id) == 0)
{
break;
}
}
if (got_result)
{
VEvent_ptr event = this->currentEvent;
if (event != nullptr && event->recurrence.valid())
{
// If this is an instance of a reoccuring event, mark it so we don't process it twice
CalendarIter::recurence_id_t recurence_id = std::make_tuple(event->uid, event->recurrence);
this->recurence_id_set.insert(recurence_id);
}
for (VEvent::exdate_t &exdate : event->exdates)
{
DateTime dt = std::get<0>(exdate);
CalendarIter::recurence_id_t recurence_id = std::make_tuple(event->uid, dt);
this->recurence_id_set.insert(recurence_id);
}
}
return got_result;
}
CalendarEntry_ptr CalendarIter::current() const
{
if (!this->currentEntry)
{
log_warning("%s", "No more entries");
throw RecurrenceError("No more entries");
}
return this->currentEntry;
}
}