an iCal processing library

Committer:
WiredHome
Date:
Sun Jun 22 20:52:26 2014 +0000
Revision:
5:69577415c16e
Parent:
4:a1c25d936346
Child:
6:4d1fc1cb38ad
Revise the parsing and time zone management.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 2:1f5dbc624b95 1 //
WiredHome 2:1f5dbc624b95 2 // TODO
WiredHome 2:1f5dbc624b95 3 // Repeat parsing is quite weak right now. It handles repeating days w/in a week
WiredHome 2:1f5dbc624b95 4 // (e.g. repeat weekly, on Mon, Tue, Thu)
WiredHome 2:1f5dbc624b95 5 //
WiredHome 4:a1c25d936346 6 //#include "stdafx.h"
WiredHome 4:a1c25d936346 7 //#pragma warning (disable: 4996)
WiredHome 0:49245357cd1b 8
WiredHome 0:49245357cd1b 9 #include "iCal.h"
WiredHome 0:49245357cd1b 10 #include <algorithm>
WiredHome 0:49245357cd1b 11
WiredHome 5:69577415c16e 12 //#ifdef _DEBUG
WiredHome 2:1f5dbc624b95 13 #define DEBUG "iCal"
WiredHome 5:69577415c16e 14 //#endif
WiredHome 4:a1c25d936346 15 #ifdef WIN32
WiredHome 4:a1c25d936346 16 #define LF "\n"
WiredHome 5:69577415c16e 17 #else // mbed
WiredHome 4:a1c25d936346 18 #define LF "\r\n"
WiredHome 5:69577415c16e 19 #endif // WIN32
WiredHome 0:49245357cd1b 20 #include <cstdio>
WiredHome 0:49245357cd1b 21 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 4:a1c25d936346 22 #define DBG(x, ...) std::printf("[DBG %s %3d] " x LF, DEBUG, __LINE__, ##__VA_ARGS__)
WiredHome 4:a1c25d936346 23 #define WARN(x, ...) std::printf("[WRN %s %3d] " x LF, DEBUG, __LINE__, ##__VA_ARGS__)
WiredHome 4:a1c25d936346 24 #define ERR(x, ...) std::printf("[ERR %s %3d] " x LF, DEBUG, __LINE__, ##__VA_ARGS__)
WiredHome 4:a1c25d936346 25 #define INFO(x, ...) std::printf("[INF %s %3d] " x LF, DEBUG, __LINE__, ##__VA_ARGS__)
WiredHome 0:49245357cd1b 26 #else
WiredHome 0:49245357cd1b 27 #define DBG(x, ...)
WiredHome 0:49245357cd1b 28 #define WARN(x, ...)
WiredHome 0:49245357cd1b 29 #define ERR(x, ...)
WiredHome 0:49245357cd1b 30 #define INFO(x, ...)
WiredHome 0:49245357cd1b 31 #endif
WiredHome 0:49245357cd1b 32
WiredHome 0:49245357cd1b 33 Event_T EventList[EVENT_COUNT];
WiredHome 0:49245357cd1b 34 int EventCount = 0;
WiredHome 4:a1c25d936346 35 int32_t tzoTZIDSec = 0;
WiredHome 0:49245357cd1b 36
WiredHome 0:49245357cd1b 37 const char * RPT_DAYS[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA", "" };
WiredHome 0:49245357cd1b 38
WiredHome 0:49245357cd1b 39 int GetNumEvents(void)
WiredHome 0:49245357cd1b 40 {
WiredHome 0:49245357cd1b 41 return EventCount;
WiredHome 0:49245357cd1b 42 }
WiredHome 0:49245357cd1b 43
WiredHome 0:49245357cd1b 44 const char * RepeatDayAbbrev(int i)
WiredHome 0:49245357cd1b 45 {
WiredHome 0:49245357cd1b 46 if (i < 7)
WiredHome 0:49245357cd1b 47 return RPT_DAYS[i];
WiredHome 0:49245357cd1b 48 else
WiredHome 0:49245357cd1b 49 return RPT_DAYS[7];
WiredHome 0:49245357cd1b 50 }
WiredHome 0:49245357cd1b 51
WiredHome 0:49245357cd1b 52 void SortEvents()
WiredHome 0:49245357cd1b 53 {
WiredHome 0:49245357cd1b 54 bool swapped;
WiredHome 0:49245357cd1b 55 int e;
WiredHome 0:49245357cd1b 56 Event_T Event;
WiredHome 0:49245357cd1b 57
WiredHome 0:49245357cd1b 58 do {
WiredHome 0:49245357cd1b 59 swapped = false;
WiredHome 0:49245357cd1b 60 for (e=0; e<EventCount-1; e++) {
WiredHome 0:49245357cd1b 61 if (EventList[e].Start > EventList[e+1].Start) {
WiredHome 0:49245357cd1b 62 Event = EventList[e];
WiredHome 0:49245357cd1b 63 EventList[e] = EventList[e+1];
WiredHome 0:49245357cd1b 64 EventList[e+1] = Event;
WiredHome 0:49245357cd1b 65 swapped = true;
WiredHome 0:49245357cd1b 66 }
WiredHome 0:49245357cd1b 67 }
WiredHome 0:49245357cd1b 68 } while (swapped);
WiredHome 0:49245357cd1b 69 }
WiredHome 0:49245357cd1b 70
WiredHome 0:49245357cd1b 71 uint16_t AtoIxN(char * p, int n)
WiredHome 0:49245357cd1b 72 {
WiredHome 0:49245357cd1b 73 uint16_t res = 0;
WiredHome 0:49245357cd1b 74
WiredHome 0:49245357cd1b 75 while (n--) {
WiredHome 0:49245357cd1b 76 res = (res * 10) + (*p - '0');
WiredHome 0:49245357cd1b 77 p++;
WiredHome 0:49245357cd1b 78 }
WiredHome 0:49245357cd1b 79 return res;
WiredHome 0:49245357cd1b 80 }
WiredHome 0:49245357cd1b 81
WiredHome 4:a1c25d936346 82 // YYYYMMDD[THHMMSS[Z]]
WiredHome 5:69577415c16e 83 // VALUE=DATE:YYYYMMDD
WiredHome 5:69577415c16e 84 time_t ParseDateStamp(char * string, tz_sec_t tzoSec)
WiredHome 0:49245357cd1b 85 {
WiredHome 0:49245357cd1b 86 time_t tStamp;
WiredHome 0:49245357cd1b 87 struct tm t;
WiredHome 4:a1c25d936346 88 struct tm * tnow;
WiredHome 4:a1c25d936346 89
WiredHome 4:a1c25d936346 90 time(&tStamp);
WiredHome 4:a1c25d936346 91 tnow = localtime(&tStamp);
WiredHome 5:69577415c16e 92 if (strncmp(string, "VALUE=DATE:", 11) == 0) {
WiredHome 5:69577415c16e 93 string += 11;
WiredHome 5:69577415c16e 94 }
WiredHome 4:a1c25d936346 95 //INFO("ParseDateStamp(%s,%d)\n", string, tzoSec);
WiredHome 0:49245357cd1b 96 t.tm_year = AtoIxN(string, 4) - 1900;
WiredHome 0:49245357cd1b 97 t.tm_mon = AtoIxN(string+4, 2) - 1;
WiredHome 0:49245357cd1b 98 t.tm_mday = AtoIxN(string+6, 2);
WiredHome 4:a1c25d936346 99 if (strlen(string) > 8) {
WiredHome 4:a1c25d936346 100 t.tm_hour = AtoIxN(string+9, 2);
WiredHome 4:a1c25d936346 101 t.tm_min = AtoIxN(string+11, 2);
WiredHome 4:a1c25d936346 102 t.tm_sec = AtoIxN(string+13, 2);
WiredHome 4:a1c25d936346 103 t.tm_isdst = tnow->tm_isdst;
WiredHome 4:a1c25d936346 104 } else {
WiredHome 4:a1c25d936346 105 t.tm_hour = 0;
WiredHome 4:a1c25d936346 106 t.tm_min = 0;
WiredHome 4:a1c25d936346 107 t.tm_sec = 0;
WiredHome 4:a1c25d936346 108 t.tm_isdst = tnow->tm_isdst;
WiredHome 4:a1c25d936346 109 }
WiredHome 0:49245357cd1b 110 tStamp = mktime(&t);
WiredHome 2:1f5dbc624b95 111 if (string[strlen(string)-1] == 'Z') {
WiredHome 4:a1c25d936346 112 //INFO("Applying tzoSec %d", tzoSec);
WiredHome 4:a1c25d936346 113 tStamp = tStamp + tzoTZIDSec;
WiredHome 4:a1c25d936346 114 } else {
WiredHome 1:db274b9e40cc 115 tStamp = tStamp + tzoSec;
WiredHome 2:1f5dbc624b95 116 }
WiredHome 0:49245357cd1b 117 return tStamp;
WiredHome 0:49245357cd1b 118 //int tm_sec //seconds after the minute – [0, 60][@1] (public member object)
WiredHome 0:49245357cd1b 119 //int tm_min //minutes after the hour – [0, 59] (public member object)
WiredHome 0:49245357cd1b 120 //int tm_hour //hours since midnight – [0, 23] (public member object)
WiredHome 0:49245357cd1b 121 //int tm_mday //day of the month – [1, 31] (public member object)
WiredHome 0:49245357cd1b 122 //int tm_mon //months since January – [0, 11] (public member object)
WiredHome 0:49245357cd1b 123 //int tm_year //years since 1900 (public member object)
WiredHome 0:49245357cd1b 124 //int tm_wday //days since Sunday – [0, 6] (public member object)
WiredHome 0:49245357cd1b 125 //int tm_yday //days since January 1 – [0, 365]
WiredHome 0:49245357cd1b 126 //int tm_isdst
WiredHome 0:49245357cd1b 127 }
WiredHome 0:49245357cd1b 128
WiredHome 0:49245357cd1b 129 char * FormatCTime(time_t t)
WiredHome 0:49245357cd1b 130 {
WiredHome 0:49245357cd1b 131 static char temp[4][80];
WiredHome 0:49245357cd1b 132 static int i = 0;
WiredHome 2:1f5dbc624b95 133
WiredHome 0:49245357cd1b 134 i &= 3;
WiredHome 0:49245357cd1b 135 strcpy(temp[i], ctime(&t));
WiredHome 0:49245357cd1b 136 temp[i][strlen(temp[i])-1] = '\0';
WiredHome 0:49245357cd1b 137 return temp[i++];
WiredHome 0:49245357cd1b 138 }
WiredHome 0:49245357cd1b 139
WiredHome 0:49245357cd1b 140
WiredHome 0:49245357cd1b 141 void ShowEventInfo(Event_T & Event)
WiredHome 0:49245357cd1b 142 {
WiredHome 4:a1c25d936346 143 char scratch[80];
WiredHome 2:1f5dbc624b95 144
WiredHome 4:a1c25d936346 145 printf("******* Summary: %s" LF, Event.Summary);
WiredHome 4:a1c25d936346 146 printf(" Location: %s" LF, Event.Location);
WiredHome 4:a1c25d936346 147 printf(" Category: %s" LF, Event.Category);
WiredHome 4:a1c25d936346 148 printf(" Priority: %d" LF, Event.Priority);
WiredHome 4:a1c25d936346 149 sprintf(scratch, "%d ", Event.Start);
WiredHome 4:a1c25d936346 150 sprintf(scratch + strlen(scratch), "%s", (Event.Start == 0) ? "" : ctime(&Event.Start));
WiredHome 4:a1c25d936346 151 scratch[strlen(scratch)-1] = '\0';
WiredHome 4:a1c25d936346 152 printf(" Start: %s" LF, scratch);
WiredHome 4:a1c25d936346 153 sprintf(scratch, "%d ", Event.End);
WiredHome 4:a1c25d936346 154 sprintf(scratch + strlen(scratch), "%s", (Event.End == 0) ? "" : ctime(&Event.End));
WiredHome 4:a1c25d936346 155 scratch[strlen(scratch)-1] = '\0';
WiredHome 4:a1c25d936346 156 printf(" End: %s" LF, scratch);
WiredHome 4:a1c25d936346 157 printf(" Count: %d" LF, Event.Count);
WiredHome 4:a1c25d936346 158 printf(" Interval: %d" LF, Event.Interval);
WiredHome 4:a1c25d936346 159 printf(" RepeatFrq: %d" LF, Event.RepeatFreq);
WiredHome 4:a1c25d936346 160 printf(" RepeatDay: %02X" LF, Event.RepeatDays);
WiredHome 4:a1c25d936346 161 printf(" RepeatMonthDay: %08X" LF, Event.RepeatMonthDay);
WiredHome 4:a1c25d936346 162 printf(" RepeatMonthDayRev: %08X" LF, Event.RepeatMonthDayRev);
WiredHome 4:a1c25d936346 163 printf(" RepeatMonth: %04X" LF, Event.RepeatMonths);
WiredHome 4:a1c25d936346 164 sprintf(scratch, "%d ", Event.Until);
WiredHome 4:a1c25d936346 165 sprintf(scratch + strlen(scratch), "%s", (Event.Until == 0) ? "" : ctime(&Event.Until));
WiredHome 4:a1c25d936346 166 scratch[strlen(scratch)-1] = '\0';
WiredHome 4:a1c25d936346 167 printf(" Until: %s" LF, scratch);
WiredHome 4:a1c25d936346 168 printf("" LF);
WiredHome 0:49245357cd1b 169 }
WiredHome 0:49245357cd1b 170
WiredHome 0:49245357cd1b 171
WiredHome 0:49245357cd1b 172 /// Computes the intersection of time1 and time2 ranges, and modifies time1
WiredHome 0:49245357cd1b 173 /// range to represent the intersection.
WiredHome 0:49245357cd1b 174 ///
WiredHome 0:49245357cd1b 175 /// @param start1 is input as the start of the time1 range, and is written
WiredHome 0:49245357cd1b 176 /// to represent the intersection of the two ranges.
WiredHome 0:49245357cd1b 177 /// @param end1 is input as the end of the time1 range and is written to
WiredHome 0:49245357cd1b 178 /// represent the intersection of the two ranges.
WiredHome 0:49245357cd1b 179 /// @param start2 is the start of the time2 range.
WiredHome 0:49245357cd1b 180 /// @param end2 is the end of the time2 range.
WiredHome 0:49245357cd1b 181 /// @returns true if the ranges have an intersection, and the time1 range
WiredHome 0:49245357cd1b 182 /// values have been modified.
WiredHome 0:49245357cd1b 183 ///
WiredHome 0:49245357cd1b 184 bool TimeIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2)
WiredHome 0:49245357cd1b 185 {
WiredHome 0:49245357cd1b 186 // |----Time1----|
WiredHome 0:49245357cd1b 187 // |--Time2--| false
WiredHome 0:49245357cd1b 188 //
WiredHome 0:49245357cd1b 189 // |----Time1----|
WiredHome 0:49245357cd1b 190 // |--Time2--| false
WiredHome 0:49245357cd1b 191 //
WiredHome 0:49245357cd1b 192 // |----Time1----|
WiredHome 0:49245357cd1b 193 // |----Time2----|
WiredHome 0:49245357cd1b 194 // |-Time1-| true
WiredHome 0:49245357cd1b 195 //
WiredHome 0:49245357cd1b 196 // |----Time1----|
WiredHome 0:49245357cd1b 197 // |----Time2----|
WiredHome 0:49245357cd1b 198 // |-Time1-| true
WiredHome 0:49245357cd1b 199 //
WiredHome 0:49245357cd1b 200 // |----Time1-------|
WiredHome 0:49245357cd1b 201 // |-Time2-|
WiredHome 0:49245357cd1b 202 // |-Time1-| true
WiredHome 0:49245357cd1b 203 //
WiredHome 4:a1c25d936346 204 // | Time1 (end1 == 0)
WiredHome 4:a1c25d936346 205 // | Time2 (end2 == 0) true
WiredHome 4:a1c25d936346 206 //
WiredHome 4:a1c25d936346 207 if (*start1 == *start2 && *end1 == 0 && *end2 == 0)
WiredHome 4:a1c25d936346 208 return true;
WiredHome 0:49245357cd1b 209 if (*end1 < *start2 || *end2 < *start1)
WiredHome 0:49245357cd1b 210 return false;
WiredHome 0:49245357cd1b 211 if (max(*start1,*start2) < min(*end1,*end2)) {
WiredHome 0:49245357cd1b 212 *start1 = max(*start1,*start2);
WiredHome 0:49245357cd1b 213 *end1 = min(*end1,*end2);
WiredHome 0:49245357cd1b 214 return true;
WiredHome 0:49245357cd1b 215 } else {
WiredHome 0:49245357cd1b 216 return false;
WiredHome 0:49245357cd1b 217 }
WiredHome 0:49245357cd1b 218 }
WiredHome 0:49245357cd1b 219
WiredHome 4:a1c25d936346 220 bool isLeapYear(time_t t)
WiredHome 4:a1c25d936346 221 {
WiredHome 4:a1c25d936346 222 int year;
WiredHome 4:a1c25d936346 223 struct tm * ts;
WiredHome 4:a1c25d936346 224 ts = localtime(&t);
WiredHome 4:a1c25d936346 225
WiredHome 4:a1c25d936346 226 year = 1900 + ts->tm_year + 1;
WiredHome 4:a1c25d936346 227 if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0))
WiredHome 4:a1c25d936346 228 return true;
WiredHome 4:a1c25d936346 229 else
WiredHome 4:a1c25d936346 230 return false;
WiredHome 4:a1c25d936346 231 }
WiredHome 4:a1c25d936346 232
WiredHome 4:a1c25d936346 233 time_t NextInterval(time_t curTime, int repeatFreq, int interval)
WiredHome 0:49245357cd1b 234 {
WiredHome 2:1f5dbc624b95 235 const time_t secperday = 60*60*24;
WiredHome 2:1f5dbc624b95 236 const int repeatFactor[] = {0, 1, 7, 30, 365};
WiredHome 4:a1c25d936346 237 int delta = repeatFactor[repeatFreq];
WiredHome 4:a1c25d936346 238 if (repeatFreq == 4 && isLeapYear(curTime))
WiredHome 4:a1c25d936346 239 delta += 1;
WiredHome 5:69577415c16e 240 //INFO("freq %d, interval %d, delta %d", repeatFreq, interval, delta);
WiredHome 4:a1c25d936346 241 return delta * interval * secperday;
WiredHome 0:49245357cd1b 242 }
WiredHome 0:49245357cd1b 243
WiredHome 2:1f5dbc624b95 244
WiredHome 2:1f5dbc624b95 245 // start1,end1 is the time range representing the visible grid
WiredHome 2:1f5dbc624b95 246 // start2,end2 is the time range of the event being tested
WiredHome 2:1f5dbc624b95 247 // Event is also the event being tested and permits testing the repeat information.
WiredHome 2:1f5dbc624b95 248 //
WiredHome 2:1f5dbc624b95 249 // If the event repeat pattern intersects with the display pattern, indicate this as "true"
WiredHome 2:1f5dbc624b95 250 //
WiredHome 4:a1c25d936346 251 bool RepeatMaskIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event)
WiredHome 2:1f5dbc624b95 252 {
WiredHome 2:1f5dbc624b95 253 bool intersects = false;
WiredHome 2:1f5dbc624b95 254
WiredHome 5:69577415c16e 255 //INFO("RepeatFreq: %d", Event->RepeatFreq);
WiredHome 4:a1c25d936346 256 if (Event->RepeatFreq == rptfDaily) {
WiredHome 5:69577415c16e 257 //INFO("rptfDaily is not handled");
WiredHome 4:a1c25d936346 258 } else if (Event->RepeatFreq == rptfWeekly) {
WiredHome 2:1f5dbc624b95 259 struct tm * timeinfo;
WiredHome 2:1f5dbc624b95 260 timeinfo = localtime(start1);
WiredHome 4:a1c25d936346 261 uint8_t daymask = Event->RepeatDays;
WiredHome 2:1f5dbc624b95 262 // now, check the tm_wday (0=Sunday, 1=Monday, ...) and see if we intersect with the event time
WiredHome 2:1f5dbc624b95 263 uint8_t testmask = 1 << timeinfo->tm_wday;
WiredHome 2:1f5dbc624b95 264 //INFO("Mask: Event mask: %02X, test mask: %02X", daymask, testmask);
WiredHome 2:1f5dbc624b95 265 if (daymask & testmask)
WiredHome 2:1f5dbc624b95 266 intersects = true;
WiredHome 2:1f5dbc624b95 267 else
WiredHome 2:1f5dbc624b95 268 intersects = false;
WiredHome 2:1f5dbc624b95 269 //INFO(" intersects: %02X", daymask & testmask);
WiredHome 2:1f5dbc624b95 270 return intersects;
WiredHome 4:a1c25d936346 271 } else if (Event->RepeatFreq == rptfYearly) {
WiredHome 4:a1c25d936346 272 //struct tm * timeinfo;
WiredHome 4:a1c25d936346 273 //timeinfo = localtime(start1);
WiredHome 5:69577415c16e 274 //INFO("rptfYearly is not handled well yet");
WiredHome 2:1f5dbc624b95 275 }
WiredHome 2:1f5dbc624b95 276 //INFO("Mask: no handler, returning true");
WiredHome 2:1f5dbc624b95 277 return true;
WiredHome 2:1f5dbc624b95 278 }
WiredHome 2:1f5dbc624b95 279
WiredHome 4:a1c25d936346 280 bool RepeatIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event)
WiredHome 0:49245357cd1b 281 {
WiredHome 4:a1c25d936346 282
WiredHome 5:69577415c16e 283 //INFO("** 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 5:69577415c16e 284 //INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 4:a1c25d936346 285 if (TimeIntersects(start1, end1, start2, end2))
WiredHome 4:a1c25d936346 286 return true;
WiredHome 4:a1c25d936346 287 if (Event && Event->RepeatFreq) {
WiredHome 5:69577415c16e 288 //INFO("Summary: %s", Event->Summary);
WiredHome 4:a1c25d936346 289 if (Event->Start < *start2 && Event->Until > *start2 ) { // Until=....
WiredHome 0:49245357cd1b 290 do {
WiredHome 4:a1c25d936346 291 time_t interval = NextInterval(*start1, Event->RepeatFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 0:49245357cd1b 292 *start1 = *start1 + interval;
WiredHome 4:a1c25d936346 293 if (*end1)
WiredHome 4:a1c25d936346 294 *end1 = *end1 + interval;
WiredHome 5:69577415c16e 295 //INFO("** 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 5:69577415c16e 296 //INFO("until (%24s, %s)", " ", FormatCTime(Event->Until));
WiredHome 5:69577415c16e 297 //INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 2:1f5dbc624b95 298 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 2:1f5dbc624b95 299 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 2:1f5dbc624b95 300 }
WiredHome 0:49245357cd1b 301 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 0:49245357cd1b 302 return true;
WiredHome 0:49245357cd1b 303 }
WiredHome 4:a1c25d936346 304 } while ((*end2 == 0 || *start1 < *end2) && *start1 < Event->Until);
WiredHome 4:a1c25d936346 305 } else if (Event->Start < *start2 && Event->Count) { // Count=
WiredHome 4:a1c25d936346 306 int count = Event->Count - 1;
WiredHome 0:49245357cd1b 307 do {
WiredHome 4:a1c25d936346 308 time_t interval = NextInterval(*start1, Event->RepeatFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 0:49245357cd1b 309 *start1 = *start1 + interval;
WiredHome 4:a1c25d936346 310 if (*end1)
WiredHome 4:a1c25d936346 311 *end1 = *end1 + interval;
WiredHome 5:69577415c16e 312 //INFO("** 1: (%s, %s) - %d", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "", count);
WiredHome 5:69577415c16e 313 //INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 2:1f5dbc624b95 314 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 2:1f5dbc624b95 315 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 2:1f5dbc624b95 316 }
WiredHome 0:49245357cd1b 317 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 0:49245357cd1b 318 return true;
WiredHome 0:49245357cd1b 319 }
WiredHome 2:1f5dbc624b95 320 } while (--count);
WiredHome 4:a1c25d936346 321 } else if (Event->Start < *start2) { // no Count= and no Until=
WiredHome 0:49245357cd1b 322 do {
WiredHome 4:a1c25d936346 323 int rptFreq = Event->RepeatFreq;
WiredHome 4:a1c25d936346 324 if (Event->RepeatFreq == 2 && Event->RepeatDays != 0)
WiredHome 4:a1c25d936346 325 rptFreq--;
WiredHome 4:a1c25d936346 326 time_t interval = NextInterval(*start1, rptFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 0:49245357cd1b 327 *start1 = *start1 + interval;
WiredHome 4:a1c25d936346 328 if (*end1)
WiredHome 4:a1c25d936346 329 *end1 = *end1 + interval;
WiredHome 5:69577415c16e 330 //INFO("== 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 5:69577415c16e 331 //INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 2:1f5dbc624b95 332 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 2:1f5dbc624b95 333 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 2:1f5dbc624b95 334 }
WiredHome 0:49245357cd1b 335 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 0:49245357cd1b 336 return true;
WiredHome 0:49245357cd1b 337 }
WiredHome 4:a1c25d936346 338 } while (*start1 < *end2 || (*end2 == 0 && *start1 < *start2));
WiredHome 0:49245357cd1b 339 }
WiredHome 0:49245357cd1b 340 }
WiredHome 2:1f5dbc624b95 341 //INFO(" no intersection");
WiredHome 0:49245357cd1b 342 return false;
WiredHome 0:49245357cd1b 343 }
WiredHome 0:49245357cd1b 344
WiredHome 2:1f5dbc624b95 345 // All the stuff between
WiredHome 2:1f5dbc624b95 346 // BEGIN:VEVENT
WiredHome 2:1f5dbc624b95 347 // ...
WiredHome 2:1f5dbc624b95 348 // END:VEVENT
WiredHome 2:1f5dbc624b95 349 //
WiredHome 5:69577415c16e 350 void ParseEvent(Event_T * Event, char * pStart, tz_sec_t tzoSec)
WiredHome 2:1f5dbc624b95 351 {
WiredHome 5:69577415c16e 352 INFO("ParseEvent(...,'%s',%d)", pStart, tzoSec);
WiredHome 2:1f5dbc624b95 353 if (strncmp(pStart, "DTSTART:", 8) == 0) {
WiredHome 2:1f5dbc624b95 354 Event->Start = ParseDateStamp(pStart+8, tzoSec);
WiredHome 4:a1c25d936346 355 //INFO(" Start: %d\n", mktime(&Event->eventStart));
WiredHome 2:1f5dbc624b95 356 } else if (strncmp(pStart, "DTSTART;", 8) == 0) {
WiredHome 4:a1c25d936346 357 char * p = pStart + 8;
WiredHome 4:a1c25d936346 358 tzoSec = ParseTZID(p);
WiredHome 4:a1c25d936346 359 p = strrchr(pStart, ':');
WiredHome 2:1f5dbc624b95 360 if (p) {
WiredHome 2:1f5dbc624b95 361 Event->Start = ParseDateStamp(p+1, tzoSec);
WiredHome 5:69577415c16e 362 INFO(" Start: %s\n", ctime(&Event->Start));
WiredHome 2:1f5dbc624b95 363 }
WiredHome 2:1f5dbc624b95 364 } else if (strncmp(pStart, "DTEND:", 6) == 0) {
WiredHome 2:1f5dbc624b95 365 Event->End = ParseDateStamp(pStart+6, tzoSec);
WiredHome 4:a1c25d936346 366 //INFO(" End: %d\n", mktime(&Event->eventEnd));
WiredHome 2:1f5dbc624b95 367 } else if (strncmp(pStart, "DTEND;", 6) == 0) {
WiredHome 4:a1c25d936346 368 char * p = pStart + 8;
WiredHome 4:a1c25d936346 369 tzoSec = ParseTZID(p);
WiredHome 4:a1c25d936346 370 p = strrchr(pStart, ':');
WiredHome 2:1f5dbc624b95 371 if (p) {
WiredHome 2:1f5dbc624b95 372 Event->End = ParseDateStamp(p+1, tzoSec);
WiredHome 5:69577415c16e 373 INFO(" End: %s\n", ctime(&Event->End));
WiredHome 2:1f5dbc624b95 374 }
WiredHome 2:1f5dbc624b95 375 } else if (strncmp(pStart, "SUMMARY:", 8) == 0) {
WiredHome 2:1f5dbc624b95 376 strncpy(Event->Summary, pStart+8, SUMMARY_CHARS-1);
WiredHome 2:1f5dbc624b95 377 Event->Summary[SUMMARY_CHARS-1] = '\0';
WiredHome 4:a1c25d936346 378 //INFO(" Summary: %s\n", Event->Summary);
WiredHome 2:1f5dbc624b95 379 } else if (strncmp(pStart, "LOCATION:", 9) == 0) {
WiredHome 2:1f5dbc624b95 380 strncpy(Event->Location, pStart+9, LOCATION_CHARS-1);
WiredHome 2:1f5dbc624b95 381 Event->Location[LOCATION_CHARS-1] = '\0';
WiredHome 4:a1c25d936346 382 //INFO(" Location: %s\n", Event->Location);
WiredHome 2:1f5dbc624b95 383 } else if (strncmp(pStart, "PRIORITY:", 9) == 0) {
WiredHome 2:1f5dbc624b95 384 Event->Priority = *(pStart+9) - '0';
WiredHome 4:a1c25d936346 385 //INFO(" Priority: %d\n", Event->Priority);
WiredHome 2:1f5dbc624b95 386 } else if (strncmp(pStart, "CATEGORIES:", 11) == 0) {
WiredHome 2:1f5dbc624b95 387 strncpy(Event->Category, pStart+11, CATEGORY_CHARS-1);
WiredHome 2:1f5dbc624b95 388 Event->Category[CATEGORY_CHARS-1] = '\0';
WiredHome 4:a1c25d936346 389 //INFO(" Category: %s\n", Event->Category);
WiredHome 2:1f5dbc624b95 390 } else if (strncmp(pStart, "RRULE:", 6) == 0) {
WiredHome 2:1f5dbc624b95 391 //RRULE:FREQ=WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 2:1f5dbc624b95 392 char * p1, *p2;
WiredHome 2:1f5dbc624b95 393 //INFO("%s", pStart);
WiredHome 2:1f5dbc624b95 394 p1 = pStart + 6; // p1 = FREQ=WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 2:1f5dbc624b95 395 p2 = strchr(p1, ';');
WiredHome 2:1f5dbc624b95 396 if (p2)
WiredHome 2:1f5dbc624b95 397 *p2++ = '\0';
WiredHome 2:1f5dbc624b95 398 while (*p1) {
WiredHome 2:1f5dbc624b95 399 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 400 if (strncmp(p1, "FREQ=", 5) == 0) {
WiredHome 2:1f5dbc624b95 401 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 402 p1 += 5; // p1 = WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 2:1f5dbc624b95 403 if (strncmp(p1, "WEEKLY", 6) == 0) {
WiredHome 2:1f5dbc624b95 404 //INFO(" %s", p1);
WiredHome 2:1f5dbc624b95 405 Event->RepeatFreq = rptfWeekly;
WiredHome 2:1f5dbc624b95 406 p1 += 6;
WiredHome 2:1f5dbc624b95 407 } else if (strncmp(p1, "DAILY", 5) == 0) {
WiredHome 2:1f5dbc624b95 408 //INFO(" %s", p1);
WiredHome 2:1f5dbc624b95 409 Event->RepeatFreq = rptfDaily;
WiredHome 2:1f5dbc624b95 410 p1 += 5;
WiredHome 2:1f5dbc624b95 411 } else if (strncmp(p1, "MONTHLY", 7) == 0) {
WiredHome 2:1f5dbc624b95 412 //INFO(" %s", p1);
WiredHome 2:1f5dbc624b95 413 Event->RepeatFreq = rptfMonthly;
WiredHome 2:1f5dbc624b95 414 p1 += 7;
WiredHome 2:1f5dbc624b95 415 } else if (strncmp(p1, "YEARLY", 6) == 0) {
WiredHome 2:1f5dbc624b95 416 //INFO(" %s", p1);
WiredHome 2:1f5dbc624b95 417 Event->RepeatFreq = rptfYearly;
WiredHome 4:a1c25d936346 418 p1 += 6;
WiredHome 2:1f5dbc624b95 419 }
WiredHome 2:1f5dbc624b95 420 } else if (strncmp(p1, "INTERVAL=", 9) == 0) { // INTERVAL=2
WiredHome 2:1f5dbc624b95 421 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 422 p1 += 9;
WiredHome 2:1f5dbc624b95 423 Event->Interval = atoi(p1);
WiredHome 2:1f5dbc624b95 424 } else if (strncmp(p1, "COUNT=", 6) == 0) { // COUNT=12;
WiredHome 2:1f5dbc624b95 425 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 426 p1 += 6; // p1 =
WiredHome 2:1f5dbc624b95 427 Event->Count = atoi(p1);
WiredHome 2:1f5dbc624b95 428 } else if (strncmp(p1, "UNTIL=", 6) == 0) {
WiredHome 2:1f5dbc624b95 429 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 430 p1 += 6; // p1 = 20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 4:a1c25d936346 431 //printf("UNTIL= {%s}\n", p1);
WiredHome 2:1f5dbc624b95 432 Event->Until = ParseDateStamp(p1, tzoSec);
WiredHome 4:a1c25d936346 433 //printf("UNTIL:: %d: %d\n", Event->Until, tzoSec);
WiredHome 2:1f5dbc624b95 434 } else if (strncmp(p1, "BYDAY=", 6) == 0) {
WiredHome 2:1f5dbc624b95 435 //INFO("%s", p1);
WiredHome 2:1f5dbc624b95 436 p1 += 6; // p1 = MO,TU,WE,TH,FR
WiredHome 2:1f5dbc624b95 437 while (*p1 >= ' ') {
WiredHome 2:1f5dbc624b95 438 //INFO(" %s", p1);
WiredHome 2:1f5dbc624b95 439 for (int d=0; d<7; d++) {
WiredHome 2:1f5dbc624b95 440 if (strncmp(p1,RepeatDayAbbrev(d),2) == 0) {
WiredHome 2:1f5dbc624b95 441 Event->RepeatDays |= (1 << d);
WiredHome 2:1f5dbc624b95 442 //INFO(" %s %02X", RepeatDayAbbrev(d), Event->RepeatDays);
WiredHome 2:1f5dbc624b95 443 break;
WiredHome 2:1f5dbc624b95 444 }
WiredHome 2:1f5dbc624b95 445 }
WiredHome 2:1f5dbc624b95 446 p1 += 3;
WiredHome 2:1f5dbc624b95 447 }
WiredHome 2:1f5dbc624b95 448 //INFO(" RepeatDay: %02X", Event->RepeatDays);
WiredHome 4:a1c25d936346 449 } else if (strncmp(p1, "BYMONTHDAY=", 11) == 0) {
WiredHome 4:a1c25d936346 450 // RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
WiredHome 4:a1c25d936346 451 p1 += 11;
WiredHome 4:a1c25d936346 452 while (*p1 >= ' ') {
WiredHome 4:a1c25d936346 453 char * px = p1;
WiredHome 4:a1c25d936346 454 while (*px >= ' ' && *px != ',') { // find , or ; or <nul>
WiredHome 4:a1c25d936346 455 px++;
WiredHome 4:a1c25d936346 456 }
WiredHome 4:a1c25d936346 457 if (*px)
WiredHome 4:a1c25d936346 458 *px++ = '\0';
WiredHome 4:a1c25d936346 459 int num = atoi(p1);
WiredHome 4:a1c25d936346 460 if (num >= 0)
WiredHome 4:a1c25d936346 461 Event->RepeatMonthDay |= (1 << num);
WiredHome 4:a1c25d936346 462 else
WiredHome 4:a1c25d936346 463 Event->RepeatMonthDayRev |= (1 << -num);
WiredHome 4:a1c25d936346 464 p1 = px;
WiredHome 4:a1c25d936346 465 }
WiredHome 4:a1c25d936346 466 INFO(" RepeatMonthDay: %08X", Event->RepeatMonthDay);
WiredHome 4:a1c25d936346 467 } else if (strncmp(p1, "BYMONTH=", 8) == 0) {
WiredHome 4:a1c25d936346 468 // RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3
WiredHome 4:a1c25d936346 469 p1 += 8;
WiredHome 4:a1c25d936346 470 while (*p1 >= ' ') {
WiredHome 4:a1c25d936346 471 char * px = p1;
WiredHome 4:a1c25d936346 472 while (*px >= ' ' && *px != ',') { // find , or ; or <nul>
WiredHome 4:a1c25d936346 473 px++;
WiredHome 4:a1c25d936346 474 }
WiredHome 4:a1c25d936346 475 if (*px)
WiredHome 4:a1c25d936346 476 *px++ = '\0';
WiredHome 4:a1c25d936346 477 int num = atoi(p1);
WiredHome 4:a1c25d936346 478 if (num >= 0)
WiredHome 4:a1c25d936346 479 Event->RepeatMonths |= (1 << num);
WiredHome 4:a1c25d936346 480 else
WiredHome 4:a1c25d936346 481 ; // Event->RepeatMonthsRev |= (1 << -num);
WiredHome 4:a1c25d936346 482 p1 = px;
WiredHome 4:a1c25d936346 483 }
WiredHome 4:a1c25d936346 484 INFO(" RepeatMonths: %04X", Event->RepeatMonths);
WiredHome 2:1f5dbc624b95 485 }
WiredHome 2:1f5dbc624b95 486 if (!p2)
WiredHome 2:1f5dbc624b95 487 break;
WiredHome 2:1f5dbc624b95 488 p1 = p2;
WiredHome 2:1f5dbc624b95 489 p2 = strchr(p1, ';');
WiredHome 2:1f5dbc624b95 490 if (p2)
WiredHome 2:1f5dbc624b95 491 *p2++ = '\0';
WiredHome 2:1f5dbc624b95 492 }
WiredHome 2:1f5dbc624b95 493 }
WiredHome 2:1f5dbc624b95 494 }
WiredHome 0:49245357cd1b 495
WiredHome 4:a1c25d936346 496
WiredHome 4:a1c25d936346 497 // TZID="(GMT -06:00)":20140519T063000
WiredHome 4:a1c25d936346 498 // TZID:(UTC-06:00) Central Time (US & Canada)
WiredHome 4:a1c25d936346 499 // TZID:(GMT -06:00)
WiredHome 5:69577415c16e 500 tz_sec_t ParseTZID(char * string)
WiredHome 4:a1c25d936346 501 {
WiredHome 5:69577415c16e 502 tz_sec_t tzo = 0;
WiredHome 4:a1c25d936346 503 bool sign = false;
WiredHome 4:a1c25d936346 504
WiredHome 5:69577415c16e 505 INFO("ParseTZID(%s)", string);
WiredHome 4:a1c25d936346 506 if (*string == '"') // TZID="(GMT -06:00)":20140519T063000
WiredHome 4:a1c25d936346 507 string++;
WiredHome 4:a1c25d936346 508 if ((strncmp(string, "(UTC", 4) == 0)
WiredHome 4:a1c25d936346 509 || (strncmp(string, "(GMT", 4) == 0) ){
WiredHome 4:a1c25d936346 510 string += 4;
WiredHome 4:a1c25d936346 511 if (*string == ' ')
WiredHome 4:a1c25d936346 512 string++;
WiredHome 4:a1c25d936346 513 if (*string == '-') {
WiredHome 4:a1c25d936346 514 sign = true;
WiredHome 4:a1c25d936346 515 string++;
WiredHome 4:a1c25d936346 516 }
WiredHome 4:a1c25d936346 517 tzo = atoi(string) * 3600;
WiredHome 4:a1c25d936346 518 string = strchr(string, ':');
WiredHome 4:a1c25d936346 519 if (string) {
WiredHome 4:a1c25d936346 520 string++;
WiredHome 4:a1c25d936346 521 tzo += atoi(string) * 60;
WiredHome 4:a1c25d936346 522 }
WiredHome 4:a1c25d936346 523 if (sign)
WiredHome 4:a1c25d936346 524 tzo = -tzo;
WiredHome 5:69577415c16e 525 INFO(" tzo = %d", tzo);
WiredHome 4:a1c25d936346 526 } else {
WiredHome 4:a1c25d936346 527 ERR("Unhandled TZID(%s)", string);
WiredHome 4:a1c25d936346 528 }
WiredHome 4:a1c25d936346 529 return tzo;
WiredHome 4:a1c25d936346 530 }
WiredHome 4:a1c25d936346 531
WiredHome 5:69577415c16e 532 int ParseICalStream(char * pStart, time_t gridStartTime, time_t gridEndTime, tz_min_t tzoMin, bool showEvents)
WiredHome 0:49245357cd1b 533 {
WiredHome 0:49245357cd1b 534 Event_T Event;
WiredHome 0:49245357cd1b 535 bool tzAdjusted = false;
WiredHome 0:49245357cd1b 536 char * pEnd;
WiredHome 0:49245357cd1b 537 typedef enum { idle, inTimeZone, inEvent } seekstate_t;
WiredHome 0:49245357cd1b 538 seekstate_t seeking = idle;
WiredHome 4:a1c25d936346 539
WiredHome 0:49245357cd1b 540 EventCount = 0;
WiredHome 4:a1c25d936346 541 if (gridEndTime == gridStartTime)
WiredHome 4:a1c25d936346 542 gridEndTime++; // advance so they are not equal
WiredHome 0:49245357cd1b 543 while (pStart && EventCount < EVENT_COUNT) {
WiredHome 0:49245357cd1b 544 pEnd = strchr(pStart, '\n');
WiredHome 0:49245357cd1b 545 if (pEnd) {
WiredHome 0:49245357cd1b 546 if (*(pEnd-1) == '\r')
WiredHome 0:49245357cd1b 547 pEnd--;
WiredHome 0:49245357cd1b 548 *pEnd++ = '\0';
WiredHome 0:49245357cd1b 549 while (*pEnd && *pEnd < ' ') {
WiredHome 0:49245357cd1b 550 pEnd++;
WiredHome 0:49245357cd1b 551 }
WiredHome 0:49245357cd1b 552 // pStart now has a single null terminated line of text.
WiredHome 5:69577415c16e 553 //if (showEvents)
WiredHome 5:69577415c16e 554 //INFO("*** %s", pStart);
WiredHome 0:49245357cd1b 555 switch (seeking) {
WiredHome 0:49245357cd1b 556 case idle:
WiredHome 0:49245357cd1b 557 if (strcmp(pStart, "BEGIN:VTIMEZONE") == 0)
WiredHome 0:49245357cd1b 558 seeking = inTimeZone;
WiredHome 0:49245357cd1b 559 else if (strcmp(pStart, "BEGIN:VEVENT") == 0) {
WiredHome 0:49245357cd1b 560 seeking = inEvent;
WiredHome 0:49245357cd1b 561 Event.Start = 0;
WiredHome 0:49245357cd1b 562 Event.End = 0;
WiredHome 0:49245357cd1b 563 Event.Until = 0;
WiredHome 0:49245357cd1b 564 Event.Summary[0] = '\0';
WiredHome 0:49245357cd1b 565 Event.Location[0] = '\0';
WiredHome 0:49245357cd1b 566 Event.Category[0] = '\0';
WiredHome 0:49245357cd1b 567 Event.Count = 0;
WiredHome 0:49245357cd1b 568 Event.Interval = 0;
WiredHome 0:49245357cd1b 569 Event.RepeatFreq = rptfNone;
WiredHome 0:49245357cd1b 570 Event.RepeatDays = 0;
WiredHome 4:a1c25d936346 571 Event.RepeatMonthDay = 0;
WiredHome 4:a1c25d936346 572 Event.RepeatMonthDayRev = 0;
WiredHome 4:a1c25d936346 573 Event.RepeatMonths = 0;
WiredHome 0:49245357cd1b 574 Event.Priority = 5; // 5 is Normal
WiredHome 4:a1c25d936346 575 //ShowEventInfo(Event);
WiredHome 0:49245357cd1b 576 }
WiredHome 0:49245357cd1b 577 break;
WiredHome 0:49245357cd1b 578 case inTimeZone:
WiredHome 0:49245357cd1b 579 // Can also pick up daylight savings time
WiredHome 0:49245357cd1b 580 if (strcmp(pStart, "END:VTIMEZONE") == 0)
WiredHome 0:49245357cd1b 581 seeking = idle;
WiredHome 4:a1c25d936346 582 else if ((strncmp(pStart, "TZID:", 5) == 0)
WiredHome 4:a1c25d936346 583 || (strncmp(pStart, "TZID=", 5) == 0) ) {
WiredHome 4:a1c25d936346 584 tzoTZIDSec = ParseTZID(pStart + 5);
WiredHome 0:49245357cd1b 585 tzAdjusted = true;
WiredHome 4:a1c25d936346 586 }
WiredHome 0:49245357cd1b 587 break;
WiredHome 0:49245357cd1b 588 case inEvent:
WiredHome 0:49245357cd1b 589 // inEvent
WiredHome 0:49245357cd1b 590 if (strcmp(pStart, "END:VEVENT") == 0) {
WiredHome 0:49245357cd1b 591 // Timezone offset
WiredHome 0:49245357cd1b 592 if (!tzAdjusted) {
WiredHome 5:69577415c16e 593 Event.Start += (60 * tzoMin);
WiredHome 4:a1c25d936346 594 if (Event.End)
WiredHome 5:69577415c16e 595 Event.End += (60 * tzoMin);
WiredHome 0:49245357cd1b 596 }
WiredHome 0:49245357cd1b 597 // Process it
WiredHome 4:a1c25d936346 598 if (showEvents)
WiredHome 4:a1c25d936346 599 ShowEventInfo(Event);
WiredHome 0:49245357cd1b 600 if (1 || Event.Start >= gridStartTime && Event.Start < gridEndTime
WiredHome 0:49245357cd1b 601 || Event.End >= gridStartTime && Event.End < gridEndTime) {
WiredHome 0:49245357cd1b 602 EventList[EventCount++] = Event;
WiredHome 4:a1c25d936346 603 if (showEvents)
WiredHome 4:a1c25d936346 604 INFO(" +++++ Added Event %d: %s", EventCount, Event.Summary);
WiredHome 0:49245357cd1b 605 }
WiredHome 0:49245357cd1b 606 seeking = idle;
WiredHome 2:1f5dbc624b95 607 } else {
WiredHome 5:69577415c16e 608 ParseEvent(&Event, pStart, 60 * tzoMin);
WiredHome 2:1f5dbc624b95 609 }
WiredHome 0:49245357cd1b 610 // End of inEvent
WiredHome 0:49245357cd1b 611 break;
WiredHome 0:49245357cd1b 612 default:
WiredHome 0:49245357cd1b 613 seeking = idle;
WiredHome 0:49245357cd1b 614 break;
WiredHome 0:49245357cd1b 615 }
WiredHome 0:49245357cd1b 616 pStart = pEnd;
WiredHome 0:49245357cd1b 617 } else {
WiredHome 0:49245357cd1b 618 pStart = NULL;
WiredHome 0:49245357cd1b 619 }
WiredHome 0:49245357cd1b 620 } // while
WiredHome 4:a1c25d936346 621 if (EventCount > 0)
WiredHome 4:a1c25d936346 622 SortEvents();
WiredHome 4:a1c25d936346 623 return GetNumEvents();
WiredHome 4:a1c25d936346 624 }