]> err.no Git - sope/blobdiff - sope-ical/NGiCal/iCalRecurrenceCalculator.m
various bugfixes and optimizations
[sope] / sope-ical / NGiCal / iCalRecurrenceCalculator.m
index d51e845a8b24d0056f46b3866a73ef77c1bc75e9..797037e1ab4290e38964d449ed37699f8b3a67ec 100644 (file)
@@ -103,6 +103,7 @@ static Class yearlyCalcClass  = Nil;
   id                       rule;
   iCalRecurrenceCalculator *calc;
   NSMutableArray           *ranges;
+  NSMutableArray           *exDates;
   unsigned                 i, count, rCount;
   
   ranges = [NSMutableArray array];
@@ -141,22 +142,46 @@ static Class yearlyCalcClass  = Nil;
   if (![ranges count])
     return nil;
   
-  /* exception dates are also possible */
-  rCount = [ranges count];
+  /* exception dates */
+
   count  = [_exDates count];
+  if (!count) return ranges;
+
+  /* sort out exDates not within range */
+
+  exDates = [NSMutableArray arrayWithCapacity:count];
   for (i = 0; i < count; i++) {
-    id                  exDate;
-    NGCalendarDateRange *r;
-    unsigned            k;
+    id exDate;
 
     exDate = [_exDates objectAtIndex:i];
     if (![exDate isKindOfClass:NSCalendarDateClass]) {
       exDate = [NSCalendarDate calendarDateWithICalRepresentation:exDate];
     }
+    if ([_r containsDate:exDate])
+      [exDates addObject:exDate];
+  }
+
+  /* remove matching exDates from ranges */
+
+  count  = [exDates count];
+  if (!count) return ranges;
+
+  rCount = [ranges count];
+  for (i = 0; i < count; i++) {
+    NSCalendarDate      *exDate;
+    NGCalendarDateRange *r;
+    unsigned            k;
+
+    exDate = [exDates objectAtIndex:i];
     for (k = 0; k < rCount; k++) {
-      r = [ranges objectAtIndex:(rCount - k) - 1];
+      unsigned rIdx;
+      
+      rIdx = (rCount - k) - 1;
+      r    = [ranges objectAtIndex:rIdx];
       if ([r containsDate:exDate]) {
-        [ranges removeObjectAtIndex:k];
+        [ranges removeObjectAtIndex:rIdx];
+        rCount--;
+        break; /* this is safe because we know that ranges don't overlap */
       }
     }
   }
@@ -340,7 +365,8 @@ static Class yearlyCalcClass  = Nil;
         end   = [start addTimeInterval:[self->firstRange duration]];
         r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
                                      endDate:end];
-        [ranges addObject:r];
+        if ([_r containsDateRange:r])
+          [ranges addObject:r];
       }
     }
   }
@@ -437,7 +463,8 @@ static Class yearlyCalcClass  = Nil;
           end   = [start addTimeInterval:[self->firstRange duration]];
           r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
                                        endDate:end];
-          [ranges addObject:r];
+          if ([_r containsDateRange:r])
+            [ranges addObject:r];
         }
       }
     }
@@ -485,7 +512,8 @@ static Class yearlyCalcClass  = Nil;
             end   = [start addTimeInterval:[self->firstRange duration]];
             r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
                                          endDate:end];
-            [ranges addObject:r];
+            if ([_r containsDateRange:r])
+              [ranges addObject:r];
           }
         }
       }
@@ -553,7 +581,8 @@ static Class yearlyCalcClass  = Nil;
       end   = [start addTimeInterval:[self->firstRange duration]];
       r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
                                    endDate:end];
-      [ranges addObject:r];
+      if ([_r containsDateRange:r])
+        [ranges addObject:r];
     }
   }
   return ranges;
@@ -614,7 +643,8 @@ static Class yearlyCalcClass  = Nil;
       end   = [start addTimeInterval:[self->firstRange duration]];
       r     = [NGCalendarDateRange calendarDateRangeWithStartDate:start
                                    endDate:end];
-      [ranges addObject:r];
+      if ([_r containsDateRange:r])
+        [ranges addObject:r];
     }
   }
   return ranges;