Bug 1602424 - Remove xpidl [array] use in calIRecurrenceItem. r=mkmelin,darktrojan
authorBen Campbell <benc@thunderbird.net>
Mon, 23 Dec 2019 13:51:15 +1300
changeset 36959 5ba4422e867f7f2b922673b2b8bb58dac0a788e3
parent 36958 ebbfde7f5adde2b8e22f5366cb2cf3569e112f07
child 36960 e71712f49a91e1aba5123a0a5e841abd92bd0634
push id2543
push userclokep@gmail.com
push dateMon, 06 Jan 2020 23:26:40 +0000
treeherdercomm-beta@323890d47ddf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, darktrojan
bugs1602424
Bug 1602424 - Remove xpidl [array] use in calIRecurrenceItem. r=mkmelin,darktrojan
calendar/base/backend/icaljs/calRecurrenceRule.js
calendar/base/backend/libical/calRecurrenceRule.cpp
calendar/base/public/calIRecurrenceItem.idl
calendar/base/src/calRecurrenceDate.js
calendar/base/src/calRecurrenceInfo.js
--- a/calendar/base/backend/icaljs/calRecurrenceRule.js
+++ b/calendar/base/backend/icaljs/calRecurrenceRule.js
@@ -47,17 +47,17 @@ calRecurrenceRule.prototype = {
   },
 
   getNextOccurrence: function(aStartTime, aRecId) {
     aStartTime = unwrapSingle(ICAL.Time, aStartTime);
     aRecId = unwrapSingle(ICAL.Time, aRecId);
     return wrapGetter(calDateTime, this.innerObject.getNextOccurrence(aStartTime, aRecId));
   },
 
-  getOccurrences: function(aStartTime, aRangeStart, aRangeEnd, aMaxCount, aCount) {
+  getOccurrences: function(aStartTime, aRangeStart, aRangeEnd, aMaxCount) {
     aStartTime = unwrapSingle(ICAL.Time, aStartTime);
     aRangeStart = unwrapSingle(ICAL.Time, aRangeStart);
     aRangeEnd = unwrapSingle(ICAL.Time, aRangeEnd);
 
     if (!aMaxCount && !aRangeEnd && this.count == 0 && this.until == null) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
@@ -68,17 +68,16 @@ calRecurrenceRule.prototype = {
     let dtend = null;
 
     if (aRangeEnd) {
       dtend = aRangeEnd.clone();
       dtend.isDate = false;
 
       // If the start of the recurrence is past the end, we have no dates
       if (aStartTime.compare(dtend) >= 0) {
-        aCount.value = 0;
         return [];
       }
     }
 
     let iter = this.innerObject.iterator(aStartTime);
 
     for (let next = iter.next(); next; next = iter.next()) {
       let dtNext = next.clone();
@@ -100,17 +99,16 @@ calRecurrenceRule.prototype = {
 
       occurrences.push(new calDateTime(next));
 
       if (aMaxCount && aMaxCount >= occurrences.length) {
         break;
       }
     }
 
-    aCount.value = occurrences.length;
     return occurrences;
   },
 
   get icalString() {
     return "RRULE:" + this.innerObject.toString() + ICAL.newLineChar;
   },
   set icalString(val) {
     this.ensureMutable();
--- a/calendar/base/backend/libical/calRecurrenceRule.cpp
+++ b/calendar/base/backend/libical/calRecurrenceRule.cpp
@@ -381,21 +381,20 @@ static inline icaltimetype ensureDateTim
     return ret;
   }
 }
 
 NS_IMETHODIMP
 calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
                                   calIDateTime *aRangeStart,
                                   calIDateTime *aRangeEnd, uint32_t aMaxCount,
-                                  uint32_t *aCount, calIDateTime ***aDates) {
+                                  nsTArray<RefPtr<calIDateTime>> &aDates) {
   NS_ENSURE_ARG_POINTER(aStartTime);
   NS_ENSURE_ARG_POINTER(aRangeStart);
-  NS_ENSURE_ARG_POINTER(aCount);
-  NS_ENSURE_ARG_POINTER(aDates);
+  aDates.ClearAndRetainStorage();
 
   // make sure the request is sane; infinite recurrence
   // with no end time is bad times.
   if (!aMaxCount && !aRangeEnd && mIcalRecur.count == 0 &&
       icaltime_is_null_time(mIcalRecur.until))
     return NS_ERROR_INVALID_ARG;
 
   nsCOMArray<calIDateTime> dates;
@@ -433,74 +432,50 @@ calRecurrenceRule::GetOccurrences(calIDa
     NS_ENSURE_SUCCESS(rv, rv);
 
     icalrangeend->ToIcalTime(&dtend);
     dtend = ensureDateTime(dtend);
 
     // if the start of the recurrence is past the end,
     // we have no dates
     if (icaltime_compare(dtstart, dtend) >= 0) {
-      *aDates = nullptr;
-      *aCount = 0;
       return NS_OK;
     }
   }
 
   icalrecur_iterator *recur_iter;
   recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
   if (!recur_iter) return NS_ERROR_OUT_OF_MEMORY;
 
-  uint32_t count = 0;
-
   for (icaltimetype next = icalrecur_iterator_next(recur_iter);
        !icaltime_is_null_time(next);
        next = icalrecur_iterator_next(recur_iter)) {
     icaltimetype const dtNext(ensureDateTime(next));
 
     // if this thing is before the range start
     if (icaltime_compare(dtNext, rangestart) < 0) {
       continue;
     }
 
     if (aRangeEnd && icaltime_compare(dtNext, dtend) >= 0) break;
 
-    calIDateTime *const cdt = new calDateTime(&next, tz);
-    if (!cdt) {
-      icalrecur_iterator_free(recur_iter);
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    dates.AppendObject(cdt);
+    calIDateTime *cdt = new calDateTime(&next, tz);
+    aDates.AppendElement(cdt);
 #ifdef DEBUG_dbo
     {
       nsAutoCString str;
       cdt->ToString(str);
       printf("  occ: %s\n", str.get());
     }
 #endif
-    count++;
-    if (aMaxCount && aMaxCount <= count) break;
+    if (aMaxCount && aMaxCount <= aDates.Length()) break;
   }
 
   icalrecur_iterator_free(recur_iter);
 
-  if (count) {
-    calIDateTime **const dateArray = static_cast<calIDateTime **>(
-        moz_xmalloc(sizeof(calIDateTime *) * count));
-    CAL_ENSURE_MEMORY(dateArray);
-    for (uint32_t i = 0; i < count; ++i) {
-      NS_ADDREF(dateArray[i] = dates[i]);
-    }
-    *aDates = dateArray;
-  } else {
-    *aDates = nullptr;
-  }
-
-  *aCount = count;
-
   return NS_OK;
 }
 
 /**
  ** ical property getting/setting
  **/
 NS_IMETHODIMP
 calRecurrenceRule::GetIcalProperty(calIIcalProperty **prop) {
--- a/calendar/base/public/calIRecurrenceItem.idl
+++ b/calendar/base/public/calIRecurrenceItem.idl
@@ -40,17 +40,16 @@ interface calIRecurrenceItem : nsISuppor
    * @param aTime           The earliest time to find the occurrence after.
    */
   calIDateTime getNextOccurrence(in calIDateTime aRecurrenceId,
                                  in calIDateTime aTime);
 
   // return array of calIDateTime of the start of all occurrences of
   // this event starting at aStartTime, between rangeStart and an
   // optional rangeEnd
-  void getOccurrences (in calIDateTime aStartTime,
-                       in calIDateTime aRangeStart,
-                       in calIDateTime aRangeEnd,
-                       in unsigned long aMaxCount,
-                       out unsigned long aCount, [array,size_is(aCount),retval] out calIDateTime aDates);
+  Array<calIDateTime> getOccurrences(in calIDateTime aStartTime,
+                                     in calIDateTime aRangeStart,
+                                     in calIDateTime aRangeEnd,
+                                     in unsigned long aMaxCount);
 
   attribute calIIcalProperty icalProperty;
   attribute AUTF8String icalString;
 };
--- a/calendar/base/src/calRecurrenceDate.js
+++ b/calendar/base/src/calRecurrenceDate.js
@@ -65,26 +65,24 @@ calRecurrenceDate.prototype = {
   getNextOccurrence: function(aStartTime, aOccurrenceTime) {
     if (this.mDate && this.mDate.compare(aStartTime) > 0) {
       return this.mDate;
     } else {
       return null;
     }
   },
 
-  getOccurrences: function(aStartTime, aRangeStart, aRangeEnd, aMaxCount, aCount) {
+  getOccurrences: function(aStartTime, aRangeStart, aRangeEnd, aMaxCount) {
     if (
       this.mDate &&
       this.mDate.compare(aRangeStart) >= 0 &&
       (!aRangeEnd || this.mDate.compare(aRangeEnd) < 0)
     ) {
-      aCount.value = 1;
       return [this.mDate];
     } else {
-      aCount.value = 0;
       return [];
     }
   },
 
   get icalString() {
     let comp = this.icalProperty;
     return comp ? comp.icalString : "";
   },
--- a/calendar/base/src/calRecurrenceInfo.js
+++ b/calendar/base/src/calRecurrenceInfo.js
@@ -291,17 +291,17 @@ calRecurrenceInfo.prototype = {
       // because its very performance hungry and could potentially
       // lead to a deadlock (i.e RRULE is canceled out by an EXRULE).
       // This is ok for now, since EXRULE is deprecated anyway.
       if (ritem.isFinite) {
         // Get all occurrences starting at our recurrence start date.
         // This is fine, since there will never be an EXDATE that
         // occurs before the event started and its illegal to EXDATE an
         // RDATE.
-        let rdates = ritem.getOccurrences(startDate, startDate, null, 0, {});
+        let rdates = ritem.getOccurrences(startDate, startDate, null, 0);
         // Map all negative dates.
         for (let rdate of rdates) {
           negMap[getRidKey(rdate)] = true;
         }
       } else {
         cal.WARN(
           "Item '" +
             this.mBaseItem.title +
@@ -502,17 +502,17 @@ calRecurrenceInfo.prototype = {
     if (rangeStart && rangeEnd) {
       maxCount = 0;
     } else {
       maxCount = aMaxCount;
     }
 
     // Apply positive rules
     for (let ritem of this.mPositiveRules) {
-      let cur_dates = ritem.getOccurrences(startDate, searchStart, rangeEnd, maxCount, {});
+      let cur_dates = ritem.getOccurrences(startDate, searchStart, rangeEnd, maxCount);
       if (cur_dates.length == 0) {
         continue;
       }
 
       // if positive, we just add these date to the existing set,
       // but only if they're not already there
 
       let index = 0;
@@ -540,17 +540,17 @@ calRecurrenceInfo.prototype = {
         // search could be optimized further
         cal.data.binaryInsert(dates, { id: date, rstart: date }, ridDateSortComptor);
         occurrenceMap[dateKey] = true;
       }
     }
 
     // Apply negative rules
     for (let ritem of this.mNegativeRules) {
-      let cur_dates = ritem.getOccurrences(startDate, searchStart, rangeEnd, maxCount, {});
+      let cur_dates = ritem.getOccurrences(startDate, searchStart, rangeEnd, maxCount);
       if (cur_dates.length == 0) {
         continue;
       }
 
       // XXX: i'm pretty sure negative dates can't really have exceptions
       // (like, you can't make a date "real" by defining an RECURRENCE-ID which
       // is an EXDATE, and then giving it a real DTSTART) -- so we don't
       // check exceptions here