an iCal processing library

Committer:
WiredHome
Date:
Sun Oct 01 18:07:46 2017 +0000
Revision:
12:3dc52826343f
Parent:
10:deeaec151283
make a private data structure static to avoid a name clash

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