diff --git a/icu4c/source/i18n/basictz.cpp b/icu4c/source/i18n/basictz.cpp index ba0c5e2fe6c..7b5449f4167 100644 --- a/icu4c/source/i18n/basictz.cpp +++ b/icu4c/source/i18n/basictz.cpp @@ -293,71 +293,77 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, } const InitialTimeZoneRule *orgini; - const TimeZoneRule **orgtrs = NULL; TimeZoneTransition tzt; - UBool avail; - UVector *orgRules = NULL; + bool avail; int32_t ruleCount; - TimeZoneRule *r = NULL; - UBool *done = NULL; - InitialTimeZoneRule *res_initial = NULL; - UVector *filteredRules = NULL; + TimeZoneRule *r = nullptr; UnicodeString name; int32_t i; UDate time, t; - UDate *newTimes = NULL; UDate firstStart; - UBool bFinalStd = FALSE, bFinalDst = FALSE; + UBool bFinalStd = false, bFinalDst = false; + + initial = nullptr; + transitionRules = nullptr; // Original transition rules ruleCount = countTransitionRules(status); if (U_FAILURE(status)) { return; } - orgRules = new UVector(ruleCount, status); + LocalPointer orgRules( + new UVector(uprv_deleteUObject, nullptr, ruleCount, status), status); if (U_FAILURE(status)) { return; } - orgtrs = (const TimeZoneRule**)uprv_malloc(sizeof(TimeZoneRule*)*ruleCount); - if (orgtrs == NULL) { + LocalMemory orgtrs( + static_cast(uprv_malloc(sizeof(TimeZoneRule*)*ruleCount))); + if (orgtrs.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; - goto error; + return; } - getTimeZoneRules(orgini, orgtrs, ruleCount, status); + getTimeZoneRules(orgini, &orgtrs[0], ruleCount, status); if (U_FAILURE(status)) { - goto error; + return; } for (i = 0; i < ruleCount; i++) { - orgRules->addElementX(orgtrs[i]->clone(), status); + LocalPointer lpRule(orgtrs[i]->clone(), status); + orgRules->adoptElement(lpRule.orphan(), status); if (U_FAILURE(status)) { - goto error; + return; } } - uprv_free(orgtrs); - orgtrs = NULL; avail = getPreviousTransition(start, TRUE, tzt); if (!avail) { // No need to filter out rules only applicable to time before the start initial = orgini->clone(); - transitionRules = orgRules; + if (initial == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + transitionRules = orgRules.orphan(); return; } - done = (UBool*)uprv_malloc(sizeof(UBool)*ruleCount); - if (done == NULL) { + LocalMemory done(static_cast(uprv_malloc(sizeof(bool)*ruleCount))); + if (done.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; - goto error; + return; } - filteredRules = new UVector(status); + LocalPointer filteredRules( + new UVector(uprv_deleteUObject, nullptr, status), status); if (U_FAILURE(status)) { - goto error; + return; } // Create initial rule tzt.getTo()->getName(name); - res_initial = new InitialTimeZoneRule(name, tzt.getTo()->getRawOffset(), - tzt.getTo()->getDSTSavings()); + LocalPointer res_initial( + new InitialTimeZoneRule(name, tzt.getTo()->getRawOffset(), tzt.getTo()->getDSTSavings()), status); + if (U_FAILURE(status)) { + return; + } // Mark rules which does not need to be processed for (i = 0; i < ruleCount; i++) { @@ -378,7 +384,7 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, // the same time. // TODO: fix getNextTransition() to prevent it? status = U_INVALID_STATE_ERROR; - goto error; + return; } time = updatedTime; @@ -392,7 +398,7 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, if (i >= ruleCount) { // This case should never happen status = U_INVALID_STATE_ERROR; - goto error; + return; } if (done[i]) { continue; @@ -418,9 +424,10 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, tar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart); if (firstStart > start) { // Just add the rule as is - filteredRules->addElementX(tar->clone(), status); + LocalPointer lpTar(tar->clone(), status); + filteredRules->adoptElement(lpTar.orphan(), status); if (U_FAILURE(status)) { - goto error; + return; } } else { // Collect transitions after the start time @@ -442,28 +449,25 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, break; } } + if (U_FAILURE(status)) { + return; + } int32_t asize = startTimes - idx; if (asize > 0) { - newTimes = (UDate*)uprv_malloc(sizeof(UDate) * asize); - if (newTimes == NULL) { + LocalMemory newTimes(static_cast(uprv_malloc(sizeof(UDate) * asize))); + if (newTimes.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; - goto error; + return; } for (int32_t newidx = 0; newidx < asize; newidx++) { tar->getStartTimeAt(idx + newidx, newTimes[newidx]); - if (U_FAILURE(status)) { - uprv_free(newTimes); - newTimes = NULL; - goto error; - } } tar->getName(name); - TimeArrayTimeZoneRule *newTar = new TimeArrayTimeZoneRule(name, - tar->getRawOffset(), tar->getDSTSavings(), newTimes, asize, timeType); - uprv_free(newTimes); - filteredRules->addElementX(newTar, status); + LocalPointer newTar(new TimeArrayTimeZoneRule( + name, tar->getRawOffset(), tar->getDSTSavings(), &newTimes[0], asize, timeType), status); + filteredRules->adoptElement(newTar.orphan(), status); if (U_FAILURE(status)) { - goto error; + return; } } } @@ -472,9 +476,10 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, ar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart); if (firstStart == tzt.getTime()) { // Just add the rule as is - filteredRules->addElementX(ar->clone(), status); + LocalPointer arClone(ar->clone(), status); + filteredRules->adoptElement(arClone.orphan(), status); if (U_FAILURE(status)) { - goto error; + return; } } else { // Calculate the transition year @@ -482,11 +487,11 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, Grego::timeToFields(tzt.getTime(), year, month, dom, dow, doy, mid); // Re-create the rule ar->getName(name); - AnnualTimeZoneRule *newAr = new AnnualTimeZoneRule(name, ar->getRawOffset(), ar->getDSTSavings(), - *(ar->getRule()), year, ar->getEndYear()); - filteredRules->addElementX(newAr, status); + LocalPointer newAr(new AnnualTimeZoneRule(name, ar->getRawOffset(), ar->getDSTSavings(), + *(ar->getRule()), year, ar->getEndYear()), status); + filteredRules->adoptElement(newAr.orphan(), status); if (U_FAILURE(status)) { - goto error; + return; } } // check if this is a final rule @@ -500,50 +505,13 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, } } } - done[i] = TRUE; + done[i] = true; } // Set the results - if (orgRules != NULL) { - while (!orgRules->isEmpty()) { - r = (TimeZoneRule*)orgRules->orphanElementAt(0); - delete r; - } - delete orgRules; - } - if (done != NULL) { - uprv_free(done); - } - - initial = res_initial; - transitionRules = filteredRules; + initial = res_initial.orphan(); + transitionRules = filteredRules.orphan(); return; - -error: - if (orgtrs != NULL) { - uprv_free(orgtrs); - } - if (orgRules != NULL) { - while (!orgRules->isEmpty()) { - r = (TimeZoneRule*)orgRules->orphanElementAt(0); - delete r; - } - delete orgRules; - } - if (done != NULL) { - if (filteredRules != NULL) { - while (!filteredRules->isEmpty()) { - r = (TimeZoneRule*)filteredRules->orphanElementAt(0); - delete r; - } - delete filteredRules; - } - delete res_initial; - uprv_free(done); - } - - initial = NULL; - transitionRules = NULL; } void diff --git a/icu4c/source/i18n/unicode/basictz.h b/icu4c/source/i18n/unicode/basictz.h index 6c94ad3bedb..250ea309279 100644 --- a/icu4c/source/i18n/unicode/basictz.h +++ b/icu4c/source/i18n/unicode/basictz.h @@ -226,8 +226,11 @@ protected: /** * Gets the set of TimeZoneRule instances applicable to the specified time and after. * @param start The start date used for extracting time zone rules - * @param initial Receives the InitialTimeZone, always not NULL - * @param transitionRules Receives the transition rules, could be NULL + * @param initial Output parameter, receives the InitialTimeZone. + * Always not nullptr (except in case of error) + * @param transitionRules Output parameter, a UVector of transition rules. + * May be nullptr, if there are no transition rules. + * The caller owns the returned vector; the UVector owns the rules. * @param status Receives error status code */ void getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, UVector*& transitionRules, diff --git a/icu4c/source/i18n/vtzone.cpp b/icu4c/source/i18n/vtzone.cpp index 35d233968c7..cade6b7d316 100644 --- a/icu4c/source/i18n/vtzone.cpp +++ b/icu4c/source/i18n/vtzone.cpp @@ -1876,10 +1876,7 @@ cleanupWritePartial: delete initial; } if (transitionRules != nullptr) { - while (!transitionRules->isEmpty()) { - TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0); - delete tr; - } + U_ASSERT(transitionRules->hasDeleter()); delete transitionRules; } }