@implementation OCSiCalFieldExtractor
-static id<NSObject,SaxXMLReader> parser = nil;
-static SaxObjectDecoder *sax = nil;
-static OCSiCalFieldExtractor *extractor = nil;
+static id<NSObject,SaxXMLReader> parser = nil;
+static SaxObjectDecoder *sax = nil;
+static OCSiCalFieldExtractor *extractor = nil;
+static NSCalendarDate *distantFuture = nil;
+static NSNumber *distantFutureNumber = nil;
+ (void)initialize {
- if (parser == nil) {
- parser = [[[SaxXMLReaderFactory standardXMLReaderFactory]
+ static BOOL didInit = NO;
+
+ if (didInit) return;
+ didInit = YES;
+
+ parser = [[[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType:@"text/calendar"]
retain];
- if (parser == nil)
- NSLog(@"ERROR: did not find a parser for text/calendar!");
- }
- if (sax == nil) {
- sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
- if (sax == nil)
+ if (parser == nil)
+ NSLog(@"ERROR: did not find a parser for text/calendar!");
+ sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
+ if (sax == nil)
NSLog(@"ERROR: could not create the iCal SAX handler!");
- }
-
[parser setContentHandler:sax];
[parser setErrorHandler:sax];
+
+ distantFuture = [[NSCalendarDate distantFuture] retain];
+ /* INT_MAX due to Postgres constraint */
+ distantFutureNumber = [[NSNumber numberWithUnsignedInt:INT_MAX] retain];
}
+ (id)sharedICalFieldExtractor {
/* operations */
- (NSNumber *)numberForDate:(NSCalendarDate *)_date {
+ if (_date == distantFuture)
+ return distantFutureNumber;
return [NSNumber numberWithUnsignedInt:[_date timeIntervalSince1970]];
}
if ([startDate isNotNull])
[row setObject:[self numberForDate:startDate] forKey:@"startdate"];
- if ([endDate isNotNull])
- [row setObject:[self numberForDate:endDate] forKey:@"enddate"];
-
+ if (![_event isRecurrent]) {
+ if ([endDate isNotNull])
+ [row setObject:[self numberForDate:endDate] forKey:@"enddate"];
+ }
+ else {
+ NSCalendarDate *date;
+
+ date = [_event lastPossibleRecurrenceStartDate];
+ if (!date) {
+ /* date might be nil, indicating an unbound recurrence - we substitute
+ this with a very distant date since 'enddate' is not allowed to be
+ NULL */
+ date = distantFuture;
+ }
+ [row setObject:[self numberForDate:date] forKey:@"enddate"];
+ }
if ([participants length] > 0)
[row setObject:participants forKey:@"participants"];
if ([partmails length] > 0)