+
+ key = [[key stringByTrimmingSpaces] lowercaseString];
+ if (![key isNotEmpty]) {
+ [self errorWithFormat:@"empty component in rrule: %@", _rrule];
+ continue;
+ }
+
+ vHolder = NULL;
+ switch ([key characterAtIndex:0]) {
+ case 'b':
+ if ([key isEqualToString:@"byday"]) vHolder = &pByday; break;
+ if ([key isEqualToString:@"bysetpos"]) vHolder = &pBysetpos; break;
+ break;
+ case 'c':
+ if ([key isEqualToString:@"count"]) vHolder = &pCount; break;
+ break;
+ case 'f':
+ if ([key isEqualToString:@"freq"]) vHolder = &pFrequency; break;
+ break;
+ case 'u':
+ if ([key isEqualToString:@"until"]) vHolder = &pUntil; break;
+ break;
+ default:
+ break;
+ }
+
+ if (vHolder != NULL) {
+ if ([*vHolder isNotEmpty])
+ [self errorWithFormat:@"more than one '%@' in: %@", key, _rrule];
+ else
+ *vHolder = [value copy];
+ }
+ else {
+ // TODO: we should just parse known keys and put remainders into a
+ // separate dictionary
+ //[self logWithFormat:@"TODO: add explicit support for key: %@", key];
+ [self takeValue:value forKey:key];
+ }
+ }
+
+ /* parse and fill individual values */
+ // TODO: this method should be a class method and create a new rrule object
+
+ if ([pFrequency isNotEmpty])
+ [self setFreq:pFrequency];
+ else
+ [self errorWithFormat:@"rrule contains no frequency: '%@'", _rrule];
+ [pFrequency release]; pFrequency = nil;
+
+ // TODO: we should parse byday in here
+ if (pByday != nil) [self setByday:pByday];
+ [pByday release]; pByday = nil;
+
+ if (pBysetpos != nil)
+ // TODO: implement
+ [self errorWithFormat:@"rrule contains bysetpos, unsupported: %@", _rrule];
+ [pBysetpos release]; pBysetpos = nil;
+
+ if (pUntil != nil) {
+ NSCalendarDate *pUntilDate;
+
+ if (pCount != nil) {
+ [self errorWithFormat:@"rrule contains 'count' AND 'until': %@", _rrule];
+ [pCount release];
+ pCount = nil;
+ }
+
+ /*
+ The spec says:
+ "If specified as a date-time value, then it MUST be specified in an
+ UTC time format."
+ TODO: we still need some object representing a 'timeless' date.
+ */
+ if (![pUntil hasSuffix:@"Z"]) {
+ [self warnWithFormat:@"'until' date has no explicit UTC marker: '%@'",
+ _rrule];
+ }
+
+ pUntilDate = [NSCalendarDate calendarDateWithICalRepresentation:pUntil];
+ if (pUntilDate != nil)
+ [self setUntilDate:pUntilDate];
+ else {
+ [self errorWithFormat:@"could not parse 'until' in rrule: %@",
+ _rrule];
+ }